public void Init(HDRenderPipelineAsset asset, HDRaytracingManager raytracingManager, SharedRTManager sharedRTManager, LightLoop lightLoop, GBufferManager gbufferManager) { // Keep track of the pipeline asset m_PipelineAsset = asset; m_PipelineResources = asset.renderPipelineResources; // keep track of the ray tracing manager m_RaytracingManager = raytracingManager; // Keep track of the shared rt manager m_SharedRTManager = sharedRTManager; // The lightloop that holds all the lights of the scene m_LightLoop = lightLoop; // GBuffer manager that holds all the data for shading the samples m_GbufferManager = gbufferManager; // Allocate the intermediate buffers m_AnalyticProbBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R16G16_SFloat), enableRandomWrite: true, useDynamicScale: true, xrInstancing: true, useMipMap: false, name: "AnalyticProbBuffer"); m_DenoiseBuffer0 = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R16G16B16A16_SFloat), enableRandomWrite: true, useDynamicScale: true, xrInstancing: true, useMipMap: false, name: "DenoiseBuffer0"); m_DenoiseBuffer1 = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R16G16B16A16_SFloat), enableRandomWrite: true, useDynamicScale: true, xrInstancing: true, useMipMap: false, name: "DenoiseBuffer1"); m_RaytracingDirectionBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R16G16B16A16_SFloat), enableRandomWrite: true, useDynamicScale: true, xrInstancing: true, useMipMap: false, name: "RaytracingDirectionBuffer"); m_RaytracingDistanceBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R32_SFloat), enableRandomWrite: true, useDynamicScale: true, xrInstancing: true, useMipMap: false, name: "RaytracingDistanceBuffer"); // Allocate the final result texture m_AreaShadowTextureArray = RTHandles.Alloc(Vector2.one, slices: 4, dimension: TextureDimension.Tex2DArray, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R16_SFloat), enableRandomWrite: true, useDynamicScale: true, xrInstancing: true, useMipMap: false, name: "AreaShadowArrayBuffer"); }
public void Init(RenderPipelineSettings settings, RenderPipelineResources resources, BlueNoise blueNoise, LightLoop lightloop, SharedRTManager sharedRTManager, DebugDisplaySettings currentDebugDisplaySettings) { // Keep track of the resources m_Resources = resources; // Keep track of the settings m_Settings = settings; // Keep track of the lightloop m_LightLoop = lightloop; // Keep track of the shared RT manager m_SharedRTManager = sharedRTManager; // Keep track of the blue noise manager m_BlueNoise = blueNoise; // Create the list of environments m_Environments = new List <HDRaytracingEnvironment>(); // Grab all the ray-tracing graphs that have been created before (in case the order of initialization has not been respected, which happens when we open unity the first time) HDRaytracingEnvironment[] environmentArray = Object.FindObjectsOfType <HDRaytracingEnvironment>(); for (int envIdx = 0; envIdx < environmentArray.Length; ++envIdx) { RegisterEnvironment(environmentArray[envIdx]); } // Init the ray count manager m_RayCountManager.Init(resources, currentDebugDisplaySettings); #if UNITY_EDITOR // We need to invalidate the acceleration structures in case the hierarchy changed EditorApplication.hierarchyChanged += OnHierarchyChanged; #endif }
public void Init(RenderPipelineSettings settings, RenderPipelineResources resources, BlueNoise blueNoise, LightLoop lightloop, SharedRTManager sharedRTManager) { // Keep track of the resources m_Resources = resources; // Keep track of the settings m_Settings = settings; // Keep track of the lightloop m_LightLoop = lightloop; // Keep track of the shared RT manager m_SharedRTManager = sharedRTManager; // Keep track of the blue noise manager m_BlueNoise = blueNoise; // Create the list of environments m_Environments = new List <HDRaytracingEnvironment>(); // Grab all the ray-tracing graphs that have been created before (in case the order of initialization has not been respected, which happens when we open unity the first time) HDRaytracingEnvironment[] environmentArray = Object.FindObjectsOfType <HDRaytracingEnvironment>(); for (int envIdx = 0; envIdx < environmentArray.Length; ++envIdx) { RegisterEnvironment(environmentArray[envIdx]); } // keep track of all the graphs that are to be supported m_Filters = new List <HDRayTracingFilter>(); // Create the sub-scenes structure m_SubScenes = new Dictionary <int, HDRayTracingSubScene>(); // The list of masks that are currently requested m_LayerMasks = new List <int>(); // Let's start by building the "default" sub-scene (used by the scene camera) HDRayTracingSubScene defaultSubScene = new HDRayTracingSubScene(); defaultSubScene.mask = m_Settings.editorRaytracingFilterLayerMask.value; defaultSubScene.persistent = true; BuildSubSceneStructure(ref defaultSubScene); m_SubScenes.Add(m_Settings.editorRaytracingFilterLayerMask.value, defaultSubScene); m_LayerMasks.Add(m_Settings.editorRaytracingFilterLayerMask.value); // Grab all the ray-tracing graphs that have been created before HDRayTracingFilter[] filterArray = Object.FindObjectsOfType <HDRayTracingFilter>(); for (int filterIdx = 0; filterIdx < filterArray.Length; ++filterIdx) { RegisterFilter(filterArray[filterIdx]); } m_RayCountManager.Init(resources); #if UNITY_EDITOR // We need to invalidate the acceleration structures in case the hierarchy changed EditorApplication.hierarchyChanged += OnHierarchyChanged; #endif }
public void CreateDrawData() { if (m_Material == null) { return; } if (m_NumResults == 0) { return; } // only add if anything in this decal set is visible. AddToTextureList(ref instance.m_TextureList); int instanceCount = 0; int batchCount = 0; Matrix4x4[] decalToWorldBatch = null; Matrix4x4[] normalToWorldBatch = null; AssignCurrentBatches(ref decalToWorldBatch, ref normalToWorldBatch, batchCount); Vector3 cameraPos = instance.CurrentCamera.transform.position; Matrix4x4 worldToView = LightLoop.WorldToCamera(instance.CurrentCamera); for (int resultIndex = 0; resultIndex < m_NumResults; resultIndex++) { int decalIndex = m_ResultIndices[resultIndex]; // do additional culling based on individual decal draw distances float distanceToDecal = (cameraPos - m_BoundingSpheres[decalIndex].position).magnitude; float cullDistance = m_CachedDrawDistances[decalIndex].x + m_BoundingSpheres[decalIndex].radius; if (distanceToDecal < cullDistance) { // d-buffer data decalToWorldBatch[instanceCount] = m_CachedDecalToWorld[decalIndex]; normalToWorldBatch[instanceCount] = m_CachedNormalToWorld[decalIndex]; float fadeFactor = Mathf.Clamp((cullDistance - distanceToDecal) / (cullDistance * (1.0f - m_CachedDrawDistances[decalIndex].y)), 0.0f, 1.0f); normalToWorldBatch[instanceCount].m03 = fadeFactor * m_Blend; // vector3 rotation matrix so bottom row and last column can be used for other data to save space normalToWorldBatch[instanceCount].SetRow(3, m_CachedUVScaleBias[decalIndex]); // clustered forward data m_DecalDatas[m_DecalDatasCount].worldToDecal = decalToWorldBatch[instanceCount].inverse; m_DecalDatas[m_DecalDatasCount].normalToWorld = normalToWorldBatch[instanceCount]; m_DecalDatas[m_DecalDatasCount].diffuseScaleBias = m_Diffuse.m_ScaleBias; m_DecalDatas[m_DecalDatasCount].normalScaleBias = m_Normal.m_ScaleBias; m_DecalDatas[m_DecalDatasCount].maskScaleBias = m_Mask.m_ScaleBias; GetDecalVolumeDataAndBound(decalToWorldBatch[instanceCount], worldToView); m_DecalDatasCount++; instanceCount++; if (instanceCount == kDrawIndexedBatchSize) { instanceCount = 0; batchCount++; AssignCurrentBatches(ref decalToWorldBatch, ref normalToWorldBatch, batchCount); } } } }
public void Initialize(RenderPipelineResources resources, HDRaytracingManager raytracingManager, SharedRTManager sharedRTManager, LightLoop lightLoop) { // Keep track of the external buffers m_RenderPipelineResources = resources; m_RaytracingManager = raytracingManager; // Keep track of the lightloop m_LightLoop = lightLoop; // Keep track of the shader rt manager m_SharedRTManager = sharedRTManager; // Texture used to output debug information m_DebugLightClusterTexture = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: "DebugLightClusterTexture"); }
public void Initialize(RenderPipelineResources resources, HDRaytracingManager raytracingManager, SharedRTManager sharedRTManager, LightLoop lightLoop) { // Keep track of the external buffers m_RenderPipelineResources = resources; m_RaytracingManager = raytracingManager; // Keep track of the lightloop m_LightLoop = lightLoop; // Keep track of the shader rt manager m_SharedRTManager = sharedRTManager; // Texture used to output debug information m_DebugLightClusterTexture = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R16G16B16A16_SFloat), enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: "DebugLightClusterTexture"); // Pre allocate the cluster with a dummy size m_LightCluster = new ComputeBuffer(1, sizeof(uint)); }
public void Init(HDRenderPipelineAsset asset, HDRaytracingManager raytracingManager, SharedRTManager sharedRTManager, LightLoop lightLoop, GBufferManager gbufferManager) { // Keep track of the pipeline asset m_PipelineAsset = asset; m_PipelineResources = asset.renderPipelineResources; // keep track of the ray tracing manager m_RaytracingManager = raytracingManager; // Keep track of the shared rt manager m_SharedRTManager = sharedRTManager; // The lightloop that holds all the lights of the scene m_LightLoop = lightLoop; // GBuffer manager that holds all the data for shading the samples m_GbufferManager = gbufferManager; // Allocate the intermediate buffers m_SNBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: "SNBuffer"); m_UNBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: "UNBuffer"); m_UBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: "UBuffer"); m_AreaShadowTextureArray = RTHandles.Alloc(Vector2.one, slices: 4, dimension: TextureDimension.Tex2DArray, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16_SFloat, enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: "AreaShadowArrayBuffer"); }
public void VolumeVoxelizationPass(HDCamera hdCamera, CommandBuffer cmd, uint frameIndex, DensityVolumeList densityVolumes, LightLoop lightLoop) { if (!hdCamera.frameSettings.IsEnabled(FrameSettingsField.Volumetrics)) { return; } var visualEnvironment = VolumeManager.instance.stack.GetComponent <VisualEnvironment>(); if (visualEnvironment.fogType.value != FogType.Volumetric) { return; } using (new ProfilingSample(cmd, "Volume Voxelization")) { int numVisibleVolumes = m_VisibleVolumeBounds.Count; bool tiledLighting = lightLoop.HasLightToCull() && hdCamera.frameSettings.IsEnabled(FrameSettingsField.BigTilePrepass); bool highQuality = preset == VolumetricLightingPreset.High; int kernel = (tiledLighting ? 1 : 0) | (highQuality ? 2 : 0); var currFrameParams = hdCamera.vBufferParams[0]; var cvp = currFrameParams.viewportSize; Vector4 resolution = new Vector4(cvp.x, cvp.y, 1.0f / cvp.x, 1.0f / cvp.y); #if UNITY_2019_1_OR_NEWER var vFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; var lensShift = hdCamera.camera.GetGateFittedLensShift(); #else var vFoV = hdCamera.camera.fieldOfView * Mathf.Deg2Rad; var lensShift = Vector2.zero; #endif // Compose the matrix which allows us to compute the world space view direction. Matrix4x4 transform = HDUtils.ComputePixelCoordToWorldSpaceViewDirectionMatrix(vFoV, lensShift, resolution, hdCamera.mainViewConstants.viewMatrix, false); // Compute texel spacing at the depth of 1 meter. float unitDepthTexelSpacing = HDUtils.ComputZPlaneTexelSpacing(1.0f, vFoV, resolution.y); Texture3D volumeAtlas = DensityVolumeManager.manager.volumeAtlas.GetAtlas(); Vector4 volumeAtlasDimensions = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); if (volumeAtlas != null) { volumeAtlasDimensions.x = (float)volumeAtlas.width / volumeAtlas.depth; // 1 / number of textures volumeAtlasDimensions.y = volumeAtlas.width; volumeAtlasDimensions.z = volumeAtlas.depth; volumeAtlasDimensions.w = Mathf.Log(volumeAtlas.width, 2); // Max LoD } else { volumeAtlas = CoreUtils.blackVolumeTexture; } if (hdCamera.frameSettings.VolumeVoxelizationRunsAsync()) { // We explicitly set the big tile info even though it is set globally, since this could be running async before the PushGlobalParams cmd.SetComputeIntParam(m_VolumeVoxelizationCS, HDShaderIDs._NumTileBigTileX, lightLoop.GetNumTileBigTileX(hdCamera)); cmd.SetComputeIntParam(m_VolumeVoxelizationCS, HDShaderIDs._NumTileBigTileY, lightLoop.GetNumTileBigTileY(hdCamera)); if (tiledLighting) { cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs.g_vBigTileLightList, lightLoop.GetBigTileLightList()); } } cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VBufferDensity, m_DensityBufferHandle); cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeBounds, s_VisibleVolumeBoundsBuffer); cmd.SetComputeBufferParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeData, s_VisibleVolumeDataBuffer); cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeMaskAtlas, volumeAtlas); // TODO: set the constant buffer data only once. cmd.SetComputeMatrixParam(m_VolumeVoxelizationCS, HDShaderIDs._VBufferCoordToViewDirWS, transform); cmd.SetComputeFloatParam(m_VolumeVoxelizationCS, HDShaderIDs._VBufferUnitDepthTexelSpacing, unitDepthTexelSpacing); cmd.SetComputeIntParam(m_VolumeVoxelizationCS, HDShaderIDs._NumVisibleDensityVolumes, numVisibleVolumes); cmd.SetComputeVectorParam(m_VolumeVoxelizationCS, HDShaderIDs._VolumeMaskDimensions, volumeAtlasDimensions); int w = (int)resolution.x; int h = (int)resolution.y; // The shader defines GROUP_SIZE_1D = 8. cmd.DispatchCompute(m_VolumeVoxelizationCS, kernel, (w + 7) / 8, (h + 7) / 8, hdCamera.computePassCount); } }
public void CreateDrawData() { int instanceCount = 0; int batchCount = 0; Matrix4x4[] decalToWorldBatch = null; Matrix4x4[] normalToWorldBatch = null; bool anyAffectTransparency = false; AssignCurrentBatches(ref decalToWorldBatch, ref normalToWorldBatch, batchCount); Vector3 cameraPos = instance.CurrentCamera.transform.position; Matrix4x4 worldToView = LightLoop.WorldToCamera(instance.CurrentCamera); bool perChannelMask = instance.perChannelMask; for (int resultIndex = 0; resultIndex < m_NumResults; resultIndex++) { int decalIndex = m_ResultIndices[resultIndex]; // do additional culling based on individual decal draw distances float distanceToDecal = (cameraPos - m_BoundingSpheres[decalIndex].position).magnitude; float cullDistance = m_CachedDrawDistances[decalIndex].x + m_BoundingSpheres[decalIndex].radius; if (distanceToDecal < cullDistance) { // d-buffer data decalToWorldBatch[instanceCount] = m_CachedDecalToWorld[decalIndex]; normalToWorldBatch[instanceCount] = m_CachedNormalToWorld[decalIndex]; float fadeFactor = Mathf.Clamp((cullDistance - distanceToDecal) / (cullDistance * (1.0f - m_CachedDrawDistances[decalIndex].y)), 0.0f, 1.0f); normalToWorldBatch[instanceCount].m03 = fadeFactor * m_Blend; // vector3 rotation matrix so bottom row and last column can be used for other data to save space normalToWorldBatch[instanceCount].m13 = m_AlbedoContribution; normalToWorldBatch[instanceCount].SetRow(3, m_CachedUVScaleBias[decalIndex]); // clustered forward data if (m_CachedAffectsTransparency[decalIndex]) { m_DecalDatas[m_DecalDatasCount].worldToDecal = decalToWorldBatch[instanceCount].inverse; m_DecalDatas[m_DecalDatasCount].normalToWorld = normalToWorldBatch[instanceCount]; m_DecalDatas[m_DecalDatasCount].baseColor = m_BaseColor; m_DecalDatas[m_DecalDatasCount].blendParams = m_BlendParams; if (!perChannelMask) { m_DecalDatas[m_DecalDatasCount].blendParams.z = (float)Decal.MaskBlendFlags.Smoothness; } // we have not allocated the textures in atlas yet, so only store references to them m_DiffuseTextureScaleBias[m_DecalDatasCount] = m_Diffuse; m_NormalTextureScaleBias[m_DecalDatasCount] = m_Normal; m_MaskTextureScaleBias[m_DecalDatasCount] = m_Mask; GetDecalVolumeDataAndBound(decalToWorldBatch[instanceCount], worldToView); m_DecalDatasCount++; anyAffectTransparency = true; } instanceCount++; if (instanceCount == kDrawIndexedBatchSize) { instanceCount = 0; batchCount++; AssignCurrentBatches(ref decalToWorldBatch, ref normalToWorldBatch, batchCount); } } } // only add if any projectors in this decal set affect transparency, doesn't actually allocate textures in the atlas yet, this is because we want all the textures in the list so we can optimize the packing if (anyAffectTransparency) { AddToTextureList(ref instance.m_TextureList); } }
public void RenderReflections(HDCamera hdCamera, CommandBuffer cmd, RTHandleSystem.RTHandle outputTexture, ScriptableRenderContext renderContext, uint frameCount) { // First thing to check is: Do we have a valid ray-tracing environment? HDRaytracingEnvironment rtEnvironement = m_RaytracingManager.CurrentEnvironment(); LightLoop lightLoop = m_RaytracingManager.GetLightLoop(); BlueNoise blueNoise = m_RaytracingManager.GetBlueNoiseManager(); ComputeShader reflectionFilter = m_PipelineAsset.renderPipelineResources.shaders.reflectionBilateralFilterCS; RaytracingShader reflectionShader = m_PipelineAsset.renderPipelineResources.shaders.reflectionRaytracing; bool invalidState = rtEnvironement == null || blueNoise == null || reflectionFilter == null || reflectionShader == null || m_PipelineResources.textures.owenScrambledTex == null || m_PipelineResources.textures.scramblingTex == null; // If no acceleration structure available, end it now if (invalidState) { return; } // Grab the acceleration structures and the light cluster to use RaytracingAccelerationStructure accelerationStructure = m_RaytracingManager.RequestAccelerationStructure(rtEnvironement.reflLayerMask); HDRaytracingLightCluster lightCluster = m_RaytracingManager.RequestLightCluster(rtEnvironement.reflLayerMask); // Compute the actual resolution that is needed base on the quality string targetRayGen = ""; switch (rtEnvironement.reflQualityMode) { case HDRaytracingEnvironment.ReflectionsQuality.QuarterRes: { targetRayGen = m_RayGenHalfResName; }; break; case HDRaytracingEnvironment.ReflectionsQuality.Integration: { targetRayGen = m_RayGenIntegrationName; }; break; } // Define the shader pass to use for the reflection pass cmd.SetRaytracingShaderPass(reflectionShader, "IndirectDXR"); // Set the acceleration structure for the pass cmd.SetRaytracingAccelerationStructure(reflectionShader, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure); // Inject the ray-tracing sampling data cmd.SetRaytracingTextureParam(reflectionShader, targetRayGen, HDShaderIDs._OwenScrambledTexture, m_PipelineResources.textures.owenScrambledTex); cmd.SetRaytracingTextureParam(reflectionShader, targetRayGen, HDShaderIDs._ScramblingTexture, m_PipelineResources.textures.scramblingTex); // Global reflection parameters cmd.SetRaytracingFloatParams(reflectionShader, HDShaderIDs._RaytracingIntensityClamp, rtEnvironement.reflClampValue); cmd.SetRaytracingFloatParams(reflectionShader, HDShaderIDs._RaytracingReflectionMinSmoothness, rtEnvironement.reflMinSmoothness); cmd.SetRaytracingFloatParams(reflectionShader, HDShaderIDs._RaytracingReflectionMaxDistance, rtEnvironement.reflBlendDistance); // Inject the ray generation data cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironement.rayBias); cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayMaxLength, rtEnvironement.reflRayLength); cmd.SetRaytracingIntParams(reflectionShader, HDShaderIDs._RaytracingNumSamples, rtEnvironement.reflNumMaxSamples); int frameIndex = hdCamera.IsTAAEnabled() ? hdCamera.taaFrameIndex : (int)frameCount % 8; cmd.SetGlobalInt(HDShaderIDs._RaytracingFrameIndex, frameIndex); // Set the data for the ray generation cmd.SetRaytracingTextureParam(reflectionShader, targetRayGen, HDShaderIDs._SsrLightingTextureRW, m_LightingTexture); cmd.SetRaytracingTextureParam(reflectionShader, targetRayGen, HDShaderIDs._SsrHitPointTexture, m_HitPdfTexture); cmd.SetRaytracingTextureParam(reflectionShader, targetRayGen, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRaytracingTextureParam(reflectionShader, targetRayGen, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer()); // Set ray count tex cmd.SetRaytracingIntParam(reflectionShader, HDShaderIDs._RayCountEnabled, m_RaytracingManager.rayCountManager.RayCountIsEnabled()); cmd.SetRaytracingTextureParam(reflectionShader, targetRayGen, HDShaderIDs._RayCountTexture, m_RaytracingManager.rayCountManager.rayCountTexture); // Compute the pixel spread value float pixelSpreadAngle = Mathf.Atan(2.0f * Mathf.Tan(hdCamera.camera.fieldOfView * Mathf.PI / 360.0f) / Mathf.Min(hdCamera.actualWidth, hdCamera.actualHeight)); cmd.SetRaytracingFloatParam(reflectionShader, 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, rtEnvironement.maxNumLightsPercell); 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, lightLoop.directionalLightDatas); cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, lightLoop.m_lightList.directionalLights.Count); // Evaluate the clear coat mask texture based on the lit shader mode RenderTargetIdentifier clearCoatMaskTexture = hdCamera.frameSettings.litShaderMode == LitShaderMode.Deferred ? m_GbufferManager.GetBuffersRTI()[2] : Texture2D.blackTexture; cmd.SetRaytracingTextureParam(reflectionShader, targetRayGen, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMaskTexture); // Set the data for the ray miss cmd.SetRaytracingTextureParam(reflectionShader, m_MissShaderName, HDShaderIDs._SkyTexture, m_SkyManager.skyReflection); // Compute the actual resolution that is needed base on the quality uint widthResolution = 1, heightResolution = 1; switch (rtEnvironement.reflQualityMode) { case HDRaytracingEnvironment.ReflectionsQuality.QuarterRes: { widthResolution = (uint)hdCamera.actualWidth / 2; heightResolution = (uint)hdCamera.actualHeight / 2; }; break; case HDRaytracingEnvironment.ReflectionsQuality.Integration: { widthResolution = (uint)hdCamera.actualWidth; heightResolution = (uint)hdCamera.actualHeight; }; break; } // Force to disable specular lighting cmd.SetGlobalInt(HDShaderIDs._EnableSpecularLighting, 0); // Run the calculus cmd.DispatchRays(reflectionShader, targetRayGen, widthResolution, heightResolution, 1); // Restore the previous state of specular lighting cmd.SetGlobalInt(HDShaderIDs._EnableSpecularLighting, hdCamera.frameSettings.IsEnabled(FrameSettingsField.SpecularLighting) ? 1 : 0); using (new ProfilingSample(cmd, "Filter Reflection", CustomSamplerId.RaytracingFilterReflection.GetSampler())) { switch (rtEnvironement.reflQualityMode) { case HDRaytracingEnvironment.ReflectionsQuality.QuarterRes: { // Fetch the right filter to use int currentKernel = reflectionFilter.FindKernel("RaytracingReflectionFilter"); // Inject all the parameters for the compute cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._SsrLightingTextureRW, m_LightingTexture); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._SsrHitPointTexture, m_HitPdfTexture); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer()); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_NoiseTexture", blueNoise.textureArray16RGB); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_VarianceTexture", m_VarianceBuffer); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_MinColorRangeTexture", m_MinBoundBuffer); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_MaxColorRangeTexture", m_MaxBoundBuffer); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_RaytracingReflectionTexture", outputTexture); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._ScramblingTexture, m_PipelineResources.textures.scramblingTex); cmd.SetComputeIntParam(reflectionFilter, HDShaderIDs._SpatialFilterRadius, rtEnvironement.reflSpatialFilterRadius); cmd.SetComputeFloatParam(reflectionFilter, HDShaderIDs._RaytracingReflectionMinSmoothness, rtEnvironement.reflMinSmoothness); // Texture dimensions int texWidth = outputTexture.rt.width; int texHeight = outputTexture.rt.height; // Evaluate the dispatch parameters int areaTileSize = 8; int numTilesXHR = (texWidth + (areaTileSize - 1)) / areaTileSize; int numTilesYHR = (texHeight + (areaTileSize - 1)) / areaTileSize; // Bind the right texture for clear coat support cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._SsrClearCoatMaskTexture, clearCoatMaskTexture); // Compute the texture cmd.DispatchCompute(reflectionFilter, currentKernel, numTilesXHR, numTilesYHR, 1); int numTilesXFR = (texWidth + (areaTileSize - 1)) / areaTileSize; int numTilesYFR = (texHeight + (areaTileSize - 1)) / areaTileSize; RTHandleSystem.RTHandle history = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedReflection) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedReflection, ReflectionHistoryBufferAllocatorFunction, 1); // Fetch the right filter to use currentKernel = reflectionFilter.FindKernel("TemporalAccumulationFilter"); cmd.SetComputeFloatParam(reflectionFilter, HDShaderIDs._TemporalAccumuationWeight, rtEnvironement.reflTemporalAccumulationWeight); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._AccumulatedFrameTexture, history); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, HDShaderIDs._CurrentFrameTexture, outputTexture); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_MinColorRangeTexture", m_MinBoundBuffer); cmd.SetComputeTextureParam(reflectionFilter, currentKernel, "_MaxColorRangeTexture", m_MaxBoundBuffer); cmd.DispatchCompute(reflectionFilter, currentKernel, numTilesXFR, numTilesYFR, 1); } break; case HDRaytracingEnvironment.ReflectionsQuality.Integration: { switch (rtEnvironement.reflFilterMode) { case HDRaytracingEnvironment.ReflectionsFilterMode.SpatioTemporal: { // Grab the history buffer RTHandleSystem.RTHandle reflectionHistory = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedReflection) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedReflection, ReflectionHistoryBufferAllocatorFunction, 1); // Texture dimensions int texWidth = hdCamera.actualWidth; int texHeight = hdCamera.actualHeight; // Evaluate the dispatch parameters int areaTileSize = 8; int numTilesX = (texWidth + (areaTileSize - 1)) / areaTileSize; int numTilesY = (texHeight + (areaTileSize - 1)) / areaTileSize; int m_KernelFilter = reflectionFilter.FindKernel("RaytracingReflectionTAA"); // Compute the combined TAA frame var historyScale = new Vector2(hdCamera.actualWidth / (float)reflectionHistory.rt.width, hdCamera.actualHeight / (float)reflectionHistory.rt.height); cmd.SetComputeVectorParam(reflectionFilter, HDShaderIDs._ScreenToTargetScaleHistory, historyScale); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DenoiseInputTexture, m_LightingTexture); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DenoiseOutputTextureRW, m_HitPdfTexture); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._ReflectionHistorybufferRW, reflectionHistory); cmd.DispatchCompute(reflectionFilter, m_KernelFilter, numTilesX, numTilesY, 1); // Output the new history HDUtils.BlitCameraTexture(cmd, hdCamera, m_HitPdfTexture, reflectionHistory); m_KernelFilter = reflectionFilter.FindKernel("ReflBilateralFilterH"); // Horizontal pass of the bilateral filter cmd.SetComputeIntParam(reflectionFilter, HDShaderIDs._RaytracingDenoiseRadius, rtEnvironement.reflFilterRadius); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DenoiseInputTexture, reflectionHistory); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer()); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DenoiseOutputTextureRW, m_HitPdfTexture); cmd.DispatchCompute(reflectionFilter, m_KernelFilter, numTilesX, numTilesY, 1); m_KernelFilter = reflectionFilter.FindKernel("ReflBilateralFilterV"); // Horizontal pass of the bilateral filter cmd.SetComputeIntParam(reflectionFilter, HDShaderIDs._RaytracingDenoiseRadius, rtEnvironement.reflFilterRadius); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DenoiseInputTexture, m_HitPdfTexture); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer()); cmd.SetComputeTextureParam(reflectionFilter, m_KernelFilter, HDShaderIDs._DenoiseOutputTextureRW, outputTexture); cmd.DispatchCompute(reflectionFilter, m_KernelFilter, numTilesX, numTilesY, 1); } break; case HDRaytracingEnvironment.ReflectionsFilterMode.None: { HDUtils.BlitCameraTexture(cmd, hdCamera, m_LightingTexture, outputTexture); } break; } } break; } } }
public void Render(HDCamera hdCamera, CommandBuffer cmd, RTHandleSystem.RTHandle outputTexture, ScriptableRenderContext renderContext, CullingResults cull) { // First thing to check is: Do we have a valid ray-tracing environment? HDRaytracingEnvironment rtEnvironement = m_RaytracingManager.CurrentEnvironment(); LightLoop lightLoop = m_RaytracingManager.GetLightLoop(); RaytracingShader forwardShader = m_PipelineAsset.renderPipelineResources.shaders.forwardRaytracing; Shader raytracingMask = m_PipelineAsset.renderPipelineResources.shaders.raytracingFlagMask; // Check the validity of the state before computing the effect bool invalidState = rtEnvironement == null || !rtEnvironement.raytracedObjects || forwardShader == null || raytracingMask == null || m_PipelineResources.textures.owenScrambledTex == null || m_PipelineResources.textures.scramblingTex == null; // If any resource or game-object is missing We stop right away if (invalidState) { return; } // Grab the acceleration structure and the list of HD lights for the target camera RaytracingAccelerationStructure accelerationStructure = m_RaytracingManager.RequestAccelerationStructure(rtEnvironement.raytracedLayerMask); HDRaytracingLightCluster lightCluster = m_RaytracingManager.RequestLightCluster(rtEnvironement.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, m_RayGenShaderName, HDShaderIDs._OwenScrambledTexture, m_PipelineResources.textures.owenScrambledTex); cmd.SetRaytracingTextureParam(forwardShader, m_RayGenShaderName, HDShaderIDs._ScramblingTexture, m_PipelineResources.textures.scramblingTex); // Inject the ray generation data cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayBias, rtEnvironement.rayBias); cmd.SetGlobalFloat(HDShaderIDs._RaytracingRayMaxLength, rtEnvironement.raytracingRayLength); cmd.SetGlobalFloat(HDShaderIDs._RaytracingMaxRecursion, rtEnvironement.rayMaxDepth); cmd.SetGlobalFloat(HDShaderIDs._RaytracingCameraNearPlane, hdCamera.camera.nearClipPlane); // Set the data for the ray generation cmd.SetRaytracingTextureParam(forwardShader, m_RayGenShaderName, HDShaderIDs._RaytracingFlagMask, m_RaytracingFlagTarget); cmd.SetRaytracingTextureParam(forwardShader, m_RayGenShaderName, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRaytracingTextureParam(forwardShader, m_RayGenShaderName, 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, rtEnvironement.maxNumLightsPercell); 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, lightLoop.directionalLightDatas); cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, lightLoop.m_lightList.directionalLights.Count); // Set the data for the ray miss cmd.SetRaytracingTextureParam(forwardShader, m_MissShaderName, 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, m_RayGenShaderName, HDShaderIDs._RaytracingPrimaryDebug, m_DebugRaytracingTexture); hdrp.PushFullScreenDebugTexture(hdCamera, cmd, m_DebugRaytracingTexture, FullScreenDebugMode.PrimaryVisibility); // Run the calculus cmd.DispatchRays(forwardShader, m_RayGenShaderName, (uint)hdCamera.actualWidth, (uint)hdCamera.actualHeight, 1); }