Renders meshes using cascaded shadow mapping
| 743 | |
| 744 | // Renders meshes using cascaded shadow mapping |
| 745 | void MeshRenderer::RenderSunShadowMap(ID3D11DeviceContext* context, const Camera& camera) |
| 746 | { |
| 747 | PIXEvent event(L"Sun Shadow Map Rendering"); |
| 748 | |
| 749 | const float MinDistance = reductionDepth.x; |
| 750 | const float MaxDistance = reductionDepth.y; |
| 751 | |
| 752 | // Compute the split distances based on the partitioning mode |
| 753 | float CascadeSplits[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; |
| 754 | |
| 755 | { |
| 756 | float lambda = 1.0f; |
| 757 | |
| 758 | float nearClip = camera.NearClip(); |
| 759 | float farClip = camera.FarClip(); |
| 760 | float clipRange = farClip - nearClip; |
| 761 | |
| 762 | float minZ = nearClip + MinDistance * clipRange; |
| 763 | float maxZ = nearClip + MaxDistance * clipRange; |
| 764 | |
| 765 | float range = maxZ - minZ; |
| 766 | float ratio = maxZ / minZ; |
| 767 | |
| 768 | for(uint32 i = 0; i < NumCascades; ++i) |
| 769 | { |
| 770 | float p = (i + 1) / static_cast<float>(NumCascades); |
| 771 | float log = minZ * std::pow(ratio, p); |
| 772 | float uniform = minZ + range * p; |
| 773 | float d = lambda * (log - uniform) + uniform; |
| 774 | CascadeSplits[i] = (d - nearClip) / clipRange; |
| 775 | } |
| 776 | } |
| 777 | |
| 778 | Float3 c0Extents; |
| 779 | Float4x4 c0Matrix; |
| 780 | |
| 781 | const Float3 lightDir = AppSettings::SunDirection; |
| 782 | |
| 783 | // Render the meshes to each cascade |
| 784 | for(uint32 cascadeIdx = 0; cascadeIdx < NumCascades; ++cascadeIdx) |
| 785 | { |
| 786 | PIXEvent cascadeEvent((L"Rendering Shadow Map Cascade " + ToString(cascadeIdx)).c_str()); |
| 787 | |
| 788 | // Set the viewport |
| 789 | SetViewport(context, ShadowMapSize, ShadowMapSize); |
| 790 | |
| 791 | // Set the shadow map as the depth target |
| 792 | ID3D11DepthStencilView* dsv = sunShadowDepthMap.DSView; |
| 793 | ID3D11RenderTargetView* nullRenderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = { NULL }; |
| 794 | context->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, nullRenderTargets, dsv); |
| 795 | context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0); |
| 796 | |
| 797 | // Get the 8 points of the view frustum in world space |
| 798 | XMVECTOR frustumCornersWS[8] = |
| 799 | { |
| 800 | XMVectorSet(-1.0f, 1.0f, 0.0f, 1.0f), |
| 801 | XMVectorSet( 1.0f, 1.0f, 0.0f, 1.0f), |
| 802 | XMVectorSet( 1.0f, -1.0f, 0.0f, 1.0f), |