I was trying to implement GLSL per-pixel fog in my game engine. However, there is a problem. When I enable linear or exp2 fog, the whole scene goes black, and when I implement exp fog, nothing happens to the scene.
Here is the fragment shader code:
[source lang="cpp"]
#define FOG_OFF 0
#define FOG_LINEAR 1
#define FOG_EXP 2
#define FOG_EXP2 3
/* clipping plane (used here) */
uniform float clip_near;
uniform float clip_far;
/* texture */
uniform sampler2D tex;
uniform int use_texture;
/* fog */
uniform int fog_type;
uniform float fog_start;
uniform float fog_end;
uniform float fog_density;
uniform float fog_red;
uniform float fog_green;
uniform float fog_blue;
void main()
{
vec4 texel = texture2D(tex, gl_TexCoord[0].st);
vec4 color = gl_Color;
if (use_texture == 1)
{
color *= texel;
};
float fog_factor = 1.0;
vec4 fog_color = vec4(fog_red, fog_green, fog_blue, 1.0);
float z = gl_FragCoord.z / gl_FragCoord.w;
//float z = 1.0 - (gl_FragCoord.z / gl_FragCoord.w) / clip_far;
if (fog_type == FOG_LINEAR)
{
fog_factor = (fog_end-z)/(fog_end-fog_start);
};
if (fog_type == FOG_EXP)
{
fog_factor = exp(-(fog_density - z));
};
if (fog_type == FOG_EXP2)
{
fog_factor = exp2((-(fog_density - z))*(-(fog_density - z)));
};
fog_factor = clamp(fog_factor, 0.0, 1.0);
float alpha;
alpha = color[3];
color = mix(fog_color, color, fog_factor);
color[3] = alpha;
gl_FragColor = color;
}
[/source]
Here is the C code for setting fog parameters (it also sets up the OpenGL pipeline fog, for complicated reasons that I don't need to mention):
[source lang="cpp"]
void meEnableLinearFog(double start, double end, double density, MEVECTOR color)
{
fog_on = 1;
glFogf(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, (float)start);
glFogf(GL_FOG_END, (float)end);
glFogf(GL_FOG_DENSITY, (float)density);
float col[4];
col[0] = color.x;
col[1] = color.y;
col[2] = color.z;
col[3] = 1.0;
glFogfv(GL_FOG_COLOR, &col[0]);
me_shader_variablef("fog_start", (float)start);
me_shader_variablef("fog_end", (float)end);
me_shader_variablef("fog_density", (float)density);
me_shader_variablef("fog_red", (float)color.x);
me_shader_variablef("fog_green", (float)color.y);
me_shader_variablef("fog_blue", (float)color.z);
};
void meEnableExpFog(double start, double end, double density, MEVECTOR color)
{
fog_on = 2;
glFogf(GL_FOG_MODE, GL_EXP);
glFogf(GL_FOG_START, (float)start);
glFogf(GL_FOG_END, (float)end);
glFogf(GL_FOG_DENSITY, (float)density);
float col[4];
col[0] = color.x;
col[1] = color.y;
col[2] = color.z;
col[3] = 1.0;
glFogfv(GL_FOG_COLOR, &col[0]);
me_shader_variablef("fog_start", (float)start);
me_shader_variablef("fog_end", (float)end);
me_shader_variablef("fog_density", (float)density);
me_shader_variablef("fog_red", (float)color.x);
me_shader_variablef("fog_green", (float)color.y);
me_shader_variablef("fog_blue", (float)color.z);
};
void meEnableSquareFog(double start, double end, double density, MEVECTOR color)
{
fog_on = 3;
glFogf(GL_FOG_MODE, GL_EXP2);
glFogf(GL_FOG_START, (float)start);
glFogf(GL_FOG_END, (float)end);
glFogf(GL_FOG_DENSITY, (float)density);
float col[4];
col[0] = color.x;
col[1] = color.y;
col[2] = color.z;
col[3] = 1.0;
glFogfv(GL_FOG_COLOR, &col[0]);
me_shader_variablef("fog_start", (float)start);
me_shader_variablef("fog_end", (float)end);
me_shader_variablef("fog_density", (float)density);
me_shader_variablef("fog_red", (float)color.x);
me_shader_variablef("fog_green", (float)color.y);
me_shader_variablef("fog_blue", (float)color.z);
};
[/source]
The shader variable functions are as follows:
[source lang="cpp"]
void me_shader_variablei(const char *name, int value)
{
int location;
#ifdef ARB_SHADER
location = glGetUniformLocationARB(me_shader_program, name);
glUniform1iARB(location, value);
#else
location = glGetUniformLocation(me_shader_program, name);
glUniform1i(location, value);
#endif
};
void me_shader_variabled(const char *name, double value)
{
int location;
#ifdef ARB_SHADER
location = glGetUniformLocationARB(me_shader_program, name);
glUniform1dARB(location, value);
#else
location = glGetUniformLocation(me_shader_program, name);
glUniform1d(location, value);
#endif
};
void me_shader_variablef(const char *name, float value)
{
int location;
#ifdef ARB_SHADER
location = glGetUniformLocationARB(me_shader_program, name);
glUniform1fARB(location, value);
#else
location = glGetUniformLocation(me_shader_program, name);
glUniform1f(location, value);
#endif
};
[/source]
The code is compiled without the ARB_SHADER macro, so it uses the standard functions.
I'm sorry for posting so much code, but I really don't know where to start looking for the problem. I am very new to shaders.
Does anyone know what could be wrong? Thanks.
EDIT: Just fixed the equation error, I updated the code. Now when I enable the exp fog the whole scene turns black again.
Hello Madd,
1. Why are you doing glFog<..> calls if you don't use "gl_Fog" structure in your fragment shader?
BUILD-IN UNIFORM:
2. (checked only your linear fog): In glFog<...> parameters (start,end) are in view space, while in your shader, looks like, screen space.
3. "mix" function description:
float mix (float x, float y, float a)
vec2 mix (vec2 x, vec2 y, float a)
vec3 mix (vec3 x, vec3 y, float a)
vec4 mix (vec4 x, vec4 y, float a)
vec2 mix (vec2 x, vec2 y, vec2 a)
vec3 mix (vec3 x, vec3 y, vec3 a)
vec4 mix (vec4 x, vec4 y, vec4 a)
Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of vectors x and y using the vector a. The value for a is not restricted to the range [0,1].
In this case, you will receive inverse of expecting result (flip "fog_color"<->"color")...
4. gl_FragCoord.z is already divided to gl_FragCoord.w by OpenGL and clamped to [0,0 .. 1.0] (glDepthRange parameters)...
Hope, this helps you...
Best wishes, FXACE.
1. Why are you doing glFog<..> calls if you don't use "gl_Fog" structure in your fragment shader?
BUILD-IN UNIFORM:
//
// Fog
//
struct gl_FogParameters
{
vec4 color;
float density;
float start;
float end;
float scale; // 1.0 / (gl_Fog.end - gl_Fog.start)
};
uniform gl_FogParameters gl_Fog;
2. (checked only your linear fog): In glFog<...> parameters (start,end) are in view space, while in your shader, looks like, screen space.
3. "mix" function description:
float mix (float x, float y, float a)
vec2 mix (vec2 x, vec2 y, float a)
vec3 mix (vec3 x, vec3 y, float a)
vec4 mix (vec4 x, vec4 y, float a)
vec2 mix (vec2 x, vec2 y, vec2 a)
vec3 mix (vec3 x, vec3 y, vec3 a)
vec4 mix (vec4 x, vec4 y, vec4 a)
Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of vectors x and y using the vector a. The value for a is not restricted to the range [0,1].
In this case, you will receive inverse of expecting result (flip "fog_color"<->"color")...
4. gl_FragCoord.z is already divided to gl_FragCoord.w by OpenGL and clamped to [0,0 .. 1.0] (glDepthRange parameters)...
Hope, this helps you...
Best wishes, FXACE.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement