Jump to content
  • Advertisement
Sign in to follow this  
Arith

[solved] GLSL Fog

This topic is 3018 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

So, I'm writing a random terrain generator and I'm at the stage where I'm playing around with shaders. I've been trying for over a week to get fog to coexist with my lighting shader with very little to show for it. I've read leagues upon leagues of sites on the subject, including a few on this wonderful site to no avail. I've even found an excerpt from the orange book.. alas nothing. I'm very new to GLSL, and it's clear I need some individualized help. The shaders below amount to this; http://i138.photobucket.com/albums/q257/Serojin/mountains1.jpg Vertex Shader
varying vec3 lightDir,normal;
void main()
{
	normal = normalize(gl_NormalMatrix * gl_Normal);
	lightDir = normalize(vec3(gl_LightSource[0].position));
	gl_TexCoord[0] = gl_MultiTexCoord0;
	gl_Position = ftransform();
}


Fragment Shader
varying vec3 lightDir,normal;
uniform sampler2D tex;
void main()
{
	vec3 ct,cf;
	vec4 texel;
	vec3 color;
	float intensity,at,af;
	intensity = max(dot(lightDir,normalize(normal)),0.0);
	color = vec3(intensity/0.7,intensity/0.7,intensity/0.7);
	cf = intensity * (gl_FrontMaterial.diffuse).rgb; 
	af = gl_FrontMaterial.diffuse.a;
	texel = texture2D(tex, gl_TexCoord[0].st);
	ct = texel.rgb * color;
	at = texel.a;
	gl_FragColor = vec4(ct * cf, at * af);	
}


I've taken out everything having to do with fog in those shaders just to have a clean slate so to speak. All the sources I've come across gives me a good idea of the theory behind what to do, I just can't seem to get the actual implementation down. At this point in the project I'm only dealing with one texture and one light. Though, as a side question, if anyone has a really clear cut tutorial on multitexturing with glsl I'd love to see it. If anyone can help me out it would be greatly appreciated. [Edited by - Arith on March 20, 2010 4:21:21 PM]

Share this post


Link to post
Share on other sites
Advertisement
I use my own lighting (phong lighting and shading) and for fog, I do linear fog.
This is for 1 point light.


[VERTEX SHADER]

#version 110

//UNIFORM
uniform mat4 ProjectionModelviewMatrix;
uniform vec4 TexMatrix0_a;
uniform vec4 TexMatrix0_b;
uniform vec4 LightPosition0;
uniform mat4 ModelviewMatrix;

//VARYING
varying vec2 TexCoord0;
varying vec4 LightVector0; //xyz is lightvector and w is light distance from vertex
varying vec3 HalfVector0;
varying vec4 EyeNormal; //w is also FragmentDistance that we use in the fs


//GLOBALFUNCTION


void main()
{
vec3 eyeVertex;
vec3 lightVector, eyeVector;
float mysqrtdistance;


gl_Position = ProjectionModelviewMatrix * gl_Vertex;
TexCoord0.x = dot(TexMatrix0_a, gl_MultiTexCoord0);
TexCoord0.y = dot(TexMatrix0_b, gl_MultiTexCoord0);

eyeVertex = vec3(ModelviewMatrix * gl_Vertex);
EyeNormal.w = length(eyeVertex);
eyeVector = normalize(-eyeVertex);
lightVector = normalize(LightPosition0.xyz - eyeVertex);
LightVector0.xyz = lightVector;
mysqrtdistance = sqrt(distance(LightPosition0.xyz, eyeVertex));
LightVector0.w = mysqrtdistance * sqrt(mysqrtdistance);
HalfVector0 = lightVector + eyeVector; //No need to normalize the sum

EyeNormal.xyz = vec3(ModelviewMatrix * vec4(gl_Normal, 0.0));
}



[FRAGMENT SHADER]

#version 110

//UNIFORM
uniform sampler2D Texture0;
uniform vec4 AllLightAmbient_MaterialAmbient;
uniform vec4 LightMaterialDiffuse0;
uniform vec4 LightMaterialSpecular0;
uniform float MaterialShininess;
uniform float Light0LinearAttenuation0;
uniform vec4 FogColor; //FogColor. If w is 1.0, it means we don't want fogging. If 0.0, we want fogging enabled.
uniform float FogDensity; //FogDensity


//VARYING
varying vec2 TexCoord0;
varying vec4 LightVector0; //xyz is lightvector and w is light distance from vertex
varying vec3 HalfVector0;
varying vec4 EyeNormal; //w is also FragmentDistance that we use in the fs


//GLOBALFUNCTION

//eyeNormal must be normalized already
//lightVector must be normalized already. xyz is lightvector and w is light distance from vertex
//halfVector must be normalized already
//
//output diffuse color and output specular color
//Then do diffuse * texture_color + specular
//diffuse.a = material_diffuse.a
void ComputePointLight(out vec4 diffuseColor, out vec4 specularColor, in vec3 eyeNormal, in vec4 lightVector, in vec3 halfVector, in vec4 lightMaterialDiffuse, in vec4 lightMaterialSpecular, in float light0LinearAttenuation0)
{
float dotProduct;
float atten;

atten = 1.0 / (light0LinearAttenuation0 * lightVector.w);

dotProduct = clamp(dot(eyeNormal, lightVector.xyz), 0.0, 1.0);
diffuseColor = dotProduct * lightMaterialDiffuse * atten;

specularColor = vec4(0.0);
dotProduct = clamp(dot(eyeNormal, halfVector), 0.0, 1.0);
if(dotProduct>0.0)
specularColor = pow(dotProduct, MaterialShininess) * lightMaterialSpecular * atten;
}

void main()
{
vec4 texel, diffuseColor, specularColor;
vec4 ColorSum;
vec3 eyeNormal, halfVector;
vec4 lightVector;
float fogFactor;

texel = texture2D(Texture0, TexCoord0);

eyeNormal = normalize(EyeNormal.xyz);
lightVector.xyz = normalize(LightVector0.xyz);
lightVector.w = LightVector0.w;
halfVector = normalize(HalfVector0);


ComputePointLight(diffuseColor, specularColor, eyeNormal, lightVector, halfVector, LightMaterialDiffuse0, LightMaterialSpecular0, Light0LinearAttenuation0);
ColorSum = (AllLightAmbient_MaterialAmbient + diffuseColor) * texel + specularColor;

fogFactor = max(FogColor.a, exp(-(FogDensity * EyeNormal.w)));
ColorSum = mix(FogColor, ColorSum, fogFactor);

ColorSum.a = texel.a * LightMaterialDiffuse0.a;

gl_FragColor = clamp(ColorSum, 0.0, 1.0);
}

Share this post


Link to post
Share on other sites
Alright, so I achieved what I wanted. A friend, Zhasha showed me a good way to do what I was ultimately trying to do (which was blend that hard edge at the vanishing point -- see the first picture I posted) So, thanks to his help here is the result (the camera is elevated to show more of the blending)
http://i138.photobucket.com/albums/q257/Serojin/fog.jpg

And here are the new shaders. I realize they aren't gold, indeed I'm still learning and playing around with things. It does what I want;

Vertex Shader

varying vec3 lightDir,normal;
varying vec4 pt;

void main()
{
normal = normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(vec3(gl_LightSource[0].position));
gl_TexCoord[0] = gl_MultiTexCoord0;
pt = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = pt;
gl_FrontColor = gl_Color;
}



Fragment Shader

varying vec3 lightDir,normal;
uniform sampler2D tex;

const float far = 5000.0;
const float margin = far - (far/2.0);
varying vec4 pt;

void main()
{


vec3 ct,cf;
vec4 texel;
vec3 color;
float intensity,at,af;

float alpha = 1.0;
if (pt.z > margin) alpha = 1.0 - ((pt.z-margin)/(far-margin));



float bright = 0.35;
intensity = max(dot(lightDir,normalize(normal)),0.0);
color = vec3(intensity/bright,intensity/bright,intensity/bright);
cf = intensity * (gl_FrontMaterial.diffuse).rgb;
af = gl_FrontMaterial.diffuse.a;
texel = texture2D(tex, gl_TexCoord[0].st);
ct = texel.rgb * color;
at = texel.a;
gl_FragColor = vec4(ct * cf, at * af) * alpha;
}



Thanks V-Man for your input, unfortunately it was a bit over my head. Still learning the basics of GLSL while playing with working code -- fun times. Thanks again

Arith

Share this post


Link to post
Share on other sites
It's pretty simple for fog alone. It is these 2 lines that do the job in the FS
fogFactor = max(FogColor.a, exp(-(FogDensity * EyeNormal.w)));
ColorSum = mix(FogColor, ColorSum, fogFactor);

plus 1 or 2 lines in the VS.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!