GLSL Additive environment mapping of transparent fragments
Hi,
I'm making my first forays into GLSL and have stumbled across a problem with either my code or expectations of GLSL. I'm simply trying to texture an object with a base texture then to simulate a glossy coating a reflected cube map is added. The base texture has an alpha component and OpenGL has GL_BLEND enabled and glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) setup.
I originally got this working this using combiners which gets the colour of the previous fragment and adds the environment map to it as follows:
// The environment map is modulated with the alpha channel of texture0, then
// added to the previous fragment color.
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_EXT, GL_TEXTURE3_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_EXT, GL_SRC_ALPHA);
But I can't seem replicate this in GLSL because it looks like the alpha component of the base texture is modulating the environement map's intensisty giving a very dark reflection. I'm guessing this is a result of the blending in later stages?
My fragment program is as follows:
varying vec4 col; // gl_Color from vertex shader
varying vec3 norm; // world normal vector
varying vec3 viewVec; // world view vector
uniform sampler2D TexUnit0;
uniform samplerCube CubeMap;
void main(void)
{
vec4 color = col;
// Modulate the vertex colour by the transparent texel colour
vec4 basetexture = texture2D(TexUnit0, gl_TexCoord[0].st);
color *= basetexture;
// Normalize the object space normal and view vector
vec3 normViewVec = normalize(viewVec);
vec3 envNormal = normalize(norm);
// Reflect view vector around the normal
vec3 reflVec = reflect(normViewVec, envNormal);
// Get environment map contribution for this point
vec4 envMapDiffuse = textureCube(CubeMap, -normalize(reflVec).xyz);
// Add the environment map to the transparent colour
color.rgb += envMapDiffuse.rgb;
color = clamp(color, 0.0, 1.0);
gl_FragColor = color;
}
What I need is the environment map to be additive so that even if the base texture is nearly fully transparent (glass) and blended with other polyons, you still get a bright reflection/specular highlight. Is this possible without having to do multiple passes or anything?
Help, please!
Cheers,
Chris.
yes it should be possible (esp if you have done it with GL_COMBINE4_NV)
im not 100% sure what u want
perhaps write in the color + alpha buffer seperatly
eg
gl_FragColor.xyz = color (from textures etc)
gl_FragColor.w = visability
+ then with glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) gl_FragColor.w will control the opaciniss
im not 100% sure what u want
perhaps write in the color + alpha buffer seperatly
eg
gl_FragColor.xyz = color (from textures etc)
gl_FragColor.w = visability
+ then with glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) gl_FragColor.w will control the opaciniss
Hi zedz,
Basically, I want to get rid of the GL_COMBINE4_NV code and replace it with GLSL code as much as possible. To explain it simply, the fragment colour I set in gl_FragColor.rgb is modulated by the opaicity set in gl_FragColor.a, which is fine for the actual basetexture colour because its a property of the material.
However, I don't want the environment/specular reflection to be modulated by the gl_FragColor.a component because it should be ADDED to whatever the final fragement colour is after blending is done. So, adding it to gl_FragColor.rgb isn't working.
The GL_COMBINE4_NV code added the reflection to the PREVIOUS fragment colour but I can't find equivalent functionality in GLSL to make the reflection appear unchanged "on top of" of the final blended result.
I guess what I want is a bit like "seperate specualar" but per-pixel.
Basically, I want to get rid of the GL_COMBINE4_NV code and replace it with GLSL code as much as possible. To explain it simply, the fragment colour I set in gl_FragColor.rgb is modulated by the opaicity set in gl_FragColor.a, which is fine for the actual basetexture colour because its a property of the material.
However, I don't want the environment/specular reflection to be modulated by the gl_FragColor.a component because it should be ADDED to whatever the final fragement colour is after blending is done. So, adding it to gl_FragColor.rgb isn't working.
The GL_COMBINE4_NV code added the reflection to the PREVIOUS fragment colour but I can't find equivalent functionality in GLSL to make the reflection appear unchanged "on top of" of the final blended result.
I guess what I want is a bit like "seperate specualar" but per-pixel.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement