ShadowDepthBase.bslinc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "$ENGINE$\PerObjectData.bslinc"
  2. #include "$ENGINE$\SkinnedVertexInput.bslinc"
  3. #include "$ENGINE$\NormalVertexInput.bslinc"
  4. #define USE_BLEND_SHAPES
  5. #include "$ENGINE$\SkinnedVertexInput.bslinc"
  6. #include "$ENGINE$\NormalVertexInput.bslinc"
  7. #undef USE_BLEND_SHAPES
  8. mixin ShadowDepthBase
  9. {
  10. code
  11. {
  12. struct ShadowVStoFS
  13. {
  14. float4 position : SV_Position;
  15. #ifdef USES_GS
  16. float4 worldPos : TEXCOORD0;
  17. #else
  18. #ifdef USES_PS
  19. float shadowPos : TEXCOORD0;
  20. #endif
  21. #endif
  22. };
  23. cbuffer ShadowParams
  24. {
  25. float4x4 gMatViewProj;
  26. float2 gNDCZToDeviceZ;
  27. float gDepthBias;
  28. float gInvDepthRange;
  29. };
  30. /** Converts Z value from device range ([0, 1]) to NDC space. */
  31. float DeviceZToNDCZ(float deviceZ)
  32. {
  33. return deviceZ / gNDCZToDeviceZ.x - gNDCZToDeviceZ.y;
  34. }
  35. /** Converts Z value from NDC space to device Z value in range [0, 1]. */
  36. float NDCZToDeviceZ(float ndcZ)
  37. {
  38. return (ndcZ + gNDCZToDeviceZ.y) * gNDCZToDeviceZ.x;
  39. }
  40. void linearizeDepth(inout float4 clipPos)
  41. {
  42. #ifdef CLAMP_TO_NEAR_PLANE
  43. float ndcZ = clipPos.z / clipPos.w;
  44. float deviceZ = NDCZToDeviceZ(ndcZ);
  45. // Clamp to near plane if behind it
  46. if (deviceZ < 0)
  47. {
  48. clipPos.z = DeviceZToNDCZ(0);
  49. clipPos.w = 1.0f;
  50. }
  51. #endif
  52. // Output linear depth
  53. #ifdef LINEAR_DEPTH_RANGE
  54. float linearDepth = clipPos.z * gInvDepthRange + gDepthBias;
  55. clipPos.z = linearDepth * clipPos.w;
  56. #endif
  57. }
  58. ShadowVStoFS vsmain(VertexInput_PO input)
  59. {
  60. ShadowVStoFS output;
  61. float4 worldPosition = getVertexWorldPosition(input);
  62. // If using a geometry shader, just pass through the relevant information
  63. // as the GS does the necessary transform and applies the depth bias
  64. #ifdef USES_GS
  65. output.worldPos = worldPosition;
  66. output.position = worldPosition;
  67. #else // USES_GS
  68. // Not using a geometry shader, transform to clip space
  69. float4 clipPos = mul(gMatViewProj, worldPosition);
  70. // Clamp geometry behind the near plane
  71. #ifdef CLAMP_TO_NEAR_PLANE
  72. float ndcZ = clipPos.z / clipPos.w;
  73. float deviceZ = NDCZToDeviceZ(ndcZ);
  74. if (deviceZ < 0)
  75. {
  76. clipPos.z = DeviceZToNDCZ(0);
  77. clipPos.w = 1.0f;
  78. }
  79. #endif // CLAMP_TO_NEAR_PLANE
  80. // If using a pixel shader, output shadow depth in clip space, as
  81. // we'll apply bias to it in PS (depth needs to be interpolated in
  82. // a perspective correct way)
  83. #ifdef USES_PS
  84. output.shadowPos = clipPos.z;
  85. #else // Otherwise apply bias immediately
  86. clipPos.z += gDepthBias;
  87. #endif // USES_PS
  88. output.position = clipPos;
  89. #endif // USES_GS
  90. return output;
  91. }
  92. };
  93. };
  94. technique ShadowDepth
  95. {
  96. mixin PerObjectData;
  97. mixin NormalVertexInput;
  98. mixin ShadowDepthBase;
  99. mixin ShadowDepth;
  100. };
  101. technique ShadowDepthSkinned
  102. {
  103. mixin PerObjectData;
  104. mixin SkinnedVertexInput;
  105. mixin ShadowDepthBase;
  106. mixin ShadowDepth;
  107. tags = { "Skinned" };
  108. };
  109. technique ShadowDepthMorph
  110. {
  111. mixin PerObjectData;
  112. mixin MorphVertexInput;
  113. mixin ShadowDepthBase;
  114. mixin ShadowDepth;
  115. tags = { "Morph" };
  116. };
  117. technique ShadowDepthSkinnedMorph
  118. {
  119. mixin PerObjectData;
  120. mixin SkinnedMorphVertexInput;
  121. mixin ShadowDepthBase;
  122. mixin ShadowDepth;
  123. tags = { "SkinnedMorph" };
  124. };