| 79 | } |
| 80 | |
| 81 | bool CascadedShadowMap::SetupForPlanarView(const DirectionalLight& light, frustum viewFrustum, float maxShadowDistance, float lightSpaceZUp, float lightSpaceZDown, float exponent, float3 preViewTranslation, int numberOfCascades) |
| 82 | { |
| 83 | assert(exponent > 1); |
| 84 | |
| 85 | assert(length(viewFrustum.planes[frustum::NEAR_PLANE].normal) > 0); |
| 86 | |
| 87 | if (numberOfCascades < 0) |
| 88 | m_NumberOfCascades = static_cast<int>(m_Cascades.size()); |
| 89 | else |
| 90 | m_NumberOfCascades = std::min(numberOfCascades, static_cast<int>(m_Cascades.size())); |
| 91 | |
| 92 | if (maxShadowDistance > 0.f) |
| 93 | { |
| 94 | plane& nearPlane = viewFrustum.planes[frustum::NEAR_PLANE]; |
| 95 | plane& farPlane = viewFrustum.planes[frustum::FAR_PLANE]; |
| 96 | farPlane.normal = -nearPlane.normal; |
| 97 | farPlane.distance = -nearPlane.distance + maxShadowDistance; |
| 98 | } |
| 99 | else |
| 100 | { |
| 101 | assert(length(viewFrustum.planes[frustum::FAR_PLANE].normal) > 0); |
| 102 | } |
| 103 | |
| 104 | std::array<float3, frustum::numCorners> corners; |
| 105 | for (uint32_t i = 0; i < frustum::numCorners; i++) |
| 106 | { |
| 107 | corners[i] = viewFrustum.getCorner(i); |
| 108 | } |
| 109 | |
| 110 | float far = 1.f; |
| 111 | float near = far / exponent; |
| 112 | |
| 113 | daffine3 viewToWorld = light.GetNode()->GetLocalToWorldTransform(); |
| 114 | viewToWorld = dm::scaling(dm::double3(1.0, 1.0, -1.0)) * viewToWorld; |
| 115 | affine3 worldToView = affine3(inverse(viewToWorld)); |
| 116 | bool viewModified = false; |
| 117 | |
| 118 | for (int cascade = m_NumberOfCascades - 1; cascade >= 0; cascade--) |
| 119 | { |
| 120 | if (cascade == 0) |
| 121 | near = 0.f; |
| 122 | |
| 123 | std::array<float3, frustum::numCorners> cascadeViewCorners; |
| 124 | for (uint32_t i = 0; i < frustum::numCorners; i++) |
| 125 | { |
| 126 | float3 corner = lerp(corners[i & 3], corners[(i & 3) + 4], (i & 4) ? far : near); |
| 127 | cascadeViewCorners[i] = worldToView.transformPoint(corner); |
| 128 | } |
| 129 | |
| 130 | box3 cascadeViewBounds = box3(frustum::numCorners, cascadeViewCorners.data()); |
| 131 | |
| 132 | float3 cascadeCenter = dm::float3(viewToWorld.transformPoint(dm::double3(cascadeViewBounds.center()))); |
| 133 | float3 halfShadowBoxSize = cascadeViewBounds.diagonal() * 0.5f; |
| 134 | halfShadowBoxSize.xy() = std::max(halfShadowBoxSize.x, halfShadowBoxSize.y); |
| 135 | float fadeRange = halfShadowBoxSize.x * 0.1f; |
| 136 | |
| 137 | float zDown = std::max(halfShadowBoxSize.z, lightSpaceZDown); |
| 138 | float zUp = std::max(halfShadowBoxSize.z, lightSpaceZUp); |
nothing calls this directly
no test coverage detected