Sign in to follow this  

[GLSL] NormalMap and CubeMap

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

Hello, I'm having a problem wich I can't seem to solve;

Purpose is a simplistic water shader wich reflect the enviroment from a CubeMap with offset from a NormalMap, no lightning.

The reflection of the enviroment is working as long I'm using a static tangent-spaced-normal, eg ( 0.5, 0.5, 1.0)
But when I retrieve the normals from the NormalMap then I have no enviroment, I only see the glClearColor in the water plane.
To eliminate possible errors I have fully filled the NormalMap with a default up-vector in tangent space, eg ( 0.5, 0.5, 1.0 )
However, there still seems the be a diffrence when using a static-vector (CASE1) and using the texture-based-vector (CASE2) in the fragment shader.

Fragment Shader :

uniform sampler2D TexNormal;
uniform samplerCube TexSkyBox;

varying vec3 E;

void main(void) {

/* CASE 1 : default */
vec3 mat_normal = vec3( 0.5, 0.5, 1.0 );

/* CASE 2 : normal-map, flooded with rgb( 0.5, 0.5, 1.0 ) */
mat_normal = texture2D( TexNormal, gl_TexCoord[0].xy ).rgb;

/* ////////////////////////////////////// */

/* 0/1 range to -1/1 */
vec3 N = normalize( mat_normal * 2.0 - 1.0 );

/* Test Check for N : wich results in BOTH CASES as full blue color, rgb(0,0,1) */
/* gl_FragColor = vec4( N, 1.0 ); */

/* ////////////////////////////////////// */

/* get color from cubemap, only works using CASE 1 */
vec3 mat_skybox = textureCube( TexSkyBox, reflect(E,N).xyz ).rgb;
gl_FragColor = vec4( mat_skybox, 1.0 );

}





Vertex Shader :

varying vec3 E;

void main(void) {

vec3 t = gl_NormalMatrix * vec3(1,0,0); /* tangent */
vec3 b = gl_NormalMatrix * vec3(0,1,0); /* bitangent */
vec3 n = gl_NormalMatrix * vec3(0,0,1); /* normal */

vec3 V = vec3( gl_ModelViewMatrix * gl_Vertex );
E.x = dot( V, t );
E.y = dot( V, b );
E.z = dot( V, n );

gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0; /* normalmap */

}



Share this post


Link to post
Share on other sites
Is your question simply related to normal lookups from the texture?

If you say that you get different results when using a constant vec3 of (0.5,0.5,1.0) versus a texture where all texels have that value, then you can throw out all the rest of your code and focus purely on the texture sampling, as you must be doing something wrong.

Have you considered a debugging shader like the following?


void main(void) {

vec3 a = vec3( 0.5, 0.5, 1.0 );
vec3 b = texture2D( TexNormal, gl_TexCoord[0].xy ).rgb;

gl_FragColor = vec4( abs(a-b) , 1.0 );

}




If your texture is correct the output should be completely black, otherwise you should see something that can help you figure out what is wrong with your texture.

Share this post


Link to post
Share on other sites
Well anytime a texture map lookup fails to produce the color you put in, its probably not bound. Make sure to use glUniform to send the uniform value (in your application). Make sure you are binding the texture correctly glActiveTexture(..texture1).

Share this post


Link to post
Share on other sites
@ karwosts :

Yes, that's why I added in the fragment shader above the following line to see if the texturemap is working and getting passed trough:
/* Test Check for N : ... */
/* gl_FragColor = vec4( N, 1.0 ); */

I'll try your debug approach this evening when I'm back home, update follows.

Also I've tried to render the NormalMap as diffuse color to see if texcoords are correct, wich they were.
gl_FragColor = vec4( texture2D( TexNormal, gl_TexCoord[0].xy ).rgb , 1.0 );


@ dpadam450 :
Yes, all 'should' be correct, but I will add the setup and render functions a soon a I'm back online.

Share this post


Link to post
Share on other sites
@ karwosts : Did what you advised and the water plane is completely black (Fig.1)

Here is the render function followed with 3 diffrent shaders,
all 3 using same render function below, use the reference image at the end of this post to see the result foreach shader version.
( also note that printing the infolog after compiling the shader shows no errors )

Render Function :
void render_main(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt( ex,ey,ez, tx,ty,tz, 0.0f,1.0f,0.0f );
shader_water.render();
SDL_GL_SwapBuffers();
}

void rcShaderObject_Water::render(){
if(!this->bLoaded){ return; } /* lame exit */

/* various states */
glDisable( GL_DEPTH_TEST );
glDisable( GL_LIGHT0 );
glDisable( GL_LIGHTING );
glColor3f( 1.0f, 1.0f, 1.0f );

/* enable custom shader */
glUseProgramObjectARB( this->shader_prog );

/* enable and bind texture(s) : */
/* normap map */
glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, this->TEXID_NORMAL );
/* cube map */
glActiveTextureARB( GL_TEXTURE1_ARB );
glEnable( GL_TEXTURE_CUBE_MAP_ARB );
glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, this->TEXID_CUBE );

/* uniform(s) for fragment shader : */
glUniform1iARB( this->locTexNormal, 0 );
glUniform1iARB( this->locTexCube, 1 );

/* enable states */
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY ); /* absolute ? */
glEnableClientState( GL_TEXTURE_COORD_ARRAY );

/* arrays for vertices, normals and texcoords */
glVertexPointer( 3, GL_FLOAT, 0, MyMngrMsh.mesh[ this->MSHID_WATER ]->arr_v );
glNormalPointer( GL_FLOAT, 0, MyMngrMsh.mesh[ this->MSHID_WATER ]->arr_n ); /* absolute ? */
glTexCoordPointer( 2, GL_FLOAT, 0, MyMngrMsh.mesh[ this->MSHID_WATER ]->arr_t );
/* draw */
glDrawArrays( GL_TRIANGLES, 0, MyMngrMsh.mesh[ this->MSHID_WATER ]->tri_qty*3 );

/* disable states */
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY ); /* absolute ? */
glDisableClientState( GL_VERTEX_ARRAY );

/* disable texture(s) : */
/* cube map */
glActiveTextureARB( GL_TEXTURE1_ARB );
glDisable( GL_TEXTURE_CUBE_MAP_ARB );
/* normal map */
glActiveTextureARB( GL_TEXTURE0_ARB );
glDisable( GL_TEXTURE_2D );

/* restore to opengl default shader */
glUseProgramObjectARB( 0 );

/* various states */
glEnable( GL_DEPTH_TEST );
glEnable( GL_LIGHT0 );
glEnable( GL_LIGHTING );

}


Shader Version 1 :
Check the texcoords for normal-map, see Fig.2 in reference image, shows correct.
/* vertex shader */
void main(void) {
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
}

/* fragment shader */
uniform sampler2D TexNormal;
uniform samplerCube TexSkyBox; /* NOT USED, but required for 'glUniform1iARB()' in render function */
void main(void) {
vec3 mat_normal = texture2D( TexNormal, gl_TexCoord[0].xy ).rgb;
gl_FragColor = vec4( mat_normal, 1.0 );
}


Shader Version 2 :
Check the reflected cubemap from a STATIC tangent-normal, see Fig.3 in reference image, shows correct.
/* vertex shader */
varying vec3 E;
void main(void) {

vec3 t = gl_NormalMatrix * vec3(1,0,0); /* tangent */
vec3 b = gl_NormalMatrix * vec3(0,1,0); /* bitangent */
vec3 n = gl_NormalMatrix * vec3(0,0,1); /* normal */

vec3 V = vec3( gl_ModelViewMatrix * gl_Vertex );
E.x = dot( V, t );
E.y = dot( V, b );
E.z = dot( V, n );

gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0; /* normalmap */

}

/* fragment shader */
uniform sampler2D TexNormal; /* NOT USED, but required for 'glUniform1iARB()' in render function */
uniform samplerCube TexSkyBox;
varying vec3 E;
void main(void) {
vec3 mat_normal = vec3( 0.5, 0.5, 1.0 );
vec3 N = normalize( mat_normal * 2.0 - 1.0 );
vec3 mat_skybox = textureCube( TexSkyBox, reflect(E,N).xyz ).rgb;
gl_FragColor = vec4( mat_skybox, 1.0 );
}


Shader Version 3 :
Check the reflected cubemap from the normal-map, see Fig.4 in reference image, shows incorrect abivious... the water palne is not visible
/* vertex shader */
varying vec3 E;
void main(void) {

vec3 t = gl_NormalMatrix * vec3(1,0,0); /* tangent */
vec3 b = gl_NormalMatrix * vec3(0,1,0); /* bitangent */
vec3 n = gl_NormalMatrix * vec3(0,0,1); /* normal */

vec3 V = vec3( gl_ModelViewMatrix * gl_Vertex );
E.x = dot( V, t );
E.y = dot( V, b );
E.z = dot( V, n );

gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0; /* normalmap */

}

/* fragment shader */
uniform sampler2D TexNormal;
uniform samplerCube TexSkyBox;
varying vec3 E;
void main(void) {
vec3 mat_normal = texture2D( TexNormal, gl_TexCoord[0].xy ).rgb;
vec3 N = normalize( mat_normal * 2.0 - 1.0 );
vec3 mat_skybox = textureCube( TexSkyBox, reflect(E,N).xyz ).rgb;
gl_FragColor = vec4( mat_skybox, 1.0 );
}


Reference image :
Reference Image

Share this post


Link to post
Share on other sites

This topic is 2596 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this