!!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