PDA

View Full Version : The daily lighting question ;-)



dbugger
07-10-2003, 11:36 PM
Hi! I'm calculating my specular like this:


DP3 temp, lightvec, normal;
MUL temp, temp, 2.0;
MAD temp, temp, normal, -lightvec;
DP3 LITin.y, temp, ViewVector;

The light and view vectors are normalized, so is the normal. It looks quite ok but not as the fixed function specular.

Do you know what's wrong?
Thanks alot! / David
Btw I'm using LIT.

Jan
07-11-2003, 06:22 AM
What is "normal"? Is it the face normal? If this is the case, it is wrong.
Instead of the face-normal you have to use the "half-angle" vector. You get it this way:

VECTOR a = Normalized (LightPos - VertexPos);
VECTOR b = Normalized (CameraPos - VertexPos);
VECTOR ha = Normalized (a + b);

If you wonder, why a and b have to be normalized, then thereīs two of us. However if you donīt normalize them, you get a specular lighting, where the shape of the highlight is always a circle (and therefore very unnatural).

On the other hand, when you implement this stuff, you will get tesselation problems, cause then you will see, where two big polys share an edge. This can only be improved by tesselating the world, or by just using specular lighting only for small stuff.

But this is only the case for per-pixel lighting. I donīt really know how it looks if you do only vertex-lighting.
Are you implementing per-pixel or vertex-lighting?

Jan.

SirKnight
07-11-2003, 07:15 AM
If you wonder, why a and b have to be normalized, then thereīs two of us. However if you donīt normalize them, you get a specular lighting, where the shape of the highlight is always a circle (and therefore very unnatural).


If you mean you wonder why you have to normalize the addition of a and b then it's simple. Adding unit vectors never, at least I have never seen it happen, result in a unit vector. For instance, let a = [1,0,0] and b = [0,1,0]. Now c = a + b = [1,1,0]. Now the magnitude is sqrt( 1^2 + 1^2 + 0^2 ) = sqrt( 2 ). sqrt( 2 ) isn't 1 so we don't have a unit vector any more. Thus, we need to normalize the result of a + b.

-SirKnight

Jan
07-11-2003, 10:35 AM
No, i know why i have to normalize the result. But i didnīt know, why i have to normalize the other vectors. I implemented specular lighting just one week ago and got the tip to normalize the other vectors from this board.
I see a huge difference, but i didnīt really understand, why those other vectors have to be normalized, cause i always thought, that two vectors which point in the one direction, will always point in one direction when they get added, no matter how long they are.
However i just thought it through, and now it is quite clear to me. But i still think itīs not that intuitive at first, and you donīt learn that at school. But then there are a lot of important things, you donīt learn at school ;-)

Jan.

V-man
07-12-2003, 05:24 AM
It's pretty simple why you have to normalize the light and view vector. It's a question of balance.

But in reality, they need not be normalized. They just need to have the same magnitude.

OK, just ignore the first sentence and read the second one. It's less confusing that way http://www.opengl.org/discussion_boards/ubb/smile.gif

dbugger
07-12-2003, 06:33 AM
Thanks for all replies! Yes I found out about the halfvector and used that instead, but it still didn't look like the fixed function vertex lighting. The highlights "flickers" and shows up in wrong places, although it seems more accurate now than before. I can't provide you with more details now, I have the code at work.
Thanks all again! I'll investigate further on monday.

okapota
07-12-2003, 10:37 AM
i think they have to be normalized becuase otherwise, the dot product does not represent cos(theta), but Length1*Length2*cos(theta).
when normalized, length is simply 1.
no?

JotDot
07-13-2003, 05:30 AM
The final result (the half angle) has to be normalized in order be useful. The values a and b in the sum "a+b" do not have to be normalized. V-man is correct: a and b simply need their magnitudes to be the same in order to produce the half angle. Normalization is just one method to achieve that.

Trivia:

If a and b are not the same length, another method could be:
VECTOR ha = Normalize( a * Length(b) + b * Length(a) );


Heck, another way to calculate the half angle is by using the Cosine Law (a generalization of Pythagorean Theorem):
Symbol Notation: z^2 is z*z
C^2 = A^2 + B^2 - 2*A*B*cos(a_b_angle); // where A,B,C are the scalar lengths of the vectors a,b,c
From a generalization of the Cosine Law we get an identity that states:
DotProduct(a+b,a+b) is identical to A^2 + B^2 + 2*A*B*cos(a_b_angle) (Note there was only one sign change)
Which can be rewritten with vectors as: DotProduct(a,a)+DotProduct(b,b)+2*DotProduct(a,b)

Thus, using the same variables in the previous posts we get:
VECTOR ha=(a+b)/sqrt( DotProduct(a,a)+DotProduct(b,b)+2*DotProduct(a,b) ); // a,b don't have to be normalized

If a and b are both unity vectors (as mentioned by dbugger in his first post) then the calculation simplifies to:
VECTOR ha=(a+b)/sqrt(2+2*DotProduct(a,b))

Sorry. Couldn't sleep last night. Nothing better to do.

ToolTech
07-13-2003, 07:59 AM
David is using a correct Phong model. Is it defined that openGL fixed function uses the half vector variant or can it be driver dependant ? It should be more accurate to use the correct Phong model but if the OpenGL fixed function uses compensation for the specular exponent, then he might need to use the half vector varian instead...

Is there a "exact" definition of what openGL uses for the vertex light ?

Jan
07-13-2003, 09:30 AM
Because of the flickering: Do you rotate that half-angle vector (or the light-vector, iīm not sure at the moment) into tangent-space?
If not, this could be the reason.

Jan.