[12115] | 1 | //--------------------------------------------------------------------------- |
---|
| 2 | //These materials/shaders are part of the NEW InstanceManager implementation |
---|
| 3 | //Written by Matias N. Goldberg ("dark_sylinc") |
---|
| 4 | //--------------------------------------------------------------------------- |
---|
| 5 | |
---|
| 6 | //--------------------------------------------- |
---|
| 7 | //Vertex Shader Input |
---|
| 8 | //--------------------------------------------- |
---|
| 9 | struct VS_INPUT |
---|
| 10 | { |
---|
| 11 | float4 Position : POSITION; |
---|
| 12 | float3 Normal : NORMAL; |
---|
| 13 | float3 Tangent : TANGENT; |
---|
| 14 | #ifdef BONE_TWO_WEIGHTS |
---|
| 15 | float4 weights : BLENDWEIGHT; |
---|
| 16 | #endif |
---|
| 17 | float2 uv0 : TEXCOORD0; |
---|
| 18 | float4 m03 : TEXCOORD1; //m03.w is always 0 |
---|
| 19 | |
---|
| 20 | float2 mOffset : TEXCOORD2; |
---|
| 21 | |
---|
| 22 | #ifdef BONE_MATRIX_LUT |
---|
| 23 | float4 worldMatrix0 : TEXCOORD3; |
---|
| 24 | float4 worldMatrix1 : TEXCOORD4; |
---|
| 25 | float4 worldMatrix2 : TEXCOORD5; |
---|
| 26 | #endif |
---|
| 27 | }; |
---|
| 28 | |
---|
| 29 | #include "InstancingVertexInterpolators.cg" |
---|
| 30 | #ifdef ST_DUAL_QUATERNION |
---|
| 31 | #include "DualQuaternionSkinning_Shadow.cg" |
---|
| 32 | #endif |
---|
| 33 | |
---|
| 34 | //--------------------------------------------- |
---|
| 35 | //Main Vertex Shader |
---|
| 36 | //--------------------------------------------- |
---|
| 37 | VS_OUTPUT main_vs( in VS_INPUT input, |
---|
| 38 | uniform float4x4 viewProjMatrix, |
---|
| 39 | |
---|
| 40 | #ifdef DEPTH_SHADOWCASTER |
---|
| 41 | uniform sampler2D matrixTexture : register(s0) |
---|
| 42 | #else |
---|
| 43 | uniform sampler2D matrixTexture : register(s2) |
---|
| 44 | #endif |
---|
| 45 | |
---|
| 46 | #if defined( DEPTH_SHADOWCASTER ) || defined( DEPTH_SHADOWRECEIVER ) |
---|
| 47 | , uniform float4 depthRange |
---|
| 48 | #endif |
---|
| 49 | #ifdef DEPTH_SHADOWRECEIVER |
---|
| 50 | , uniform float4x4 texViewProjMatrix |
---|
| 51 | #endif |
---|
| 52 | ) |
---|
| 53 | { |
---|
| 54 | VS_OUTPUT output; |
---|
| 55 | float4 worldPos; |
---|
| 56 | float3 worldNorm; |
---|
| 57 | |
---|
| 58 | |
---|
| 59 | #ifdef ST_DUAL_QUATERNION |
---|
| 60 | float2x4 blendDQ; |
---|
| 61 | blendDQ[0] = tex2D( matrixTexture, float2(input.m03.x, 0.0) + input.mOffset ); |
---|
| 62 | blendDQ[1] = tex2D( matrixTexture, float2(input.m03.y, 0.0) + input.mOffset ); |
---|
| 63 | #ifdef BONE_TWO_WEIGHTS |
---|
| 64 | float2x4 blendDQ2; |
---|
| 65 | //Use the empty parts of m03, z and w, for the second dual quaternion |
---|
| 66 | blendDQ2[0] = tex2D( matrixTexture, float2(input.m03.z, 0.0) + input.mOffset ); |
---|
| 67 | blendDQ2[1] = tex2D( matrixTexture, float2(input.m03.w, 0.0) + input.mOffset ); |
---|
| 68 | |
---|
| 69 | //Accurate antipodality handling. For speed increase, remove the following line |
---|
| 70 | if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0; |
---|
| 71 | |
---|
| 72 | //Blend the dual quaternions based on the weights |
---|
| 73 | blendDQ *= input.weights.x; |
---|
| 74 | blendDQ += input.weights.y*blendDQ2; |
---|
| 75 | //Normalize the resultant dual quaternion |
---|
| 76 | blendDQ /= length(blendDQ[0]); |
---|
| 77 | #endif |
---|
| 78 | worldPos = float4(calculateBlendPosition(input.Position, blendDQ), 1.0); |
---|
| 79 | worldNorm = calculateBlendNormal(input.Normal, blendDQ); |
---|
| 80 | #else |
---|
| 81 | float3x4 worldMatrix; |
---|
| 82 | worldMatrix[0] = tex2D( matrixTexture, input.m03.xw + input.mOffset ); |
---|
| 83 | worldMatrix[1] = tex2D( matrixTexture, input.m03.yw + input.mOffset ); |
---|
| 84 | worldMatrix[2] = tex2D( matrixTexture, input.m03.zw + input.mOffset ); |
---|
| 85 | |
---|
| 86 | worldPos = float4( mul( worldMatrix, input.Position ).xyz, 1.0f ); |
---|
| 87 | worldNorm= mul( (float3x3)(worldMatrix), input.Normal ); |
---|
| 88 | #endif |
---|
| 89 | |
---|
| 90 | #ifdef BONE_MATRIX_LUT |
---|
| 91 | float3x4 worldCompMatrix; |
---|
| 92 | worldCompMatrix[0] = input.worldMatrix0; |
---|
| 93 | worldCompMatrix[1] = input.worldMatrix1; |
---|
| 94 | worldCompMatrix[2] = input.worldMatrix2; |
---|
| 95 | |
---|
| 96 | worldPos = float4( mul( worldCompMatrix, worldPos ).xyz, 1.0f ); |
---|
| 97 | worldNorm = mul( (float3x3)(worldCompMatrix), worldNorm ); |
---|
| 98 | |
---|
| 99 | #endif |
---|
| 100 | |
---|
| 101 | |
---|
| 102 | //Transform the position |
---|
| 103 | output.Position = mul( viewProjMatrix, worldPos ); |
---|
| 104 | |
---|
| 105 | #ifdef DEPTH_SHADOWCASTER |
---|
| 106 | output.ps.unused = float3( 0 ); |
---|
| 107 | output.ps.depth = (output.Position.z - depthRange.x + SHADOW_BIAS) * depthRange.w; |
---|
| 108 | #else |
---|
| 109 | output.ps.uv0 = input.uv0; |
---|
| 110 | |
---|
| 111 | //Pass Normal and position for Blinn Phong lighting |
---|
| 112 | output.ps.Normal = normalize(worldNorm); |
---|
| 113 | output.ps.vPos = worldPos.xyz; |
---|
| 114 | |
---|
| 115 | #ifdef DEPTH_SHADOWRECEIVER |
---|
| 116 | // Calculate the position of vertex in light space to do shadows |
---|
| 117 | output.ps.lightSpacePos = mul( texViewProjMatrix, worldPos ); |
---|
| 118 | // make linear |
---|
| 119 | output.ps.lightSpacePos.z = (output.ps.lightSpacePos.z - depthRange.x) * depthRange.w; |
---|
| 120 | #endif |
---|
| 121 | #endif |
---|
| 122 | |
---|
| 123 | return output; |
---|
| 124 | } |
---|