it's my first question on stack.
Is it possible to infer length of the half angle vector for specular lighting from N·L and N·V without the whole view and light vectors?
I may be completely off-track, but I have this gut feeling it's possible... Why? I'm working on a skin shader and I'm already doing one texture lookup with N·L+N·E and one texture lookup for specular with N·H+N·V. The latter one can be transformed into N·L+N·E lookup if only I had the half vector length. Doing so could simplify the shader a bit and move some operations into the pre-computed lookup texture. It would make a huge difference since I'm trying to squeeze as much functionality as possible to a single pass mobile version so instruction count matters.


Edit, for clarity, I'm doing something like this:

float NdotL = dot(s.Normal, lightDir);
float NdotE = dot(s.Normal, viewDir);

fixed3 diffAndTransl = 2.0 * tex3D(_Lookup3d, half3(diffNdotL, NdotE * 0.5 + 0.5, depth)).rgb;

now we have diffuse with SSS and backscattering from lookup everything below could be just a lookup if I had length(h) information when calculating the lookup

float3 h = lightDir + viewDir;
float hLen = length(h);
//float3 H = normalize(h);
float3 H = h/hLen;
//float NdotH = dot(s.Normal, H);
float NdotH = (NdotL + NdotE)/hLen;
float EdotH = dot(viewDir, H);

fixed ph_by_fresnelReflectance = tex3D(_Lookup3d, half3(NdotH* 0.5 + 0.5, EdotH * 0.5 + 0.5, s.Gloss)).a;
half spec = saturate(NdotL) * max(ph_by_fresnelReflectance / hLensq, 0 ); // this could go into lookup as well

I was thinking I could infer length(h) from NdotL and NdotE when generating the specular lookup to reduce above code. In my mind I was imagining something like a triangle on the plane made by lightDir and viewDir vectors could be thought of in 2D space. Don't the two dot products give me the (half?) angle and since both vectors are of length one, wouldn't it be possible to infer the length of the last side? I tried some trigonometric voodoo programming but with no luck (chord of theta inferred from dot products?). Does anybody have any idea if it's at all possible? Maybe I just need to sleep more.

ps.: I know tex3D won't work well on mobile, just testing the grounds...


2 Answers 2


The trouble is that knowing N·L and N·V doesn't tell you anything about the relative orientation of L and V. Imagine holding L fixed and rotating V around the normal (or vice versa) - it doesn't change N·L and N·V, but the relationship between L and V can change greatly, so N·H will change as well.

For skin shading, you may want to look into Preintegrated Skin Rendering by Eric Penner. It's a cheap enough technique that it can certainly run on mobile. It uses a lookup texture based on geometric curvature and N·L, as well as a pre-blurred normal map (which can just be a higher mip level of the regular normal map).

  • \$\begingroup\$ Actually I am successfully using penner's technique already. \$\endgroup\$
    – cician
    Nov 1, 2013 at 19:17

Well, I don't think you can infer the half vector without using the view vector and light vector, or even pre-compute the half vector.

The problem is with the whole specular lighting concept in the blinn-phong model, specular lighting is dependant on the viewer, the specular term will be different for two people looking at the object and standing at different locations.

Unless you have both the light and the viewer at fixed a fixed positions, -the light can be fixed - but fixing the viewer though, is usually not possible, you won't be able to pre-compute it. If you have your camera with minimal movement you can get away with a pre-computed light texture (read:lightmap).

There are other shading algorithms but I doubt you will find any that can model the specular lighting without calculating the Reflection or the Half vector.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .