Problem converting to Vertex/Fragment shaders

I have written this little vertex/fragment program code a little while ago to simulate per-pixel reflection using normal maps.
Everything worked just fine and seeing how everyone seems to jump on the OGLSL bandwagon, I thought I’d give it a try and see if I can convert my mentioned shaders into OGLSL.

Spent few hours reading the pdf posted on the forums webhost, and then proceeded to convert my code.
After many attempts, I got it to work, well not with a serious visual bug though.
The problem is, I’m not getting the correct result and the cube map texture seems to rotate as I move my object around instead of staying fix.

Here’s the code, can someone help me out figure what errors I might have skipped during the conversion?

!!ARBvp1.0

#********************************************************************#
# Coder  : Abdul Bezrati                                             #
# Contact: [email]abezrati@hotmail.com[/email]                                      #
# Info   : Texture  Coordinates = vertex.texcoord[0]                 #
#          Tangent  Vector      = vertex.texcoord[1]                 #
#          Binoraml Vector      = vertex.texcoord[2]                 #
#********************************************************************#

OPTION ARB_position_invariant;
 
PARAM modelViewInvTrans[4] = { state.matrix.modelview.invtrans};
PARAM modelView[4]         = { state.matrix.modelview};

TEMP  eyeVector;

DP4 eyeVector.x, modelView[0], vertex.position;
DP4 eyeVector.y, modelView[1], vertex.position;
DP4 eyeVector.z, modelView[2], vertex.position;

MOV eyeVector, -eyeVector;

MOV result.texcoord[0], vertex.texcoord[0];

DP3 result.texcoord[1].x, modelViewInvTrans[0], vertex.texcoord[1];
DP3 result.texcoord[1].y, modelViewInvTrans[0], vertex.texcoord[2];
DP3 result.texcoord[1].z, modelViewInvTrans[0], vertex.normal;

DP3 result.texcoord[2].x, modelViewInvTrans[1], vertex.texcoord[1];
DP3 result.texcoord[2].y, modelViewInvTrans[1], vertex.texcoord[2];
DP3 result.texcoord[2].z, modelViewInvTrans[1], vertex.normal;

DP3 result.texcoord[3].x, modelViewInvTrans[2], vertex.texcoord[1];
DP3 result.texcoord[3].y, modelViewInvTrans[2], vertex.texcoord[2];
DP3 result.texcoord[3].z, modelViewInvTrans[2], vertex.normal;

MOV result.texcoord[1].w, eyeVector.x; 
MOV result.texcoord[2].w, eyeVector.y;   
MOV result.texcoord[3].w, eyeVector.z;  
END
#
!!ARBfp1.0

#*********************************************************************#
#Author:Abdul Bezrati    "Java Cool Dude"                             #
#*********************************************************************#
 
TEMP normalVector, reflectionVector, viewVector;
TEMP usefulTemp, cubeMapFragment;

TEX  usefulTemp, fragment.texcoord[0], texture[0], 2D;

MAD  usefulTemp, usefulTemp, 2.0, -1.0;

DP3 normalVector.x, usefulTemp, fragment.texcoord[1];
DP3 normalVector.y, usefulTemp, fragment.texcoord[2];
DP3 normalVector.z, usefulTemp, fragment.texcoord[3];

DP3 normalVector.w, normalVector, normalVector;
RSQ normalVector.w, normalVector.w;
MUL normalVector, normalVector, normalVector.w;

MOV viewVector.x  , fragment.texcoord[1].w;
MOV viewVector.y  , fragment.texcoord[2].w;
MOV viewVector.z  , fragment.texcoord[3].w;

DP3 usefulTemp , normalVector, viewVector;
ADD usefulTemp , usefulTemp  , usefulTemp;

MAD reflectionVector, usefulTemp, normalVector, -viewVector;

TEX usefulTemp     , fragment.texcoord[0], texture[1], 2D;
TEX cubeMapFragment, reflectionVector    , texture[2], CUBE;

MUL usefulTemp, usefulTemp, 1.6;
MUL result.color, usefulTemp, cubeMapFragment;
END
varying vec3 binormalVector,
             tangentVector,
             normalVector,
             eyeVector;

void main(void)
{
  gl_TexCoord[0]   = gl_MultiTexCoord0;

  eyeVector        =  -(gl_Vertex * gl_ModelViewMatrix).xyz;

  binormalVector.x = dot(gl_MultiTexCoord1.xyz, gl_NormalMatrix[1]);
  binormalVector.y = dot(gl_MultiTexCoord2.xyz, gl_NormalMatrix[1]);
  binormalVector.z = dot(gl_Normal.xyz        , gl_NormalMatrix[1]);

  tangentVector.x  = dot(gl_MultiTexCoord1.xyz, gl_NormalMatrix[0]);
  tangentVector.y  = dot(gl_MultiTexCoord2.xyz, gl_NormalMatrix[0]);
  tangentVector.z  = dot(gl_Normal.xyz        , gl_NormalMatrix[0]);

  normalVector.x   = dot(gl_MultiTexCoord1.xyz, gl_NormalMatrix[2]);
  normalVector.y   = dot(gl_MultiTexCoord2.xyz, gl_NormalMatrix[2]);
  normalVector.z   = dot(gl_Normal.xyz        , gl_NormalMatrix[2]);

  gl_Position =   gl_ModelViewProjectionMatrix * gl_Vertex; 
}

varying vec3 binormalVector,
             tangentVector,
             normalVector,
             eyeVector;

uniform sampler2D   Bump,
                    Base;
uniform samplerCube Cube;

  void main (void)
  {
    vec3 bump       = texture2D(Bump, vec2(gl_TexCoord[0])).xyz * 2.0 - 1.0,
         TBNnormal  = normalize(vec3(dot(tangentVector , bump),
                                     dot(binormalVector, bump),
                                     dot(normalVector  , bump)));

    vec3 reflection = (2.0*dot(eyeVector, TBNnormal)*TBNnormal - eyeVector); 
    vec4 base       = texture2D(Base, vec2(gl_TexCoord[0])),
         cube       = textureCube(Cube, reflection);

    gl_FragColor =  cube*base *1.6; 
  }

Thanks in advance :slight_smile:

Why… the… hell are you using all those dot product calls? Just use the ‘*’ operator, because GLSL does proper linear algebra with vectors and matrices.

Why don’t you compute the light and view vector in tagent space and pass it to the fragment shader instead of calculating a tangent-space matrix, passing it to the fragment shader and then compute the normal in world space? That would be a lot easier!

Here’s my bump mapping shader:

Vertex Shader:

attribute vec3 a2v_Normal;
attribute vec3 a2v_Tangent;
attribute vec3 a2v_Binormal;
attribute vec2 a2v_TexCoord;

varying vec3 v2f_LightVec;
varying vec3 v2f_ViewVec;
varying vec2 v2f_TexCoord;

void main()
{
	// Vertex transformation
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

	mat3 TBN_Matrix;
	TBN_Matrix[0] =  gl_NormalMatrix * a2v_Tangent;
	TBN_Matrix[1] =  gl_NormalMatrix * a2v_Binormal;
	TBN_Matrix[2] =  gl_NormalMatrix * a2v_Normal;

	// Calculation Light vector in ModelView Space
	vec4 Vertex_ModelView = gl_ModelViewMatrix * gl_Vertex;
	v2f_LightVec = TBN_Matrix * vec3(gl_LightSource[0].position - Vertex_ModelView);
	v2f_ViewVec = TBN_Matrix * vec3(-Vertex_ModelView);
	
	v2f_TexCoord = a2v_TexCoord;
}

Fragment Shader:

uniform sampler2D BaseMap;
uniform sampler2D BumpMap;

varying vec3 v2f_LightVec;
varying vec3 v2f_ViewVec;
varying vec2 v2f_TexCoord;

void main()
{
	vec4 LightColor = vec4(1.0, 0.0, 0.0, 1.0);

	vec4 Color = texture2D(BaseMap, v2f_TexCoord);
	vec3 Normal = normalize(vec3(texture2D(BumpMap, v2f_TexCoord)) - 0.5);

	// Normalize the interpolated Light and View Vector
	vec3 LightVec = normalize(v2f_LightVec);
	vec3 ViewVec = normalize(v2f_ViewVec);

	// Calculating Diffuse Term
	float DiffuseTerm = clamp(dot(Normal, LightVec), 0.0, 1.0);
 
	//float Shadow = clamp(DiffuseTerm * 4.0, 0.0, 1.0);

	// Calculating Specular Term 
	vec3 Reflect = normalize(2.0 * DiffuseTerm * Normal - LightVec);
	vec4 Specular = vec4(min(pow(clamp(dot(Reflect, ViewVec), 0.0, 1.0), 16.0), Color.w));

	// Calculating the final Color
	gl_FragColor = Color*0.2 + (Color*DiffuseTerm + Specular);
}

Thanks for the help people, I do really appreciate it :slight_smile:
Having said that, keep in mind that I’m trying to put together my very first OGLSL shader, therefore don’t expect me to write cutting-edge code on the first try(hint plenty of dot products here and there).
I took sometime and analyzed the sample code posted above which helped me out learning a lot more about the syntax and the cool optimizations that could be done.

Now here’s my shaders for anyone who wanna try em :slight_smile:

varying vec3 eyeVector;
varying mat3 normalMatrix;

void main(void)
{

  eyeVector      = -(gl_ModelViewMatrix * gl_Vertex).xyz;
  normalMatrix   = gl_NormalMatrix*mat3(gl_MultiTexCoord1.x, gl_MultiTexCoord1.y, gl_MultiTexCoord1.z,
                                        gl_MultiTexCoord2.x, gl_MultiTexCoord2.y, gl_MultiTexCoord2.z,
                                        gl_Normal.x        , gl_Normal.y        , gl_Normal.z);

  gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex; 
  gl_TexCoord[0] = gl_MultiTexCoord0;
}


uniform samplerCube Cube;
uniform sampler2D   Bump,
                    Base;
varying mat3        normalMatrix;
varying vec3        eyeVector;

void main()
{
  vec3 bump       = vec3(texture2D(Bump, vec2(gl_TexCoord[0]))* 2.0 - 1.0),
       normal     = normalize(normalMatrix*bump);

  vec3 reflection = normalize((2.0*dot(eyeVector, normal)*normal - eyeVector)); 
  vec4 base       = texture2D(Base, vec2(gl_TexCoord[0])),
       cube       = textureCube(Cube, reflection);

  gl_FragColor    =  cube*base; 
}

The performance is a bit slower compared to the Fragment/Vertex programs combo though :insert confused smiley here:

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.