1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
!!ARBvp1.0
# Vertex Program for lit, skinned avatars
# Parameters
#PARAM gGravity = program.env[62];
PARAM gMat[45] = { program.env[0..44] };
PARAM gWindDir = program.env[60]; # wind direction with strength stored in w
PARAM gSinWaveParams = program.env[61]; # frequency, frequency2, frequency, phase
PARAM gMinMaxConstants = {1.0, 0.166666, 0.0083143, .00018542}; #minimax-generated coefficients
PARAM gPiConstants = {0.159154943, 6.28318530, 3.141592653, 1.5707963}; # {1/2PI, 2PI, PI, PI/2}
PARAM gProjection[4] = { state.matrix.projection };
PARAM gModelAmbient = state.lightmodel.ambient;
PARAM gMaterialDiffuse = state.material.diffuse;
PARAM gLightDir0 = state.light[0].position;
PARAM gDiffuseCol0 = state.light[0].diffuse;
PARAM gLightDir1 = state.light[1].position;
PARAM gDiffuseCol1 = state.light[1].diffuse;
PARAM gLightPos2 = state.light[2].position;
PARAM gDiffuseCol2 = state.light[2].diffuse;
PARAM gLightPos3 = state.light[3].position;
PARAM gDiffuseCol3 = state.light[3].diffuse;
# Per vertex inputs
ATTRIB iPos = vertex.position;
ATTRIB iNormal = vertex.normal;
ATTRIB iTex0 = vertex.texcoord;
ATTRIB iWeight = vertex.attrib[1];
ATTRIB iClothing = vertex.attrib[4];
# Temporaries
TEMP blendedPos; # weighted sum of tpos0 and tpos1
TEMP blendNorm; # weighted sum of eyeNormal0 and eyeNormal1
TEMP temp0;
TEMP temp1; # another general purpose temp
TEMP temp2;
TEMP windEffect; # amount of displacement from wind
TEMP blendMatX;
TEMP blendMatY;
TEMP blendMatZ;
ALIAS colorAcc = temp0;
ALIAS sinWave = temp0;
ALIAS offsetPos = temp1;
ALIAS dots = temp1; # dot product for lighting calculations
ALIAS posDelta = windEffect; # movement of vertex according to joint angle
ALIAS pivot_pos = windEffect;
ALIAS scaledWeight = temp0;
ALIAS divisor = temp2;
ALIAS lightDir = windEffect;
ADDRESS address;
# Outputs
OUTPUT oPos = result.position; # position
OUTPUT oCol0 = result.color; # primary color
OUTPUT oTex0 = result.texcoord; # texture coordinate set 0
OUTPUT oFog = result.fogcoord; # output fog coordinates
#fix input blending weight
ARL address.x, iWeight.x;
FRC scaledWeight.x, iWeight;
# Blend joint matrices
MUL blendMatX, gMat[address.x + 1], {1,1,1,1};
SUB blendMatX, blendMatX, gMat[address.x + 0];
MAD blendMatX, scaledWeight.x, blendMatX, gMat[address.x + 0];
DP3 blendNorm.x, blendMatX, iNormal;
MUL blendMatY, gMat[address.x + 16], {1,1,1,1};
SUB blendMatY, blendMatY, gMat[address.x + 15];
MAD blendMatY, scaledWeight.x, blendMatY, gMat[address.x + 15];
DP3 blendNorm.y, blendMatY, iNormal;
MUL blendMatZ, gMat[address.x + 31], {1,1,1,1};
SUB blendMatZ, blendMatZ, gMat[address.x + 30];
MAD blendMatZ, scaledWeight.x, blendMatZ, gMat[address.x + 30];
DP3 blendNorm.z, blendMatZ, iNormal;
#wind
DP3 windEffect, blendNorm, gWindDir;
MAD windEffect.xyz, windEffect, gSinWaveParams, gSinWaveParams.w; # use sin wave params to scale and offset input
#reduce to period of 2 PI
MUL temp1.xyz, windEffect, gPiConstants.x; # change input as multiple of [0-2PI] to [0-1]
EXP temp0, temp1.x; # find mod(x, 1)
MUL windEffect.x, temp0.y, gPiConstants.y; # scale from [0,1] to [0, 2PI]
# offset to [-PI, PI]
ADD windEffect.xyz, windEffect, {-3.141592, -3.141592, -3.141592, -3.141592};
#calculate sinusoid
MUL temp1, windEffect, windEffect; # x^2
MAD sinWave, -temp1, gMinMaxConstants.w, gMinMaxConstants.z; # y = -(x^2)/7! + 1/5!
MAD sinWave, sinWave, -temp1, gMinMaxConstants.y; # y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3!
MAD sinWave, sinWave, -temp1, gMinMaxConstants.x; # y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1
MUL sinWave, sinWave, windEffect; # y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1)
# sinWave.x holds sin(norm . wind_direction)+
MUL sinWave.xyz, sinWave, gWindDir.w; # multiply by wind strength in gWindDir.w [-wind, wind]
SUB sinWave.xyz, sinWave, {0.2, 0.2, 0.2, 0.2};
MUL sinWave.xyz, sinWave, iClothing.w; # modulate by clothing coverage
DP3 temp2.x, iClothing, iClothing;
MAX temp2.x, temp2, {0, 0, 0, 0.2};
MUL temp2.x, temp2.x, {3, 0, 0, 0};
MUL sinWave.x, sinWave, temp2;
#add pseudo-specular effect
ADD blendNorm, blendNorm, {0, 0, -0.5, 0};
#renormalize normal
DP3 divisor.w, blendNorm, blendNorm;
RSQ divisor.xyz, divisor.w;
MUL blendNorm.xyz, blendNorm, divisor;
#Output position
DP4 blendedPos.x, blendMatX, iPos;
DP4 blendedPos.y, blendMatY, iPos;
DP4 blendedPos.z, blendMatZ, iPos;
MUL offsetPos, gWindDir, sinWave.x; # multiply wind effect times clothing displacement
MAD blendedPos, {-1.0, -1.0, -1.0, 0.0}, offsetPos, blendedPos; # add to offset vertex position, and zero out effect from w
MOV blendedPos.w, {0, 0, 0, 1};
#Projection
DP4 oPos.x, gProjection[0], blendedPos; # projection matrix
DP4 oPos.y, gProjection[1], blendedPos;
DP4 oPos.z, gProjection[2], blendedPos;
DP4 oPos.w, gProjection[3], blendedPos;
#Light 0
DP3 dots.x, blendNorm, gLightDir0;
MAD dots.x, dots.x, {0.55, 0.55, 0.55, 0.55}, {0.3, 0.3, 0.3, 0.3};
MAX dots, dots, {0, 0, 0, 0};
# Accumulate color contributions.
MAD temp2, dots.x, gDiffuseCol0, gModelAmbient;
MOV colorAcc.xyz, temp2;
#Light 1
DP3 dots.x, blendNorm, gLightDir1;
#Light 2
SUB lightDir, gLightPos2, blendedPos;
DP3 divisor.w, lightDir, lightDir;
RSQ divisor.xyz, divisor.w;
MUL lightDir.xyz, lightDir, divisor;
DP3 dots.y, blendNorm, lightDir;
#Light 3
SUB lightDir, gLightPos3, blendedPos;
DP3 divisor.w, lightDir, lightDir;
RSQ divisor.xyz, divisor.w;
MUL lightDir.xyz, lightDir, divisor;
DP3 dots.z, blendNorm, lightDir;
#Apply lights
MAD dots, dots, {0.55, 0.55, 0.55, 0.55}, {0.3, 0.3, 0.3, 0.3};
MAX dots, dots, {0, 0, 0, 0};
MAD colorAcc.xyz, dots.x, gDiffuseCol1, colorAcc;
MAD colorAcc.xyz, dots.y, gDiffuseCol2, colorAcc;
MAD colorAcc.xyz, dots.z, gDiffuseCol3, colorAcc;
#Output fog
# This causes issues on ATI when fog is disabled
MOV oFog.x, blendedPos.z;
#Output color
MOV colorAcc.w, {0, 0, 0, 1.0};
MUL oCol0, gMaterialDiffuse, colorAcc;
#Output tex coordinate
MOV oTex0, iTex0;
END
|