!!ARBvp1.0

# standard shader, can be used for all materials or none, with or without normal mapping
#textures:
#texture[0], 2D		- (diffuse) color map, RGB
#texture[1], 2D		- normal map, RGB
#texture[2], 2D		- (if existent) specular map, LUMINANCE

ATTRIB inputpos = vertex.position;		# object space
ATTRIB normal = vertex.normal; 			# object space
ATTRIB texcoordmodel = vertex.texcoord[0];
ATTRIB tangentx = vertex.texcoord[1];
ATTRIB righthanded = vertex.color;

PARAM mvp[4] = { state.matrix.mvp };
PARAM mvinv[4] = { state.matrix.modelview.inverse };
PARAM mvinvcol3 = state.matrix.modelview.invtrans.row[3];
PARAM lightpos = state.light[0].position;	# world space

# fixme: we could have two different texture matrices for both units.... argh
PARAM texmatdiff[4] = { state.matrix.texture[0] };
PARAM texmatnrml[4] = { state.matrix.texture[1] };

# fixme: fog computation!
# vertex.fogcoord; ???!

OUTPUT outputpos = result.position;		# world space
OUTPUT outtexcoorddiff = result.texcoord[0];
OUTPUT outtexcoordnrml = result.texcoord[1];
OUTPUT lightdirout = result.texcoord[2];
OUTPUT halfangle = result.texcoord[3];

TEMP tmp;
TEMP tmp2;					# could be replaced with viewerdir...
TEMP tangenty;
TEMP lightdir;					# lightdir in object space
TEMP viewerdir;

#when not doing normal mapping, we need not to transform light/viewer vectors to tangent space
#so we need no tangentx/righthanded info.
#we even don't need to transform it to object space, instead transform normal to world space.
#give normal as texcoord[1] to fp, multiply normal and lightdir and set primary color to result
#do not give lightdir to fp.
#fp does not compute diff. brightness but just takes color, fp does not retrieve normal from map
#but takes texcoord[1] instead, rest is the same


# 1. compute tangent space
# 1.1. expand righthanded info
MAD	tmp.x, righthanded.x, 2, -1;

# 1.2. compute tangenty
XPD	tangenty, normal, tangentx;
MUL	tangenty, tangenty, tmp.x;


# 2. compute direction to light
# 2.1. transform light pos to object space. we assume mvinv has no projection coefficients.
DP4	tmp.x, mvinv[0], lightpos;
DP4	tmp.y, mvinv[1], lightpos;
DP4	tmp.z, mvinv[2], lightpos;

# 2.2. compute direction in object space (independent if directional light or not!)
# if (lightpos.w == 0) lp = lightpos; else lp = lightpos - inputpos;
# if w is only 0 or 1, use  lp = lightpos - w * inputpos;
#fixme: test!
MAD	tmp, -lightpos.w, inputpos, tmp;

# 2.3. normalize it
DP3	tmp.w, tmp, tmp;
RSQ	tmp.w, tmp.w;
MUL	lightdir.xyz, tmp.w, tmp;

# 2.4. project light position to tangent space, needed for diffuse lighting
# note that lightdir has unit length and thus lightdirout too (except the tangent
# space is no orthonormal system, which happens only for degenerated triangles).
DP3	lightdirout.x, tangentx, lightdir;
DP3	lightdirout.y, tangenty, lightdir;
DP3	lightdirout.z, normal, lightdir;
# fixme: the wrong L vector is caused by this transformation. Maybe some tangentx/y
# values or normals are defunct?
#tangenty seems to be a bit weird, tangentx maybe too, the normal is wrong!!!
#MAD	lightdirout, normal, 0.5, 0.5;
#MOV	lightdirout, normal;


# 3. compute halfangle vector (H = ||L+E||)
# 3.1. compute direction to viewer (E) in object space (mvinv*(0,0,0,1) - inputpos)
SUB	tmp, mvinvcol3, inputpos;

# 3.2. normalize it. add lightdir-vector (L) and viewerdir-vector (E)
DP3	tmp.w, tmp, tmp;
RSQ	tmp.w, tmp.w;
MAD	tmp, tmp.w, tmp, lightdir;	# compute direction to viewer (is normalized) and add
					# direction to light (saves one instruction)
# 3.4. normalize (L+E)
DP3	tmp.w, tmp, tmp;
RSQ	tmp.w, tmp.w;
MUL	tmp, tmp.w, tmp;

# 3.5. convert halfangle to tangent space
DP3	halfangle.x, tangentx, tmp;
DP3	halfangle.y, tangenty, tmp;
DP3	halfangle.z, normal, tmp;


# 4. compute texture coordinates. (z/w components are not used)
# 4.1. for map 1
DP4	outtexcoorddiff.x, texmatdiff[0], texcoordmodel;
DP4	outtexcoorddiff.y, texmatdiff[1], texcoordmodel;

# 4.2. for map 2
DP4	outtexcoordnrml.x, texmatnrml[0], texcoordmodel;
DP4	outtexcoordnrml.y, texmatnrml[1], texcoordmodel;


# 5. transform vertex to projection space (clip coordinates)
DP4	outputpos.x, mvp[0], inputpos;
DP4	outputpos.y, mvp[1], inputpos;
DP4	outputpos.z, mvp[2], inputpos;
DP4	outputpos.w, mvp[3], inputpos;

END
