Jump to content
  • Advertisement
Sign in to follow this  
1A2S3D

Fog Shader

This topic is 838 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello guys!

I'm quite new to OpenGL and I am trying to visualize a Mobile with spheres, squares, triangles, and so on. I have also made some light sources and moving animations.
Also rotating the camera is possible.
But now I'm quite stuck creating some fog.

I've figured out that standard GL_FOG is not working when using vertex and fragment shaders.

So now I want to ask you if you can help me creating such shaders.

BTW here are my shaders:

 

fragmentshader:

#version 330 core
 
in vec4 vColor;
in float FogFragCoord;
out vec4 FragColor;
in vec2 UVcoords;
uniform sampler2D myTexture1Sampler;
uniform vec3 camera;
 
void main()
{
    float fog;
    vec4 color;
    
    color = texture2D(myTexture1Sampler, UVcoords) * vColor;

    fog = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale;

    FragColor = mix(gl_Fog.color,color, fog);
}

 

vertexshader:

#version 330 core

uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ModelMatrix;
uniform vec3 LightPosition1;
uniform vec3 LightPosition2;
uniform vec3 LightColor1;
uniform vec3 LightColor2;
uniform float DiffuseFactor;
uniform float SpecularFactor;
uniform float AmbientFactor;

layout (location = 0) in vec3 Position; //this somehow is effecting from the glVertexAttribPointer index
layout (location = 1) in vec3 Color;
layout (location = 2) in vec3 Normal;

//texturing
layout (location = 3) in vec2 UV;

out vec2 UVcoords;

out vec4 vColor;

void main()
{
    gl_FogFragCoord = gl_Position.z;

    mat4 normalMatrix = transpose(inverse(ViewMatrix * ModelMatrix));
    vec3 normal = normalize((normalMatrix * vec4(normalize(Normal), 1.0)).xyz);

    vec3 lightPosition1 = (ViewMatrix * vec4(LightPosition1, 1.0)).xyz;
    vec3 lightPosition2 = (ViewMatrix * vec4(LightPosition2, 1.0)).xyz;
    vec4 vertexPositionModelSpace = (ViewMatrix * ModelMatrix) * vec4(Position,1.0);
    vec3 vertexNormalized = normalize(-vertexPositionModelSpace.xyz);
    
    vec3 lightVector1 = normalize(lightPosition1 - vertexPositionModelSpace.xyz);
    vec3 lightVector2 = normalize(lightPosition2 - vertexPositionModelSpace.xyz);
    vec3 halfVector1 = normalize(lightVector1 + vertexNormalized);
    vec3 halfVector2 = normalize(lightVector2 + vertexNormalized);   
    
    vec3 diffusePart = (clamp(dot(normal,lightVector1), 0.0, 1.0)*LightColor1 + clamp(dot(normal,lightVector2), 0.0, 1.0)*LightColor2);
    vec3 specularPart = (pow(clamp(dot(normal,halfVector1),0.0,1.0),127.0 )*LightColor1 + pow(clamp(dot(normal,halfVector2),0.0,1.0 ),127.0)*LightColor2);
    vec3 ambientPart = vec3(Color * AmbientFactor);
    diffusePart *= vec3(DiffuseFactor);
    specularPart *= vec3(SpecularFactor);
    
    
    vColor = vec4(Color*diffusePart + specularPart + ambientPart, 1.0);
    gl_Position = ProjectionMatrix*ViewMatrix*ModelMatrix*vec4(Position.x, Position.y, Position.z, 1.0);
    UVcoords = UV;

    gl_FogFragCoord = gl_Position.z;
}

 

 

The only thing working for me now is that the whole view is foggy and completely grey.

 

I hope you can help me.

 

Thanks in advance!

Edited by 1A2S3D

Share this post


Link to post
Share on other sites
Advertisement

If you would like to do linear fog, you need something along the lines of

float linear_fog_factor(vec3 worldPos, vec3 camWorldPos, float fogNear, float fogFar)
{
	vec3 dVec = (camWorldPos - worldPos);
	float factor = (fogFar - length(dVec) ) / (fogFar - fogNear);
	factor = clamp(factor, 0.0, 1.0);
	return factor;
}

where worldPos is the interpolated world position of the fragment being rendered, camWorldPos is the world position of the camera the scene is being rendered from, fogNear is the depth where the fog should begin (in world space units), and fogFar is the depth where the fog should end.

 

For blending the fog with the final fog fragment I use something like

final_col = mix(fdat.color * light_factor, fog_color, 1 - fog_factor);

where fdat.color is a 3d vector with the color of the fragment before applying lighting, light_factor is a 3d vector calculated based on the scene lighting, fog_color is a 3d vector with the color of the fog, and fog_factor is the value returned by the previous function.

 

Note that doing fog in this manner can be tricky because you are only "fogging" your geometry and not the background itself. If you have a solid color background, you can make the fog color the same as the background. But if you have a 2d texture or skybox or something it is a bit trickier to make the fog look right.

 

This is a good starting point though. You can work other things out yourself.

 

EDIT: By the way - please use code tags around source code snippets. It looks much prettier.

Edited by EarthBanana

Share this post


Link to post
Share on other sites

The truth for fog is simple calculations.

What GL_Fog does in the old versino of openGL is using a given formula to calculate the result color.

This was done via changing the parameters and the formula itself, they used 4 methods to calculate the fog.

However, with shaders you do the calculations by yourself.

This article explains the common equations (Linear, exponential and exponential^2):

 

https://msdn.microsoft.com/en-us/library/windows/desktop/bb173401(v=vs.85).aspx

 

Calculate the result and blend it with the result from texture and lighting. 

Minor tweaks could be done to achieve good results.

Edited by WoopsASword

Share this post


Link to post
Share on other sites

You can also use the depth buffer to create a cheap screen-space fog. This is actually how GL_FOG works by default, and it's not that hard to implement in the pipeline.

Edited by Tangletail

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!