PDA

View Full Version : Problem converting to Vertex/Fragment shaders



Java Cool Dude
04-04-2004, 08:20 PM
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: abezrati@hotmail.com #
# 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 :)

Descenterace
04-05-2004, 11:09 AM
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.

Corrail
04-05-2004, 12:42 PM
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!

Corrail
04-05-2004, 12:50 PM
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);
}

Java Cool Dude
04-05-2004, 05:32 PM
Thanks for the help people, I do really appreciate it :)
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 :)


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: