diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 301b64b1ec5..47cc81c2f86 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed computation of geometric normal in path tracing (case 1293029). - Fixed issues with path-traced volumetric scattering (cases 1295222, 1295234). - Fixed the default background color for previews to use the original color. +- Fixed an issue with the frame count management for the volumetric fog (case 1299251). ### Changed - Removed the material pass probe volumes evaluation mode. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs index 71073b330b4..a6f17c2fe62 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricLighting.cs @@ -270,6 +270,12 @@ static internal void SafeDestroy(ref RenderTexture rt) } } + static uint VolumetricFrameIndex(HDCamera hdCamera) + { + // Here we do modulo 14 because we need the enable to detect a change every frame, but the accumulation is done on 7 frames (7x2=14) + return hdCamera.GetCameraFrameCount() % 14; + } + static internal Vector3Int ComputeVolumetricViewportSize(HDCamera hdCamera, ref float voxelSize) { var controller = hdCamera.volumeStack.GetComponent(); @@ -356,7 +362,7 @@ static internal void ReinitializeVolumetricBufferParams(HDCamera hdCamera) // This function relies on being called once per camera per frame. // The results are undefined otherwise. - static internal void UpdateVolumetricBufferParams(HDCamera hdCamera, int frameIndex) + static internal void UpdateVolumetricBufferParams(HDCamera hdCamera) { if (!Fog.IsVolumetricFogEnabled(hdCamera)) return; @@ -366,6 +372,7 @@ static internal void UpdateVolumetricBufferParams(HDCamera hdCamera, int frameIn var currentParams = ComputeVolumetricBufferParameters(hdCamera); + int frameIndex = (int)VolumetricFrameIndex(hdCamera); var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; @@ -419,7 +426,7 @@ struct GenerateMaxZParameters } - GenerateMaxZParameters PrepareGenerateMaxZParameters(HDCamera hdCamera, HDUtils.PackedMipChainInfo depthMipInfo, int frameIndex) + GenerateMaxZParameters PrepareGenerateMaxZParameters(HDCamera hdCamera, HDUtils.PackedMipChainInfo depthMipInfo) { var parameters = new GenerateMaxZParameters(); parameters.generateMaxZCS = defaultResources.shaders.maxZCS; @@ -436,6 +443,7 @@ GenerateMaxZParameters PrepareGenerateMaxZParameters(HDCamera hdCamera, HDUtils. parameters.minDepthMipOffset.x = depthMipInfo.mipLevelOffsets[4].x; parameters.minDepthMipOffset.y = depthMipInfo.mipLevelOffsets[4].y; + int frameIndex = (int)VolumetricFrameIndex(hdCamera); var currIdx = frameIndex & 1; var currentParams = hdCamera.vBufferParams[currIdx]; @@ -549,7 +557,7 @@ static internal void DestroyVolumetricHistoryBuffers(HDCamera hdCamera) // Must be called AFTER UpdateVolumetricBufferParams. static readonly string[] volumetricHistoryBufferNames = new string[2] { "VBufferHistory0", "VBufferHistory1" }; - static internal void ResizeVolumetricHistoryBuffers(HDCamera hdCamera, int frameIndex) + static internal void ResizeVolumetricHistoryBuffers(HDCamera hdCamera) { if (!hdCamera.IsVolumetricReprojectionEnabled()) return; @@ -558,6 +566,7 @@ static internal void ResizeVolumetricHistoryBuffers(HDCamera hdCamera, int frame Debug.Assert(hdCamera.vBufferParams.Length == 2); Debug.Assert(hdCamera.volumetricHistoryBuffers != null); + int frameIndex = (int)VolumetricFrameIndex(hdCamera); var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; @@ -627,7 +636,7 @@ internal void DestroyVolumetricLightingBuffers() } // Must be called AFTER UpdateVolumetricBufferParams. - internal void ResizeVolumetricLightingBuffers(HDCamera hdCamera, int frameIndex) + internal void ResizeVolumetricLightingBuffers(HDCamera hdCamera) { if (!Fog.IsVolumetricFogEnabled(hdCamera)) return; @@ -643,6 +652,7 @@ internal void ResizeVolumetricLightingBuffers(HDCamera hdCamera, int frameIndex) CreateVolumetricLightingBuffers(); } + int frameIndex = (int)VolumetricFrameIndex(hdCamera); var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; @@ -819,11 +829,12 @@ unsafe void SetPreconvolvedAmbientLightProbe(ref ShaderVariablesVolumetric cb, H cb._AmbientProbeCoeffs[i * 4 + j] = m_PackedCoeffs[i][j]; } - unsafe void UpdateShaderVariableslVolumetrics(ref ShaderVariablesVolumetric cb, HDCamera hdCamera, in Vector4 resolution, int frameIndex) + unsafe void UpdateShaderVariableslVolumetrics(ref ShaderVariablesVolumetric cb, HDCamera hdCamera, in Vector4 resolution) { var fog = hdCamera.volumeStack.GetComponent(); var vFoV = hdCamera.camera.GetGateFittedFieldOfView() * Mathf.Deg2Rad; var gpuAspect = HDUtils.ProjectionMatrixAspect(hdCamera.mainViewConstants.projMatrix); + int frameIndex = (int)VolumetricFrameIndex(hdCamera); // Compose the matrix which allows us to compute the world space view direction. hdCamera.GetPixelCoordToViewDirWS(resolution, gpuAspect, ref m_PixelCoordToViewDirWS); @@ -886,10 +897,11 @@ unsafe void UpdateShaderVariableslVolumetrics(ref ShaderVariablesVolumetric cb, cb._NumTileBigTileY = (uint)GetNumTileBigTileY(hdCamera); } - VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCamera, int frameIndex) + VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCamera) { var parameters = new VolumeVoxelizationParameters(); + int frameIndex = (int)VolumetricFrameIndex(hdCamera); var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; @@ -912,7 +924,7 @@ VolumeVoxelizationParameters PrepareVolumeVoxelizationParameters(HDCamera hdCame parameters.volumeAtlas = CoreUtils.blackVolumeTexture; } - UpdateShaderVariableslVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, parameters.resolution, frameIndex); + UpdateShaderVariableslVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, parameters.resolution); parameters.volumetricCB = m_ShaderVariablesVolumetricCB; parameters.lightListCB = m_ShaderVariablesLightListCB; @@ -992,10 +1004,11 @@ struct VolumetricLightingParameters public ShaderVariablesLightList lightListCB; } - VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCamera, int frameIndex) + VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCamera) { var parameters = new VolumetricLightingParameters(); + int frameIndex = (int)VolumetricFrameIndex(hdCamera); var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; @@ -1032,7 +1045,7 @@ VolumetricLightingParameters PrepareVolumetricLightingParameters(HDCamera hdCame parameters.filterVolume = ((int)fog.denoisingMode.value & (int)FogDenoisingMode.Gaussian) != 0; parameters.sliceCount = (int)(cvp.z); - UpdateShaderVariableslVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, parameters.resolution, frameIndex); + UpdateShaderVariableslVolumetrics(ref m_ShaderVariablesVolumetricCB, hdCamera, parameters.resolution); parameters.volumetricCB = m_ShaderVariablesVolumetricCB; parameters.lightListCB = m_ShaderVariablesLightListCB; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs index 945bb74a54a..7cff5f8e8de 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Camera/HDCamera.cs @@ -573,8 +573,8 @@ internal void Update(FrameSettings currentFrameSettings, HDRenderPipeline hdrp, isFirstFrame = false; cameraFrameCount++; - HDRenderPipeline.UpdateVolumetricBufferParams(this, hdrp.GetFrameCount()); - HDRenderPipeline.ResizeVolumetricHistoryBuffers(this, hdrp.GetFrameCount()); + HDRenderPipeline.UpdateVolumetricBufferParams(this); + HDRenderPipeline.ResizeVolumetricHistoryBuffers(this); } /// Set the RTHandle scale to the actual camera size (can be scaled) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs index e655b29e3b9..57e6cd1ff45 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.LightLoop.cs @@ -600,8 +600,7 @@ TextureHandle VolumeVoxelizationPass(RenderGraph renderGraph, HDCamera hdCamera, ComputeBuffer visibleVolumeBoundsBuffer, ComputeBuffer visibleVolumeDataBuffer, - ComputeBufferHandle bigTileLightList, - int frameIndex) + ComputeBufferHandle bigTileLightList) { if (Fog.IsVolumetricFogEnabled(hdCamera)) { @@ -609,7 +608,7 @@ TextureHandle VolumeVoxelizationPass(RenderGraph renderGraph, { builder.EnableAsyncCompute(hdCamera.frameSettings.VolumeVoxelizationRunsAsync()); - passData.parameters = PrepareVolumeVoxelizationParameters(hdCamera, frameIndex); + passData.parameters = PrepareVolumeVoxelizationParameters(hdCamera); passData.visibleVolumeBoundsBuffer = visibleVolumeBoundsBuffer; passData.visibleVolumeDataBuffer = visibleVolumeDataBuffer; if (passData.parameters.tiledLighting) @@ -657,7 +656,7 @@ TextureHandle GenerateMaxZPass(RenderGraph renderGraph, HDCamera hdCamera, Textu using (var builder = renderGraph.AddRenderPass("Generate Max Z Mask for Volumetric", out var passData)) { - passData.parameters = PrepareGenerateMaxZParameters(hdCamera, depthMipInfo, frameIndex); + passData.parameters = PrepareGenerateMaxZParameters(hdCamera, depthMipInfo); passData.depthTexture = builder.ReadTexture(depthTexture); passData.maxZ8xBuffer = builder.ReadTexture(renderGraph.ImportTexture(m_MaxZMask8x)); passData.maxZ8xBuffer = builder.WriteTexture(passData.maxZ8xBuffer); @@ -691,11 +690,12 @@ class VolumetricLightingPassData public ComputeBufferHandle bigTileLightListBuffer; } - TextureHandle VolumetricLightingPass(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthTexture, TextureHandle densityBuffer, TextureHandle maxZBuffer, ComputeBufferHandle bigTileLightListBuffer, ShadowResult shadowResult, int frameIndex) + TextureHandle VolumetricLightingPass(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthTexture, TextureHandle densityBuffer, TextureHandle maxZBuffer, ComputeBufferHandle bigTileLightListBuffer, ShadowResult shadowResult) { if (Fog.IsVolumetricFogEnabled(hdCamera)) { - var parameters = PrepareVolumetricLightingParameters(hdCamera, frameIndex); + // Evaluate the parameters + var parameters = PrepareVolumetricLightingParameters(hdCamera); using (var builder = renderGraph.AddRenderPass("Volumetric Lighting", out var passData)) { @@ -717,6 +717,7 @@ TextureHandle VolumetricLightingPass(RenderGraph renderGraph, HDCamera hdCamera, if (passData.parameters.enableReprojection) { + int frameIndex = (int)VolumetricFrameIndex(hdCamera); var currIdx = (frameIndex + 0) & 1; var prevIdx = (frameIndex + 1) & 1; diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs index bc0be083191..9da56017ace 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.RenderGraph.cs @@ -103,7 +103,7 @@ void ExecuteWithRenderGraph(RenderRequest renderRequest, lightingBuffers.contactShadowsBuffer = RenderContactShadows(m_RenderGraph, hdCamera, msaa ? prepassOutput.depthValuesMSAA : prepassOutput.depthPyramidTexture, gpuLightListOutput, GetDepthBufferMipChainInfo().mipLevelOffsets[1].y); - var volumetricDensityBuffer = VolumeVoxelizationPass(m_RenderGraph, hdCamera, m_VisibleVolumeBoundsBuffer, m_VisibleVolumeDataBuffer, gpuLightListOutput.bigTileLightList, m_FrameCount); + var volumetricDensityBuffer = VolumeVoxelizationPass(m_RenderGraph, hdCamera, m_VisibleVolumeBoundsBuffer, m_VisibleVolumeDataBuffer, gpuLightListOutput.bigTileLightList); RenderShadows(m_RenderGraph, hdCamera, cullingResults, ref shadowResult); @@ -146,7 +146,7 @@ void ExecuteWithRenderGraph(RenderRequest renderRequest, var maxZMask = GenerateMaxZPass(m_RenderGraph, hdCamera, prepassOutput.depthPyramidTexture, m_DepthBufferMipChainInfo, m_FrameCount); - var volumetricLighting = VolumetricLightingPass(m_RenderGraph, hdCamera, prepassOutput.depthPyramidTexture, volumetricDensityBuffer, maxZMask, gpuLightListOutput.bigTileLightList, shadowResult, m_FrameCount); + var volumetricLighting = VolumetricLightingPass(m_RenderGraph, hdCamera, prepassOutput.depthPyramidTexture, volumetricDensityBuffer, maxZMask, gpuLightListOutput.bigTileLightList, shadowResult); var deferredLightingOutput = RenderDeferredLighting(m_RenderGraph, hdCamera, colorBuffer, prepassOutput.depthBuffer, prepassOutput.depthPyramidTexture, lightingBuffers, prepassOutput.gbuffer, shadowResult, gpuLightListOutput); diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs index f8b955e821c..c3f54d42171 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -2299,7 +2299,7 @@ out ScriptableCullingParameters cullingParams // From this point, we should only use frame settings from the camera hdCamera.Update(currentFrameSettings, this, m_MSAASamples, xrPass); - ResizeVolumetricLightingBuffers(hdCamera, GetFrameCount()); // Safe to update the Volumetric Lighting System now + ResizeVolumetricLightingBuffers(hdCamera); // Safe to update the Volumetric Lighting System now // Custom Render requires a proper HDCamera, so we return after the HDCamera was setup if (additionalCameraData != null && additionalCameraData.hasCustomRender)