| 225 | } |
| 226 | |
| 227 | void IntroPathTracer::RenderSSR(nvrhi::CommandListHandle commandList, const SampleConstants& constants) |
| 228 | { |
| 229 | ScopedPerfMarker perfMarker("SSR", commandList); |
| 230 | |
| 231 | // Get pipeline from hot-reloadable variant |
| 232 | auto pipeline = m_ssrVariant ? m_ssrVariant->GetPipeline() : nullptr; |
| 233 | if (!pipeline || !m_ssrBindingLayout) |
| 234 | return; // Pipeline not yet compiled |
| 235 | |
| 236 | // Lazy creation of dedicated binding set (depends on render targets) |
| 237 | auto depthHierarchy = m_depthHierarchyRenderer->m_depthHierarchy; |
| 238 | if (!m_ssrBindingSet && depthHierarchy && m_renderTargets->SSRResult) |
| 239 | { |
| 240 | nvrhi::BindingSetDesc bindingSetDesc; |
| 241 | bindingSetDesc.bindings = { |
| 242 | nvrhi::BindingSetItem::PushConstants(0, sizeof(SSRPushConstants)), |
| 243 | nvrhi::BindingSetItem::Texture_SRV(0, depthHierarchy), // t_SSR_DepthHierarchy |
| 244 | nvrhi::BindingSetItem::Texture_SRV(1, m_renderTargets->Depth), // t_SSR_Depth |
| 245 | nvrhi::BindingSetItem::Texture_SRV(2, m_renderTargets->SpecNormal), // t_SSR_Normal |
| 246 | nvrhi::BindingSetItem::Texture_SRV(3, m_renderTargets->RoughnessMetal), // t_SSR_RoughnessMetal |
| 247 | nvrhi::BindingSetItem::Texture_SRV(4, m_renderTargets->BaseColor), // t_SSR_BaseColor |
| 248 | nvrhi::BindingSetItem::Texture_SRV(5, m_ggxFilteredCubemap ? m_ggxFilteredCubemap : GetCommonPasses()->m_BlackCubeMapArray), // t_SSR_CubemapGGX |
| 249 | nvrhi::BindingSetItem::Texture_SRV(6, m_IrradianceCube ? m_IrradianceCube : GetCommonPasses()->m_BlackCubeMapArray), // t_SSR_IrradianceCube |
| 250 | nvrhi::BindingSetItem::Texture_SRV(7, GetEnvMapBaker()->GetBRDFLUT()), // t_SSR_BRDFLUT |
| 251 | nvrhi::BindingSetItem::Texture_UAV(0, m_renderTargets->SSRResult), // u_SSR_Result |
| 252 | nvrhi::BindingSetItem::Sampler(0, m_ssrSampler), // s_SSR_LinearClamp |
| 253 | nvrhi::BindingSetItem::Sampler(1, m_nearestSampler), // s_SSR_NearestClamp |
| 254 | }; |
| 255 | m_ssrBindingSet = GetDevice()->createBindingSet(bindingSetDesc, m_ssrBindingLayout); |
| 256 | } |
| 257 | |
| 258 | if (!m_ssrBindingSet) |
| 259 | return; |
| 260 | |
| 261 | nvrhi::Viewport viewport = GetView().GetViewport(); |
| 262 | uint32_t width = (uint32_t)(viewport.maxX - viewport.minX); |
| 263 | uint32_t height = (uint32_t)(viewport.maxY - viewport.minY); |
| 264 | |
| 265 | // Extract view and projection matrices |
| 266 | const auto& view = GetView(); |
| 267 | dm::float4x4 viewMatrix = dm::affineToHomogeneous(view.GetViewMatrix()); |
| 268 | dm::float4x4 projMatrix = view.GetProjectionMatrix(false); |
| 269 | |
| 270 | // SSR parameters |
| 271 | float maxRayDistance = 100.0f; |
| 272 | uint32_t maxSteps = 512; |
| 273 | float thickness = 0.1f; |
| 274 | float jitter = 0; // TODO: Use DLSS/TAA jitter |
| 275 | uint32_t ssrNumMips = m_depthHierarchyRenderer ? m_depthHierarchyRenderer->GetNumMips() : 1; |
| 276 | |
| 277 | // Pack push constants (96 bytes) |
| 278 | // See SSRPushConstants in SSRPasses.hlsl for layout |
| 279 | SSRPushConstants pushConst; |
| 280 | |
| 281 | // View matrix rows (xyz) + projection diagonal (w) |
| 282 | pushConst.viewRow0_P00 = dm::float4(viewMatrix.m_data[0], viewMatrix.m_data[1], viewMatrix.m_data[2], projMatrix.m_data[0]); |
| 283 | pushConst.viewRow1_P11 = dm::float4(viewMatrix.m_data[4], viewMatrix.m_data[5], viewMatrix.m_data[6], projMatrix.m_data[5]); |
| 284 | pushConst.viewRow2_P22 = dm::float4(viewMatrix.m_data[8], viewMatrix.m_data[9], viewMatrix.m_data[10], projMatrix.m_data[10]); |
nothing calls this directly
no test coverage detected