PDA

View Full Version : Adding reflection to transparent fragments (GLSL)



Chris Weaver
02-24-2008, 04:52 AM
Hi,

I'm texturing a semi-transparent object with a base texture then adding a reflection from a cube map. The base texture has an alpha component and OpenGL has glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) setup. I need the reflection to be independant from the base textures transparency so that even if the alpha channel is 100% transparent the environment reflection is still ADDED with its full brightness (not modulated by the base texture).

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:

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'm now moving to GLSL to add bump mapping and can't seem to replicate this. The alpha component of the base texture is modulating the environement map's intensisty giving a very dark reflection. It looks like it needs something like "seperate specular" but for per pixel environment mapping.

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.rgb = color.rgb;
gl_FragColor.a = basetexture.a;
}

Is this possible without having to do multiple passes to add the environment maps contribution? Can the GL_COMBINE4_NV code be replicated in GLSL by getting the previous colour (GL_PREVIOUS_EXT)?

Thanks,
Chris.

Komat
02-24-2008, 11:28 AM
One thing you can do is to use glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) blending mode and calculate the fragment color as


gl_FragColor.rgb = ( col.rgb * base_texture.rgb ) * base_texture.a + envMapDiffuse.rgb ;