// Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors. // All rights reserved. // Code licensed under the BSD License. // http://www.anki3d.org/LICENSE // This shader draws tile aligned boxes in order to fill the HZB buffer for cascaded shadows #pragma anki technique vert pixel #include Texture2D g_maxDepthRt : register(t0); struct Constants { Mat4 m_reprojectionMat; F32 m_cascadeMinDepth; F32 m_cascadeMaxDepth; F32 m_padding0; F32 m_padding1; }; ANKI_FAST_CONSTANTS(Constants, g_consts) #if ANKI_VERTEX_SHADER Vec4 main(U32 svVertexId : SV_VERTEXID, U32 svInstanceId : SV_INSTANCEID) : SV_POSITION { UVec2 maxDepthRtSize; g_maxDepthRt.GetDimensions(maxDepthRtSize.x, maxDepthRtSize.y); const U32 tileX = svInstanceId % maxDepthRtSize.x; const U32 tileY = svInstanceId / maxDepthRtSize.x; const F32 maxDepth = min(g_maxDepthRt[UVec2(tileX, tileY)].x, g_consts.m_cascadeMaxDepth); const F32 minDepth = g_consts.m_cascadeMinDepth; if(maxDepth <= minDepth) { // Tile's depth is outside the cascade, make the box digenerate return 0.0f; } // Z Vec3 ndc; ndc.z = (svVertexId <= 3) ? minDepth : maxDepth; // X ndc.x = F32(tileX); if(svVertexId == 1 || svVertexId == 2 || svVertexId == 5 || svVertexId == 6) { // Right side, move the point ndc.x += 1.0f; } // Y ndc.y = F32(tileY); if(svVertexId == 0 || svVertexId == 1 || svVertexId == 4 || svVertexId == 5) { // Top side, move the point ndc.y += 1.0f; } ndc.xy /= Vec2(maxDepthRtSize); ndc.xy = uvToNdc(saturate(ndc.xy)); // Unproject and project return mul(g_consts.m_reprojectionMat, Vec4(ndc, 1.0)); } #endif // ANKI_VERTEX_SHADER #if ANKI_PIXEL_SHADER void main() { } #endif // ANKI_PIXEL_SHADER