A problem I had previously with normal mapping was the size of the maps, using floats meant the maps used 12 bytes per pixel. Been thinking of ways to reduce that and remembered that dot3 in opengl used the 8 bit colour channels so I've come up with this:
option explicit
sub normalise(byref x as single,byref y as single,byref z as single)
dim as single d=1.0/sqr(x*x+y*y+z*z)
x*=d
y*=d
z*=d
end sub
function int_dot(byval vx as integer,byval vy as integer,byval vz as integer,byval map as integer)
return (vx*((map shl 8)shr 24)+vy*((map shl 16)shr 24)+vz*((map shl 24)shr 24))shr 23
end function
'set up a couple of random vectors for test
randomize timer
dim as single vx0=rnd*100.0-50.0,vy0=rnd*100.0-50.0,vz0=rnd*100.0-50.0
dim as single vx1=rnd*100.0-50.0,vy1=rnd*100.0-50.0,vz1=rnd*100.0-50.0
normalise vx0,vy0,vz0
normalise vx1,vy1,vz1
print "float_dot = ";(vx0*vx1+vy0*vy1+vz0*vz1)*127.0
print
dim as integer ivx=vx0*127.0
dim as integer ivy=vy0*127.0
dim as integer ivz=vz0*127.0
'v0=read integer value from normal map
dim as integer v0=((ivx and &hff) shl 16)or((ivy and &hff) shl 8)or (ivz and &hff)
'ivx,ivy,ivz=interpolated fixed point normalised light vector (don't renormalise inside pixel loop for speed)
ivx=(vx1*127.0)shl 16
ivy=(vy1*127.0)shl 16
ivz=(vz1*127.0)shl 16
'calculate the dot product for normal mapping
print "int_dot =";int_dot(ivx,ivy,ivz,v0)
sleep
end
Cheers, Fryer.