| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #include "$ENGINE$\PerObjectData.bslinc"
- #include "$ENGINE$\SkinnedVertexInput.bslinc"
- #include "$ENGINE$\NormalVertexInput.bslinc"
- #define USE_BLEND_SHAPES
- #include "$ENGINE$\SkinnedVertexInput.bslinc"
- #include "$ENGINE$\NormalVertexInput.bslinc"
- #undef USE_BLEND_SHAPES
- mixin ShadowDepthBase
- {
- code
- {
- struct ShadowVStoFS
- {
- float4 position : SV_Position;
-
- #ifdef USES_GS
- float4 worldPos : TEXCOORD0;
- #else
- #ifdef USES_PS
- float shadowPos : TEXCOORD0;
- #endif
- #endif
- };
-
- cbuffer ShadowParams
- {
- float4x4 gMatViewProj;
- float2 gNDCZToDeviceZ;
- float gDepthBias;
- float gInvDepthRange;
- };
-
- /** Converts Z value from device range ([0, 1]) to NDC space. */
- float DeviceZToNDCZ(float deviceZ)
- {
- return deviceZ / gNDCZToDeviceZ.x - gNDCZToDeviceZ.y;
- }
-
- /** Converts Z value from NDC space to device Z value in range [0, 1]. */
- float NDCZToDeviceZ(float ndcZ)
- {
- return (ndcZ + gNDCZToDeviceZ.y) * gNDCZToDeviceZ.x;
- }
- void linearizeDepth(inout float4 clipPos)
- {
- #ifdef CLAMP_TO_NEAR_PLANE
- float ndcZ = clipPos.z / clipPos.w;
- float deviceZ = NDCZToDeviceZ(ndcZ);
-
- // Clamp to near plane if behind it
- if (deviceZ < 0)
- {
- clipPos.z = DeviceZToNDCZ(0);
- clipPos.w = 1.0f;
- }
- #endif
- // Output linear depth
- #ifdef LINEAR_DEPTH_RANGE
- float linearDepth = clipPos.z * gInvDepthRange + gDepthBias;
- clipPos.z = linearDepth * clipPos.w;
- #endif
- }
-
- ShadowVStoFS vsmain(VertexInput_PO input)
- {
- ShadowVStoFS output;
-
- float4 worldPosition = getVertexWorldPosition(input);
-
- // If using a geometry shader, just pass through the relevant information
- // as the GS does the necessary transform and applies the depth bias
- #ifdef USES_GS
- output.worldPos = worldPosition;
- output.position = worldPosition;
- #else // USES_GS
-
- // Not using a geometry shader, transform to clip space
- float4 clipPos = mul(gMatViewProj, worldPosition);
-
- // Clamp geometry behind the near plane
- #ifdef CLAMP_TO_NEAR_PLANE
- float ndcZ = clipPos.z / clipPos.w;
- float deviceZ = NDCZToDeviceZ(ndcZ);
-
- if (deviceZ < 0)
- {
- clipPos.z = DeviceZToNDCZ(0);
- clipPos.w = 1.0f;
- }
- #endif // CLAMP_TO_NEAR_PLANE
- // If using a pixel shader, output shadow depth in clip space, as
- // we'll apply bias to it in PS (depth needs to be interpolated in
- // a perspective correct way)
- #ifdef USES_PS
- output.shadowPos = clipPos.z;
- #else // Otherwise apply bias immediately
- clipPos.z += gDepthBias;
- #endif // USES_PS
-
- output.position = clipPos;
- #endif // USES_GS
-
- return output;
- }
- };
- };
- technique ShadowDepth
- {
- mixin PerObjectData;
- mixin NormalVertexInput;
- mixin ShadowDepthBase;
- mixin ShadowDepth;
- };
- technique ShadowDepthSkinned
- {
- mixin PerObjectData;
- mixin SkinnedVertexInput;
- mixin ShadowDepthBase;
- mixin ShadowDepth;
- tags = { "Skinned" };
- };
- technique ShadowDepthMorph
- {
- mixin PerObjectData;
- mixin MorphVertexInput;
- mixin ShadowDepthBase;
- mixin ShadowDepth;
- tags = { "Morph" };
- };
- technique ShadowDepthSkinnedMorph
- {
- mixin PerObjectData;
- mixin SkinnedMorphVertexInput;
- mixin ShadowDepthBase;
- mixin ShadowDepth;
- tags = { "SkinnedMorph" };
- };
|