!!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, 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], 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], 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], 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], 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, program.env[5], vertex.position;

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

# texture 6's texcoords will be the halfangle in texture space

# calculate normalized vector to light in R0
SUB R0, program.env[4], vertex.position;
DP3 R1, R0, R0;
RSQ R1, R1.x;
MUL R0, R0, R1.x;

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

DP3 R2, R1, R1;
RSQ R2, R2.x;

MAD R0, R1, R2.x, R0;
#MUL	R1, R1, R2.x;

# add together to become the half angle vector in object space (non-normalized)
#ADD	R0, R0, R1;

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

SUB R1, 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;

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

END

#=======================================================================
# Brilliant highlights ver 0.60a			        2.6.2006
#=======================================================================
#
# Version history
# ---------------
#
# 0.60 # Lost cause makes a return, also a backlight idea...
#
# 0.50 # Redesigned specular lights to reflection vector model
#
# 0.40 # Redesigned whole lighting, now specular is independent of diffuse
#
# 0.31 # Finally a working result combining with .30 and .21 strenghts
#	   Also, no boosting or overshooting needed anymore
#
# 0.30 # Rewamped result compositing to MUL based (no glow in the dark)
#
# 0.21 # Spied the Quake4 shader and found some performance tweaks
#	   Few performance tweaks for my own code as well
#
# 0.20 # Finalized the pow range and overshoot/boost values
#
#-----------------------------------------------------------------------

!!ARBfp1.0 
OPTION ARB_precision_hint_nicest;
#OPTION NV_fragment_program2;

# 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

# env[0] is the diffuse modifier
# env[1] is the specular modifier

TEMP	light, backlight, color, R1, R2, R3, localNormal, specular, clamp;

#########################################################
############## adjustable parameters ####################
#########################################################

# Maximum power (shinyness, default 8.0)
PARAM	maxpow = 9.95;

# Minimum power	(default 2.0)
PARAM	minpow = 0.05;

# Backlight scatter (0.0 - 1.0, default 0.33)
PARAM	blscatter = 0.66;

# Backlight strenght (0.0 - 1.0, default 0.175)
PARAM	blstr = 0.175;

#########################################################

#PARAM	subOne = { -2, -2, -2, -2 };
#PARAM	scaleTwo = { 4, 4, 4, 4 };
PARAM	subOne = { -1, -1, -1, -1 };
PARAM	scaleTwo = { 2, 2, 2, 2 };

#PARAM	xero = { 0, 0, 0, 1 };
PARAM	saab = { 0, 0, 0, 0.75 };	# specular AA bias

# ----------------------------------- normalize -- #

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

# light
DP3	light.w, fragment.texcoord[0], fragment.texcoord[0];
RSQ	light.w, light.w;
MUL	light.xyz, light.w, fragment.texcoord[0];

# setup clamp for lights behind objects
MAX	clamp.w, -light.z, 0.065;
ADD	clamp.w, clamp, clamp;

# backlight
MOV	backlight, light;

# localNormal (load)
TEX	localNormal, fragment.texcoord[1], texture[1], 2D;
MOV 	localNormal.x, localNormal.a;
MOV	localNormal.z, 0.75;
MAD	localNormal, localNormal, scaleTwo, subOne;

# localNormal filter
ADD	R1, fragment.texcoord[1], saab;
TXB	R2, R1, texture[1], 2D;
MOV 	R2.x, R2.a;
MAD	R2, R2, scaleTwo, subOne;

ADD	localNormal, localNormal, R2;
MUL	localNormal, localNormal, 0.75;

# localNormal (normalize)
DP3	R1.w, localNormal, localNormal;
RSQ	R1.w, R1.w;
MUL	localNormal.xyz, R1.w, localNormal;

# -------- diffuse map modulated by light color -- #

TEX	R1, fragment.texcoord[4], texture[4], 2D;
MUL	color.xyz, R1, program.env[0];

# ------------------------------------- reflect -- #

# reflect light from localNormal

DP3	R2.w, localNormal, localNormal;
DP3	R2.x, localNormal, light;
MUL	R2.x, R2, 2.15;

# divide by mul
RCP	R1.w, R2.w;
MUL	R2.x, R2.x, R1.w;

MAD	R1.xyz, R2.xxxx, localNormal, -light;

# ------------------------------------------------ #

# specular.w is the specular volume
DP3	specular.w, R1, specular;
SUB	specular.w, specular, clamp.w;

DP3	light, light, localNormal;
SUB_SAT light, light, clamp.w;

# create backlight
DP3	backlight, backlight, localNormal;
ADD_SAT	backlight, backlight, blscatter;
MUL	backlight, backlight, blstr;

# ------------------------------------------------ #

# R3 is the specular map (* 2)
TEX	R3, fragment.texcoord[5], texture[5], 2D;
# no color please!
ADD	R3.rgb, R3.gggg, R3.gggg;

# MIN + MAX power to R1.w (modulated by specular map)
# Change the values 8.0 and 2.0 to change the maximum and minimum of the highlight tightness range (in that order)
MAD	R1.w, R3.y, maxpow, minpow;

# pow specular
POW_SAT	R2.rgb, specular.w, R1.w;

# mask specular with specular map
MUL	R2.rgb, R2, R3;

# --------------------------------------------- #

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


# boost projection, specular light reaches further
MUL_SAT	R3.rgb, R1, 6.4;
MUL	R2.rgb, R2, R3;

MUL_SAT	R3.rgb, R1, 3.0;
MAD	light.rgb, backlight, R3, light;

# compute "length" from diffuse falloff texcoords
SUB	R1.xy, fragment.texcoord[2], 0.485;
MUL	R1.xy, R1, R1;
ADD	R1.w, R1.x, R1.y;
RSQ	R1.w, R1.w;
RCP	R1.w, R1.w;
MUL	R1.w, R1, 0.485;

# modulate by "lenght"
SUB_SAT	light.rgb, light, R1.w;
SUB_SAT	R2.rgb, R2, R1.w;

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

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

# perform the specular bump mapping
#DP3_SAT specular.w, specular, localNormal;

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

# modulate by the constant specular factor
#MUL	R1, R1, program.env[1];

# modulate by the specular map * 2
#TEX	R2, fragment.texcoord[5], texture[5], 2D;
#ADD	R2, R2, R2;
#MAD	color.xyz, R1, R2, color;

#MUL	color.xyz, light, color;

# --------------------------------------------- #

# turn highlight to light color
MUL	R2.rgb, R2, program.env[0];

# add up result

#
# Note to self:
#   MUL only is not good for result as dark colors dont get highlights
#   must use MAD or such...
#

# specular is now in R2
MAD	color.rgb, color, light, R2;

# --------------------------------------------- #

# modify by the vertex color

MUL result.color.xyz, color, fragment.color;

END


