# OpenGL specualr lighting, why use half vectors?

This topic is 4506 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

ok, typically one uses as specular lighting this formaula (openGL vertex lighting does this): spec=pow( clamp(0,1,dot(halfV,normal)), power) where halfV=normalize( normalized_toLightVector + normalized_toEyeVector ) note the 3 normalizes, but actually the following is more accurate (do a Google to see why): spec=pow( clamp(0,1,dot(normalize(toEyeVector),refectV),power) where reflectV = 2*dot(normalized_toLightVector),normal) * normal - normalized_toLightVector note that then we need only normalize toLightVector (which is needed anyways for difffuse lighting) and the vector to the eye.. so why on earth is the first method often used? also note that the dot prodcut to calculate reflectV is used in diffuse anyways as is normalizing the vetor to the light... so the cost of doing this specular is pow, one extra dot and one extra normalize where as the other it is pow, one extra dot and two extra normalizes.... so why one Earth is the first method done so often?? escpecially considering if you do this at the fragment shader level... [Edited by - kRogue on July 8, 2006 1:30:44 PM]

nothing?

##### Share on other sites
Quote:
 Original post by kRoguewhere halfV=normalize( normalized_toLightVector + normalized_toEyeVector )

AFAIK, halfV is actually defined as
halfV = (normalized_toLightVector + normalized_toEyeVector)*0.5;

You eliminate one subtract and dot product from not having to calculate the reflection vector.

HTH

##### Share on other sites
The half-vector is actually different to the light vector, and so yields a different dot product. this is the reason why the specular highlight appears in the corner as opposed to in the centre.

##### Share on other sites
The second equation looks interesting. Do you get the same result as the first?

If I count the number of oprtations for the first, it gives
7

If I count the number of operations for the second, it gives
10

Quote:
 AFAIK, halfV is actually defined ashalfV = (normalized_toLightVector + normalized_toEyeVector)*0.5;

Nope, that's just a approximation.
The correct way is
halfV=normalize( normalized_toLightVector + normalized_toEyeVector )

##### Share on other sites
Quote:
 If I count the number of oprtations for the first, it gives7

not just the opreatyoin vount matters, but what: normalize is kind of pricey (sqrt typically, 3 mults and 2 adds, but if the hardware has that normalize is just as cheap as others, then the first would be better)

Quote:
 If I count the number of operations for the second, it gives10

typically vector add mults are fast operations in hardware, ie c.xyz=t*a.xyz + b.xyz is very cheap.. me thinks maybe just one operation in NVASM (I could be wrong though)...

but back to the original question, why?? Moreover the legnth of the vectors can be computet in the vertex shader and then used in fragment shader (at a cost to accuracy, but not so bad) anyone have ATI hardware to compare the 2 approaches (cause on my nVidia the 2nd is faster)

##### Share on other sites
On SM 2.0, normalize is 3 instructions and I beleive each is 1 cycle, so it is somewhat expensive as you said. On SM 3.0, you have a real normalize instruction. I don't have a reference with me on cycle count.

MAD is a single instruction (special circuit).
Most instructions have a clamp version to, which doesn't add any cycles.

For SM 2.0
First case
If I count all ops as 1 cycle
except If I count clamp as 0 cycle
except If I count norm as 3 cycle
total = 3 * 3 + 3 = 10

Second case
If I count all ops as 1 cycle
except If I count clamp as 0 cycle
except If I count norm as 3 cycle
except there is a MAD, so - 1
total = 2 * 3 + 7 - 1 = 12

I must be doing something wrong if you say it is faster.

##### Share on other sites
lets take a look: the real difference is what dot is done in the specular: halfV against normal or reflect against eye: (note both methods have same overhead, eye vector) and the other costs per light are normalized_toLightVector and dot(normalized_toLightVector, normal) {for diffuse lighting}

to find halfV: one vector add and a normaize
to find reflect one vector add because the dot used in it is already needed for diffuse lighting. {note that the clamp is done seperately for the diffuse lighting!)

so per light,

1st method: MAD, normalize and a dot --> 5 instructions (SM2.0)
2nd method: dot and MAD --> 2 instructions (SM2.0 and even older)

so on SM2.0, it _looks_ like the 2nd method take 3 less instructions... basicly the 2nd method replaces a normalize and MAD with just a MAD... but the clamp for diffuse has to be done seperately, so 2nd method is really replace MAD and normalize with a clamp and MAD. (I am not looking at the total operation count though, so the question comes down to what is the extra 2 or 3 instructions worth per light, eh?) on the other hand if one just uses

halfV= 0.5*(normalized_toLightVector + normalized_toEyeVector)

then the costs for the first method is better by not needing to do that clamp....

[Edited by - kRogue on July 19, 2006 12:34:46 PM]

1. 1
Rutin
42
2. 2
3. 3
4. 4
5. 5

• 9
• 27
• 20
• 14
• 14
• ### Forum Statistics

• Total Topics
633385
• Total Posts
3011605
• ### Who's Online (See full list)

There are no registered users currently online

×