1#include "DualQuaternionSkinning_Shadow.cg" 2 3//Dual quaternion skinning with per-vertex antipodality handling (this is the most robust, but not the most efficient way): 4void dualQuaternionHardwareSkinningTwoWeights_vp( 5 float4 position : POSITION, 6 float3 normal : NORMAL, 7 float2 uv : TEXCOORD0, 8 float4 blendIdx : BLENDINDICES, 9 float4 blendWgt : BLENDWEIGHT, 10 11 out float4 oPosition : POSITION, 12 out float2 oUv : TEXCOORD0, 13 out float4 colour : COLOR, 14 // Support up to 24 bones of float3x4 15 // vs_1_1 only supports 96 params so more than this is not feasible 16 uniform float2x4 worldDualQuaternion2x4Array[24], 17 uniform float4x4 viewProjectionMatrix, 18 uniform float4 lightPos[2], 19 uniform float4 lightDiffuseColour[2], 20 uniform float4 ambient, 21 uniform float4 diffuse) 22{ 23 float2x4 blendDQ = blendTwoWeightsAntipod(blendWgt, blendIdx, worldDualQuaternion2x4Array); 24 25 float len = length(blendDQ[0]); 26 blendDQ /= len; 27 28 float3 blendPosition = calculateBlendPosition(position, blendDQ); 29 30 //No need to normalize, the magnitude of the normal is preserved because only rotation is performed 31 float3 blendNormal = calculateBlendNormal(normal, blendDQ); 32 33 oPosition = mul(viewProjectionMatrix, float4(blendPosition, 1.0)); 34 35 // Lighting - support point and directional 36 float3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition.xyz * lightPos[0].w)); 37 float3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition.xyz * lightPos[1].w)); 38 39 oUv = uv; 40 41 colour = diffuse * (ambient + (saturate(dot(lightDir0, blendNormal)) * lightDiffuseColour[0]) + 42 (saturate(dot(lightDir1, blendNormal)) * lightDiffuseColour[1])); 43} 44 45//Two-phase skinning: dual quaternion skinning with scale and shear transformations 46void dualQuaternionHardwareSkinningTwoWeightsTwoPhase_vp( 47 float4 position : POSITION, 48 float3 normal : NORMAL, 49 float2 uv : TEXCOORD0, 50 float4 blendIdx : BLENDINDICES, 51 float4 blendWgt : BLENDWEIGHT, 52 53 54 out float4 oPosition : POSITION, 55 out float2 oUv : TEXCOORD0, 56 out float4 colour : COLOR, 57 // Support up to 24 bones of float3x4 58 // vs_1_1 only supports 96 params so more than this is not feasible 59 uniform float2x4 worldDualQuaternion2x4Array[24], 60 uniform float3x4 scaleM[24], 61 uniform float4x4 viewProjectionMatrix, 62 uniform float4 lightPos[2], 63 uniform float4 lightDiffuseColour[2], 64 uniform float4 ambient, 65 uniform float4 diffuse) 66{ 67 //First phase - applies scaling and shearing: 68 float3x4 blendS = blendWgt.x*scaleM[blendIdx.x]; 69 blendS += blendWgt.y*scaleM[blendIdx.y]; 70 71 float3 pass1_position = mul(blendS, position); 72 float3x3 blendSrotAT = adjointTransposeMatrix(float3x3(blendS)); 73 float3 pass1_normal = normalize(mul(blendSrotAT, normal.xyz)); 74 75 //Second phase 76 float2x4 blendDQ = blendTwoWeightsAntipod(blendWgt, blendIdx, worldDualQuaternion2x4Array); 77 78 float len = length(blendDQ[0]); 79 blendDQ /= len; 80 81 float3 blendPosition = calculateBlendPosition(float4(pass1_position, 1.0), blendDQ); 82 83 //No need to normalize, the magnitude of the normal is preserved because only rotation is performed 84 float3 blendNormal = calculateBlendNormal(pass1_normal, blendDQ); 85 86 oPosition = mul(viewProjectionMatrix, float4(blendPosition, 1.0)); 87 88 // Lighting - support point and directional 89 float3 lightDir0 = normalize(lightPos[0].xyz - (blendPosition.xyz * lightPos[0].w)); 90 float3 lightDir1 = normalize(lightPos[1].xyz - (blendPosition.xyz * lightPos[1].w)); 91 92 oUv = uv; 93 colour = diffuse * (ambient + (saturate(dot(lightDir0, blendNormal)) * lightDiffuseColour[0]) + 94 (saturate(dot(lightDir1, blendNormal)) * lightDiffuseColour[1])); 95} 96