//--------------------------------------------------------------------------- //These materials/shaders are part of the NEW InstanceManager implementation //Written by Matias N. Goldberg ("dark_sylinc") //--------------------------------------------------------------------------- //--------------------------------------------- //Vertex Shader Input //--------------------------------------------- struct VS_INPUT { float4 Position : POSITION; float3 Normal : NORMAL; float3 Tangent : TANGENT; #ifdef BONE_TWO_WEIGHTS float4 weights : BLENDWEIGHT; #endif float2 uv0 : TEXCOORD0; float4 m01 : TEXCOORD1; float4 m23 : TEXCOORD2; }; #include "InstancingVertexInterpolators.cg" #ifdef ST_DUAL_QUATERNION #include "DualQuaternion_Common.cg" #endif //--------------------------------------------- //Main Vertex Shader //--------------------------------------------- VS_OUTPUT main_vs( in VS_INPUT input, uniform float4x4 viewProjMatrix, #ifdef DEPTH_SHADOWCASTER uniform sampler2D matrixTexture : register(s0) #else uniform sampler2D matrixTexture : register(s2) #endif #if defined( DEPTH_SHADOWCASTER ) || defined( DEPTH_SHADOWRECEIVER ) , uniform float4 depthRange #endif #ifdef DEPTH_SHADOWRECEIVER , uniform float4x4 texViewProjMatrix #endif ) { VS_OUTPUT output; float4 worldPos = 0; float3 worldNorm = 0; #ifdef ST_DUAL_QUATERNION float2x4 blendDQ; blendDQ[0] = tex2D( matrixTexture, input.m01.xy ); blendDQ[1] = tex2D( matrixTexture, input.m01.zw ); #ifdef BONE_TWO_WEIGHTS float2x4 blendDQ2; //Use the empty parts of m03, z and w, for the second dual quaternion blendDQ2[0] = tex2D( matrixTexture, input.m23.xy ); blendDQ2[1] = tex2D( matrixTexture, input.m23.zw ); //Accurate antipodality handling. For speed increase, remove the following line if (dot(blendDQ[0], blendDQ2[0]) < 0.0) blendDQ2 *= -1.0; //Blend the dual quaternions based on the weights blendDQ *= input.weights.x; blendDQ += input.weights.y*blendDQ2; //Normalize the resultant dual quaternion blendDQ /= length(blendDQ[0]); #endif //Only dealing with one weight so normalization of the dual quaternion and weighting are unnecessary worldPos = float4(calculateBlendPosition(input.Position.xyz, blendDQ), 1.0); worldNorm = calculateBlendNormal(input.Normal.xyz, blendDQ); #else float3x4 worldMatrix; worldMatrix[0] = tex2D( matrixTexture, input.m01.xy ); worldMatrix[1] = tex2D( matrixTexture, input.m01.zw ); worldMatrix[2] = tex2D( matrixTexture, input.m23.xy ); worldPos = float4( mul( worldMatrix, input.Position ).xyz, 1.0f ); worldNorm= mul( (float3x3)(worldMatrix), input.Normal ); #endif //Transform the position output.Position = mul( viewProjMatrix, worldPos ); #ifdef DEPTH_SHADOWCASTER output.ps.unused = float3( 0 ); output.ps.depth = (output.Position.z - depthRange.x + SHADOW_BIAS) * depthRange.w; #else output.ps.uv0 = input.uv0; //Pass Normal and position for Blinn Phong lighting output.ps.Normal = normalize(worldNorm); output.ps.vPos = worldPos.xyz; #ifdef DEPTH_SHADOWRECEIVER // Calculate the position of vertex in light space to do shadows output.ps.lightSpacePos = mul( texViewProjMatrix, worldPos ); // make linear output.ps.lightSpacePos.z = (output.ps.lightSpacePos.z - depthRange.x) * depthRange.w; #endif #endif return output; }