!!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];

# 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[17].x, program.env[17].y;
#MAD		result.color.xyz, vertex.color, program.env[17].x, program.env[16].y;

#MAD		result.color.xyz, vertex.color, program.env[16].x, program.env[17].y;
#MAD		result.color.xyz, vertex.color, program.env[16].x, program.env[16].y;

END

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

!!ARBfp1.0
OPTION ARB_precision_hint_nicest;

# env[0] is the constant diffuse modifier

TEMP	light, R0, R2, localNormal, specular, newtexcoord;

#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 };
PARAM   subOne = { -1.0625, -1.0625, -1.0625, -1.0625 };
PARAM   scaleTwo = { 2.125, 2.125, 2.125, 2.125 };

PARAM	GlobalLight = 0.9;	#1.0
PARAM	ZeroFive = 0.5;
#PARAM   scaleTwoX = { 4, 4, 4, 4 };
#PARAM   subOneX = { -3.5, -3.5, -3.5, -3.5 };
PARAM   scaleTwoX = { 8, 8, 8, 8 };
PARAM   subOneX = { -7.5, -7.5, -7.5, -7.5 };
#PARAM   scaleTwoY = { -1, -1, -1, -1 };
#PARAM   subOneY = { 1, 1, 1, 1 };
PARAM   scaleTwoY = -1;
PARAM   subOneY = 1;

# specular is actually now viewer
DP3	specular, fragment.texcoord[6],fragment.texcoord[6];
RSQ	specular, specular.w;
MUL	specular.xyz, specular.w, fragment.texcoord[6];

# load heightmap
TXB		R0, fragment.texcoord[1], texture[7], 2D;
MAD		R0, R0, program.local[0].x, program.local[0].y; # scale and bias
MAD		newtexcoord.xyz, R0, specular, fragment.texcoord[1];

# load the local space surface normal
TXB	localNormal, fragment.texcoord[0], texture[1], 2D;
MOV localNormal.x, localNormal.a;			# rxgb normal map compression
MOV   localNormal.z, 0.99;
MAD	localNormal.xyz, localNormal, scaleTwo, subOne;
DP3   localNormal.w, localNormal, localNormal;
RSQ   localNormal.w, localNormal.w;
MUL   localNormal.xyz, localNormal.w, localNormal;
MUL localNormal.zw, localNormal.xyxy, localNormal.xyxy;

ADD_SAT localNormal.z, localNormal, localNormal.w;
ADD localNormal.z, -localNormal, GlobalLight;
RSQ localNormal.z, localNormal.z;
RCP localNormal.z, localNormal.z;
MUL R2, R2, GlobalLight; # dfm added

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

# normalize localNormal
#DP3   localNormal.w, localNormal, localNormal;
#RSQ   localNormal.w, localNormal.w;
#MUL   localNormal.xyz, localNormal, localNormal.w;

# localNormal filter
MOV	R0.xyz, localNormal;
MOV	R0.z, ZeroFive;
DP3	R0, R0, R0;
MAD_SAT	R0.z, R0.w, scaleTwoY, subOneY;
RSQ	R0, R0.z;
RCP	localNormal.z, R0.w;

# localNormal filter
#MOV		localNormal.z, ZeroFive;
#DP3	R0.x, localNormal,localNormal;
#ADD_SAT	R0.x, 1, -R0.x;
#RSQ		R0.x, R0.x;
#RCP		localNormal.z, R0.x;

#TXB		localNormal, localNormal, texture[0], CUBE;
#MAD		localNormal, localNormal, scaleTwo, subOne;

# localNormal filter
ADD_SAT	R0, newtexcoord, ZeroFive;
TXB	R2, R0, texture[1], 2D;
MOV R2.x, R2.a;
MAD_SAT	R2, R2, scaleTwoX, subOneX;

#ADD	localNormal, localNormal, R2;
#MUL	localNormal, localNormal, 0.5;

# flatten normal over distance (Z)
MAD_SAT	R0, fragment.position.z, scaleTwoX, subOneX;
MAX	R0, R0.w, ZeroFive;
ADD_SAT	localNormal.z, localNormal.z, R0.w;

# normalize the bumpmap
#DP3		R0, localNormal,localNormal;
#RSQ		R0, R0.x;
#MUL		localNormal.xyz, R0.x, localNormal;

#TXB		localNormal, localNormal, texture[0], CUBE;
#MAD		localNormal, localNormal, scaleTwo, subOne;

DP3		R0, localNormal,localNormal;
RSQ		R0, R0.w;
MUL		localNormal.xyz, localNormal, R0.w;

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

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

# modulate by the surface diffuse map
TXP	R0, newtexcoord, texture[4], 2D;
MUL	light.xyz, light, R0;

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

# boost projection, specular light reaches further - DFM added
ADD_SAT	R0.xyz, R0, R0;
MUL	R2.xyz, R2, R0;

# modulate by the light projection
TXP	R2, fragment.texcoord[3], texture[3], 2D;
MUL	light.xyz, light, R2;

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

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

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

END
