!!ARBvp1.0
# road vertex shader
PARAM WORLD_VIEW_PROJECTION[4] = { program.env[0..3] };
PARAM WORLD_VIEW[4] = { program.env[4..7] };
PARAM WORLD[4] = { program.env[8..11] };

PARAM SUN_DIRECTION = program.env[12];			#(.w = intensity)		
PARAM SUN_ANGLE = program.env[14];
PARAM SUN_COLOR = program.env[15];
PARAM TERRAIN_REFLECTANCE = program.env[13];

PARAM BETA_1 = program.env[30];
PARAM BETA_2 = program.env[29];
PARAM BETA_DASH_1 = program.env[27];
PARAM BETA_DASH_2 = program.env[26];
PARAM BETA_1_PLUS_2 = program.env[24];
PARAM ONE_OVER_BETA_1_PLUS_2 = program.env[23];

PARAM HG = program.env[28];		# = 1-g^2, 1+g, 2g, 0
PARAM CONSTANTS = program.env[31];		# = 1.0, log_2 e, 0.5, 0
PARAM TERM_MULTIPLIERS = program.env[25];		# = frac_ext, frac_ins.

PARAM ZERO = program.env[20];
PARAM ONE = program.env[21];
PARAM SHADOWSHARPNESS = program.env[32];
PARAM AMBIENT = program.env[33];      # Ambient term to add to the rendering
PARAM INSCATTERINGMULTIPLIER = program.env[34];      # Term to attenuate the inscattering

PARAM BASE_TEX_PROJECTION = program.env[16];
PARAM DETAIL_TEX_PROJECTION = program.env[17];
PARAM CLOUD_TEX_PROJECTION_0 = program.env[18];
PARAM CLOUD_TEX_PROJECTION_1 = program.env[19];

PARAM EYE_POSITION = program.env[22];

PARAM SPECULAR_POWER = program.env[35];
PARAM DIFFUSE_COLOUR = program.env[36];
PARAM SPECULAR_COLOUR = program.env[37];

PARAM CARCOLOR0 = program.env[38];
PARAM CARCOLOR1 = program.env[39];
PARAM CARCOLOR2 = program.env[40];

ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
ATTRIB iTexCoord0 = vertex.texcoord[0];
ATTRIB iTexCoord1 = vertex.texcoord[1];
ATTRIB iTexCoord2 = vertex.texcoord[2];

OUTPUT oPos = result.position;
OUTPUT oD0 = result.color.primary;
OUTPUT oD1 = result.color.secondary;
OUTPUT oT0 = result.texcoord[0];
OUTPUT oT1 = result.texcoord[1];
OUTPUT oT2 = result.texcoord[2];
OUTPUT oT3 = result.texcoord[3];

# 
# V - View direction
# L - Sun direction
# Theta - Scattering angle
# s - Distance
# E - Total extinction (including reflectance).

TEMP r0, r1, r2, r3, r4, r5, r6, r7;

# Transformation.
DP4     oPos.x, iPos, WORLD_VIEW_PROJECTION[0];
DP4     oPos.y, iPos, WORLD_VIEW_PROJECTION[1];
DP4     oPos.z, iPos, WORLD_VIEW_PROJECTION[2];
DP4     oPos.w, iPos, WORLD_VIEW_PROJECTION[3];

# Dot product sun direction with vertex normal
DP3 r0.xyzw, iNormal, SUN_DIRECTION;
# scale by sun color
MUL     r0.xyz, r0, SUN_COLOR;

# scale by sun and car color and output to diffuse
MUL     r1.xyz, r0, SUN_COLOR;
MUL     oD0, r1, DIFFUSE_COLOUR;

DP4     r1.x, iPos, WORLD[0];
DP4     r1.y, iPos, WORLD[1];
DP4     r1.z, iPos, WORLD[2];
DP4     r1.w, iPos, WORLD[3];

# Calculate V
SUB     r1, EYE_POSITION, r1;	        # V = eye - position
DP3     r1.w, r1, r1;            # Normalize V.
RSQ     r1.w, r1.w;							
MUL     r1, r1, r1.w;

# Calculate specular
# transform Normal to view space and renormalise
DP3     r2.x, iNormal, WORLD[0];
DP3     r2.y, iNormal, WORLD[1];
DP3     r2.z, iNormal, WORLD[2];
DP3		r3, r2, r2;
RSQ		r3.x, r3.x;
MUL		r2, r2, r3.x;

# N.L
DP3	    r3, r2, SUN_DIRECTION;
# (N.L) * N
MUL	    r4, r3, r2;
# (2* (N.L) * N)
ADD	    r4, r4, r4;
#( 2 * (N.L) * N) - L
SUB	    r4, r4, SUN_DIRECTION;
# Renormalise
DP3	    r3, r4, r4;
RSQ	    r3.x, r3.x;
# R = Normalise(2*dot(N,L)*N-L)
MUL	    r4, r4, r3.x;

#dot(R,V)
DP3	    r2, r1, r4;
#max(0,dot(R,V))
MAX	    r2, r2, CONSTANTS.wwww;

# Evaluate specular
MOV     r3.x, r0.x;
MOV     r3.y, r2.x;
MOV 	r3.w, SPECULAR_POWER.x;
LIT     r2, r3;

# Scale by sun colour
MUL	    r2, r2.zzzz, SUN_COLOR;

# Scale by material specular and output
MUL     oD1, r2, SPECULAR_COLOUR;  # Specular


# Angle (theta) between sun direction (L) and view direction (V).
DP3     r0.x, r1, SUN_DIRECTION;       # r0.x = [cos(theta)] = V.L
MAD     r0.y, r0.x, r0.x, CONSTANTS.x;	# r0.y = [1+cos^2(theta)] = Phase1(theta)

# Distance (s)
DP4     r1.x, iPos, WORLD[0];
DP4     r1.y, iPos, WORLD[1];
DP4     r1.z, iPos, WORLD[2];
DP4     r1.w, iPos, WORLD[3];
MOV     r0.z, r1.z;			# store in r0.z for future use.

# Terms used in the scattering equation.
# r0 = [cos(theta), 1+cos^2(theta), s] 

# Extinction term E
MUL     r1, BETA_1_PLUS_2, -r0.z;       # -(beta_1+beta_2) * s
MUL     r1, r1, CONSTANTS.y;           # -(beta_1+beta_2) * s * log_2 e
EX2     r1.x, r1.x;					
EX2     r1.y, r1.y;					
EX2     r1.z, r1.z;                          # r1 = e^(-(beta_1 + beta_2) * s) = E1

# Apply Reflectance to E to get total net effective E
MUL     r3, r1, TERRAIN_REFLECTANCE;   #r3 = E (Total extinction) 

# Phase2(theta) = (1-g^2)/(1+g-2g*cos(theta))^(3/2)
# theta is 180 - actual theta (this corrects for sign)
# c[28] = [1-g^2, 1+g, 2g]
MAD     r4.x, HG.z, r0.x, HG.y;

RSQ     r4.x, r4.x;
MUL     r4.y, r4.x, r4.x;
MUL     r4.x, r4.y, r4.x;
MUL     r0.w, r4.x, HG.x;              # r0.w = Phase2(theta)

# Inscattering (I) = (Beta'_1 * Phase_1(theta) + Beta'_2 * Phase_2(theta)) * 
#        [1-exp(-Beta_1*s).exp(-Beta_2*s)] / (Beta_1 + Beta_2)

MUL     r4, BETA_DASH_1, r0.y;
MUL     r5, BETA_DASH_2, r0.w;
SUB     r6, CONSTANTS.x, r1;
MOV     r7, BETA_1_PLUS_2;

ADD     r4, r4, r5;
MUL     r4, r4, r6;
MUL     r4, r4, ONE_OVER_BETA_1_PLUS_2;	# r4 = I (inscattering)


# Apply Inscattering contribution factors.

MUL     r4, r4, TERM_MULTIPLIERS.y;

# Scale with Sun color & intesity.
MUL     r4, r4, SUN_COLOR;
MUL     r4, r4, SUN_COLOR.w;

MUL     r3, r3, SUN_COLOR;
MUL     r3, r3, SUN_COLOR.w;

# Outputs.
MOV     oT0, r3;                             # Extinction
ADD     oT1, r4, AMBIENT;                      # Inscattering + Ambient term
MOV     oT2, iTexCoord0;
END
