lighting problem in my vertex program

Im trying to make a light in my vertex program but i want it (for now) to use the the most simple lighting calculations. I looked at the nvidia lit quad example and i hope i can do less than that to make a simple light. I dont quite understand all of what they are doing yet. Here is what i have so far, and my spinning quad (how exciting eh? ) is all black.

// c[0] - c[3] will contain the modelview + projection matrix
// c[10] - c[13] will contain the inverse modelview matrix
// c[4] will contain the diffuse color
// c[5] will contain the light vector
// c[6] will contain some zeros
// o[HPOS] will be the output vector
// o[COL0] will contain the diffuse color
// v[OPOS] will contain the vertex
// v[NRML] will contain the vertex normal
char vtx_prog[] =
"!!VP1.0 # This is a sample vertex program!.
"
“DP4 o[HPOS].x, c[0], v[OPOS];” // Perform the standard transform
“DP4 o[HPOS].y, c[1], v[OPOS];” // …
“DP4 o[HPOS].z, c[2], v[OPOS];” // …
“DP4 o[HPOS].w, c[3], v[OPOS];” // …
“MOV o[COL0], c[4];”

// Compute the object space light vector
“MOV R3, c[5];” // Move to a temp register so we dont get an error when the DP3 occurs
“DP3 R1.x, c[10], R3;” // An instruction wont work if the operands are the same ‘type’
“DP3 R1.y, c[11], R3;” // ie both c registers (DP3 R1.x, c[10], c[5]) << ERROR!
“DP3 R1.z, c[12], R3;”
“MOV R2, -R1;” // Why negate this?

“DP3 R0, v[NRML], R2;”
“MAX R0, R0, c[6].x;”
“MUL o[COL0], R0.x, v[4];”

“MOV o[TEX0], v[TEX0];” // Copy texture coords over
“END”;

Am i missing something here? I just want a simple diffuse light and nothing more right now.

-SirKnight

ehm, how do you specify the light vector?
(when you load it to the constant memory?)

also, you first load a constant to COL0
and then you overwrite it later with
light intensity*v[4] <— ??? v[4]?
should be c[4] probably…

Ok here is my light vector:
float light[4] = { 0.7531f, 0.0f, -0.7531f, 0.0f };

And v[4] like i say in my comments contains a color which looks like this:
float color[4] = { 0.0f, 0.0f, 1.0f, 0.0f };

If i take out the lighting stuff i see a blue spining quad but once i put all of the lighting stuff in, i get a pure black one.

-SirKnight

Here is something that works for simple diffuse:

c[0]-c[3]: GL_PROJECTION, GL_IDENTITY_NV
c[4]-c[7]: GL_MODELVIEW, GL_IDENTITY_NV
c[8]-c[11]: GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV
c[20]: Light direction
The v registers contain what they are supposed to contain…

“!!VP1.0
DP4 R0.x,v[OPOS],c[4];
DP4 R0.y,v[OPOS],c[5];
DP4 R0.z,v[OPOS],c[6];
DP4 R0.w,v[OPOS],c[7];
DP4 o[HPOS].x,R0,c[0];
DP4 o[HPOS].y,R0,c[1];
DP4 o[HPOS].z,R0,c[2];
DP4 o[HPOS].w,R0,c[3];
DP3 R1.x,v[NRML],c[8];
DP3 R1.y,v[NRML],c[9];
DP3 R1.z,v[NRML],c[10];
DP3 R1.w,R1,R1;
RSQ R1.w,R1.w;
MUL R1,R1,R1.w;
DP3 R0.x,R1,c[20];
MUL o[COL0],v[COL0],R0.x;
END”

The problem with your code might lie in the transformation to object-space of the light (I transform the normal into world-space instead).

It could also lie in your MAX instruction. What are you using it for ?

Regards.

Eric

My MAX is just to zero out the negative values. nVidia had it in their lit quad example so i thought i would put it in too. Also i noticed in your code you do 8 DP4s. 4 with the modelview and 4 with the projection. What you could do to make the vertex program faster is do like i did and concatinate the modelview and projection together and that will reduce 4 DP4’s. But hey it still works so its all good.

Also i noticed you use the inverse transpose modelview matrix whereas I use just the inverse modelview. I think ill try what you did there to see if it works. The nvidia lit quad sample just used the inverse modelview so i figured it would work fine. I guess it would if i was using the specular calculations also, i dont know for sure though. I really dont know a whole lot about the math for lights, this is my first time actually trying to do the lighting math myself instead of letting opengl do it for me.

-SirKnight

[This message has been edited by SirKnight (edited 06-07-2001).]

I’ll try to answer your points:

  1. I know I could save 4 DP4 : this is just because this program source is the base I use for testing effects. I could need to use the projection matrix only.

  2. When you transform vertices using a modelview matrix, the normals are transformed by the inverse transpose of the modelview matrix (I read that in an online version of the Red or Blue book…). Actually, I need to check in my Maths book coz’ I find it funny !

Regards.

Eric

“2) When you transform vertices using a modelview matrix, the normals are transformed by the inverse transpose of the modelview matrix (I read that in an online version of the Red or Blue book…). Actually, I need to check in my Maths book coz’ I find it funny !”

Draw a circle on paper with normals pointing outside. Now squish that sphere (non-uniform scale) to get an ellipse. Apply the same scale (with normalization) to the normals and you’ll see why it has to be the inverse.

Ok i think i somewhat have some lighting. But then again i dont know. Here is my new vertex program and then ill bring up some points about it:

// c[0] - c[3] will contain the modelview + projection matrix
// c[10] - c[13] will contain the inverse modelview matrix
// c[14] - c[17] will contain the inverse transpose modelview matrix
// c[4] will contain the diffuse color
// c[5] will contain the light vector
// c[6] will contain (0.0f, 0.50f, 1.0f, 50.0f)
// c[18] will contain diffuse light color & diffuse mat.
// c[19] will contain ambient light color & diffuse mat.
// c[20] will contain material color (white)
// o[HPOS] will be the output vector
// o[COL0] will contain the diffuse color
// v[OPOS] will contain the vertex
// v[NRML] will contain the vertex normal

“DP4 o[HPOS].x, c[0], v[OPOS];”
“DP4 o[HPOS].y, c[1], v[OPOS];”
“DP4 o[HPOS].z, c[2], v[OPOS];”
“DP4 o[HPOS].w, c[3], v[OPOS];”

// Compute the object space light vector
“MOV R3, c[5];”
“DP3 R1.x, c[10], R3;”
“DP3 R1.y, c[11], R3;”
“DP3 R1.z, c[12], R3;”

“DP3 R1.w, R1, R1;”
“RSQ R1.w, R1.w;”
“MUL R1, R1, R1.w;”

“DP3 R0.x, v[NRML], -R1;”
“MUL o[COL0], R0.x, c[20];”

“MOV o[TEX0], v[TEX0];”
“END”;

Ok and my light vector is like this:
float light[4] = { 0.0f, 0.0f, -1.0f, 0.0f };

And my normals (the z part) are -1’s and the x & y parts are 0.0’s.

Now on to what its doing. I get a white spining quad. So that seems ok. But the quad no matter which way its facing the light fullbright. In the D3D and OGL lit quad examples, the quad is dimmed depending on the angle of the quad. And if its not facing the viewer its all black. Mine is not like that. Also no matter what color i put in c[20] its always white. I know thats not right. And the thing is, this example looks just like the D3D example yet it dont work like it. Also one more thing, where i transform the light vector to object space (all of these different spaces are starting to confuse me) even if i use the inverse transpose instead of the inverse like im using now, i still get the same results.

Also, do any of you know of some places on the net or some books or something that talks about this kind of stuff. I would like to learn more about the math of lights and stuff but none of my books go into that. Also the only opengl book i have is the superbible 2nd ed. Im thinking of buying that book called 3D Computer Graphics by i think his name is Watt. It sounds good, maybe you guys would know if that would be the book i need.

-SirKnight