Advertisement

Problem in vertex/fragment programs

Started by April 25, 2005 04:40 AM
7 comments, last by _DarkWIng_ 19 years, 7 months ago
I’m trying to replace the fixed function pipeline in my demo with vp/fp , and after several weeks of tinkering with it, it started to work but it seems that something is not right and I can’t put my hand on it, The problem is with the lighting(diffuse, specualr), it looks wrong as if only one vertex is affected by lighting, and the lighting acts funny when moving the camera, and i'm putting the lightsource in the center of the cube. here's a screenshot http://www.myfilestash.com/userfiles/L0rdDiabl0/Normal.JPG so i thought some of the expert guys can spot where the problem is. Thanks in advance. here's the vertex program:


!!ARBvp1.0

#Per-vertex inputs
ATTRIB Position       = vertex.position;
ATTRIB Color          = vertex.color;
ATTRIB Normal         = vertex.attrib[1];
ATTRIB Tangent        = vertex.attrib[2];
ATTRIB DecalTex       = vertex.texcoord[0];
ATTRIB NormalTex      = vertex.texcoord[1];

#Constant Parameters
PARAM mvp[4]          = {state.matrix.mvp};          
PARAM mvinv[4]        = {state.matrix.modelview.invtrans}; 
PARAM EyeLightPos     =  state.light[0].position;
PARAM EyeCameraPos    =  program.local[5];

TEMP LightPos, CameraPos, LightVector, ViewVector, HalfVector, Binormal, TS_LightVector, TS_HalfVector, mag;

#Per-vertex outputs 
OUTPUT oPosition      = result.position;
OUTPUT oColor         = result.color;
OUTPUT oDecalTex      = result.texcoord[0];
OUTPUT oNormalTex     = result.texcoord[1];
OUTPUT LV_TexCoord    = result.texcoord[2];
OUTPUT HV_TexCoord    = result.texcoord[3];

#Transform the Vertex to Clip Space
DP4 oPosition.x, mvp[0], Position;  
DP4 oPosition.y, mvp[1], Position;   
DP4 oPosition.z, mvp[2], Position;  
DP4 oPosition.w, mvp[3], Position;

#Transform Light Position from Eye Space to Object Space (Using Inverse Model-View Matrix)
DP4 LightPos.x, mvinv[0], EyeLightPos;
DP4 LightPos.y, mvinv[1], EyeLightPos;
DP4 LightPos.z, mvinv[2], EyeLightPos;

#Transform Camera Position from Eye Space to Object Space (Using Inverse Model-View Matrix)
DP4 CameraPos.x, mvinv[0], EyeCameraPos;
DP4 CameraPos.y, mvinv[1], EyeCameraPos;
DP4 CameraPos.z, mvinv[2], EyeCameraPos;

#Create Light Vector
ADD LightVector, -Position, LightPos; 

#Create View Vector
ADD ViewVector,  -Position, CameraPos;

#Create Half Vector
ADD HalfVector, LightVector, ViewVector;

#Normalize Light Vector
DP3 mag.w, LightVector, LightVector;
RSQ mag.w, mag.w;
MUL LightVector.xyz, mag.w, LightVector;

#Normalize Half Vector
DP3 mag.w, HalfVector, HalfVector;
RSQ mag.w, mag.w;
MUL HalfVector.xyz, mag.w, HalfVector;

#Calculate Binormal
XPD Binormal, Normal, Tangent;

#Transform Light Vector to Tangent Space
DP3 TS_LightVector.x, LightVector, Tangent;
DP3 TS_LightVector.y, LightVector, Binormal;
DP3 TS_LightVector.z, LightVector, Normal;

#Transform View Vector to Tangent Space
DP3 TS_HalfVector.x, HalfVector, Tangent;
DP3 TS_HalfVector.y, HalfVector, Binormal;
DP3 TS_HalfVector.z, HalfVector, Normal;

MOV oColor, Color;
MOV oDecalTex , DecalTex;
MOV oNormalTex, NormalTex;
MOV LV_TexCoord , TS_LightVector;  
MOV HV_TexCoord , TS_HalfVector;     

END



and here's the fragment program:


!!ARBfp1.0

#Fragment inputs

ATTRIB DecalTexCoord   = fragment.texcoord[0];
ATTRIB NormalTexCoord  = fragment.texcoord[1];
ATTRIB LVTexCoord      = fragment.texcoord[2];
ATTRIB HVTexCoord      = fragment.texcoord[3];

#Fragment outputs
OUTPUT outColor        = result.color;

TEMP texelColor, texelNormal, NdotL, NdotH, NormalizedLight, NormalizedHalf, Color;

#Texture Fetch
TEX texelColor,  DecalTexCoord,  texture[0], 2D;
TEX texelNormal, NormalTexCoord, texture[1], 2D;

#Normalize Light Vector, no need for it if LV is normalized with the cube map
DP3 NormalizedLight.w, LVTexCoord, LVTexCoord;
RSQ NormalizedLight.w, NormalizedLight.w;
MUL NormalizedLight.xyz, NormalizedLight.w, LVTexCoord;

#Normalize Half Vector, no need for it if HV is normalized with the cube map
DP3 NormalizedHalf.w, HVTexCoord, HVTexCoord;
RSQ NormalizedHalf.w, NormalizedHalf.w;
MUL NormalizedHalf.xyz, NormalizedHalf.w, HVTexCoord;

#This Computes N.L
DP3 NdotL, texelNormal, NormalizedLight;

#This Computes N.H
DP3 NdotH, texelNormal, NormalizedHalf;

MUL Color, NdotL, NdotH;
 
#Modulate texel color with vertex color
MUL outColor, texelColor, Color;  
  
END



For start don't normalize light and view vectors in vertex program but in fragment program.
You should never let your fears become the boundaries of your dreams.
Advertisement
I found out that i was entering only one value of (Normal, Tangent) and not using arrays, so i switched to glVertexAttribPointerARB and it gotten worse, all i can see now is flashing triangles, and when i tried commenting the input for (Normal, Tangent) i see correctly rendered cube with diffuse lighting but without specular.

_DarkWIng_
I did what you asked but it didn't help, as i was normalizing in vp and fp
If you get the chance, you should check out Cg. I got it ages ago, then had a look at how to implement it into my applications and dumped the entire thing into my todo list. That was until I found myself trying to figure out how to improve my rendering speeds, along with trying to get vertx programs to do the things I wanted them to do. I decided to have a look at Cg again, and finally noticed the different profiles you can compile to. Basically, you can compile the Cg code to produce vertex/fragment programs. Since the code's similar to the fixed-function pipeline (ok, far from similar, but a lot closer than what you're using at the moment), you should also find it easier to implement this. It takes a little getting used to, but I think it's worth it.
Quote: Original post by Anonymous Poster
I did what you asked but it didn't help, as i was normalizing in vp and fp

You have to normalize only in FP.

Try creating VP&FP step by step. First by using only flat color then, passing object space light and eye, doing simple ppl without normalmaps and so on..
You should never let your fears become the boundaries of your dreams.
Thanks for the advice _DarkWIng_
I'll do that, and I'll report back when i find the source of the problem
Advertisement
I did what _DarkWIng_ suggested, and I found out that the problem is with (Normal, Tangent) everything seems alright before transforming Light Vector to the Tangent Space, but TBN Matrix calculations are definitely right as they produce correct results using VBO and RC, so the only thing that might cause the error is the input of them in the vertex program, I’m doing this for the input

glEnableVertexAttribArrayARB(1);
glVertexAttribPointerARB(1, 3, GL_FLOAT, GL_FALSE, sizeof(Cube_Vertices), &cube.vertices[0].Normal);

glEnableVertexAttribArrayARB(2);
glVertexAttribPointerARB(2, 3, GL_FLOAT, GL_FALSE, sizeof(Cube_Vertices), &cube.vertices[0].Tangent);

Is there something wrong with this?

And here’s the updated vp/fp for diffuse light only, the result is flashing triangles and cube.

Vertex program
!!ARBvp1.0#Per-vertex inputsATTRIB Position       = vertex.position;ATTRIB Color          = vertex.color;ATTRIB Normal         = vertex.attrib[1];ATTRIB Tangent        = vertex.attrib[2];ATTRIB DecalTex       = vertex.texcoord[0];ATTRIB NormalTex      = vertex.texcoord[1];#Constant ParametersPARAM mvp[4]          = {state.matrix.mvp};                 PARAM mvinv[4]        = {state.matrix.modelview.invtrans};  PARAM EyeLightPos     =  program.local[5];TEMP LightPos, Binormal, LightVector;#Per-vertex outputs OUTPUT oPosition      = result.position;OUTPUT oColor         = result.color;OUTPUT oDecalTex      = result.texcoord[0];OUTPUT oNormalTex     = result.texcoord[1];OUTPUT TS_LightVector = result.texcoord[2];    #Transform the Vertex to Clip SpaceDP4 oPosition.x, mvp[0], Position;  DP4 oPosition.y, mvp[1], Position;   DP4 oPosition.z, mvp[2], Position;  DP4 oPosition.w, mvp[3], Position;#Transform Light Position from Eye Space to Object Space (Using Inverse Model-View Matrix)DP3 LightPos.x, mvinv[0], EyeLightPos;DP3 LightPos.y, mvinv[1], EyeLightPos;DP3 LightPos.z, mvinv[2], EyeLightPos;#Calculate BinormalXPD Binormal, Normal, Tangent;#Create Light VectorADD LightVector, LightPos, -Position; #Transform Light Vector to Tangent SpaceDP3 TS_LightVector.x, LightVector, Tangent;DP3 TS_LightVector.y, LightVector, Binormal;DP3 TS_LightVector.z, LightVector, Normal;MOV oColor, Color;MOV oDecalTex  , DecalTex;MOV oNormalTex , NormalTex;END


fragment program
!!ARBfp1.0#Fragment inputsATTRIB Color        = fragment.color.primary; # Diffuse interpolated colorATTRIB DecalTex     = fragment.texcoord[0];ATTRIB NormalTex    = fragment.texcoord[1];ATTRIB LightVector  = fragment.texcoord[2];TEMP texelColor, texelNormal, nLightVector, NdotL;#Fragment outputsOUTPUT outColor        = result.color;#Texture FetchTEX texelColor,  DecalTex,  texture[0], 2D;TEX texelNormal, NormalTex, texture[1], 2D;#Normalize Light VectorDP3 nLightVector.w, LightVector, LightVector;RSQ nLightVector.w, nLightVector.w;MUL nLightVector.xyz, nLightVector.w, LightVector;DP3 NdotL, texelNormal, nLightVector;#Modulate texel color with vertex colorMUL outColor, texelColor, NdotL;END

Nobody can help me?

at least tell me if this is the correct way of input, I suspect the problem has something to do with the input

glEnableVertexAttribArrayARB(1);
glVertexAttribPointerARB(1, 3, GL_FLOAT, GL_FALSE, sizeof(Cube_Vertices), &cube.vertices[0].Normal);

glEnableVertexAttribArrayARB(2);
glVertexAttribPointerARB(2, 3, GL_FLOAT, GL_FALSE, sizeof(Cube_Vertices), &cube.vertices[0].Tangent);

Thanks
The problem might becouse (some) generic attributs and standard attributs mapp to same HW. So you might get a clash in the data. There was an old chart from nVidia that showed what maps to what on their hw. I suget you try other generic attributes.

edit: another possible solution would be to use only standard attributes (like on of the texture coordinats) or only generic ones.
You should never let your fears become the boundaries of your dreams.

This topic is closed to new replies.

Advertisement