internal void BuildRayTracingLightCluster(CommandBuffer cmd, HDCamera hdCamera) { ScreenSpaceReflection reflSettings = VolumeManager.instance.stack.GetComponent <ScreenSpaceReflection>(); GlobalIllumination giSettings = VolumeManager.instance.stack.GetComponent <GlobalIllumination>(); RecursiveRendering recursiveSettings = VolumeManager.instance.stack.GetComponent <RecursiveRendering>(); PathTracing pathTracingSettings = VolumeManager.instance.stack.GetComponent <PathTracing>(); if (m_ValidRayTracingState && (reflSettings.rayTracing.value || giSettings.rayTracing.value || recursiveSettings.enable.value || pathTracingSettings.enable.value)) { m_RayTracingLightCluster.EvaluateLightClusters(cmd, hdCamera, m_RayTracingLights); m_ValidRayTracingCluster = true; } }
internal bool RayTracingLightClusterRequired(HDCamera hdCamera) { ScreenSpaceReflection reflSettings = hdCamera.volumeStack.GetComponent <ScreenSpaceReflection>(); GlobalIllumination giSettings = hdCamera.volumeStack.GetComponent <GlobalIllumination>(); RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); PathTracing pathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>(); SubSurfaceScattering subSurface = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>(); return(m_ValidRayTracingState && (reflSettings.rayTracing.value || giSettings.rayTracing.value || recursiveSettings.enable.value || pathTracingSettings.enable.value || subSurface.rayTracing.value)); }
/// <summary> /// Function that returns the ray tracing and path tracing effects that are enabled for a given camera. /// </summary> /// <param name="hdCamera">The input camera</param> /// <param name="rayTracedShadows">Flag that defines if at least one light has ray traced shadows.</param> /// <param name="rayTracedContactShadows">Flag that defines if at least one light has ray traced contact shadows</param> /// <returns>HDEffectsParameters type.</returns> public static HDEffectsParameters EvaluateEffectsParameters(HDCamera hdCamera, bool rayTracedShadows, bool rayTracedContactShadows) { HDEffectsParameters parameters = new HDEffectsParameters(); // Aggregate the shadow requirements parameters.shadows = hdCamera.frameSettings.IsEnabled(FrameSettingsField.ScreenSpaceShadows) && (rayTracedShadows || rayTracedContactShadows); // Aggregate the ambient occlusion parameters AmbientOcclusion aoSettings = hdCamera.volumeStack.GetComponent <AmbientOcclusion>(); parameters.ambientOcclusion = aoSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSAO); parameters.aoLayerMask = aoSettings.layerMask.value; // Aggregate the reflections parameters ScreenSpaceReflection reflSettings = hdCamera.volumeStack.GetComponent <ScreenSpaceReflection>(); parameters.reflections = reflSettings.enabled.value && ScreenSpaceReflection.RayTracingActive(reflSettings) && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSR); parameters.reflLayerMask = reflSettings.layerMask.value; // Aggregate the global illumination parameters GlobalIllumination giSettings = hdCamera.volumeStack.GetComponent <GlobalIllumination>(); parameters.globalIllumination = giSettings.enable.value && GlobalIllumination.RayTracingActive(giSettings) && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSGI); parameters.giLayerMask = giSettings.layerMask.value; // Aggregate the global illumination parameters RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); parameters.recursiveRendering = recursiveSettings.enable.value; parameters.recursiveLayerMask = recursiveSettings.layerMask.value; // Aggregate the sub surface parameters SubSurfaceScattering sssSettings = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>(); parameters.subSurface = sssSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SubsurfaceScattering); // Aggregate the path parameters PathTracing pathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>(); parameters.pathTracing = pathTracingSettings.enable.value; parameters.ptLayerMask = pathTracingSettings.layerMask.value; // We need to check if at least one effect will require the acceleration structure parameters.rayTracingRequired = parameters.ambientOcclusion || parameters.reflections || parameters.globalIllumination || parameters.recursiveRendering || parameters.subSurface || parameters.pathTracing || parameters.shadows; // Return the result return(parameters); }
TextureHandle RaytracingRecursiveRender(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle colorBuffer, TextureHandle depthPyramid, TextureHandle flagMask, TextureHandle rayCountTexture) { // If ray tracing is disabled in the frame settings or the effect is not enabled RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) || !recursiveSettings.enable.value) { return(colorBuffer); } // Build the parameter structure RecursiveRendererParameters rrParams = PrepareRecursiveRendererParameters(hdCamera, recursiveSettings); using (var builder = renderGraph.AddRenderPass <RecursiveRenderingPassData>("Recursive Rendering Evaluation", out var passData, ProfilingSampler.Get(HDProfileId.RayTracingRecursiveRendering))) { builder.EnableAsyncCompute(false); passData.parameters = rrParams; passData.depthStencilBuffer = builder.ReadTexture(depthPyramid); passData.flagMask = builder.ReadTexture(flagMask); passData.rayCountTexture = builder.ReadWriteTexture(rayCountTexture); passData.outputBuffer = builder.ReadWriteTexture(colorBuffer); // Right now the debug buffer is written to independently of what is happening. This must be changed // TODO RENDERGRAPH passData.debugBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Recursive Rendering Debug Texture" })); builder.SetRenderFunc( (RecursiveRenderingPassData data, RenderGraphContext ctx) => { RecursiveRendererResources rrResources = new RecursiveRendererResources(); rrResources.depthStencilBuffer = data.depthStencilBuffer; rrResources.flagMask = data.flagMask; rrResources.debugBuffer = data.debugBuffer; rrResources.rayCountTexture = data.rayCountTexture; rrResources.outputBuffer = data.outputBuffer; ExecuteRecursiveRendering(ctx.cmd, data.parameters, rrResources); }); PushFullScreenDebugTexture(m_RenderGraph, passData.debugBuffer, FullScreenDebugMode.RecursiveRayTracing); return(passData.outputBuffer); } }
// Recursive rendering works as follow: // - Shader have a _RayTracing property // When this property is setup to true, a RayTracingPrepass pass on the material is enabled (otherwise it is disabled) // - Before prepass we render all object with a RayTracingPrepass pass enabled into the depth buffer for performance saving. // Note that we will exclude from the rendering of DepthPrepass, GBuffer and Forward pass the raytraced objects but not from // motion vector pass, so we can still benefit from motion vector. This is handled in VertMesh.hlsl (see below). // However currently when rendering motion vector this will tag the stencil for deferred lighting, and thus could produce overshading. // - After Transparent Depth pass we render all object with a RayTracingPrepass pass enabled into output a mask buffer (need to depth test but not to write depth) // Note: we render two times: one to save performance and the other to write the mask, otherwise if we write the mask in the first pass it // will not take into account the objects which could render on top of the raytracing one (If we want to do that we need to perform the pass after that // the depth buffer is ready, which is after the Gbuffer pass, so we can't save performance). // - During RaytracingRecursiveRender we perform a RayTracingRendering.raytrace call on all pixel tag in the mask // It is require to exclude mesh from regular pass to save performance (for opaque) and get correct result (for transparent) // For this we cull the mesh by setuping their position to NaN if _RayTracing is true and _EnableRecursiveRayTracing true. // We use this method to avoid to have to deal with RenderQueue and it allow to dynamically disabled Recursive rendering // and fallback to classic rasterize transparent this way. The code for the culling is in VertMesh() // If raytracing is disable _EnableRecursiveRayTracing is set to false and no culling happen. // Objects are still render in shadow and motion vector pass to keep their properties. // We render Recursive render object before transparent, so transparent object can be overlayed on top // like lens flare on top of headlight. We write the depth, so it correctly z-test object behind as recursive rendering // re-render everything (Mean we should also support fog and sky into it). void RaytracingRecursiveRender(HDCamera hdCamera, CommandBuffer cmd) { // If ray tracing is disabled in the frame settings or the effect is not enabled RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent<RecursiveRendering>(); if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) || !recursiveSettings.enable.value) return; using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.RayTracingRecursiveRendering))) { RTHandle debugBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); RecursiveRendererParameters rrParams = PrepareRecursiveRendererParameters(hdCamera, recursiveSettings); RecursiveRendererResources rrResources = PrepareRecursiveRendererResources(debugBuffer); ExecuteRecursiveRendering(cmd, rrParams, rrResources); PushFullScreenDebugTexture(hdCamera, cmd, debugBuffer, FullScreenDebugMode.RecursiveRayTracing); } }
void RaytracingRecursiveRender(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, CullingResults cull) { // If ray tracing is disabled in the frame settings or the effect is not enabled RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) || !recursiveSettings.enable.value) { return; } // Recursive rendering works as follow: // - Shader have a _RayTracing property // When this property is setup to true, a RayTracingPrepass pass on the material is enabled (otherwise it is disabled) // - Before prepass we render all object with a RayTracingPrepass pass enabled into the depth buffer for performance saving. // Note that we will exclude from the rendering of DepthPrepass, GBuffer and Forward pass the raytraced objects but not from // motion vector pass, so we can still benefit from motion vector. This is handled in VertMesh.hlsl (see below). // However currently when rendering motion vector this will tag the stencil for deferred lighting, and thus could produce overshading. // - After Transparent Depth pass we render all object with a RayTracingPrepass pass enabled into output a mask buffer (need to depth test but not to write depth) // Note: we render two times: one to save performance and the other to write the mask, otherwise if we write the mask in the first pass it // will not take into account the objects which could render on top of the raytracing one (If we want to do that we need to perform the pass after that // the depth buffer is ready, which is after the Gbuffer pass, so we can't save performance). // - During RaytracingRecursiveRender we perform a RayTracingRendering.raytrace call on all pixel tag in the mask // It is require to exclude mesh from regular pass to save performance (for opaque) and get correct result (for transparent) // For this we cull the mesh by setuping their position to NaN if _RayTracing is true and _EnableRecursiveRayTracing true. // We use this method to avoid to have to deal with RenderQueue and it allow to dynamically disabled Recursive rendering // and fallback to classic rasterize transparent this way. The code for the culling is in VertMesh() // If raytracing is disable _EnableRecursiveRayTracing is set to false and no culling happen. // Objects are still render in shadow and motion vector pass to keep their properties. // We render Recursive render object before transparent, so transparent object can be overlayed on top // like lens flare on top of headlight. We write the depth, so it correctly z-test object behind as recursive rendering // re-render everything (Mean we should also support fog and sky into it). using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.RayTracingRecursiveRendering))) { RTHandle debugBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); RecursiveRendererParameters rrParams = PrepareRecursiveRendererParameters(hdCamera, recursiveSettings); RecursiveRendererResources rrResources = PrepareRecursiveRendererResources(debugBuffer); ExecuteRecursiveRendering(cmd, rrParams, rrResources); PushFullScreenDebugTexture(hdCamera, cmd, debugBuffer, FullScreenDebugMode.RecursiveRayTracing); } }
RecursiveRendererParameters PrepareRecursiveRendererParameters(HDCamera hdCamera, RecursiveRendering recursiveRendering) { RecursiveRendererParameters rrParams = new RecursiveRendererParameters(); // Camera parameters rrParams.texWidth = hdCamera.actualWidth; rrParams.texHeight = hdCamera.actualHeight; rrParams.viewCount = hdCamera.viewCount; // Effect parameters rrParams.rayLength = recursiveRendering.rayLength.value; rrParams.maxDepth = recursiveRendering.maxDepth.value; rrParams.minSmoothness = recursiveRendering.minSmoothness.value; // Other data rrParams.accelerationStructure = RequestAccelerationStructure(); rrParams.lightCluster = RequestLightCluster(); rrParams.recursiveRenderingRT = m_Asset.renderPipelineRayTracingResources.forwardRaytracing; rrParams.skyTexture = m_SkyManager.GetSkyReflection(hdCamera); rrParams.shaderVariablesRayTracingCB = m_ShaderVariablesRayTracingCB; BlueNoise blueNoise = GetBlueNoiseManager(); rrParams.ditheredTextureSet = blueNoise.DitheredTextureSet8SPP(); return(rrParams); }
internal void BuildRayTracingAccelerationStructure(HDCamera hdCamera) { // Clear all the per frame-data m_RayTracingRendererReference.Clear(); m_RayTracingLights.hdDirectionalLightArray.Clear(); m_RayTracingLights.hdPointLightArray.Clear(); m_RayTracingLights.hdLineLightArray.Clear(); m_RayTracingLights.hdRectLightArray.Clear(); m_RayTracingLights.hdLightArray.Clear(); m_RayTracingLights.reflectionProbeArray.Clear(); m_RayTracingLights.lightCount = 0; m_CurrentRAS.Dispose(); m_CurrentRAS = new RayTracingAccelerationStructure(); m_ValidRayTracingState = false; m_ValidRayTracingCluster = false; m_ValidRayTracingClusterCulling = false; m_RayTracedShadowsRequired = false; m_RayTracedContactShadowsRequired = false; // If the camera does not have a ray tracing frame setting // or it is a preview camera (due to the fact that the sphere does not exist as a game object we can't create the RTAS) // we do not want to build a RTAS if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) || hdCamera.camera.cameraType == CameraType.Preview) { return; } // We only support ray traced shadows if the camera supports ray traced shadows bool screenSpaceShadowsSupported = hdCamera.frameSettings.IsEnabled(FrameSettingsField.ScreenSpaceShadows); // fetch all the lights in the scene HDAdditionalLightData[] hdLightArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalLightData>(); for (int lightIdx = 0; lightIdx < hdLightArray.Length; ++lightIdx) { HDAdditionalLightData hdLight = hdLightArray[lightIdx]; if (hdLight.enabled) { // Check if there is a ray traced shadow in the scene m_RayTracedShadowsRequired |= (hdLight.useRayTracedShadows && screenSpaceShadowsSupported); m_RayTracedContactShadowsRequired |= (hdLight.useContactShadow.@override && hdLight.rayTraceContactShadow); switch (hdLight.type) { case HDLightType.Directional: m_RayTracingLights.hdDirectionalLightArray.Add(hdLight); break; case HDLightType.Point: case HDLightType.Spot: m_RayTracingLights.hdPointLightArray.Add(hdLight); break; case HDLightType.Area: switch (hdLight.areaLightShape) { case AreaLightShape.Rectangle: m_RayTracingLights.hdRectLightArray.Add(hdLight); break; case AreaLightShape.Tube: m_RayTracingLights.hdLineLightArray.Add(hdLight); break; //TODO: case AreaLightShape.Disc: } break; } } } // Aggregate the shadow requirement bool rayTracedShadows = m_RayTracedShadowsRequired || m_RayTracedContactShadowsRequired; m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdPointLightArray); m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdLineLightArray); m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdRectLightArray); HDAdditionalReflectionData[] reflectionProbeArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalReflectionData>(); for (int reflIdx = 0; reflIdx < reflectionProbeArray.Length; ++reflIdx) { HDAdditionalReflectionData reflectionProbe = reflectionProbeArray[reflIdx]; // Add it to the list if enabled if (reflectionProbe.enabled) { m_RayTracingLights.reflectionProbeArray.Add(reflectionProbe); } } m_RayTracingLights.lightCount = m_RayTracingLights.hdPointLightArray.Count + m_RayTracingLights.hdLineLightArray.Count + m_RayTracingLights.hdRectLightArray.Count + m_RayTracingLights.reflectionProbeArray.Count; AmbientOcclusion aoSettings = hdCamera.volumeStack.GetComponent <AmbientOcclusion>(); bool rtAOEnabled = aoSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSAO); ScreenSpaceReflection reflSettings = hdCamera.volumeStack.GetComponent <ScreenSpaceReflection>(); bool rtREnabled = reflSettings.enabled.value && reflSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSR); GlobalIllumination giSettings = hdCamera.volumeStack.GetComponent <GlobalIllumination>(); bool rtGIEnabled = giSettings.enable.value && giSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SSGI); RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); bool rrEnabled = recursiveSettings.enable.value; SubSurfaceScattering sssSettings = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>(); bool rtSSSEnabled = sssSettings.rayTracing.value && hdCamera.frameSettings.IsEnabled(FrameSettingsField.SubsurfaceScattering); PathTracing pathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>(); bool ptEnabled = pathTracingSettings.enable.value; // We need to check if we should be building the ray tracing acceleration structure (if required by any effect) bool rayTracingRequired = rtAOEnabled || rtREnabled || rtGIEnabled || rrEnabled || rtSSSEnabled || ptEnabled || rayTracedShadows; if (!rayTracingRequired) { return; } // We need to process the emissive meshes of the rectangular area lights for (var i = 0; i < m_RayTracingLights.hdRectLightArray.Count; i++) { // Fetch the current renderer of the rectangular area light (if any) MeshRenderer currentRenderer = m_RayTracingLights.hdRectLightArray[i].emissiveMeshRenderer; // If there is none it means that there is no emissive mesh for this light if (currentRenderer == null) { continue; } // This objects should be included into the RAS AddInstanceToRAS(currentRenderer, rayTracedShadows, rtAOEnabled, aoSettings.layerMask.value, rtREnabled, reflSettings.layerMask.value, rtGIEnabled, giSettings.layerMask.value, rrEnabled, recursiveSettings.layerMask.value, ptEnabled, pathTracingSettings.layerMask.value); } int matCount = m_MaterialCRCs.Count; LODGroup[] lodGroupArray = UnityEngine.GameObject.FindObjectsOfType <LODGroup>(); for (var i = 0; i < lodGroupArray.Length; i++) { // Grab the current LOD group LODGroup lodGroup = lodGroupArray[i]; // Get the set of LODs LOD[] lodArray = lodGroup.GetLODs(); for (int lodIdx = 0; lodIdx < lodArray.Length; ++lodIdx) { LOD currentLOD = lodArray[lodIdx]; // We only want to push to the acceleration structure the lod0, we do not have defined way to select the right LOD at the moment if (lodIdx == 0) { for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx) { // Fetch the renderer that we are interested in Renderer currentRenderer = currentLOD.renderers[rendererIdx]; // This objects should but included into the RAS AddInstanceToRAS(currentRenderer, rayTracedShadows, aoSettings.rayTracing.value, aoSettings.layerMask.value, reflSettings.rayTracing.value, reflSettings.layerMask.value, giSettings.rayTracing.value, giSettings.layerMask.value, recursiveSettings.enable.value, recursiveSettings.layerMask.value, pathTracingSettings.enable.value, pathTracingSettings.layerMask.value); } } // Add them to the processed set so that they are not taken into account when processing all the renderers for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx) { Renderer currentRenderer = currentLOD.renderers[rendererIdx]; // Add this fella to the renderer list // Unfortunately, we need to check that this renderer was not already pushed into the list (happens if the user uses the same mesh renderer // for two LODs) if (!m_RayTracingRendererReference.ContainsKey(currentRenderer.GetInstanceID())) { m_RayTracingRendererReference.Add(currentRenderer.GetInstanceID(), 1); } } } } // Grab all the renderers from the scene var rendererArray = UnityEngine.GameObject.FindObjectsOfType <Renderer>(); for (var i = 0; i < rendererArray.Length; i++) { // Fetch the current renderer Renderer currentRenderer = rendererArray[i]; // If it is not active skip it if (currentRenderer.enabled == false) { continue; } // Grab the current game object GameObject gameObject = currentRenderer.gameObject; // Has this object already been processed, just skip it if (m_RayTracingRendererReference.ContainsKey(currentRenderer.GetInstanceID())) { continue; } // Does this object have a reflection probe component? if yes we do not want to have it in the acceleration structure if (gameObject.TryGetComponent <ReflectionProbe>(out reflectionProbe)) { continue; } // This objects should be included into the RAS AddInstanceToRAS(currentRenderer, rayTracedShadows, aoSettings.rayTracing.value, aoSettings.layerMask.value, reflSettings.rayTracing.value, reflSettings.layerMask.value, giSettings.rayTracing.value, giSettings.layerMask.value, recursiveSettings.enable.value, recursiveSettings.layerMask.value, pathTracingSettings.enable.value, pathTracingSettings.layerMask.value); } // Check if the amount of materials being tracked has changed m_MaterialsDirty |= (matCount != m_MaterialCRCs.Count); // build the acceleration structure m_CurrentRAS.Build(); // tag the structures as valid m_ValidRayTracingState = true; }
void RaytracingRecursiveRender(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, CullingResults cull) { // First thing to check is: Do we have a valid ray-tracing environment? RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); // Check the validity of the state before computing the effect bool invalidState = !hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) || !recursiveSettings.enable.value; // If any resource or game-object is missing We stop right away if (invalidState) { return; } RayTracingShader forwardShader = m_Asset.renderPipelineRayTracingResources.forwardRaytracing; Shader raytracingMask = m_Asset.renderPipelineRayTracingResources.raytracingFlagMask; LightCluster lightClusterSettings = hdCamera.volumeStack.GetComponent <LightCluster>(); RayTracingSettings rtSettings = hdCamera.volumeStack.GetComponent <RayTracingSettings>(); // Grab the acceleration structure and the list of HD lights for the target camera RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure(); HDRaytracingLightCluster lightCluster = RequestLightCluster(); // Fecth the temporary buffers we shall be using RTHandle flagBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.R0); if (m_RaytracingFlagMaterial == null) { m_RaytracingFlagMaterial = CoreUtils.CreateEngineMaterial(raytracingMask); } // Before going into ray tracing, we need to flag which pixels needs to be raytracing EvaluateRaytracingMask(cull, hdCamera, cmd, renderContext, flagBuffer); // 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_Asset.renderPipelineResources.textures.owenScrambledRGBATex); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex); // Inject the ray generation data cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtSettings.rayBias.value); 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, flagBuffer); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._CameraColorTextureRW, m_CameraColorBuffer); // Set ray count texture RayCountManager rayCountManager = GetRayCountManager(); cmd.SetRayTracingIntParam(forwardShader, HDShaderIDs._RayCountEnabled, rayCountManager.RayCountIsEnabled()); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RayCountTexture, rayCountManager.GetRayCountTexture()); // Compute an approximate pixel spread angle value (in radians) cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, GetPixelSpreadAngle(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight)); // LightLoop data lightCluster.BindLightClusterData(cmd); // Note: Just in case, we rebind the directional light data (in case they were not) cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, m_LightLoopLightData.directionalLightData); cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, m_lightList.directionalLights.Count); // Set the data for the ray miss cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera)); // If this is the right debug mode and we have at least one light, write the first shadow to the de-noised texture RTHandle debugBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingPrimaryDebug, debugBuffer); // Run the computation cmd.DispatchRays(forwardShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, (uint)hdCamera.viewCount); HDRenderPipeline hdrp = (RenderPipelineManager.currentPipeline as HDRenderPipeline); hdrp.PushFullScreenDebugTexture(hdCamera, cmd, debugBuffer, FullScreenDebugMode.RecursiveRayTracing); }
void RaytracingRecursiveRender(HDCamera hdCamera, CommandBuffer cmd, ScriptableRenderContext renderContext, CullingResults cull) { if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing)) { return; } RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); if (!recursiveSettings.enable.value) { return; } // Recursive rendering works as follow: // - Shader have a _RayTracing property // When this property is setup to true, a RayTracingPrepass pass on the material is enabled (otherwise it is disabled) // - Before prepass we render all object with a RayTracingPrepass pass enabled into the depth buffer for performance saving. // Note that we will exclude from the rendering of DepthPrepass, GBuffer and Forward pass the raytraced objects but not from // motion vector pass, so we can still benefit from motion vector. This is handled in VertMesh.hlsl (see below). // However currently when rendering motion vector this will tag the stencil for deferred lighting, and thus could produce overshading. // - After Transparent Depth pass we render all object with a RayTracingPrepass pass enabled into output a mask buffer (need to depth test but not to write depth) // Note: we render two times: one to save performance and the other to write the mask, otherwise if we write the mask in the first pass it // will not take into account the objects which could render on top of the raytracing one (If we want to do that we need to perform the pass after that // the depth buffer is ready, which is after the Gbuffer pass, so we can't save performance). // - During RaytracingRecursiveRender we perform a RayTracingRendering.raytrace call on all pixel tag in the mask // It is require to exclude mesh from regular pass to save performance (for opaque) and get correct result (for transparent) // For this we cull the mesh by setuping their position to NaN if _RayTracing is true and _EnableRecursiveRayTracing true. // We use this method to avoid to have to deal with RenderQueue and it allow to dynamically disabled Recursive rendering // and fallback to classic rasterize transparent this way. The code for the culling is in VertMesh() // If raytracing is disable _EnableRecursiveRayTracing is set to false and no culling happen. // Objects are still render in shadow and motion vector pass to keep their properties. // We render Recursive render object before transparent, so transparent object can be overlayed on top // like lens flare on top of headlight. We write the depth, so it correctly z-test object behind as recursive rendering // re-render everything (Mean we should also support fog and sky into it). using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.RayTracingRecursiveRendering))) { RayTracingShader forwardShader = m_Asset.renderPipelineRayTracingResources.forwardRaytracing; LightCluster lightClusterSettings = hdCamera.volumeStack.GetComponent <LightCluster>(); RayTracingSettings rtSettings = hdCamera.volumeStack.GetComponent <RayTracingSettings>(); // Grab the acceleration structure and the list of HD lights for the target camera RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure(); HDRaytracingLightCluster lightCluster = RequestLightCluster(); // 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_Asset.renderPipelineResources.textures.owenScrambledRGBATex); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex); // Inject the ray generation data cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtSettings.rayBias.value); 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 // Fecth the temporary buffers we shall be using RTHandle flagBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.R0); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingFlagMask, flagBuffer); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._CameraColorTextureRW, m_CameraColorBuffer); // Set ray count texture RayCountManager rayCountManager = GetRayCountManager(); cmd.SetGlobalInt(HDShaderIDs._RayCountEnabled, rayCountManager.RayCountIsEnabled()); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RayCountTexture, rayCountManager.GetRayCountTexture()); // Compute an approximate pixel spread angle value (in radians) cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, GetPixelSpreadAngle(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight)); // LightLoop data lightCluster.BindLightClusterData(cmd); // Note: Just in case, we rebind the directional light data (in case they were not) cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, m_LightLoopLightData.directionalLightData); // Set the data for the ray miss cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera)); // If this is the right debug mode and we have at least one light, write the first shadow to the de-noised texture RTHandle debugBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingPrimaryDebug, debugBuffer); // Run the computation cmd.DispatchRays(forwardShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, (uint)hdCamera.viewCount); HDRenderPipeline hdrp = (RenderPipelineManager.currentPipeline as HDRenderPipeline); hdrp.PushFullScreenDebugTexture(hdCamera, cmd, debugBuffer, FullScreenDebugMode.RecursiveRayTracing); } }
public void RaytracingRecursiveRender(HDCamera hdCamera, CommandBuffer cmd, 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_Asset.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_Asset.renderPipelineRayTracingResources.forwardRaytracing; Shader raytracingMask = m_Asset.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_Asset.renderPipelineResources.textures.owenScrambledRGBATex); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.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, m_CameraColorBuffer); // Set ray count texture cmd.SetRayTracingIntParam(forwardShader, HDShaderIDs._RayCountEnabled, m_RayTracingManager.rayCountManager.RayCountIsEnabled()); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RayCountTexture, m_RayTracingManager.rayCountManager.GetRayCountTexture()); // 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 de-noised texture HDRenderPipeline hdrp = (RenderPipelineManager.currentPipeline as HDRenderPipeline); cmd.SetRayTracingTextureParam(forwardShader, HDShaderIDs._RaytracingPrimaryDebug, m_DebugRaytracingTexture); hdrp.PushFullScreenDebugTexture(hdCamera, cmd, m_DebugRaytracingTexture, FullScreenDebugMode.RecursiveTracing); // Run the computation cmd.DispatchRays(forwardShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); }
internal void BuildRayTracingAccelerationStructure(HDCamera hdCamera) { // Clear all the per frame-data m_RayTracingRendererReference.Clear(); m_RayTracingLights.hdDirectionalLightArray.Clear(); m_RayTracingLights.hdPointLightArray.Clear(); m_RayTracingLights.hdLineLightArray.Clear(); m_RayTracingLights.hdRectLightArray.Clear(); m_RayTracingLights.hdLightArray.Clear(); m_RayTracingLights.reflectionProbeArray.Clear(); m_RayTracingLights.lightCount = 0; m_CurrentRAS.Dispose(); m_CurrentRAS = new RayTracingAccelerationStructure(); m_ValidRayTracingState = false; m_ValidRayTracingCluster = false; bool rayTracedShadow = false; // fetch all the lights in the scene HDAdditionalLightData[] hdLightArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalLightData>(); for (int lightIdx = 0; lightIdx < hdLightArray.Length; ++lightIdx) { HDAdditionalLightData hdLight = hdLightArray[lightIdx]; if (hdLight.enabled) { // Check if there is a ray traced shadow in the scene rayTracedShadow |= (hdLight.useRayTracedShadows || (hdLight.useContactShadow.@override && hdLight.rayTraceContactShadow)); switch (hdLight.type) { case HDLightType.Directional: m_RayTracingLights.hdDirectionalLightArray.Add(hdLight); break; case HDLightType.Point: case HDLightType.Spot: m_RayTracingLights.hdPointLightArray.Add(hdLight); break; case HDLightType.Area: switch (hdLight.areaLightShape) { case AreaLightShape.Rectangle: m_RayTracingLights.hdRectLightArray.Add(hdLight); break; case AreaLightShape.Tube: m_RayTracingLights.hdLineLightArray.Add(hdLight); break; //TODO: case AreaLightShape.Disc: } break; } } } m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdPointLightArray); m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdLineLightArray); m_RayTracingLights.hdLightArray.AddRange(m_RayTracingLights.hdRectLightArray); HDAdditionalReflectionData[] reflectionProbeArray = UnityEngine.GameObject.FindObjectsOfType <HDAdditionalReflectionData>(); for (int reflIdx = 0; reflIdx < reflectionProbeArray.Length; ++reflIdx) { HDAdditionalReflectionData reflectionProbe = reflectionProbeArray[reflIdx]; // Add it to the list if enabled if (reflectionProbe.enabled) { m_RayTracingLights.reflectionProbeArray.Add(reflectionProbe); } } m_RayTracingLights.lightCount = m_RayTracingLights.hdPointLightArray.Count + m_RayTracingLights.hdLineLightArray.Count + m_RayTracingLights.hdRectLightArray.Count + m_RayTracingLights.reflectionProbeArray.Count; AmbientOcclusion aoSettings = hdCamera.volumeStack.GetComponent <AmbientOcclusion>(); ScreenSpaceReflection reflSettings = hdCamera.volumeStack.GetComponent <ScreenSpaceReflection>(); GlobalIllumination giSettings = hdCamera.volumeStack.GetComponent <GlobalIllumination>(); RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); PathTracing pathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>(); LODGroup[] lodGroupArray = UnityEngine.GameObject.FindObjectsOfType <LODGroup>(); for (var i = 0; i < lodGroupArray.Length; i++) { // Grab the current LOD group LODGroup lodGroup = lodGroupArray[i]; // Get the set of LODs LOD[] lodArray = lodGroup.GetLODs(); for (int lodIdx = 0; lodIdx < lodArray.Length; ++lodIdx) { LOD currentLOD = lodArray[lodIdx]; // We only want to push to the acceleration structure the lod0, we do not have defined way to select the right LOD at the moment if (lodIdx == 0) { for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx) { // Fetch the renderer that we are interested in Renderer currentRenderer = currentLOD.renderers[rendererIdx]; // This objects should but included into the RAS AddInstanceToRAS(currentRenderer, rayTracedShadow, aoSettings.rayTracing.value, aoSettings.layerMask.value, reflSettings.rayTracing.value, reflSettings.layerMask.value, giSettings.rayTracing.value, giSettings.layerMask.value, recursiveSettings.enable.value, recursiveSettings.layerMask.value, pathTracingSettings.enable.value, pathTracingSettings.layerMask.value); } } // Add them to the processed set so that they are not taken into account when processing all the renderers for (int rendererIdx = 0; rendererIdx < currentLOD.renderers.Length; ++rendererIdx) { Renderer currentRenderer = currentLOD.renderers[rendererIdx]; // Add this fella to the renderer list m_RayTracingRendererReference.Add(currentRenderer.GetInstanceID(), 1); } } } // Grab all the renderers from the scene var rendererArray = UnityEngine.GameObject.FindObjectsOfType <Renderer>(); for (var i = 0; i < rendererArray.Length; i++) { // Fetch the current renderer Renderer currentRenderer = rendererArray[i]; // If it is not active skip it if (currentRenderer.enabled == false) { continue; } // Grab the current game object GameObject gameObject = currentRenderer.gameObject; // Has this object already been processed, just skip it if (m_RayTracingRendererReference.ContainsKey(currentRenderer.GetInstanceID())) { continue; } // Does this object have a reflection probe component? if yes we do not want to have it in the acceleration structure if (gameObject.TryGetComponent <ReflectionProbe>(out reflectionProbe)) { continue; } // This objects should but included into the RAS AddInstanceToRAS(currentRenderer, rayTracedShadow, aoSettings.rayTracing.value, aoSettings.layerMask.value, reflSettings.rayTracing.value, reflSettings.layerMask.value, giSettings.rayTracing.value, giSettings.layerMask.value, recursiveSettings.enable.value, recursiveSettings.layerMask.value, pathTracingSettings.enable.value, pathTracingSettings.layerMask.value); } // build the acceleration structure m_CurrentRAS.Build(); // tag the structures as valid m_ValidRayTracingState = true; }
TextureHandle RaytracingRecursiveRender(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle colorBuffer, TextureHandle depthPyramid, TextureHandle flagMask, TextureHandle rayCountTexture) { // If ray tracing is disabled in the frame settings or the effect is not enabled RecursiveRendering recursiveSettings = hdCamera.volumeStack.GetComponent <RecursiveRendering>(); // Make sure all the requirements are there to render the effect bool validEffect = hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && recursiveSettings.enable.value && GetRayTracingState() && GetRayTracingClusterState(); if (!validEffect) { return(colorBuffer); } using (var builder = renderGraph.AddRenderPass <RecursiveRenderingPassData>("Recursive Rendering Evaluation", out var passData, ProfilingSampler.Get(HDProfileId.RayTracingRecursiveRendering))) { builder.EnableAsyncCompute(false); // Camera parameters passData.texWidth = hdCamera.actualWidth; passData.texHeight = hdCamera.actualHeight; passData.viewCount = hdCamera.viewCount; // Effect parameters passData.rayLength = recursiveSettings.rayLength.value; passData.maxDepth = recursiveSettings.maxDepth.value; passData.minSmoothness = recursiveSettings.minSmoothness.value; passData.rayMissFallbackHiearchy = (int)recursiveSettings.rayMiss.value; passData.lastBounceFallbackHiearchy = (int)recursiveSettings.lastBounce.value; // Other data passData.accelerationStructure = RequestAccelerationStructure(hdCamera); passData.lightCluster = RequestLightCluster(); passData.recursiveRenderingRT = m_GlobalSettings.renderPipelineRayTracingResources.forwardRaytracing; passData.skyTexture = m_SkyManager.GetSkyReflection(hdCamera); passData.shaderVariablesRayTracingCB = m_ShaderVariablesRayTracingCB; passData.ditheredTextureSet = GetBlueNoiseManager().DitheredTextureSet8SPP(); passData.depthStencilBuffer = builder.ReadTexture(depthPyramid); passData.flagMask = builder.ReadTexture(flagMask); passData.rayCountTexture = builder.ReadWriteTexture(rayCountTexture); passData.outputBuffer = builder.ReadWriteTexture(colorBuffer); // Right now the debug buffer is written to independently of what is happening. This must be changed // TODO RENDERGRAPH passData.debugBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Recursive Rendering Debug Texture" })); builder.SetRenderFunc( (RecursiveRenderingPassData data, RenderGraphContext ctx) => { // Define the shader pass to use for the reflection pass ctx.cmd.SetRayTracingShaderPass(data.recursiveRenderingRT, "ForwardDXR"); // Set the acceleration structure for the pass ctx.cmd.SetRayTracingAccelerationStructure(data.recursiveRenderingRT, HDShaderIDs._RaytracingAccelerationStructureName, data.accelerationStructure); // Inject the ray-tracing sampling data BlueNoise.BindDitheredTextureSet(ctx.cmd, data.ditheredTextureSet); // Update Global Constant Buffer. data.shaderVariablesRayTracingCB._RaytracingRayMaxLength = data.rayLength; #if NO_RAY_RECURSION data.shaderVariablesRayTracingCB._RaytracingMaxRecursion = 1; #else data.shaderVariablesRayTracingCB._RaytracingMaxRecursion = data.maxDepth; #endif data.shaderVariablesRayTracingCB._RaytracingReflectionMinSmoothness = data.minSmoothness; data.shaderVariablesRayTracingCB._RayTracingRayMissFallbackHierarchy = data.rayMissFallbackHiearchy; data.shaderVariablesRayTracingCB._RayTracingLastBounceFallbackHierarchy = data.lastBounceFallbackHiearchy; ConstantBuffer.PushGlobal(ctx.cmd, data.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing); // Fecth the temporary buffers we shall be using ctx.cmd.SetRayTracingTextureParam(data.recursiveRenderingRT, HDShaderIDs._RaytracingFlagMask, data.flagMask); ctx.cmd.SetRayTracingTextureParam(data.recursiveRenderingRT, HDShaderIDs._DepthTexture, data.depthStencilBuffer); ctx.cmd.SetRayTracingTextureParam(data.recursiveRenderingRT, HDShaderIDs._CameraColorTextureRW, data.outputBuffer); // Set ray count texture ctx.cmd.SetRayTracingTextureParam(data.recursiveRenderingRT, HDShaderIDs._RayCountTexture, data.rayCountTexture); // LightLoop data data.lightCluster.BindLightClusterData(ctx.cmd); // Set the data for the ray miss ctx.cmd.SetRayTracingTextureParam(data.recursiveRenderingRT, HDShaderIDs._SkyTexture, data.skyTexture); // If this is the right debug mode and we have at least one light, write the first shadow to the de-noised texture ctx.cmd.SetRayTracingTextureParam(data.recursiveRenderingRT, HDShaderIDs._RaytracingPrimaryDebug, data.debugBuffer); // Run the computation ctx.cmd.DispatchRays(data.recursiveRenderingRT, m_RayGenShaderName, (uint)data.texWidth, (uint)data.texHeight, (uint)data.viewCount); }); PushFullScreenDebugTexture(m_RenderGraph, passData.debugBuffer, FullScreenDebugMode.RecursiveRayTracing); return(passData.outputBuffer); } }