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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
!!ARBvp1.0
# Vertex Program for lit, skinned avatars
# Parameters
PARAM gMat[45] = { program.env[0..44] };
PARAM gEmbossScale = program.env[63];
PARAM gWindDir = program.env[60]; # wind direction with strength stored in w
PARAM gSinWaveParams = program.env[61]; # frequency, frequency2, frequency, phase
PARAM gGravity = program.env[62];
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 gProj[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[0];
ATTRIB iTex1 = vertex.texcoord[1];
ATTRIB iWeight = vertex.attrib[1];
ATTRIB iClothing = vertex.attrib[4];
ATTRIB iBinormal = vertex.attrib[6];
# Temporaries
TEMP blendMatX;
TEMP blendMatY;
TEMP blendMatZ;
TEMP blendPos; # weighted sum of tpos0 and tpos1
TEMP blendNorm; # weighted sum of eyeNormal0 and eyeNormal1
TEMP blendBinorm; # result of skinned binormal
TEMP temp0;
TEMP temp1; # another general purpose temp
TEMP temp2;
ALIAS blendTangent = temp2; # result of skinned tangent
ALIAS colorAcc = temp0;
ALIAS offsetPos = temp1;
ALIAS dots = temp1; # dot product for lighting calculations
ALIAS scaledWeight = temp0; # vertex weight as decoded from input weight
ALIAS divisor = temp2;
ALIAS sinWave = temp0;
ALIAS windEffect = temp2;
ALIAS lightDir = blendMatX;
ADDRESS address;
# Outputs
OUTPUT oPos = result.position; # position
OUTPUT oCol0 = result.color; # primary color
OUTPUT oTex0 = result.texcoord[0]; # texture coordinate set 0
OUTPUT oTex1 = result.texcoord[1]; # texture coordinate set 1
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;
DP3 blendBinorm.x, blendMatX, iBinormal;
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;
DP3 blendBinorm.y, blendMatY, iBinormal;
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;
DP3 blendBinorm.z, blendMatZ, iBinormal;
#wind
DP3 windEffect, blendNorm, gWindDir;
DP3 blendPos.x, blendMatZ, iPos;
MAD windEffect.xyz, blendPos.x, {0.015, 0.015, 0.015, 0}, windEffect;
MAD windEffect.w, windEffect, {0, 0, 0, 2}, {0, 0, 0, 1}; # move wind offset value to [-1, 3]
MUL windEffect.w, windEffect, gWindDir; # modulate wind strength
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]
ADD temp1.z, temp1.z, -gPiConstants.w; # shift normal oscillation by PI/2
EXP temp0, temp1.z; # find mod(x, 1)
MUL windEffect.z, 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) with primary frequency
# sinWave.y holds sin(norm . wind_direction) with secondary frequency
# sinWave.z hold cos(norm . wind_direction) with primary frequency
MAD sinWave.xyz, sinWave, gWindDir.w, windEffect.w; # multiply by wind strength in gWindDir.w [-wind, wind]
# add normal facing bias offset [-wind,wind] -> [-wind - .25, wind + 1]
DP3 temp1, blendNorm, gGravity; # how much is this normal facing in direction of gGravity?
MIN temp1, temp1, {0.2, 0, 0, 0}; # clamp [-1, 1] to [-1, 0.2]
MUL temp1, temp1, {1.5, 0, 0, 0}; # scale from [-1,0.2] to [-1.5, 0.3]
ADD sinWave.x, sinWave, temp1; # add gGravity effect to sinwave (only primary frequency)
MUL sinWave.xyz, sinWave, iClothing.w; # modulate by clothing coverage
#MAD temp2, {1,1,1,1}, iClothing.w, {-1,-1,-1,-1};
#ADD sinWave, sinWave, temp2;
MAX sinWave.xyz, sinWave, {-1, -1, -1, -1}; # clamp to underlying body shape
MUL offsetPos, iClothing, sinWave.x; # multiply wind effect times clothing displacement
MAD temp2, gWindDir, sinWave.z, blendNorm; # calculate normal offset due to wind oscillation
MAD offsetPos, {1.0, 1.0, 1.0, 0.0}, offsetPos, iPos; # add to offset vertex position, and zero out effect from w
MAD blendNorm, temp2, {2, 2, 2, 2}, blendNorm; # add sin wave effect on normals (exaggerated)
#add "backlighting" effect
SUB colorAcc, {1, 1, 1, 1}, iClothing;
MAD blendNorm, colorAcc.w, {0, 0, -0.2, 0}, blendNorm;
#renormalize normal (again)
DP3 divisor.w, blendNorm, blendNorm;
RSQ divisor.xyz, divisor.w;
MUL blendNorm.xyz, blendNorm, divisor;
#project binormal to normal plane to ensure orthogonality
DP3 temp2, blendNorm, blendBinorm;
SUB blendBinorm, blendBinorm, temp2;
#renormalize binormal
DP3 divisor.w, blendBinorm, blendBinorm;
RSQ divisor.xyz, divisor.w;
MUL blendBinorm.xyz, blendBinorm, divisor;
#tangent = binormal X normal
XPD blendTangent, blendNorm, blendBinorm;
#oTex1 = iTex0 + LLVector2( gLightDir0 * tangent, gLightDir0 * binormal );
DP3 blendTangent.x, gLightDir0, blendTangent;
DP3 blendTangent.y, gLightDir0, blendBinorm;
MAD oTex1, gEmbossScale.x, blendTangent, iTex0;
#Output position
DP4 blendPos.x, blendMatX, offsetPos;
DP4 blendPos.y, blendMatY, offsetPos;
DP4 blendPos.z, blendMatZ, offsetPos;
MOV blendPos.w, {0, 0, 0, 1};
#Projection
DP4 oPos.x, gProj[0], blendPos;
DP4 oPos.y, gProj[1], blendPos;
DP4 oPos.z, gProj[2], blendPos;
DP4 oPos.w, gProj[3], blendPos;
#Light 0
DP3 colorAcc.x, blendNorm, gLightDir0;
MAD colorAcc.x, colorAcc.x, {0.55, 0.55, 0.55, 0.55}, {0.3, 0.3, 0.3, 0.3};
MAX colorAcc, colorAcc, {0, 0, 0, 0};
# Accumulate color contributions.
MAD colorAcc.xyz, colorAcc.x, gDiffuseCol0, gModelAmbient;
#Light 1
DP3 dots.x, blendNorm, gLightDir1;
#Light 2
SUB lightDir, gLightPos2, blendPos;
DP3 divisor.w, lightDir, lightDir;
RSQ divisor.xyz, divisor.w;
MUL lightDir, lightDir, divisor;
DP3 dots.y, blendNorm, lightDir;
#Light 3
SUB lightDir, gLightPos3, blendPos;
DP3 divisor.w, lightDir, lightDir;
RSQ divisor.xyz, divisor.w;
MUL lightDir, lightDir, divisor;
DP3 dots.z, blendNorm, lightDir;
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, dots.x, gDiffuseCol1, colorAcc;
MAD colorAcc, dots.y, gDiffuseCol2, colorAcc;
MAD colorAcc, dots.z, gDiffuseCol3, colorAcc;
#Output color
MOV colorAcc.w, {0, 0, 0, 1.0};
MUL oCol0, gMaterialDiffuse, colorAcc;
#Output tex coordinate
MOV oTex0, iTex0;
#Output fog
MOV oFog.x, blendPos.z;
END
|