Original Post
Hi, I'm quite a beginner and do some experimenting with the NV FX composer to write an effect for my models. It should include diffuse and specular lighting for a directional light. I read some tutorials on this site and they always use tangent space for the normal maps so I followed this way. As I code for GF4 hardware (vs 1.1, ps 1.3) I wrote this shader:
ps_1_3
tex t0 //diffuse color texture
tex t1 //nornmal map in tangent space
texdp3tex t2, t1_bx2 //H as coord, specular function pow(N.H,16) as 1D tex
tex t3 //L normalized by cube map
dp3 r0, t3_bx2, t1_bx2 //diffuse term
mul r0.rgb, t0, v0 //diffuse*(vertex diffuse)
+mul r0.a, r0, t3_bx2.z //(self shadow)*(diffuse term)
mul r0.rgb, r0, r0.a //(diffuse term)*(diffuse color)
+mul t2.a, t2, t3_bx2.z //(self shadow)*(specular term)
mul r1, t2.a, v1 //(specular term) * (vertex specular)
add_sat r0, r0, r1 //diffuse + specular
The problem is that with low tesselation the specular highlight looks quite bad. I think this is because the half vector H is not renormalized in the pixel shader and I see no way of doing that. I think creating the normal maps in object space could solve this. This way I could do:
ps_1_3
//light in c0 in object space computed by the cpu
tex t0 //diffuse color texture
tex t1 //nornmal map in object space
texdp3tex t2, t1_bx2 //H as coord in obj space (const), spec func as 1D tex
tex t3 //vertex N (obj space) renormalized
dp3 r0, c0, t1_bx2 //diffuse term
mul r0.rgb, t0, v0 //diffuse*(vertex diffuse)
+mul r0.a, r0, t3_bx2.z //(self shadow)*(diffuse term)
mul r0.rgb, r0, r0.a //(diffuse term)*(diffuse color)
+mul t2.a, t2, t3_bx2.z //(self shadow)*(specular term)
mul r1, t2.a, v1 //(specular term) * (vertex specular)
add_sat r0, r0, r1 //diffuse + specular
Where is the major drawback in object space normal mapping that nobody uses it? Am I overlooking something? I think this must have been discussed several times before but I couldn't find a satisfying answer. Please post your opinion. Thank you in advance Markus