| 232 | } |
| 233 | |
| 234 | void LightProbeProcessingPass::RenderDiffuseMap( |
| 235 | nvrhi::ICommandList* commandList, |
| 236 | nvrhi::ITexture* inEnvironmentMap, |
| 237 | nvrhi::TextureSubresourceSet inSubresources, |
| 238 | nvrhi::ITexture* outDiffuseMap, |
| 239 | uint32_t outBaseArraySlice, |
| 240 | uint32_t outMipLevel) |
| 241 | { |
| 242 | const nvrhi::TextureDesc& inDesc = inEnvironmentMap->getDesc(); |
| 243 | assert(inDesc.dimension == nvrhi::TextureDimension::TextureCube || inDesc.dimension == nvrhi::TextureDimension::TextureCubeArray); |
| 244 | float inputSize = ceilf(float(inDesc.width) * powf(0.5f, float(inSubresources.baseMipLevel))); |
| 245 | |
| 246 | const nvrhi::TextureDesc& outDesc = outDiffuseMap->getDesc(); |
| 247 | assert(outDesc.dimension == nvrhi::TextureDimension::TextureCube || outDesc.dimension == nvrhi::TextureDimension::TextureCubeArray); |
| 248 | float outputSize = ceilf(float(outDesc.width) * powf(0.5f, float(outMipLevel))); |
| 249 | |
| 250 | uint32_t intermediateMipLevel = static_cast<uint32_t>(std::max(0.f, dm::log2f(float(m_IntermediateTextureSize) / outputSize) - 2.f)); |
| 251 | float intermediateSize = ceilf(float(m_IntermediateTextureSize) * powf(0.5f, float(intermediateMipLevel))); |
| 252 | |
| 253 | commandList->beginMarker("Diffuse Light Probe"); |
| 254 | |
| 255 | nvrhi::FramebufferHandle framebuffer = GetCachedFramebuffer(m_IntermediateTexture, nvrhi::TextureSubresourceSet(intermediateMipLevel, 1, 0, 6)); |
| 256 | |
| 257 | nvrhi::FramebufferInfo const& framebufferInfo = framebuffer->getFramebufferInfo(); |
| 258 | nvrhi::GraphicsPipelineHandle& pso = m_DiffusePsoCache[framebufferInfo]; |
| 259 | |
| 260 | if (!pso) |
| 261 | { |
| 262 | nvrhi::GraphicsPipelineDesc psoDesc; |
| 263 | psoDesc.VS = m_CommonPasses->m_FullscreenVS; |
| 264 | psoDesc.GS = m_GeometryShader; |
| 265 | psoDesc.PS = m_DiffusePixelShader; |
| 266 | psoDesc.bindingLayouts = { m_BindingLayout }; |
| 267 | psoDesc.primType = nvrhi::PrimitiveType::TriangleStrip; |
| 268 | psoDesc.renderState.rasterState.setCullNone(); |
| 269 | psoDesc.renderState.depthStencilState.depthTestEnable = false; |
| 270 | psoDesc.renderState.depthStencilState.stencilEnable = false; |
| 271 | pso = m_Device->createGraphicsPipeline(psoDesc, framebufferInfo); |
| 272 | } |
| 273 | |
| 274 | LightProbeProcessingConstants constants = {}; |
| 275 | constants.sampleCount = 4096; |
| 276 | constants.lodBias = 1.0f + 0.5f * dm::log2f((inputSize * inputSize) / constants.sampleCount); |
| 277 | commandList->writeBuffer(m_LightProbeCB, &constants, sizeof(constants)); |
| 278 | |
| 279 | nvrhi::BindingSetHandle bindingSet = GetCachedBindingSet(inEnvironmentMap, inSubresources); |
| 280 | |
| 281 | nvrhi::GraphicsState state; |
| 282 | state.pipeline = pso; |
| 283 | state.framebuffer = framebuffer; |
| 284 | state.bindings = { bindingSet }; |
| 285 | state.viewport.scissorRects = { nvrhi::Rect(int(intermediateSize), int(intermediateSize)) }; |
| 286 | state.viewport.viewports = { nvrhi::Viewport(intermediateSize, intermediateSize) }; |
| 287 | commandList->setGraphicsState(state); |
| 288 | |
| 289 | nvrhi::DrawArguments args; |
| 290 | args.instanceCount = 1; |
| 291 | args.vertexCount = 4; |