!!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
#
# output:
#
# texture 0 is the 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 the per-surface specular map
# texture 6 is the specular lookup table

TEMP	R0, R1, R2;

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


# calculate vector to light in R0
SUB		R0.xyz, program.env[4], vertex.position;

# put into texture space for TEX0
DP3		result.texcoord[0].x, vertex.attrib[9], R0;
DP3		result.texcoord[0].y, vertex.attrib[10], R0;
DP3		result.texcoord[0].z, vertex.attrib[11], R0;

# 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[10];
DP4		result.texcoord[1].y, vertex.attrib[8], program.env[11];

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

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

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

# calculate normalized vector to viewer in R1
SUB		R1.xyz, program.env[5], vertex.position;

# put viewer to texture space
DP3		result.texcoord[6].x, vertex.attrib[9], R1;
DP3		result.texcoord[6].y, vertex.attrib[10], R1;
DP3		result.texcoord[6].z, vertex.attrib[11], R1;

SUB R1.xyz, program.env[6], 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[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;
OPTION NV_fragment_program2;

#SHORT TEMP light, color, R1, R2, R3, R4, R5, localNormal;	#, specular;
SHORT TEMP toLight, light, toViewer, halfAngle, color, R1, R2, R3, localNormal, specular, newtexcoord;
#TEMP view, view2, sample, height, R0, tmp, offset, Noffset, Toffset, Soffset, Eoffset;

#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.25, -1.25, -1.25, -1.25 };
#PARAM   scaleTwo = { 2.5, 2.5, 2.5, 2.5 };
#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	specExp = { 32, 0, 0, 0 };
#PARAM	specExp = { 16, 0, 0, 0 };

#PARAM	pointFive = { 0.5, 0.5, 0.5, 0.5 };

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;

# load the specular half angle first, because
# the ATI shader gives a "too many indirections" error
# if this is done right before the texture indirection

#-----------------
##TXL	specular, fragment.texcoord[6], texture[0], CUBE;	*ORIGINALE
##MADH	specular, specular, scaleTwo, subOne;			*ORIGINALE


# instead of using the normalization cube map, normalize with math
#DP3H		specular, fragment.texcoord[6],fragment.texcoord[6];
#RSQH		specular, specular.x;
#MULH		specular.xyz, specular.x, fragment.texcoord[6];
#-----------------

#
# the amount of light contacting the fragment is the
# product of the two light projections and the surface
# bump mapping
#

# perform the diffuse bump mapping

#-----------------
##TXL	light, fragment.texcoord[0], texture[0], CUBE;
##MADH	light, light, scaleTwo, subOne;

# instead of using the normalization cube map, normalize with math
#DP3H		light, fragment.texcoord[0],fragment.texcoord[0];
#RSQH		light, light.x;
#MULH		light.xyz, light.x, fragment.texcoord[0];
#-----------------

# normalize the direction to the light
#DP3H		toLight, fragment.texcoord[0],fragment.texcoord[0];
#RSQH		toLight, toLight.x;
#MULH		toLight.xyz, toLight.x, fragment.texcoord[0];

#TXL		toLight, fragment.texcoord[0], texture[0], CUBE;
#MADH		toLight.xyz, toLight, scaleTwo, subOne;

# normalize the direction to the viewer
#DP3H		toViewer, fragment.texcoord[6],fragment.texcoord[6];
#RSQH		toViewer, toViewer.x;
#MULH		toViewer.xyz, toViewer.x, fragment.texcoord[6];

#TXL		toViewer, fragment.texcoord[6], texture[0], CUBE;
#MADH		toViewer.xyz, toViewer, scaleTwo, subOne;

NRMH toLight.xyz, fragment.texcoord[0];
NRMH toViewer.xyz, fragment.texcoord[6];

#NRMH specular.xyz, fragment.texcoord[6];
#NRMH light.xyz, fragment.texcoord[0];

# load heightmap
TXL		R1, fragment.texcoord[1], texture[7], 2D;
MADH	R1, R1, program.local[0].x, program.local[0].y; # scale and bias
MADH	newtexcoord.xyz, R1, toViewer, fragment.texcoord[1];

#TXL localNormal, Noffset, texture[1], 2D;
TXL localNormal, fragment.texcoord[1], texture[1], 2D;
MOVH localNormal.x, localNormal.a;
MOVH localNormal.z, 0.99;
MADH localNormal.xyz, localNormal, scaleTwo, subOne;
NRMH localNormal.xyz, localNormal;
MULH localNormal.zw, localNormal.xyxy, localNormal.xyxy;

ADDH_SAT localNormal.z, localNormal, localNormal.w;
ADDH localNormal.z, -localNormal, GlobalLight;
RSQH localNormal.z, localNormal.z;
RCPH localNormal.z, localNormal.z;
RFLH_SAT R3, localNormal, light;
MULH R3, R3, GlobalLight; # dfm added

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

# normalize localNormal
#DP3H   localNormal.w, localNormal, localNormal;
#RSQH   localNormal.w, localNormal.w;
#MULH   localNormal.xyz, localNormal, localNormal.w;

# localNormal filter
MOVH	R1.xyz, localNormal;
MOVH	R1.z, ZeroFive; #0.0;
DP3H	R1, R1, R1;
MADH_SAT	R1.z, R1.w, scaleTwoY, subOneY;	#-1, 1;
RSQH	R1, R1.z;
RCPH	localNormal.z, R1.w;

# localNormal filter
#MOVH		localNormal.z, ZeroFive; #0.0;
#DP3H	R1.x, localNormal,localNormal;
#ADDH_SAT	R1.x, 1, -R1.x;
#RSQH		R1.x, R1.x;
#RCPH		localNormal.z, R1.x;

# localNormal filter
ADDH_SAT	R1, newtexcoord, ZeroFive;
TXL	R2, R1, texture[1], 2D;		#TXB
MOVH R2.x, R2.a;
MADH_SAT	R2, R2, scaleTwoX, subOneX;

#ADDH	localNormal, localNormal, R2;
#MULH	localNormal, localNormal, 0.5;

# flatten normal over distance (Z)
MADH_SAT	R1.w, fragment.position.z, scaleTwoX, subOneX;	#4.0, -3.5;
MAXH	R1.w, R1.w, ZeroFive; #0.0;
ADDH_SAT	localNormal.z, localNormal.z, R1.w;

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

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

# localNormal (normalize)
DP3H	R1.w, localNormal, localNormal;
RSQH	R1.w, R1.w;
MULH	localNormal.xyz, R1.w, localNormal;

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

# diffuse dot product
DP3H light, toLight, localNormal;

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

# boost projection, specular light reaches further - DFM added
ADDH_SAT	R1.xyz, R1, R1;
MULH	R2.xyz, R2, R1;

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

#
# the light will be modulated by the diffuse and
# specular surface characteristics
#

# modulate by the diffuse map and constant diffuse factor
#TXL R1, Toffset, texture[4], 2D;
#TXL R1, fragment.texcoord[1], texture[4], 2D;
TXL		color.xyz, fragment.texcoord[1], texture[4], 2D;
#MULH color.xyz, R1, program.env[0];

# calculate the half angle vector and normalize
ADDH		halfAngle, toLight, toViewer;
DP3H		R1, halfAngle, halfAngle;
RSQH		R1, R1.x;
MULH		halfAngle.xyz, halfAngle, R1.x;

# calculate specular
DP3H	R1, halfAngle, localNormal;

# perform the specular bump mapping
#DP3H specular.xyz, halfAngle, localNormal;
DP3H toViewer.xyz, halfAngle, localNormal;

# modulate falloff by diffusemap alpha
RCPH   R2, R1.w;
MULH   R2, specExp, R2;

# use power instead of table
#POWH		R1, R1.x, program.env[2].x;
#MULH		R1, R1, program.env[2].y;

# use power instead of table
#POWH		R1.w, R1.w, program.env[2].x;
#MULH		R1.w, R1.w, program.env[2].y;

# perform a dependent table read for the specular falloff
##TXL	R1, R1.x, texture[6], 2D;

POWH_SAT   R1, R1.x, R2.x;
#POWH_SAT R1, R1.x, specExp.x;
#MADH_SAT R1, R1.x, 18.0, -16.5;	#ALTERNATIVO CON ACCENTUAZIONE SPECULARE
#MADH_SAT R1, R1.x, 10.0, -8.5;
#MADH_SAT R1, R1.x, 4.0, -3.0;		#VERSIONE DI HUMUS ESTREMAMENTE SIMILE ALL'ORIGINALE
MULH R1, R1, R1;

# use power instead of table
#POWH		R1, R1.x, R2.a;

# use power instead of table
#POWH		R1, R1.x, specExp.x;
#MULH		R1.xyz, R1, 2.0;

#SUBH_SAT R1.x, toViewer.x, 0.24;
#MULH R1.x, R1.x, R1.x;
#MULH_SAT R1.x, R1.x, 16.0;		#8.0

MADH_SAT R1, toViewer, R3.x, R1;
MADH_SAT R1, R3.x, 0.32, R1;

# no color please!
#ADDH	R1.rgb, R1.gggg, R1.gggg;

MULH R1.xyz, R1.x, program.env[1];

#TXL R2, Soffset, texture[5], 2D;
TXL R2, fragment.texcoord[1], texture[5], 2D;
ADDH R2, R2, R2;
#ADDH	R2, R2, 0.121875;
#ADDH	R2, R2, 0.2575;
#ADDH	R2, R2, 0.02875;
#ADDH	R2, 0.7, 0.175;
#MULH R2, R2, 1.4;

MADH color.xyz, R1, R2, color;
MULH color.xyz, light, color;

# light color
MULH color.xyz, color, program.env[0];

# global illumination trick
MULH	R1.w, localNormal.z, GlobalLight;	#1.0;
MULH	R1.w, R1, R1;
MULH	color.xyz, color, R1.w;

MULH result.color.xyz, color, fragment.color;

END
