Public Group

# Question about fog based on height

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

## Recommended Posts

I am reading Inigo Quilez http://iquilezles.org/www/articles/fog/fog.htm about fog and I just cant understand few things when he talks about fog based on height.

He has a shader function there but I have problems understanding how to make it work and add that additional fog.

He uses this function to apply fog

vec3 applyFog( in vec3  rgb,       // original color of the pixel
in float distance ) // camera to point distance
{
float fogAmount = 1.0 - exp( -distance*b );
vec3  fogColor  = vec3(0.5,0.6,0.7);
return mix( rgb, fogColor, fogAmount );
}


then he has the other one based on height

vec3 applyFog( in vec3  rgb,      // original color of the pixel
in float distance, // camera to point distance
in vec3  rayOri,   // camera position
in vec3  rayDir )  // camera to point vector
{
float fogAmount = c * exp(-rayOri.y*b) * (1.0-exp( -distance*rayDir.y*b ))/rayDir.y;
vec3  fogColor  = vec3(0.5,0.6,0.7);
return mix( rgb, fogColor, fogAmount );
}


My questions is do i add them because so far i just cant make it work with my shader

#version 400 core

in vec3 Position;
in vec3 Normal;
//in vec4 positionToCamera;
//in float visibility;

uniform vec3 color;
uniform vec3 CameraPosition;
uniform float near;
uniform float far;

uniform vec3 fogColor;
uniform bool enableBlending;

uniform float c;
uniform float b;

uniform int fogType;

vec3 applyFogDepth( vec3  rgb,	// original color of the pixel
float distance,			// camera to point distance
vec3  rayOri,				// camera position
vec3  rayDir)				// camera to point vector
{
//float cc = 1.0;
//float bb = 1.1;
float fogAmount = c * exp(-rayOri.y*b) * (1.0 - exp(-distance*rayDir.y*b)) / rayDir.y;
return mix(rgb,  fogColor,  fogAmount );
}

// Fog with Sun factor
vec3 applyFogSun( vec3  rgb,// original color of the pixel
float distance,		// camera to point distance
vec3  rayDir,			// camera to point vector
vec3  sunDir)			// sun light direction
{
float fogAmount = 1.0 - exp(-distance*b);
float sunAmount = max(dot(rayDir, sunDir), 0.0);

vec3 fog = mix(fogColor, // bluish
vec3(1.0, 0.9, 0.7), // yellowish
pow(sunAmount, 8.0));

return mix(rgb, fog, fogAmount);
}

//Exponential fog
vec3 applyFog( vec3  rgb, // original color of the pixel
float distance)  // camera to point distance
{
float fogAmount = 1.0 - exp(-distance*b);
return mix(rgb, fogColor, fogAmount);
}

float LinearizeDepth(float depth)
{
float z = depth * 2.0 - 1.0; // Back to NDC
return (2.0 * near * far) / (far + near - z * (far - near));
}

out vec4 gl_FragColor;
void main(void) {

vec3 fog = vec3(0.0);
//-5.0f, 900.0f, 400.0f camera coord
vec3 lightPosition = vec3(0.0, 1200.0, -6000.0);
vec3 lightDirection = normalize(lightPosition - Position);
vec3 direction = normalize(CameraPosition - Position);

float depth = LinearizeDepth(gl_FragCoord.z) / far;
switch (fogType) {
case 0:
fog = applyFog(color, depth);
break;
case 1:
fog = applyFogSun(color, depth, direction, lightDirection);
break;
case 2:
//fog = mix(applyFog(color, depth), applyFogDepth(color, depth, CameraPosition, CameraPosition - Position), 0.5)   ;
fog = applyFogDepth(color, depth, CameraPosition, CameraPosition - Position);
break;
}

//calculate light
float diff = max(dot(Normal, lightDirection), 0.0);
vec3 diffuse = diff * color;

float fogAmount = 1.0 - exp(-depth*b);

vec3 finalColor = vec3(0.0);
if (enableBlending)
finalColor = mix(diffuse, fog, fogAmount);
else
finalColor = fog;

gl_FragColor = vec4(finalColor,1.0);
//gl_FragColor = vec4(vec3(LinearizeDepth(visibility) / far), 1.0f);
}


##### Share on other sites

For something visual, it helps if a bit more description is supplied. Perhaps also pictures?

##### Share on other sites

You just need one or the other of those functions. But the real issue is that you are calculating and applying fogAmount twice (once inside the fog function, and once in the main function).

##### Share on other sites

If there is another way to create shader that has more fog at lower parts in mainlans like UE Exponential Height Fog i would be happy to read about it.

So far it has been 3 days that I am trying to fix and figure out how does non constant fog works, and I just cant see a solution so far.

##### Share on other sites

I am sorry for some reason Firefox cashed my page and I thought there was no reply to my post.

Yes, I took fog density out to mix defuse light and fog. There is no other way I know now to do that better. The idea was to calculate fog density, then light from a directional light and at the end just mix those 2 with fog amount. So far it looks good.

The problem is that "applyFogDepth" function does not work. Its fog density function is always 0. Now I dont know if i did something wrong or I am missing something small from the article.

I have changed a bit the shader, now i calculate the fog amount outside of function and I use distance from camera for depth and not Z-buffer. Here it how it looks now.

My camera system is set to X is right, Y is up and Z- is forward

#version 400 core

in vec3 Position;
in vec3 Normal;
in vec4 viewSpace;

uniform vec3 color;
uniform vec3 CameraPosition;
uniform float near;
uniform float far;

uniform vec3 fogColor;
uniform bool enableBlending;

uniform float c;
uniform float b;

uniform int fogType;

vec3 applyFogDepth( vec3  rgb,	// original color of the pixel
float distance,			// camera to point distance
vec3  rayOri,				// camera position
vec3  rayDir)				// camera to point vector
{
float fogAmount = c * exp(-rayOri.y*b) * (1.0 - exp(-distance*rayDir.y*b)) / rayDir.y;
return mix(rgb,  fogColor,  fogAmount );
}

// Fog with Sun factor
vec3 applyFogSun( vec3  rgb,// original color of the pixel
float ammount,		// camera to point distance
vec3  rayDir,			// camera to point vector
vec3  sunDir)			// sun light direction
{
float sunAmount = max(dot(rayDir, sunDir), 0.0);
//these values are from Jeremy Birn's book "Digital Lighting & Rendering"
vec3 sunColor = vec3(0.75, 0.746, 0.675); // sun at noon
//vec3 sunColor = vec3(1.0, 0.9, 0.7); // yellow sun
//vec3 sunColor = vec3(0.71, 0.49, 0.35); // sunrise sunset
vec3 fog = mix(fogColor, // bluish
sunColor, // yellowish
pow(sunAmount, 8.0));

return mix(rgb, fog, ammount);
}

//Exponential fog
vec3 applyFog( vec3  rgb, // original color of the pixel
float ammount)  // camera to point distance
{
return mix(rgb, fogColor, ammount);
}

float LinearizeDepth(float depth)
{
float z = depth * 2.0 - 1.0; // Back to NDC
return (2.0 * near * far) / (far + near - z * (far - near));
}

out vec4 gl_FragColor;
void main(void) {

vec3 fog = vec3(0.0);
//-5.0f, 900.0f, 400.0f camera coord
vec3 lightPosition = vec3(0.0, 1200.0, -6000.0);
//vec3 lightDirection = normalize(lightPosition - Position);
vec3 direction = normalize(CameraPosition - Position);
//float depth = abs(viewSpace.z) / far;

float depth = length(viewSpace) / far;
//float depth = LinearizeDepth(gl_FragCoord.z) / far;
float fogAmount = 1.0 - exp(-depth*b);
switch (fogType) {
case 0:
fog = applyFog(color, fogAmount);
break;
case 1:
fog = applyFogSun(color, fogAmount, direction, normalize(lightPosition));
break;
case 2:
//fog = mix(applyFog(color, depth), applyFogDepth(color, depth, CameraPosition, CameraPosition - Position), 0.5)   ;
fog = (applyFog(color, fogAmount) + applyFogDepth(color, depth, CameraPosition, CameraPosition - Position)) / 2.0;
break;
}

//calculate light
float diff = max(dot(Normal, normalize(lightPosition)), 0.0);
vec3 diffuse = diff * color;

vec3 finalColor = vec3(0.0);
if (enableBlending)
finalColor = mix(diffuse, fog, fogAmount) ;
else
finalColor = fog;

//float tt = t(color, 1.0 - (length(CameraPosition - Position) / far), CameraPosition, CameraPosition - Position);
//vec4 testColor = vec4(vec3(depth ), 1.0);

//gl_FragColor = testColor;
gl_FragColor = vec4(finalColor,1.0);
}

Results look like this



This is the first funciton
[attachment=30758:qst function.JPG]

This is the second function with sun factor added

[attachment=30755:2nd.JPG]

this is the third function. You can see that there is no fog applied to it.

[attachment=30756:3rd.JPG]

and this is again the third function but now with directional light.

[attachment=30757:4rth.JPG]

I am using a low ply mesh to avoid long reading times of OBJ file

1. 1
2. 2
Rutin
16
3. 3
4. 4
5. 5

• 26
• 9
• 11
• 9
• 9
• ### Forum Statistics

• Total Topics
633714
• Total Posts
3013491
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!