hi there, I'm trying to implement a per-pixel lambert shader but I don't know what the best/fastest way to do this is, I currently have:
// c0 - worldViewProject
// c4 - world
// c8 - point light matrix
vs.1.1
def c13, 0.5, 0.5, 0.5, 0.5
dcl_position v0
dcl_normal v1
dcl_texcoord v2
m4x4 oPos, v0, c0
mov oT0, v2
; convert normal to range 0 - 1
mul r0, v1, c13
add r0, r0, c13
; interpolate normal across triangle
mov oT2, r0
; r5 - world position of vertex
m4x4 r5, v0, c4
; convert position into lights space
m4x4 oT1, r5, c8
the point light matrix converts the 3d position into light space i.e. between -1 and 1 anything outside this range lies outside the radius of the light, it also moves the range from -1 to 1 to 0 - 1 by dividing by two and adding 0.5.
// c0 - light color
ps.1.1
tex t0
texcoord t1
texcoord t2
dp3_sat r0, t1_bx2, t1_bx2
mul r0, c0, 1-r0
mul r0, r0, t0
the dp3_sat intruction gives me the attenuation factor and clamps the value to 0 - 1 so that any values > 1 will remain at 1.
The problem is that I need to be able to dot the normal (t2_bx2) with the inverse direction of (t1_bx2) but I don't think ps.1.1 supports any normalization intructions such as rsq, rcp etc.
how can I get the two normals (light and surface) per-pixel? and is there any way to get the actual surface normal rather than using the interpolated vertex normals?