public void RenderAO(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture, ScriptableRenderContext renderContext, int frameCount) { // Let's check all the resources HDRaytracingEnvironment rtEnvironment = m_RaytracingManager.CurrentEnvironment(); BlueNoise blueNoise = m_RaytracingManager.GetBlueNoiseManager(); // Check if the state is valid for evaluating ambient occlusion bool invalidState = rtEnvironment == null; // If any of the previous requirements is missing, the effect is not requested or no acceleration structure, set the default one and leave right away if (invalidState) { SetDefaultAmbientOcclusionTexture(cmd); return; } RayTracingShader aoShader = m_PipelineRayTracingResources.aoRaytracing; var aoSettings = VolumeManager.instance.stack.GetComponent <AmbientOcclusion>(); // Grab the acceleration structure for the target camera RayTracingAccelerationStructure accelerationStructure = m_RaytracingManager.RequestAccelerationStructure(rtEnvironment.aoLayerMask); // Define the shader pass to use for the reflection pass cmd.SetRayTracingShaderPass(aoShader, "VisibilityDXR"); // Set the acceleration structure for the pass cmd.SetRayTracingAccelerationStructure(aoShader, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure); // Inject the ray generation data cmd.SetRayTracingFloatParams(aoShader, HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias); cmd.SetRayTracingFloatParams(aoShader, HDShaderIDs._RaytracingRayMaxLength, aoSettings.rayLength.value); cmd.SetRayTracingIntParams(aoShader, HDShaderIDs._RaytracingNumSamples, aoSettings.sampleCount.value); // Set the data for the ray generation cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer()); int frameIndex = hdCamera.IsTAAEnabled() ? hdCamera.taaFrameIndex : (int)frameCount % 8; cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameIndex); // Inject the ray-tracing sampling data blueNoise.BindDitheredRNGData8SPP(cmd); // Value used to scale the ao intensity cmd.SetRayTracingFloatParam(aoShader, HDShaderIDs._RaytracingAOIntensity, aoSettings.intensity.value); cmd.SetRayTracingIntParam(aoShader, HDShaderIDs._RayCountEnabled, m_RaytracingManager.rayCountManager.RayCountIsEnabled()); cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._RayCountTexture, m_RaytracingManager.rayCountManager.GetRayCountTexture()); // Set the output textures cmd.SetRayTracingTextureParam(aoShader, HDShaderIDs._AmbientOcclusionTextureRW, m_AOIntermediateBuffer0); // Run the computation cmd.DispatchRays(aoShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, (uint)hdCamera.viewCount); using (new ProfilingSample(cmd, "Filter Ambient Occlusion", CustomSamplerId.RaytracingAmbientOcclusion.GetSampler())) { if (aoSettings.denoise.value) { // Grab the history buffer RTHandle ambientOcclusionHistory = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedAmbientOcclusion) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedAmbientOcclusion, AmbientOcclusionHistoryBufferAllocatorFunction, 1); // Apply the temporal denoiser HDTemporalFilter temporalFilter = m_RaytracingManager.GetTemporalFilter(); temporalFilter.DenoiseBuffer(cmd, hdCamera, m_AOIntermediateBuffer0, ambientOcclusionHistory, m_AOIntermediateBuffer1); // Apply the diffuse denoiser HDDiffuseDenoiser diffuseDenoiser = m_RaytracingManager.GetDiffuseDenoiser(); diffuseDenoiser.DenoiseBuffer(cmd, hdCamera, m_AOIntermediateBuffer1, outputTexture, aoSettings.denoiserRadius.value); } else { HDUtils.BlitCameraTexture(cmd, m_AOIntermediateBuffer0, outputTexture); } } // Bind the textures and the params cmd.SetGlobalTexture(HDShaderIDs._AmbientOcclusionTexture, outputTexture); cmd.SetGlobalVector(HDShaderIDs._AmbientOcclusionParam, new Vector4(0f, 0f, 0f, VolumeManager.instance.stack.GetComponent <AmbientOcclusion>().directLightingStrength.value)); // TODO: All the push-debug stuff should be centralized somewhere (RenderPipelineManager.currentPipeline as HDRenderPipeline).PushFullScreenDebugTexture(hdCamera, cmd, outputTexture, FullScreenDebugMode.SSAO); }
public void Render(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture, ScriptableRenderContext renderContext, CullingResults cull) { // First thing to check is: Do we have a valid ray-tracing environment? HDRaytracingEnvironment rtEnvironment = m_RaytracingManager.CurrentEnvironment(); RecursiveRendering recursiveSettings = VolumeManager.instance.stack.GetComponent <RecursiveRendering>(); // Check the validity of the state before computing the effect bool invalidState = !hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) || rtEnvironment == null || !recursiveSettings.enable.value || m_PipelineAsset.currentPlatformRenderPipelineSettings.supportedRaytracingTier == RenderPipelineSettings.RaytracingTier.Tier1; // If any resource or game-object is missing We stop right away if (invalidState) { return; } HDRenderPipeline renderPipeline = m_RaytracingManager.GetRenderPipeline(); RayTracingShader forwardShader = m_PipelineAsset.renderPipelineRayTracingResources.forwardRaytracing; Shader raytracingMask = m_PipelineAsset.renderPipelineRayTracingResources.raytracingFlagMask; LightCluster lightClusterSettings = VolumeManager.instance.stack.GetComponent <LightCluster>(); // Grab the acceleration structure and the list of HD lights for the target camera RayTracingAccelerationStructure accelerationStructure = m_RaytracingManager.RequestAccelerationStructure(rtEnvironment.raytracedLayerMask); HDRaytracingLightCluster lightCluster = m_RaytracingManager.RequestLightCluster(rtEnvironment.raytracedLayerMask); if (m_RaytracingFlagMaterial == null) { m_RaytracingFlagMaterial = CoreUtils.CreateEngineMaterial(raytracingMask); } // Before going into raytracing, we need to flag which pixels needs to be raytracing EvaluateRaytracingMask(cull, hdCamera, cmd, renderContext); // Define the shader pass to use for the reflection pass cmd.SetRayTracingShaderPass(forwardShader, "ForwardDXR"); // Set the acceleration structure for the pass cmd.SetRayTracingAccelerationStructure(forwardShader, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure); // Inject the ray-tracing sampling data cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._OwenScrambledTexture, m_PipelineResources.textures.owenScrambledRGBATex); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._ScramblingTexture, m_PipelineResources.textures.scramblingTex); // Inject the ray generation data cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias); cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayMaxLength, recursiveSettings.rayLength.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingMaxRecursion, recursiveSettings.maxDepth.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingCameraNearPlane, hdCamera.camera.nearClipPlane); // Set the data for the ray generation cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingFlagMask, m_RaytracingFlagTarget); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._CameraColorTextureRW, outputTexture); // Compute an approximate pixel spread angle value (in radians) float pixelSpreadAngle = hdCamera.camera.fieldOfView * (Mathf.PI / 180.0f) / Mathf.Min(hdCamera.actualWidth, hdCamera.actualHeight); cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, pixelSpreadAngle); // LightLoop data cmd.SetGlobalBuffer(HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster()); cmd.SetGlobalBuffer(HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas()); cmd.SetGlobalVector(HDShaderIDs._MinClusterPos, lightCluster.GetMinClusterPos()); cmd.SetGlobalVector(HDShaderIDs._MaxClusterPos, lightCluster.GetMaxClusterPos()); cmd.SetGlobalInt(HDShaderIDs._LightPerCellCount, lightClusterSettings.maxNumLightsPercell.value); cmd.SetGlobalInt(HDShaderIDs._PunctualLightCountRT, lightCluster.GetPunctualLightCount()); cmd.SetGlobalInt(HDShaderIDs._AreaLightCountRT, lightCluster.GetAreaLightCount()); // Note: Just in case, we rebind the directional light data (in case they were not) cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, renderPipeline.m_LightLoopLightData.directionalLightData); cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, renderPipeline.m_lightList.directionalLights.Count); // Set the data for the ray miss cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._SkyTexture, m_SkyManager.skyReflection); // If this is the right debug mode and we have at least one light, write the first shadow to the denoise texture HDRenderPipeline hdrp = (RenderPipelineManager.currentPipeline as HDRenderPipeline); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingPrimaryDebug, m_DebugRaytracingTexture); hdrp.PushFullScreenDebugTexture(hdCamera, cmd, m_DebugRaytracingTexture, FullScreenDebugMode.PrimaryVisibility); // Run the computation cmd.DispatchRays(forwardShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); }