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)); }
internal void BuildRayTracingLightCluster(CommandBuffer cmd, 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>(); if (m_ValidRayTracingState && (reflSettings.rayTracing.value || giSettings.rayTracing.value || recursiveSettings.enable.value || pathTracingSettings.enable.value || subSurface.rayTracing.value)) { m_RayTracingLightCluster.EvaluateLightClusters(cmd, hdCamera, m_RayTracingLights); m_ValidRayTracingCluster = true; } }
private void ResetIteration() { // If we just changed the sample count, we don't want to reset the iteration PathTracing pathTracingSettings = VolumeManager.instance.stack.GetComponent <PathTracing>(); if (maxIteration != pathTracingSettings.maximumSamples.value) { maxIteration = (uint)pathTracingSettings.maximumSamples.value; } else { currentIteration = 0; } }
/// <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); }
void RenderPathTracing(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture) { RayTracingShader pathTracingShader = m_Asset.renderPipelineRayTracingResources.pathTracing; m_PathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>(); // Check the validity of the state before moving on with the computation if (!pathTracingShader || !m_PathTracingSettings.enable.value) { return; } if (hdCamera.viewCount > 1) { Debug.LogError("Path Tracing is not supported when using XR single-pass rendering."); return; } CheckDirtiness(hdCamera); // Inject the ray-tracing sampling data BlueNoise blueNoiseManager = GetBlueNoiseManager(); blueNoiseManager.BindDitheredRNGData256SPP(cmd); // Grab the acceleration structure and the list of HD lights for the target camera RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure(); HDRaytracingLightCluster lightCluster = RequestLightCluster(); LightCluster lightClusterSettings = hdCamera.volumeStack.GetComponent <LightCluster>(); if (!m_SubFrameManager.isRecording) { // If we are recording, the max iteration is set/overridden by the subframe manager, otherwise we read it from the path tracing volume m_SubFrameManager.subFrameCount = (uint)m_PathTracingSettings.maximumSamples.value; } #if UNITY_HDRP_DXR_TESTS_DEFINE if (Application.isPlaying) { m_SubFrameManager.subFrameCount = 1; } #endif CameraData camData = m_SubFrameManager.GetCameraData(hdCamera.camera.GetInstanceID()); if (camData.currentIteration < m_SubFrameManager.subFrameCount) { // Define the shader pass to use for the path tracing pass cmd.SetRayTracingShaderPass(pathTracingShader, "PathTracingDXR"); // Set the acceleration structure for the pass cmd.SetRayTracingAccelerationStructure(pathTracingShader, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure); // Inject the ray-tracing sampling data cmd.SetGlobalTexture(HDShaderIDs._OwenScrambledTexture, m_Asset.renderPipelineResources.textures.owenScrambled256Tex); cmd.SetGlobalTexture(HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex); // Update the global constant buffer m_ShaderVariablesRayTracingCB._RaytracingNumSamples = (int)m_SubFrameManager.subFrameCount; m_ShaderVariablesRayTracingCB._RaytracingMinRecursion = m_PathTracingSettings.minimumDepth.value; m_ShaderVariablesRayTracingCB._RaytracingMaxRecursion = m_PathTracingSettings.maximumDepth.value; m_ShaderVariablesRayTracingCB._RaytracingIntensityClamp = m_PathTracingSettings.maximumIntensity.value; m_ShaderVariablesRayTracingCB._RaytracingSampleIndex = (int)camData.currentIteration; ConstantBuffer.PushGlobal(cmd, m_ShaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing); // LightLoop data cmd.SetGlobalBuffer(HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster()); cmd.SetGlobalBuffer(HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas()); // Set the data for the ray miss cmd.SetRayTracingIntParam(pathTracingShader, HDShaderIDs._RaytracingCameraSkyEnabled, camData.skyEnabled ? 1 : 0); cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._RaytracingCameraClearColor, hdCamera.backgroundColorHDR); cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera)); // Additional data for path tracing cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._RadianceTexture, m_RadianceTexture); cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS); cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._PathTracedDoFConstants, ComputeDoFConstants(hdCamera, m_PathTracingSettings)); // Run the computation cmd.DispatchRays(pathTracingShader, "RayGen", (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); } RenderAccumulation(hdCamera, cmd, m_RadianceTexture, outputTexture, true); }
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; }
public void RenderPathTracing(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture, ScriptableRenderContext renderContext, int frameCount) { // First thing to check is: Do we have a valid ray-tracing environment? RayTracingShader pathTracingShader = m_Asset.renderPipelineRayTracingResources.pathTracing; PathTracing pathTracingSettings = VolumeManager.instance.stack.GetComponent <PathTracing>(); // Check the validity of the state before computing the effect if (!pathTracingShader || !pathTracingSettings.enable.value) { return; } // Inject the ray-tracing sampling data BlueNoise blueNoiseManager = GetBlueNoiseManager(); blueNoiseManager.BindDitheredRNGData256SPP(cmd); // Grab the history buffer (hijack the reflections one) RTHandle history = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.PathTracing) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.PathTracing, PathTracingHistoryBufferAllocatorFunction, 1); // Grab the acceleration structure and the list of HD lights for the target camera RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure(); HDRaytracingLightCluster lightCluster = RequestLightCluster(); LightCluster lightClusterSettings = VolumeManager.instance.stack.GetComponent <LightCluster>(); RayTracingSettings rayTracingSettings = VolumeManager.instance.stack.GetComponent <RayTracingSettings>(); // Define the shader pass to use for the path tracing pass cmd.SetRayTracingShaderPass(pathTracingShader, "PathTracingDXR"); // Set the acceleration structure for the pass cmd.SetRayTracingAccelerationStructure(pathTracingShader, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure); // Inject the ray-tracing sampling data cmd.SetGlobalTexture(HDShaderIDs._OwenScrambledTexture, m_Asset.renderPipelineResources.textures.owenScrambled256Tex); cmd.SetGlobalTexture(HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex); // Inject the ray generation data cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rayTracingSettings.rayBias.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingNumSamples, pathTracingSettings.maximumSamples.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingMinRecursion, pathTracingSettings.minimumDepth.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingMaxRecursion, pathTracingSettings.maximumDepth.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingIntensityClamp, pathTracingSettings.maximumIntensity.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingCameraNearPlane, hdCamera.camera.nearClipPlane); // Set the data for the ray generation //cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._CameraColorTextureRW, outputTexture); cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameCount); // Compute an approximate pixel spread angle value (in radians) cmd.SetRayTracingFloatParam(pathTracingShader, HDShaderIDs._RaytracingPixelSpreadAngle, GetPixelSpreadAngle(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight)); // 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()); // Set the data for the ray miss cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera)); // Additional data for path tracing cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._AccumulatedFrameTexture, history); cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS); // Run the computation cmd.DispatchRays(pathTracingShader, m_PathTracingRayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); }
void RenderPathTracing(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture) { RayTracingShader pathTracingShader = m_Asset.renderPipelineRayTracingResources.pathTracing; m_PathTracingSettings = hdCamera.volumeStack.GetComponent <PathTracing>(); // Check the validity of the state before moving on with the computation if (!pathTracingShader || !m_PathTracingSettings.enable.value) { return; } CheckDirtiness(hdCamera); // Inject the ray-tracing sampling data BlueNoise blueNoiseManager = GetBlueNoiseManager(); blueNoiseManager.BindDitheredRNGData256SPP(cmd); // Grab the acceleration structure and the list of HD lights for the target camera RayTracingAccelerationStructure accelerationStructure = RequestAccelerationStructure(); HDRaytracingLightCluster lightCluster = RequestLightCluster(); LightCluster lightClusterSettings = hdCamera.volumeStack.GetComponent <LightCluster>(); RayTracingSettings rayTracingSettings = hdCamera.volumeStack.GetComponent <RayTracingSettings>(); if (!m_SubFrameManager.isRecording) { // If we are recording, the max iteration is set/overridden by the subframe manager, otherwise we read it from the path tracing volume m_SubFrameManager.subFrameCount = (uint)m_PathTracingSettings.maximumSamples.value; } #if UNITY_HDRP_DXR_TESTS_DEFINE if (Application.isPlaying) { m_SubFrameManager.subFrameCount = 1; } #endif uint currentIteration = m_SubFrameManager.iteration; if (currentIteration < m_SubFrameManager.subFrameCount) { // Define the shader pass to use for the path tracing pass cmd.SetRayTracingShaderPass(pathTracingShader, "PathTracingDXR"); // Set the acceleration structure for the pass cmd.SetRayTracingAccelerationStructure(pathTracingShader, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure); // Inject the ray-tracing sampling data cmd.SetGlobalTexture(HDShaderIDs._OwenScrambledTexture, m_Asset.renderPipelineResources.textures.owenScrambled256Tex); cmd.SetGlobalTexture(HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex); // Inject the ray generation data cmd.SetGlobalFloat(HDShaderIDs._RaytracingNumSamples, m_SubFrameManager.subFrameCount); cmd.SetGlobalFloat(HDShaderIDs._RaytracingMinRecursion, m_PathTracingSettings.minimumDepth.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingMaxRecursion, m_PathTracingSettings.maximumDepth.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingIntensityClamp, m_PathTracingSettings.maximumIntensity.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rayTracingSettings.rayBias.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingCameraNearPlane, hdCamera.camera.nearClipPlane); // Set the data for the ray generation cmd.SetGlobalInt(HDShaderIDs._RaytracingSampleIndex, (int)m_SubFrameManager.iteration); // Compute an approximate pixel spread angle value (in radians) cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, GetPixelSpreadAngle(hdCamera.camera.fieldOfView, hdCamera.actualWidth, hdCamera.actualHeight)); // 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()); // Set the data for the ray miss cmd.SetRayTracingIntParam(pathTracingShader, HDShaderIDs._RaytracingCameraSkyEnabled, m_CameraSkyEnabled ? 1 : 0); cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._RaytracingCameraClearColor, hdCamera.backgroundColorHDR); cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._SkyTexture, m_SkyManager.GetSkyReflection(hdCamera)); // Additional data for path tracing cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._RadianceTexture, m_RadianceTexture); cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS); cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._PathTracedDoFConstants, ComputeDoFConstants(hdCamera, m_PathTracingSettings)); cmd.SetRayTracingVectorParam(pathTracingShader, HDShaderIDs._InvViewportScaleBias, HDUtils.ComputeInverseViewportScaleBias(hdCamera)); // Run the computation cmd.DispatchRays(pathTracingShader, "RayGen", (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); } RenderAccumulation(hdCamera, cmd, m_RadianceTexture, outputTexture, true); }
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; }
public void PathTracingRender(HDCamera hdCamera, CommandBuffer cmd, RTHandle outputTexture, ScriptableRenderContext renderContext, int frameCount) { // First thing to check is: Do we have a valid ray-tracing environment? HDRaytracingEnvironment rtEnvironment = m_RayTracingManager.CurrentEnvironment(); HDRenderPipeline renderPipeline = m_RayTracingManager.GetRenderPipeline(); RayTracingShader pathTracingShader = m_Asset.renderPipelineRayTracingResources.pathTracing; PathTracing pathTracingSettings = VolumeManager.instance.stack.GetComponent <PathTracing>(); LightCluster lightClusterSettings = VolumeManager.instance.stack.GetComponent <LightCluster>(); // Check the validity of the state before computing the effect bool invalidState = rtEnvironment == null || !pathTracingSettings.enable.value || pathTracingShader == null || m_Asset.renderPipelineResources.textures.owenScrambled256Tex == null || m_Asset.renderPipelineResources.textures.scramblingTex == null; // If any resource or game-object is missing We stop right away if (invalidState) { return; } // Grab the history buffer (hijack the reflections one) RTHandle history = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.PathTracing) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.PathTracing, PathTracingHistoryBufferAllocatorFunction, 1); // 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); // Define the shader pass to use for the path tracing pass cmd.SetRayTracingShaderPass(pathTracingShader, "PathTracingDXR"); // Set the acceleration structure for the pass cmd.SetRayTracingAccelerationStructure(pathTracingShader, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure); // Inject the ray-tracing sampling data cmd.SetGlobalTexture(HDShaderIDs._OwenScrambledTexture, m_Asset.renderPipelineResources.textures.owenScrambled256Tex); cmd.SetGlobalTexture(HDShaderIDs._ScramblingTexture, m_Asset.renderPipelineResources.textures.scramblingTex); // Inject the ray generation data cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias); cmd.SetGlobalFloat(HDShaderIDs._RaytracingNumSamples, pathTracingSettings.maxSamples.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingMinRecursion, pathTracingSettings.minDepth.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingMaxRecursion, pathTracingSettings.maxDepth.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingIntensityClamp, pathTracingSettings.maxIntensity.value); cmd.SetGlobalFloat(HDShaderIDs._RaytracingCameraNearPlane, hdCamera.camera.nearClipPlane); // Set the data for the ray generation //cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._CameraColorTextureRW, outputTexture); cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameCount); // 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.SetRayTracingFloatParam(pathTracingShader, 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: directional lights are not supported atm //cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, renderPipeline.directionalLightDatas); //cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, renderPipeline.m_lightList.directionalLights.Count); // Set the data for the ray miss cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._SkyTexture, m_SkyManager.skyReflection); // Additional data for path tracing cmd.SetRayTracingTextureParam(pathTracingShader, HDShaderIDs._AccumulatedFrameTexture, history); cmd.SetRayTracingMatrixParam(pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, hdCamera.mainViewConstants.pixelCoordToViewDirWS); // Run the computation cmd.DispatchRays(pathTracingShader, m_PathTracingRayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); }