!!ARBvp1.0 OPTION ARB_position_invariant ;

# VPROG_INTERACTION
#
# input:
#
# attrib[8] TEX0	texture coordinates
# attrib[9] TEX1	normal
# attrib[10] TEX2	tangent[0]
# attrib[11] TEX3	tangent[1]
# COL			vertex color
#
# c[4]	localLightOrigin
# c[5]	localViewOrigin
# c[6]	lightProjection S
# c[7]	lightProjection T
# c[8]	lightProjection Q
# c[9]	lightFalloff S
# c[10]	bumpMatrix S
# c[11]	bumpMatrix T
# c[12]	diffuseMatrix S
# c[13]	diffuseMatrix T
# c[14]	specularMatrix S
# c[15]	specularMatrix T
# c[16]	vertex color modulate
# c[17]	vertex color add
#
# c[20] model matrix
# c[21] model matrix
# c[22] model matrix
#
# output:
#
# texture[0] is the ambient cube map (was the normalization cube map)
# texture[1] is the per-surface bump map
# texture[2] is the light falloff texture
# texture[3] is the light projection texture
# texture[4] is the per-surface diffuse map
# texture[5] is empty (was the per-surface specular map)
# texture[6] is empty (was the specular lookup table)

# texcoord[0] is the surface bump map
# texcoord[1] is the surface diffuse map
# texcoord[2] is the light projection
# texcoord[3] is the light falloff
# texcoord[4] is the local normal to global normal transform
# texcoord[5] is the local normal to global normal transform
# texcoord[6] is the local normal to global normal transform

TEMP	R0, R1, R2;

PARAM	defaultTexCoord = { 0, 0.5, 0, 1 };

# textures 0 takes the base coordinates by the texture matrix
MOV		result.texcoord[0].xy, defaultTexCoord;
DP4		result.texcoord[0].x, vertex.attrib[8], program.env[10];
DP4		result.texcoord[0].y, vertex.attrib[8], program.env[11];

# textures 1 takes the base coordinates by the texture matrix
MOV		result.texcoord[1].xy, defaultTexCoord;
DP4		result.texcoord[1].x, vertex.attrib[8], program.env[12];
DP4		result.texcoord[1].y, vertex.attrib[8], program.env[13];

# texture 2 has one texgen
MOV		result.texcoord[2].xy, defaultTexCoord;
DP4		result.texcoord[2].x, vertex.position, program.env[9];

# texture 3 has three texgens
DP4		result.texcoord[3].x, vertex.position, program.env[6];
DP4		result.texcoord[3].y, vertex.position, program.env[7];
DP4		result.texcoord[3].w, vertex.position, program.env[8];

# put into texture space
DP3		result.texcoord[4].x, vertex.attrib[9], program.env[20];
DP3		result.texcoord[4].y, vertex.attrib[10], program.env[20];
DP3		result.texcoord[4].z, vertex.attrib[11], program.env[20];

# put into texture space
DP3		result.texcoord[5].x, vertex.attrib[9], program.env[21];
DP3		result.texcoord[5].y, vertex.attrib[10], program.env[21];
DP3		result.texcoord[5].z, vertex.attrib[11], program.env[21];

# put into texture space
DP3		result.texcoord[6].x, vertex.attrib[9], program.env[22];
DP3		result.texcoord[6].y, vertex.attrib[10], program.env[22];
DP3		result.texcoord[6].z, vertex.attrib[11], program.env[22];

SUB R1.xyz, program.env[5], vertex.position;

DP3 result.texcoord[7].x, vertex.attrib[9], R1;
DP3 result.texcoord[7].y, vertex.attrib[10], R1;
DP3 result.texcoord[7].z, vertex.attrib[11], R1;

#MOV result.texcoord[7].w, 1.0;

# generate the vertex color, which can be 1.0, color, or 1.0 - color
# for 1.0 : env[16] = 0, env[17] = 1
# for color : env[16] = 1, env[17] = 0
# for 1.0-color : env[16] = -1, env[17] = 1
MAD		result.color.xyz, vertex.color, program.env[16].x, program.env[17].y;
#MAD		result.color, vertex.color, program.env[16].x, program.env[16].y;

END

#======================================================================

!!ARBfp1.0
OPTION ARB_precision_hint_nicest;
OPTION NV_fragment_program2;

# env[0] is the constant diffuse modifier

SHORT TEMP light, R0, R2, R3, localNormal, specular;

#PARAM   subOne = { -2.5, -2.5, -2.5, -2.5 };
#PARAM   scaleTwo = { 5, 5, 5, 5 };
#PARAM   subOne = { -2.25, -2.25, -2.25, -2.25 };
#PARAM   scaleTwo = { 4.5, 4.5, 4.5, 4.5 };
#PARAM   subOne = { -2, -2, -2, -2 };
#PARAM   scaleTwo = { 4, 4, 4, 4 };
#PARAM   subOne = { -64, -64, -64, -64 };
#PARAM   scaleTwo = { 128, 128, 128, 128 };
PARAM   subOne = { -1, -1, -1, -1 };
PARAM   scaleTwo = { 2, 2, 2, 2 };
#PARAM   subOne = { -1.5, -1.5, -1.5, -1.5 };
#PARAM   scaleTwo = { 3, 3, 3, 3 };
#PARAM   subOne = { -1.125, -1.125, -1.125, -1.125 };
#PARAM   scaleTwo = { 2.25, 2.25, 2.25, 2.25 };

# specular is actually now viewer
#DP3H	specular, fragment.texcoord[6],fragment.texcoord[6];
#RSQH	specular, specular.w;
#MULH	specular.xyz, specular.w, fragment.texcoord[6];

NRMH specular.xyz, fragment.texcoord[6];

# load the local space surface normal
TXL	localNormal, fragment.texcoord[0], texture[1], 2D;
MOVH localNormal.x, localNormal.a;			# rxgb normal map compression
#MOVH   localNormal.z, 0.75;
MADH	localNormal.xyz, localNormal, scaleTwo, subOne;
NRMH localNormal, localNormal;
MULH localNormal.zw, localNormal.xyxy, localNormal.xyxy;

ADDH_SAT localNormal.z, localNormal, localNormal.w;
ADDH localNormal.z, -localNormal, 1.0;
RSQH localNormal.z, localNormal.z;
RCPH localNormal.z, localNormal.z;
RFLH R3, localNormal, light;

#MULH R3, R3, 1.0; # dfm added

# soften
#LRPH		localNormal.xyz, program.local[6].x, specular, localNormal;

# normalize localNormal
DP3H_SAT   localNormal.w, localNormal, localNormal;
RSQH   localNormal.w, localNormal.w;
MULH   localNormal, localNormal, localNormal.w;

# localNormal filter
MOVH	R0.xyz, localNormal;
MOVH	R0.z, { 0, 0, 0, 0.5 };
DP3H_SAT	R0, R0, R0;
MADH_SAT	R0.z, R0.w, -1, 1;
RSQH	R0, R0.z;
RCPH	localNormal.z, R0.w;

# localNormal filter
#MOVH		localNormal.z, { 0, 0, 0, 0.5 };
#DP3H_SAT	R0.x, localNormal,localNormal;
#ADDH_SAT	R0.x, 1, -R0.x;
#RSQH		R0.x, R0.x;
#RCPH		localNormal.z, R0.x;

# localNormal filter
ADDH_SAT	R0, fragment.texcoord[1], { 0, 0, 0, 0.5 };
TXB	R2, R0, texture[1], 2D;
MOVH R2.x, R2.a;
MADH_SAT	R2, R2, scaleTwo, subOne;

#TXL		localNormal, localNormal, texture[0], CUBE;
#MADH		localNormal, localNormal, scaleTwo, subOne;

# flatten normal over distance (Z)
MADH_SAT	R0, fragment.position.z, 4.0, -3.5;
MAXH	R0, R0.w, { 0, 0, 0, 0.5 }; #0.0;
ADDH_SAT	localNormal.z, localNormal.z, R0.w;

# normalize the bumpmap
#DP3H		R0, localNormal,localNormal;
#RSQH		R0, R0.x;
#MULH		localNormal.xyz, localNormal, R0.x;

#TXL		localNormal, localNormal, texture[0], CUBE;
#MADH		localNormal, localNormal, scaleTwo, subOne;

DP3H		R0, localNormal,localNormal;
RSQH		R0, R0.w;
MULH		localNormal.xyz, localNormal, R0.w;

# specular.w is the specular volume
DP3H_SAT R3.x, specular, R3;
POWH_SAT R3.x, R3.x, 16.0;	#8.0

# transform into ambient map space
DP3H	R0.x, localNormal, fragment.texcoord[4];
DP3H	R0.y, localNormal, fragment.texcoord[5];
DP3H	R0.z, localNormal, fragment.texcoord[6];

# load the ambient value
TXL	light, R0, texture[0], CUBE;

# modulate by the surface diffuse map
TXP	R0, fragment.texcoord[1], texture[4], 2D;
MULH	light, light, R0;

# modulate by the light falloff
TXP	R0, fragment.texcoord[2], texture[2], 2D;
MULH	light, light, R0;

# modulate by the light projection
TXP	R0, fragment.texcoord[3], texture[3], 2D;
MULH	light, light, R0;

# modulate by the constant diffuse factor
MULH	light.xyz, light, program.env[0];

# global illumination trick
MULH	R0, localNormal.z, 1.0;
MULH	R0, R0, R0;
MULH	light.xyz, light, R0.w;

# modulate by the vertex color
MULH result.color.xyz, light, fragment.color;

END
