View Full Version : cube map problem, please help

05-29-2009, 09:41 PM
I know this is a GLSL question, but the GLSL board seems very dead.

Anyways, I have just recently implemented a whole slew of cool GLSL shaders, like bump-mapping, cel-shading, per-pixel fog, spherical environmental mapping, and multi-texturing :D

I got to cube-mapping, and everything has gone south. There are no projects with source that I can find (please link me if there are any). I have only found two tutorials, one in my GLSL orange book, which was a sham, because the reflection is tied to the camera. The other is from oZone3D.Net. I believe I implemented it correctly, but I just get a solid blue for my reflection :(

Can anybody help, I am dying to get this last effect working :)

05-30-2009, 01:14 AM
Be sure to take in account the view vector in the direction argument of textureCube.

something like :

textureCube(cubetex, reflect(normalize(worldPosition - CameraPosition), worldNormal);

05-30-2009, 07:45 AM
Here is my frag and vertex code. It is straight from ozone3D.net. I am supplying my ModelWorld4x4 with this app code to an object at 0,0,0:

float mat16[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
glUniformMatrix4fv(getUniLoc(cubeMapProgShader, "ModelWorld4x4"), 15, false, mat16);

My CameraPos uniform var is supplied eye coordinates, the same values from the first three arguements in gluLookAt.

Vert Code:

uniform mat4 ModelWorld4x4;
uniform vec3 CameraPos;

mat3 GetLinearPart( mat4 m )
mat3 result;

result[0][0] = m[0][0];
result[0][1] = m[0][1];
result[0][2] = m[0][2];

result[1][0] = m[1][0];
result[1][1] = m[1][1];
result[1][2] = m[1][2];

result[2][0] = m[2][0];
result[2][1] = m[2][1];
result[2][2] = m[2][2];

return result;

void main()
gl_Position = ftransform();

// Color map texture coordinates.
// Increase a little bit the tiling by 2.
gl_TexCoord[0] = gl_MultiTexCoord0 * 2.0;

mat3 ModelWorld3x3 = GetLinearPart( ModelWorld4x4 );

// find world space position.
vec4 WorldPos = ModelWorld4x4 * gl_Vertex;

// find world space normal.
vec3 N = normalize( ModelWorld3x3 * gl_Normal );

// find world space eye vector.
vec3 E = normalize( WorldPos.xyz - CameraPos.xyz );

// calculate the reflection vector in world space.
gl_TexCoord[1].xyz = reflect( E, N );

Frag Code:

uniform samplerCube cubeMap;
uniform sampler2D colorMap;

const float reflect_factor = 0.9;

void main (void)
vec4 output_color;

// Perform a simple 2D texture look up.
vec3 base_color = texture2D(colorMap, gl_TexCoord[0].xy).rgb;

// Perform a cube map look up.
vec3 cube_color = textureCube(cubeMap, gl_TexCoord[1].xyz).rgb;

// Write the final pixel.
gl_FragColor = vec4( mix(base_color, cube_color, reflect_factor), 1.0);

05-30-2009, 06:36 PM
I have been trying to get cube mapping to work forever now. Can anybody help? I would kill for some sample programs... :(

No matter what I try, the camera is always locked with the reflection :(

05-31-2009, 12:36 AM
Bluebomber357, a very similar problem was mentionned solved here : http://www.ogre3d.org/forums/viewtopic.php?p=205631&sid=ce193664e1d3d7c4af509e6f4e2718c6

05-31-2009, 06:42 AM
ZBufferR, I've seen that thread before. It seems to use Ogre3D specific code for the solution, am I right?

I am still stuck on this problem, more help please :)

05-31-2009, 07:23 AM
You mean the "param_named_auto worldMatrix world_matrix" ? It seems he just passes the world matrix to the program.

You should start again with the orange book one.
Then add the camera world matrix position as well as object world matrix, and use that in the reflection vector calculation:

vec4 ecCamPos = worldMatrix * camPos;
vec3 ecCamPos3 = ecCamPos.xyz / ecCamPos.w;
vec3 i = normalize(ecPosition3 - ecCamPos3);
refvector = reflect(i, n);

Sorry I can't help more.

05-31-2009, 08:22 AM
I am still confused on how to implement it correctly, has nobody done cube-mapping in GLSL before? I feel like it is one of those effects that should have a hundred examples on the web :(

Ilian Dinev
05-31-2009, 09:43 AM
From DXSDK, HDRCubeMap sample:

void HDRVertEnvMap( float4 Pos : POSITION,
float3 Normal : NORMAL,
out float4 oPos : POSITION,
out float3 EnvTex : TEXCOORD0 )
oPos = mul( Pos, g_mWorldView );

// Compute normal in camera space
float3 vN = mul( Normal, g_mWorldView );
vN = normalize( vN );

// Obtain the reverse eye vector
float3 vEyeR = -normalize( oPos );

// Compute the reflection vector
float3 vRef = 2 * dot( vEyeR, vN ) * vN - vEyeR;

// Store the reflection vector in texcoord0
EnvTex = vRef;

// Apply the projection
oPos = mul( oPos, g_mProj );

// Pixel Shader: HDRPixEnvMap
// Desc: Process pixel for HDR environment mapped object
float4 HDRPixEnvMap( float3 Tex : TEXCOORD0 ) : COLOR
return g_fReflectivity * texCUBE( g_samCubeMap, Tex );

I usually study shader techniques from DX samples. It's just that matrix multiplication order is reverse, and texel centrinos...

05-31-2009, 09:53 AM
I am not an expert at GLSL yet, so converting DX code to GLSL isn't going to help much for me, thanks though. I am still searching the internet for good source code to study from.

Here is the only friggin GLSL cubemapping code with full source (includes application code) on the entire internet that I have found in 5 hours of searching. Amazing, I have only found one! http://tfc.duke.free.fr/screens/envmap.png

This code in Linux, and I couldn't get it to run in visual studio, but I copied the relevant code into my "shader testing program", which is just the brick shader program from 3Dshaders.com. I still have the same problem though of the camera following the reflection.

05-31-2009, 02:09 PM
I played quickly with this new example, and indeed, there is something special done to the texcoords.

Removing the texmat multiplication done below in the vert shader indeed prevents the reflection from following the camera rotation :
// Transform the reflection vector by texture matrix
// in order to orient the reflected image
gl_TexCoord[0] = gl_TextureMatrix[0] * vec4 (R, 1.0);

In the main.c source code, the following sets up the texturematrix with inverse modelview matrix. This is probably the part missing from your shader testing program :

/* Compute inverse of modelview matrix */
glGetFloatv (GL_MODELVIEW_MATRIX, mat);
compute_matrix_inverse (mat, invmat);

/* Setup texture transformation for orientation
of the reflected cube map */
glMatrixMode (GL_TEXTURE);
/* Zero out translation portion */
invmat[12] = 0.0f;
invmat[13] = 0.0f;
invmat[14] = 0.0f;
invmat[15] = 1.0f;
glLoadMatrixf (invmat);

It looks a bit convoluted to me, there _has_ to be something more straightforward.
But at least this works.

05-31-2009, 05:17 PM
I deleted "gl_TextureMatrix[0] *" from my vertex shader, but no change. I always had that invmat[] code in the correct spot I believe.

You said you played with the example, and got it to work? By chance were you using Visual Studio? Either way could you post your code files?

I feel like I am close to getting this right, I am probably just making some noob error in one or two lines, blocking the effect from working correctly :) BTW, sorry for not replying quicker, I appreciate your continued support, I am really excited about getting this to work and I'll be checking this thread for updates reguarly :)

06-01-2009, 01:29 AM
I deleted "gl_TextureMatrix[0] *" from my vertex shader, but no change. I always had that invmat[] code in the correct spot I believe.
Not sure I made myself clear : this texture matrix multiplication is _needed_ for the reflection to be correct when the camera rotates.

Use the precompiled win32 binary of the envmap sample, and simply edit the 'envmap.vert' : with this multiplication, the reflection is correct, and without, it is not correct.
You can check this without needing recompilation.

On my side I used Ubuntu 8.04, so I just typed 'make' on the command line and it compiled out of the box.

It only needs glut, glu, and glew.

If you really can't build it with VS, try codeblocks and/or MinGW :

06-01-2009, 06:24 AM
Okay, I am glad to hear that the code does work. I found a couple other examples of cube mapping that were literally broken and very depressing considering how few examples are out there with full source. Example, http://www.pixeltangent.com/, they have one towards the top that utterly fails :(

Unfortunately I have to go to class, I'll try and get this working ASAP. The problem must be right under my nose. Besides the inverse matrix code section, are there any other important parts that I could possibly be missing? This code from http://tfc.duke.free.fr/ is wonderful in that it shows three methods in one program, but I think I am messing up because of it. I'll post about my progress after classes if I got it or not.

06-01-2009, 02:37 PM
I am still stuck, I looked very carefully at the code from http://tfc.duke.free.fr/, but I just can't figure out what is wrong with my code. Can you look at my main.c? I don't think anything could be wrong in the shaders.c file or any other files.

I understand if you don't want to analyze my code. If so, could you modify the original program so there isn't any unnecessary code for classical or ARB cube-mapping? I could post my etnire VS2008 project? Let me know what you think, I am just dying to figure out what is screwing me up :(

Here is my main.c if you want to look at it: http://www.freewebs.com/bluebomber357/ogl2brick.cpp

06-03-2009, 12:23 PM
Anybody? I still want to get cubemapping to work. Any help is greatly appreciated :)

06-05-2009, 07:18 AM
Bump, please help if you can :)