float4x4 gWorld; float4x4 gLightViewProj; float4x4 gBones[70]; Texture2D gOpacityMap; bool gUseOpacity; DepthStencilState depthStencilState { DepthEnable = TRUE; DepthWriteMask = ALL; }; RasterizerState rasterizerState { FillMode = SOLID; CullMode = NONE; }; struct VS_OUTPUT_OPACITY { float4 pos : SV_POSITION; float2 texCoord : TEXCOORD; }; SamplerState gOpacitySamplerLinear { Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; // or Mirror or Clamp or Border AddressV = Wrap; // or Mirror or Clamp or Border }; //-------------------------------------------------------------------------------------- // Vertex Shader [STATIC] //-------------------------------------------------------------------------------------- float4 ShadowMapVS(float3 position:POSITION) : SV_POSITION { //TODO: return the position of the vertex in correct space (hint: seen from the view of the light) return mul(float4(position, 1.0), mul(gWorld, gLightViewProj)); } //-------------------------------------------------------------------------------------- // Vertex Shader [STATIC OPACITY] //-------------------------------------------------------------------------------------- VS_OUTPUT_OPACITY ShadowMapVS_Opacity(float3 position : POSITION, float2 texCoords : TEXCOORD0) { VS_OUTPUT_OPACITY output = (VS_OUTPUT_OPACITY) 0; // Transform the transformedPosition to Clipping Space (WVP Matrix) output.pos = mul(float4(position, 1.0), mul(gWorld, gLightViewProj)); // Save texcoord for pixel shader output.texCoord = texCoords; return output; } //-------------------------------------------------------------------------------------- // Vertex Shader [SKINNED] //-------------------------------------------------------------------------------------- float4 ShadowMapVS_Skinned(float3 position:POSITION, float4 BoneIndices : BLENDINDICES, float4 BoneWeights : BLENDWEIGHTS) : SV_POSITION { //TODO: return the position of the ANIMATED vertex in correct space (hint: seen from the view of the light) float4 transformedPosition = float4(0, 0, 0, 0); // For each bone for (int i = 0; i < 4; ++i) { if (BoneIndices[i] >= 0) { int boneIndex = BoneIndices[i]; float boneWeight = BoneWeights[i]; // Calculate BoneSpace Position & Normal float4 boneSpacePos = mul(float4(position, 1.0f), gBones[boneIndex]); // Append this Position & Normal to the transformedPosition & transformedNormal transformedPosition += boneSpacePos * boneWeight; } } // Ensure that the w-component of the transformedPosition is 1 transformedPosition.w = 1.0f; // Step 1: Transform the transformedPosition to Clipping Space (WVP Matrix) return mul(transformedPosition, mul(gWorld, gLightViewProj)); } //-------------------------------------------------------------------------------------- // Vertex Shader [SKINNED OPACITY] //-------------------------------------------------------------------------------------- VS_OUTPUT_OPACITY ShadowMapVS_Skinned_Opacity(float3 position : POSITION, float2 texCoords : TEXCOORD0, float4 BoneIndices : BLENDINDICES, float4 BoneWeights : BLENDWEIGHTS) { VS_OUTPUT_OPACITY output = (VS_OUTPUT_OPACITY) 0; float4 transformedPosition = float4(0, 0, 0, 0); // For each bone for (int i = 0; i < 4; ++i) { if (BoneIndices[i] >= 0) { int boneIndex = BoneIndices[i]; float boneWeight = BoneWeights[i]; // Calculate BoneSpace Position & Normal float4 boneSpacePos = mul(float4(position, 1.0f), gBones[boneIndex]); // Append this Position & Normal to the transformedPosition & transformedNormal transformedPosition += boneSpacePos * boneWeight; } } // Ensure that the w-component of the transformedPosition is 1 transformedPosition.w = 1.0f; // Transform the transformedPosition to Clipping Space (WVP Matrix) output.pos = mul(transformedPosition, mul(gWorld, gLightViewProj)); // Save texcoord for pixel shader output.texCoord = texCoords; return output; } //-------------------------------------------------------------------------------------- // Pixel Shaders //-------------------------------------------------------------------------------------- void ShadowMapPS_VOID(float4 position:SV_POSITION){} void ShadowMapPS_Opacity(VS_OUTPUT_OPACITY input) { if (!gUseOpacity) return; float opacityValue = gOpacityMap.Sample(gOpacitySamplerLinear, input.texCoord).r; if (opacityValue < 0.5f) discard; } technique11 GenerateShadows { pass P0 { SetRasterizerState(rasterizerState); SetDepthStencilState(depthStencilState, 0); //SetVertexShader(CompileShader(vs_4_0, ShadowMapVS())); SetVertexShader(CompileShader(vs_4_0, ShadowMapVS_Opacity())); SetGeometryShader(NULL); //SetPixelShader(CompileShader(ps_4_0, ShadowMapPS_VOID())); SetPixelShader(CompileShader(ps_4_0, ShadowMapPS_Opacity())); } } technique11 GenerateShadows_Skinned { pass P0 { SetRasterizerState(rasterizerState); SetDepthStencilState(depthStencilState, 0); //SetVertexShader(CompileShader(vs_4_0, ShadowMapVS_Skinned())); SetVertexShader(CompileShader(vs_4_0, ShadowMapVS_Skinned_Opacity())); SetGeometryShader(NULL); //SetPixelShader(CompileShader(ps_4_0, ShadowMapPS_VOID())); SetPixelShader(CompileShader(ps_4_0, ShadowMapPS_Opacity())); } }