diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4011_MotionBlur_PerObject.unity b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4011_MotionBlur_PerObject.unity index 7871e0c33d1..495d079d160 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4011_MotionBlur_PerObject.unity +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4011_MotionBlur_PerObject.unity @@ -527,7 +527,7 @@ PrefabInstance: - target: {fileID: 114995348509370400, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} propertyPath: renderGraphCompatible - value: 0 + value: 1 objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} @@ -930,6 +930,7 @@ MonoBehaviour: m_EnableSpotReflector: 0 m_LuxAtDistance: 1 m_InnerSpotPercent: 0 + m_SpotIESCutoffPercent: 100 m_LightDimmer: 1 m_VolumetricDimmer: 1 m_LightUnit: 2 @@ -948,6 +949,8 @@ MonoBehaviour: m_ApplyRangeAttenuation: 1 m_DisplayAreaLightEmissiveMesh: 0 m_AreaLightCookie: {fileID: 0} + m_IESPoint: {fileID: 0} + m_IESSpot: {fileID: 0} m_AreaLightShadowCone: 120 m_UseScreenSpaceShadows: 0 m_InteractsWithSky: 1 diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4022_PaniniProjection.unity b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4022_PaniniProjection.unity index bc8bd1f9681..a1b86b75c52 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4022_PaniniProjection.unity +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4022_PaniniProjection.unity @@ -536,7 +536,7 @@ PrefabInstance: - target: {fileID: 114995348509370400, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} propertyPath: renderGraphCompatible - value: 0 + value: 1 objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} diff --git a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4051_SMAA.unity b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4051_SMAA.unity index 8944b649e7b..aaf19dca66e 100644 --- a/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4051_SMAA.unity +++ b/TestProjects/HDRP_Tests/Assets/GraphicTests/Scenes/4x_PostProcessing/4051_SMAA.unity @@ -3643,6 +3643,7 @@ MonoBehaviour: m_EnableSpotReflector: 0 m_LuxAtDistance: 1 m_InnerSpotPercent: 0 + m_SpotIESCutoffPercent: 100 m_LightDimmer: 1 m_VolumetricDimmer: 1 m_LightUnit: 2 @@ -3661,6 +3662,8 @@ MonoBehaviour: m_ApplyRangeAttenuation: 1 m_DisplayAreaLightEmissiveMesh: 0 m_AreaLightCookie: {fileID: 0} + m_IESPoint: {fileID: 0} + m_IESSpot: {fileID: 0} m_AreaLightShadowCone: 120 m_UseScreenSpaceShadows: 0 m_InteractsWithSky: 1 @@ -4111,7 +4114,7 @@ PrefabInstance: - target: {fileID: 114995348509370400, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} propertyPath: renderGraphCompatible - value: 0 + value: 1 objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: c07ace9ab142ca9469fa377877c2f1e7, type: 3} diff --git a/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs b/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs index 73ee1dc8535..a7cb0d31c03 100644 --- a/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs +++ b/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs @@ -41,6 +41,14 @@ internal ResourceHandle(int value, RenderGraphResourceType type) [DebuggerDisplay("Texture ({handle})")] public struct TextureHandle { + private static TextureHandle s_NullHandle = new TextureHandle(); + + /// + /// Returns a null texture handle + /// + /// A null texture handle. + public static TextureHandle nullHandle { get { return s_NullHandle; } } + internal ResourceHandle handle; internal TextureHandle(int handle) { this.handle = new ResourceHandle(handle, RenderGraphResourceType.Texture); } diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.RenderGraph.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.RenderGraph.cs index 8e691623961..e1326b0d860 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.RenderGraph.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.RenderGraph.cs @@ -18,6 +18,7 @@ class UberPostPassData public TextureHandle source; public TextureHandle destination; public TextureHandle logLut; + public TextureHandle bloomTexture; } class AlphaCopyPassData @@ -27,14 +28,154 @@ class AlphaCopyPassData public TextureHandle outputAlpha; } - public void Render( RenderGraph renderGraph, - HDCamera hdCamera, - BlueNoise blueNoise, - TextureHandle colorBuffer, - TextureHandle afterPostProcessTexture, - TextureHandle depthBuffer, - TextureHandle finalRT, - bool flipY) + class GuardBandPassData + { + public ClearWithGuardBandsParameters parameters; + public TextureHandle source; + } + + class StopNaNPassData + { + public StopNaNParameters parameters; + public TextureHandle source; + public TextureHandle destination; + } + + class DynamicExposureData + { + public ExposureParameters parameters; + public TextureHandle source; + public TextureHandle prevExposure; + public TextureHandle nextExposure; + public TextureHandle exposureDebugData; + public TextureHandle tmpTarget1024; + public TextureHandle tmpTarget32; + } + + class ApplyExposureData + { + public ApplyExposureParameters parameters; + public TextureHandle source; + public TextureHandle destination; + public TextureHandle prevExposure; + } + + class TemporalAntiAliasingData + { + public TemporalAntiAliasingParameters parameters; + public TextureHandle source; + public TextureHandle destination; + public TextureHandle motionVecTexture; + public TextureHandle depthBuffer; + public TextureHandle depthMipChain; + public TextureHandle prevHistory; + public TextureHandle nextHistory; + public TextureHandle prevMVLen; + public TextureHandle nextMVLen; + } + + class SMAAData + { + public SMAAParameters parameters; + public TextureHandle source; + public TextureHandle destination; + public TextureHandle depthBuffer; + public TextureHandle smaaEdgeTex; + public TextureHandle smaaBlendTex; + } + + class FXAAData + { + public FXAAParameters parameters; + public TextureHandle source; + public TextureHandle destination; + } + + class MotionBlurData + { + public MotionBlurParameters parameters; + public TextureHandle source; + public TextureHandle destination; + public TextureHandle motionVecTexture; + public TextureHandle preppedMotionVec; + public TextureHandle minMaxTileVel; + public TextureHandle maxTileNeigbourhood; + public TextureHandle tileToScatterMax; + public TextureHandle tileToScatterMin; + } + + class PaniniProjectionData + { + public PaniniProjectionParameters parameters; + public TextureHandle source; + public TextureHandle destination; + } + + class BloomData + { + public BloomParameters parameters; + public TextureHandle source; + public TextureHandle[] mipsDown = new TextureHandle[k_MaxBloomMipCount + 1]; + public TextureHandle[] mipsUp = new TextureHandle[k_MaxBloomMipCount + 1]; + } + + class CASData + { + public CASParameters parameters; + public TextureHandle source; + public TextureHandle destination; + } + + TextureHandle GetPostprocessOutputHandle(RenderGraph renderGraph, string name) + { + return renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) + { + name = name, + colorFormat = m_ColorFormat, + useMipMap = false, + enableRandomWrite = true + }); + } + + void FillBloomMipsTextureHandles(BloomData bloomData, RenderGraph renderGraph, RenderGraphBuilder builder) + { + for (int i = 0; i < m_BloomMipCount; i++) + { + var scale = new Vector2(m_BloomMipsInfo[i].z, m_BloomMipsInfo[i].w); + var pixelSize = new Vector2Int((int)m_BloomMipsInfo[i].x, (int)m_BloomMipsInfo[i].y); + + bloomData.mipsDown[i] = builder.CreateTransientTexture(new TextureDesc(scale, true, true) + { colorFormat = m_ColorFormat, enableRandomWrite = true }); + + if (i != 0) + { + bloomData.mipsUp[i] = builder.CreateTransientTexture(new TextureDesc(scale, true, true) + { colorFormat = m_ColorFormat, enableRandomWrite = true }); + + } + } + + // the mip up 0 will be used by uber, so not allocated as transient. + var mip0Scale = new Vector2(m_BloomMipsInfo[0].z, m_BloomMipsInfo[0].w); + bloomData.mipsUp[0] = renderGraph.CreateTexture(new TextureDesc(mip0Scale, true, true) + { + name = "Bloom final mip up", + colorFormat = m_ColorFormat, + useMipMap = false, + enableRandomWrite = true + }); + } + + public void Render(RenderGraph renderGraph, + HDCamera hdCamera, + BlueNoise blueNoise, + TextureHandle colorBuffer, + TextureHandle afterPostProcessTexture, + TextureHandle depthBuffer, + TextureHandle depthBufferMipChain, + TextureHandle motionVectors, + TextureHandle finalRT, + bool flipY) { var dynResHandler = DynamicResolutionHandler.instance; @@ -50,12 +191,12 @@ public void Render( RenderGraph renderGraph, passData.parameters = PrepareCopyAlphaParameters(hdCamera); passData.source = builder.ReadTexture(source); passData.outputAlpha = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) - { name = "Alpha Channel Copy", colorFormat = GraphicsFormat.R16_SFloat, enableRandomWrite = true })); + { name = "Alpha Channel Copy", colorFormat = GraphicsFormat.R16_SFloat, enableRandomWrite = true })); builder.SetRenderFunc( (AlphaCopyPassData data, RenderGraphContext ctx) => { - DoCopyAlpha( data.parameters, + DoCopyAlpha(data.parameters, ctx.resources.GetTexture(data.source), ctx.resources.GetTexture(data.outputAlpha), ctx.cmd); @@ -65,113 +206,212 @@ public void Render( RenderGraph renderGraph, } } - // TODO RENDERGRAPH: Implement - // if (m_PostProcessEnabled) - // { - // // Guard bands (also known as "horrible hack") to avoid bleeding previous RTHandle - // // content into smaller viewports with some effects like Bloom that rely on bilinear - // // filtering and can't use clamp sampler and the likes - // // Note: some platforms can't clear a partial render target so we directly draw black triangles - // { - // int w = camera.actualWidth; - // int h = camera.actualHeight; - // cmd.SetRenderTarget(source, 0, CubemapFace.Unknown, -1); - - // if (w < source.rt.width || h < source.rt.height) - // { - // cmd.SetViewport(new Rect(w, 0, k_RTGuardBandSize, h)); - // cmd.DrawProcedural(Matrix4x4.identity, m_ClearBlackMaterial, 0, MeshTopology.Triangles, 3, 1); - // cmd.SetViewport(new Rect(0, h, w + k_RTGuardBandSize, k_RTGuardBandSize)); - // cmd.DrawProcedural(Matrix4x4.identity, m_ClearBlackMaterial, 0, MeshTopology.Triangles, 3, 1); - // } - // } - - // // Optional NaN killer before post-processing kicks in - // bool stopNaNs = camera.stopNaNs && m_StopNaNFS; - - //#if UNITY_EDITOR - // if (isSceneView) - // stopNaNs = HDAdditionalSceneViewSettings.sceneViewStopNaNs; - //#endif - - // if (stopNaNs) - // { - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.StopNaNs))) - // { - // var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - // DoStopNaNs(cmd, camera, source, destination); - // PoolSource(ref source, destination); - // } - // } - // } - - // // Dynamic exposure - will be applied in the next frame - // // Not considered as a post-process so it's not affected by its enabled state - // if (!IsExposureFixed() && m_ExposureControlFS) - // { - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.DynamicExposure))) - // { - // if (m_Exposure.mode.value == ExposureMode.AutomaticHistogram) - // { - // DoHistogramBasedExposure(cmd, camera, source); - // } - // else - // { - // DoDynamicExposure(cmd, camera, source); - // } - - // // On reset history we need to apply dynamic exposure immediately to avoid - // // white or black screen flashes when the current exposure isn't anywhere - // // near 0 - // if (camera.resetPostProcessingHistory) - // { - // var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - - // var cs = m_Resources.shaders.applyExposureCS; - // int kernel = cs.FindKernel("KMain"); - - // // Note: we call GetPrevious instead of GetCurrent because the textures - // // are swapped internally as the system expects the texture will be used - // // on the next frame. So the actual "current" for this frame is in - // // "previous". - // cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureTexture, GetPreviousExposureTexture(camera)); - // cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source); - // cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination); - // cmd.DispatchCompute(cs, kernel, (camera.actualWidth + 7) / 8, (camera.actualHeight + 7) / 8, camera.viewCount); - - // PoolSource(ref source, destination); - // } - // } - // } - if (m_PostProcessEnabled) { - // // Temporal anti-aliasing goes first - // bool taaEnabled = false; + using (var builder = renderGraph.AddRenderPass("Guard Band Clear", out var passData, ProfilingSampler.Get(HDProfileId.GuardBandClear))) + { + passData.source = builder.WriteTexture(source); + passData.parameters = PrepareClearWithGuardBandsParameters(hdCamera); - // if (m_AntialiasingFS) - // { - // taaEnabled = camera.antialiasing == AntialiasingMode.TemporalAntialiasing; + builder.SetRenderFunc( + (GuardBandPassData data, RenderGraphContext ctx) => + { + ClearWithGuardBands(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source)); + }); - // if (taaEnabled) - // { - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.TemporalAntialiasing))) - // { - // var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - // DoTemporalAntialiasing(cmd, camera, source, destination, depthBuffer, depthMipChain); - // PoolSource(ref source, destination); - // } - // } - // else if (camera.antialiasing == AntialiasingMode.SubpixelMorphologicalAntiAliasing) - // { - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SMAA))) - // { - // var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - // DoSMAA(cmd, camera, source, destination, depthBuffer); - // PoolSource(ref source, destination); - // } - // } - // } + source = passData.source; + } + + // Optional NaN killer before post-processing kicks in + bool stopNaNs = hdCamera.stopNaNs && m_StopNaNFS; + +#if UNITY_EDITOR + if (isSceneView) + stopNaNs = HDAdditionalSceneViewSettings.sceneViewStopNaNs; +#endif + if (stopNaNs) + { + using (var builder = renderGraph.AddRenderPass("Stop NaNs", out var passData, ProfilingSampler.Get(HDProfileId.StopNaNs))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareStopNaNParameters(hdCamera); + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "Stop NaNs Destination"); + passData.destination = builder.WriteTexture(dest); ; + + builder.SetRenderFunc( + (StopNaNPassData data, RenderGraphContext ctx) => + { + DoStopNaNs(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), ctx.resources.GetTexture(data.destination)); + }); + + source = passData.destination; + } + } + + // Dynamic exposure - will be applied in the next frame + // Not considered as a post-process so it's not affected by its enabled state + // Dynamic exposure - will be applied in the next frame + // Not considered as a post-process so it's not affected by its enabled state + if (!IsExposureFixed(hdCamera) && m_ExposureControlFS) + { + var exposureParameters = PrepareExposureParameters(hdCamera); + + GrabExposureRequiredTextures(hdCamera, out var prevExposure, out var nextExposure); + + var prevExposureHandle = renderGraph.ImportTexture(prevExposure); + var nextExposureHandle = renderGraph.ImportTexture(nextExposure); + + using (var builder = renderGraph.AddRenderPass("Dynamic Exposure", out var passData, ProfilingSampler.Get(HDProfileId.DynamicExposure))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareExposureParameters(hdCamera); + passData.prevExposure = builder.ReadTexture(prevExposureHandle); + passData.nextExposure = builder.WriteTexture(nextExposureHandle); + + if (m_Exposure.mode.value == ExposureMode.AutomaticHistogram) + { + passData.exposureDebugData = builder.WriteTexture(renderGraph.ImportTexture(m_DebugExposureData)); + builder.SetRenderFunc( + (DynamicExposureData data, RenderGraphContext ctx) => + { + DoHistogramBasedExposure(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), + ctx.resources.GetTexture(data.prevExposure), + ctx.resources.GetTexture(data.nextExposure), + ctx.resources.GetTexture(data.exposureDebugData)); + }); + } + else + { + passData.tmpTarget1024 = builder.CreateTransientTexture(new TextureDesc(1024, 1024, true, false) + { colorFormat = GraphicsFormat.R16G16_SFloat, enableRandomWrite = true, name = "Average Luminance Temp 1024" }); + passData.tmpTarget32 = builder.CreateTransientTexture(new TextureDesc(32, 32, true, false) + { colorFormat = GraphicsFormat.R16G16_SFloat, enableRandomWrite = true, name = "Average Luminance Temp 32" }); + + builder.SetRenderFunc( + (DynamicExposureData data, RenderGraphContext ctx) => + { + DoDynamicExposure(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), + ctx.resources.GetTexture(data.prevExposure), + ctx.resources.GetTexture(data.nextExposure), + ctx.resources.GetTexture(data.tmpTarget1024), + ctx.resources.GetTexture(data.tmpTarget32)); + }); + } + } + + if (hdCamera.resetPostProcessingHistory) + { + using (var builder = renderGraph.AddRenderPass("Apply Exposure", out var passData, ProfilingSampler.Get(HDProfileId.ApplyExposure))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareApplyExposureParameters(hdCamera); + RTHandle prevExp; + GrabExposureHistoryTextures(hdCamera, out prevExp, out _); + passData.prevExposure = builder.ReadTexture(renderGraph.ImportTexture(prevExp)); + + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "Apply Exposure Destination"); + passData.destination = builder.WriteTexture(dest); ; + + builder.SetRenderFunc( + (ApplyExposureData data, RenderGraphContext ctx) => + { + ApplyExposure(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), ctx.resources.GetTexture(data.destination), ctx.resources.GetTexture(data.prevExposure)); + }); + + source = passData.destination; + } + } + } + + // Temporal anti-aliasing goes first + bool taaEnabled = false; + + + //if (camera.frameSettings.IsEnabled(FrameSettingsField.CustomPostProcess)) + //{ + // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.CustomPostProcessBeforeTAA))) + // { + // foreach (var typeString in HDRenderPipeline.defaultAsset.beforeTAACustomPostProcesses) + // RenderCustomPostProcess(cmd, camera, ref source, colorBuffer, Type.GetType(typeString)); + // } + //} + + if (m_AntialiasingFS) + { + taaEnabled = hdCamera.antialiasing == HDAdditionalCameraData.AntialiasingMode.TemporalAntialiasing; + + if (taaEnabled) + { + using (var builder = renderGraph.AddRenderPass("Temporal Anti-Aliasing", out var passData, ProfilingSampler.Get(HDProfileId.TemporalAntialiasing))) + { + GrabTemporalAntialiasingHistoryTextures(hdCamera, out var prevHistory, out var nextHistory); + GrabVelocityMagnitudeHistoryTextures(hdCamera, out var prevMVLen, out var nextMVLen); + + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareTAAParameters(hdCamera); + passData.depthBuffer = builder.ReadTexture(depthBuffer); + passData.motionVecTexture = builder.ReadTexture(motionVectors); + passData.depthMipChain = builder.ReadTexture(depthBufferMipChain); + passData.prevHistory = builder.ReadTexture(renderGraph.ImportTexture(prevHistory)); + if (passData.parameters.camera.resetPostProcessingHistory) + { + passData.prevHistory = builder.WriteTexture(passData.prevHistory); + } + passData.nextHistory = builder.WriteTexture(renderGraph.ImportTexture(nextHistory)); + passData.prevMVLen = builder.ReadTexture(renderGraph.ImportTexture(prevMVLen)); + passData.nextMVLen = builder.WriteTexture(renderGraph.ImportTexture(nextMVLen)); + + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "TAA Destination"); + passData.destination = builder.WriteTexture(dest); ; + + builder.SetRenderFunc( + (TemporalAntiAliasingData data, RenderGraphContext ctx) => + { + DoTemporalAntialiasing(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), + ctx.resources.GetTexture(data.destination), + ctx.resources.GetTexture(data.motionVecTexture), + ctx.resources.GetTexture(data.depthBuffer), + ctx.resources.GetTexture(data.depthMipChain), + ctx.resources.GetTexture(data.prevHistory), + ctx.resources.GetTexture(data.nextHistory), + ctx.resources.GetTexture(data.prevMVLen), + ctx.resources.GetTexture(data.nextMVLen)); + }); + + source = passData.destination; + } + } + else if (hdCamera.antialiasing == HDAdditionalCameraData.AntialiasingMode.SubpixelMorphologicalAntiAliasing) + { + using (var builder = renderGraph.AddRenderPass("Temporal Anti-Aliasing", out var passData, ProfilingSampler.Get(HDProfileId.SMAA))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareSMAAParameters(hdCamera); + builder.ReadTexture(depthBuffer); + passData.depthBuffer = builder.WriteTexture(depthBuffer); + passData.smaaEdgeTex = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) + { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, enableRandomWrite = true, name = "SMAA Edge Texture" }); + passData.smaaBlendTex = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) + { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, enableRandomWrite = true, name = "SMAA Blend Texture" }); + + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "SMAA Destination"); + passData.destination = builder.WriteTexture(dest); ; + + builder.SetRenderFunc( + (SMAAData data, RenderGraphContext ctx) => + { + DoSMAA(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), + ctx.resources.GetTexture(data.smaaEdgeTex), + ctx.resources.GetTexture(data.smaaBlendTex), + ctx.resources.GetTexture(data.destination), + ctx.resources.GetTexture(data.depthBuffer)); + }); + + source = passData.destination; + + } + } + } // if (camera.frameSettings.IsEnabled(FrameSettingsField.CustomPostProcess)) // { @@ -200,49 +440,115 @@ public void Render( RenderGraph renderGraph, // } // } - // // Motion blur after depth of field for aesthetic reasons (better to see motion - // // blurred bokeh rather than out of focus motion blur) - // if (m_MotionBlur.IsActive() && m_AnimatedMaterialsEnabled && !camera.resetPostProcessingHistory && m_MotionBlurFS) - // { - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.MotionBlur))) - // { - // var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - // DoMotionBlur(cmd, camera, source, destination); - // PoolSource(ref source, destination); - // } - // } + // Motion blur after depth of field for aesthetic reasons (better to see motion + // blurred bokeh rather than out of focus motion blur) + if (m_MotionBlur.IsActive() && m_AnimatedMaterialsEnabled && !hdCamera.resetPostProcessingHistory && m_MotionBlurFS) + { + using (var builder = renderGraph.AddRenderPass("Motion Blur", out var passData, ProfilingSampler.Get(HDProfileId.MotionBlur))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareMotionBlurParameters(hdCamera); - // // Panini projection is done as a fullscreen pass after all depth-based effects are - // // done and before bloom kicks in - // // This is one effect that would benefit from an overscan mode or supersampling in - // // HDRP to reduce the amount of resolution lost at the center of the screen - // if (m_PaniniProjection.IsActive() && !isSceneView && m_PaniniProjectionFS) - // { - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.PaniniProjection))) - // { - // var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - // DoPaniniProjection(cmd, camera, source, destination); - // PoolSource(ref source, destination); - // } - // } + passData.motionVecTexture = builder.ReadTexture(motionVectors); - // Uber post-process - //// Generate the bloom texture - //bool bloomActive = m_Bloom.IsActive() && m_BloomFS; + Vector2 tileTexScale = new Vector2((float)passData.parameters.tileTargetSize.x / hdCamera.actualWidth, (float)passData.parameters.tileTargetSize.y / hdCamera.actualHeight); - //if (bloomActive) - //{ - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.Bloom))) - // { - // DoBloom(cmd, camera, source, uberPostParams.uberPostCS, uberPostParams.uberPostKernel); - // } - //} - //else - //{ - // cmd.SetComputeTextureParam(uberPostParams.uberPostCS, uberPostParams.uberPostKernel, HDShaderIDs._BloomTexture, TextureXR.GetBlackTexture()); - // cmd.SetComputeTextureParam(uberPostParams.uberPostCS, uberPostParams.uberPostKernel, HDShaderIDs._BloomDirtTexture, Texture2D.blackTexture); - // cmd.SetComputeVectorParam(uberPostParams.uberPostCS, HDShaderIDs._BloomParams, Vector4.zero); - //} + passData.preppedMotionVec = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) + { colorFormat = GraphicsFormat.B10G11R11_UFloatPack32, enableRandomWrite = true, name = "Prepped Motion Vectors" }); + + passData.minMaxTileVel = builder.CreateTransientTexture(new TextureDesc(tileTexScale, true, true) + { colorFormat = GraphicsFormat.B10G11R11_UFloatPack32, enableRandomWrite = true, name = "MinMax Tile Motion Vectors" }); + + passData.maxTileNeigbourhood = builder.CreateTransientTexture(new TextureDesc(tileTexScale, true, true) + { colorFormat = GraphicsFormat.B10G11R11_UFloatPack32, enableRandomWrite = true, name = "Max Neighbourhood Tile" }); + + passData.tileToScatterMax = TextureHandle.nullHandle; + passData.tileToScatterMin = TextureHandle.nullHandle; + + if (passData.parameters.motionblurSupportScattering) + { + passData.tileToScatterMax = builder.CreateTransientTexture(new TextureDesc(tileTexScale, true, true) + { colorFormat = GraphicsFormat.R32_UInt, enableRandomWrite = true, name = "Tile to Scatter Max" }); + + passData.tileToScatterMin = builder.CreateTransientTexture(new TextureDesc(tileTexScale, true, true) + { colorFormat = GraphicsFormat.R16_SFloat, enableRandomWrite = true, name = "Tile to Scatter Min" }); + } + + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "Motion Blur Destination"); + passData.destination = builder.WriteTexture(dest); ; + + builder.SetRenderFunc( + (MotionBlurData data, RenderGraphContext ctx) => + { + DoMotionBlur(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), + ctx.resources.GetTexture(data.destination), + ctx.resources.GetTexture(data.motionVecTexture), + ctx.resources.GetTexture(data.preppedMotionVec), + ctx.resources.GetTexture(data.minMaxTileVel), + ctx.resources.GetTexture(data.maxTileNeigbourhood), + ctx.resources.GetTexture(data.tileToScatterMax), + ctx.resources.GetTexture(data.tileToScatterMin)); + }); + + source = passData.destination; + + } + } + + // Panini projection is done as a fullscreen pass after all depth-based effects are + // done and before bloom kicks in + // This is one effect that would benefit from an overscan mode or supersampling in + // HDRP to reduce the amount of resolution lost at the center of the screen + if (m_PaniniProjection.IsActive() && !isSceneView && m_PaniniProjectionFS) + { + using (var builder = renderGraph.AddRenderPass("Panini Projection", out var passData, ProfilingSampler.Get(HDProfileId.PaniniProjection))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PreparePaniniProjectionParameters(hdCamera); + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "Panini Projection Destination"); + passData.destination = builder.WriteTexture(dest); + + builder.SetRenderFunc( + (PaniniProjectionData data, RenderGraphContext ctx) => + { + DoPaniniProjection(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), ctx.resources.GetTexture(data.destination)); + }); + + source = passData.destination; + } + } + + bool bloomActive = m_Bloom.IsActive() && m_BloomFS; + TextureHandle bloomTexture = renderGraph.defaultResources.blackTextureXR; + if (bloomActive) + { + ComputeBloomMipSizesAndScales(hdCamera); + using (var builder = renderGraph.AddRenderPass("Bloom", out var passData, ProfilingSampler.Get(HDProfileId.Bloom))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareBloomParameters(hdCamera); + FillBloomMipsTextureHandles(passData, renderGraph, builder); + passData.mipsUp[0] = builder.WriteTexture(passData.mipsUp[0]); + + + builder.SetRenderFunc( + (BloomData data, RenderGraphContext ctx) => + { + var bloomMipDown = ctx.renderGraphPool.GetTempArray(data.parameters.bloomMipCount); + var bloomMipUp = ctx.renderGraphPool.GetTempArray(data.parameters.bloomMipCount); + + for(int i=0; i("Color Grading", out var passData, ProfilingSampler.Get(HDProfileId.ColorGradingLUTBuilder))) @@ -274,34 +580,25 @@ public void Render( RenderGraph renderGraph, using (var builder = renderGraph.AddRenderPass("Uber Post", out var passData, ProfilingSampler.Get(HDProfileId.UberPost))) { - TextureHandle dest = renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) - { - name = "Uber Post Destination", - colorFormat = m_ColorFormat, - useMipMap = false, - enableRandomWrite = true - }); + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "Uber Post Destination"); + passData.parameters = PrepareUberPostParameters(hdCamera, isSceneView); passData.source = builder.ReadTexture(source); + passData.bloomTexture = builder.ReadTexture(bloomTexture); passData.logLut = builder.ReadTexture(logLutOutput); passData.destination = builder.WriteTexture(dest); + builder.SetRenderFunc( (UberPostPassData data, RenderGraphContext ctx) => { - // Temp until bloom is implemented. - ctx.cmd.SetComputeTextureParam(data.parameters.uberPostCS, data.parameters.uberPostKernel, HDShaderIDs._BloomTexture, TextureXR.GetBlackTexture()); - ctx.cmd.SetComputeTextureParam(data.parameters.uberPostCS, data.parameters.uberPostKernel, HDShaderIDs._BloomDirtTexture, Texture2D.blackTexture); - ctx.cmd.SetComputeVectorParam(data.parameters.uberPostCS, HDShaderIDs._BloomParams, Vector4.zero); - - - DoUberPostProcess( data.parameters, - ctx.resources.GetTexture(data.source), - ctx.resources.GetTexture(data.destination), - ctx.resources.GetTexture(data.logLut), - ctx.resources.GetTexture(data.source), // TODO: TMP VALUE, should be bloom texture and will be as soon as PP is ported to rendergraph. - ctx.cmd); + DoUberPostProcess(data.parameters, + ctx.resources.GetTexture(data.source), + ctx.resources.GetTexture(data.destination), + ctx.resources.GetTexture(data.logLut), + ctx.resources.GetTexture(data.bloomTexture), // TODO: TMP VALUE, should be bloom texture and will be as soon as PP is ported to rendergraph. + ctx.cmd); }); source = passData.destination; @@ -317,55 +614,52 @@ public void Render( RenderGraph renderGraph, // RenderCustomPostProcess(cmd, camera, ref source, colorBuffer, Type.GetType(typeString)); // } // } + + + if (dynResHandler.DynamicResolutionEnabled() && // Dynamic resolution is on. + hdCamera.antialiasing == HDAdditionalCameraData.AntialiasingMode.FastApproximateAntialiasing && + m_AntialiasingFS) + { + using (var builder = renderGraph.AddRenderPass("FXAA", out var passData, ProfilingSampler.Get(HDProfileId.FXAA))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareFXAAParameters(hdCamera); + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "FXAA Destination"); + passData.destination = builder.WriteTexture(dest); ; + + builder.SetRenderFunc( + (FXAAData data, RenderGraphContext ctx) => + { + DoFXAA(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), ctx.resources.GetTexture(data.destination)); + }); + + source = passData.destination; + } + } + + hdCamera.resetPostProcessingHistory = false; } - // if (dynResHandler.DynamicResolutionEnabled() && // Dynamic resolution is on. - // camera.antialiasing == AntialiasingMode.FastApproximateAntialiasing && - // m_AntialiasingFS) - // { - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.FXAA))) - // { - // var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - // DoFXAA(cmd, camera, source, destination); - // PoolSource(ref source, destination); - // } - // } - - // // Contrast Adaptive Sharpen Upscaling - // if (dynResHandler.DynamicResolutionEnabled() && - // dynResHandler.filter == DynamicResUpscaleFilter.ContrastAdaptiveSharpen) - // { - // using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.ContrastAdaptiveSharpen))) - // { - // var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - - // var cs = m_Resources.shaders.contrastAdaptiveSharpenCS; - // int kInit = cs.FindKernel("KInitialize"); - // int kMain = cs.FindKernel("KMain"); - // if (kInit >= 0 && kMain >= 0) - // { - // cmd.SetComputeFloatParam(cs, HDShaderIDs._Sharpness, 1); - // cmd.SetComputeTextureParam(cs, kMain, HDShaderIDs._InputTexture, source); - // cmd.SetComputeVectorParam(cs, HDShaderIDs._InputTextureDimensions, new Vector4(source.rt.width, source.rt.height)); - // cmd.SetComputeTextureParam(cs, kMain, HDShaderIDs._OutputTexture, destination); - // cmd.SetComputeVectorParam(cs, HDShaderIDs._OutputTextureDimensions, new Vector4(destination.rt.width, destination.rt.height)); - - // ValidateComputeBuffer(ref m_ContrastAdaptiveSharpen, 2, sizeof(uint) * 4); - - // cmd.SetComputeBufferParam(cs, kInit, "CasParameters", m_ContrastAdaptiveSharpen); - // cmd.SetComputeBufferParam(cs, kMain, "CasParameters", m_ContrastAdaptiveSharpen); - - // cmd.DispatchCompute(cs, kInit, 1, 1, 1); - - // int dispatchX = (int)System.Math.Ceiling(destination.rt.width / 16.0f); - // int dispatchY = (int)System.Math.Ceiling(destination.rt.height / 16.0f); - - // cmd.DispatchCompute(cs, kMain, dispatchX, dispatchY, camera.viewCount); - // } - - // PoolSource(ref source, destination); - // } - // } + // Contrast Adaptive Sharpen Upscaling + if (dynResHandler.DynamicResolutionEnabled() && + dynResHandler.filter == DynamicResUpscaleFilter.ContrastAdaptiveSharpen) + { + using (var builder = renderGraph.AddRenderPass("Contrast Adaptive Sharpen", out var passData, ProfilingSampler.Get(HDProfileId.ContrastAdaptiveSharpen))) + { + passData.source = builder.ReadTexture(source); + passData.parameters = PrepareContrastAdaptiveSharpeningParameters(hdCamera); + TextureHandle dest = GetPostprocessOutputHandle(renderGraph, "Contrast Adaptive Sharpen Destination"); + passData.destination = builder.WriteTexture(dest); ; + + builder.SetRenderFunc( + (CASData data, RenderGraphContext ctx) => + { + DoContrastAdaptiveSharpening(data.parameters, ctx.cmd, ctx.resources.GetTexture(data.source), ctx.resources.GetTexture(data.destination)); + }); + + source = passData.destination; + } + } using (var builder = renderGraph.AddRenderPass("Final Pass", out var passData, ProfilingSampler.Get(HDProfileId.FinalPost))) { @@ -378,7 +672,7 @@ public void Render( RenderGraph renderGraph, builder.SetRenderFunc( (FinalPassData data, RenderGraphContext ctx) => { - DoFinalPass( data.parameters, + DoFinalPass(data.parameters, ctx.resources.GetTexture(data.source), ctx.resources.GetTexture(data.afterPostProcessTexture), ctx.resources.GetTexture(data.destination), diff --git a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs index ff4e475544c..f95108fcf97 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/PostProcessSystem.cs @@ -404,7 +404,9 @@ public void BeginFrame(CommandBuffer cmd, HDCamera camera, HDRenderPipeline hdIn { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.FixedExposure))) { - DoFixedExposure(cmd, camera); + RTHandle prevExposure; + GrabExposureHistoryTextures(camera, out prevExposure, out _); + DoFixedExposure(PrepareExposureParameters(camera), cmd, prevExposure); } } @@ -428,7 +430,45 @@ void PoolSourceGuard(ref RTHandle src, RTHandle dst, RTHandle colorBuffer) src = dst; } - public void Render(CommandBuffer cmd, HDCamera camera, BlueNoise blueNoise, RTHandle colorBuffer, RTHandle afterPostProcessTexture, RenderTargetIdentifier finalRT, RTHandle depthBuffer, RTHandle depthMipChain, bool flipY) + struct ClearWithGuardBandsParameters + { + public Material clearMaterial; + public int cameraWidth; + public int cameraHeight; + } + + ClearWithGuardBandsParameters PrepareClearWithGuardBandsParameters(HDCamera camera) + { + ClearWithGuardBandsParameters parameters = new ClearWithGuardBandsParameters(); + parameters.clearMaterial = m_ClearBlackMaterial; + parameters.cameraWidth = camera.actualWidth; + parameters.cameraHeight = camera.actualHeight; + + return parameters; + } + + static void ClearWithGuardBands(in ClearWithGuardBandsParameters parameters, CommandBuffer cmd, RTHandle source) + { + // Guard bands (also known as "horrible hack") to avoid bleeding previous RTHandle + // content into smaller viewports with some effects like Bloom that rely on bilinear + // filtering and can't use clamp sampler and the likes + // Note: some platforms can't clear a partial render target so we directly draw black triangles + { + int w = parameters.cameraWidth; + int h = parameters.cameraHeight; + cmd.SetRenderTarget(source, 0, CubemapFace.Unknown, -1); + + if (w < source.rt.width || h < source.rt.height) + { + cmd.SetViewport(new Rect(w, 0, k_RTGuardBandSize, h)); + cmd.DrawProcedural(Matrix4x4.identity, parameters.clearMaterial, 0, MeshTopology.Triangles, 3, 1); + cmd.SetViewport(new Rect(0, h, w + k_RTGuardBandSize, k_RTGuardBandSize)); + cmd.DrawProcedural(Matrix4x4.identity, parameters.clearMaterial, 0, MeshTopology.Triangles, 3, 1); + } + } + } + + public void Render(CommandBuffer cmd, HDCamera camera, BlueNoise blueNoise, RTHandle colorBuffer, RTHandle afterPostProcessTexture, RenderTargetIdentifier finalRT, RTHandle depthBuffer, RTHandle depthMipChain, RTHandle motionVecTexture, bool flipY) { var dynResHandler = DynamicResolutionHandler.instance; @@ -455,23 +495,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) if (m_PostProcessEnabled) { - // Guard bands (also known as "horrible hack") to avoid bleeding previous RTHandle - // content into smaller viewports with some effects like Bloom that rely on bilinear - // filtering and can't use clamp sampler and the likes - // Note: some platforms can't clear a partial render target so we directly draw black triangles - { - int w = camera.actualWidth; - int h = camera.actualHeight; - cmd.SetRenderTarget(source, 0, CubemapFace.Unknown, -1); - - if (w < source.rt.width || h < source.rt.height) - { - cmd.SetViewport(new Rect(w, 0, k_RTGuardBandSize, h)); - cmd.DrawProcedural(Matrix4x4.identity, m_ClearBlackMaterial, 0, MeshTopology.Triangles, 3, 1); - cmd.SetViewport(new Rect(0, h, w + k_RTGuardBandSize, k_RTGuardBandSize)); - cmd.DrawProcedural(Matrix4x4.identity, m_ClearBlackMaterial, 0, MeshTopology.Triangles, 3, 1); - } - } + ClearWithGuardBands(PrepareClearWithGuardBandsParameters(camera), cmd, source); // Optional NaN killer before post-processing kicks in bool stopNaNs = camera.stopNaNs && m_StopNaNFS; @@ -486,8 +510,8 @@ void PoolSource(ref RTHandle src, RTHandle dst) using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.StopNaNs))) { var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - var stopNanParams = PrepareStopNaNParameters(); - DoStopNaNs(stopNanParams, cmd, camera, source, destination); + var stopNanParams = PrepareStopNaNParameters(camera); + DoStopNaNs(stopNanParams, cmd, source, destination); PoolSource(ref source, destination); } } @@ -499,17 +523,17 @@ void PoolSource(ref RTHandle src, RTHandle dst) { var exposureParameters = PrepareExposureParameters(camera); - GrabExposureRequiredTextures(camera, out var prevExposure, out var nextExposure, out var tmpRenderTarget1024, out var tmpRenderTarget32); + GrabExposureRequiredTextures(camera, out var prevExposure, out var nextExposure); using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.DynamicExposure))) { if (m_Exposure.mode.value == ExposureMode.AutomaticHistogram) { - DoHistogramBasedExposure(exposureParameters, cmd, camera, source, prevExposure, nextExposure, m_DebugExposureData); + DoHistogramBasedExposure(exposureParameters, cmd, source, prevExposure, nextExposure, m_DebugExposureData); } else { - DoDynamicExposure(exposureParameters, cmd, camera, source, prevExposure, nextExposure, tmpRenderTarget1024, tmpRenderTarget32); + DoDynamicExposure(exposureParameters, cmd, source, prevExposure, nextExposure, m_TempTexture1024, m_TempTexture32); } // On reset history we need to apply dynamic exposure immediately to avoid @@ -518,19 +542,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) if (camera.resetPostProcessingHistory) { var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - - var cs = m_Resources.shaders.applyExposureCS; - int kernel = cs.FindKernel("KMain"); - - // Note: we call GetPrevious instead of GetCurrent because the textures - // are swapped internally as the system expects the texture will be used - // on the next frame. So the actual "current" for this frame is in - // "previous". - cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureTexture, GetPreviousExposureTexture(camera)); - cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source); - cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination); - cmd.DispatchCompute(cs, kernel, (camera.actualWidth + 7) / 8, (camera.actualHeight + 7) / 8, camera.viewCount); - + ApplyExposure(PrepareApplyExposureParameters(camera), cmd, source, destination, GetPreviousExposureTexture(camera)); PoolSource(ref source, destination); } } @@ -562,7 +574,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) var taaParams = PrepareTAAParameters(camera); GrabTemporalAntialiasingHistoryTextures(camera, out var prevHistory, out var nextHistory); GrabVelocityMagnitudeHistoryTextures(camera, out var prevMVLen, out var nextMVLen); - DoTemporalAntialiasing(taaParams, cmd, camera, source, destination, depthBuffer, depthMipChain, prevHistory, nextHistory, prevMVLen, nextMVLen); + DoTemporalAntialiasing(taaParams, cmd, source, destination, motionVecTexture, depthBuffer, depthMipChain, prevHistory, nextHistory, prevMVLen, nextMVLen); PoolSource(ref source, destination); } } @@ -573,7 +585,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) var destination = m_Pool.Get(Vector2.one, m_ColorFormat); RTHandle smaaEdgeTex, smaaBlendTex; AllocateSMAARenderTargets(camera, out smaaEdgeTex, out smaaBlendTex); - DoSMAA(PrepareSMAAParameters(camera), cmd, camera, source, smaaEdgeTex, smaaBlendTex, destination, depthBuffer); + DoSMAA(PrepareSMAAParameters(camera), cmd, source, smaaEdgeTex, smaaBlendTex, destination, depthBuffer); RecycleSMAARenderTargets(smaaEdgeTex, smaaBlendTex); PoolSource(ref source, destination); } @@ -620,7 +632,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) out preppedMotionVec, out minMaxTileVel, out maxTileNeigbourhood, out tileToScatterMax, out tileToScatterMin); - DoMotionBlur(PrepareMotionBlurParameters(camera), cmd, camera, source, destination, preppedMotionVec, minMaxTileVel, maxTileNeigbourhood, tileToScatterMax, tileToScatterMin); + DoMotionBlur(PrepareMotionBlurParameters(camera), cmd, source, destination, motionVecTexture, preppedMotionVec, minMaxTileVel, maxTileNeigbourhood, tileToScatterMax, tileToScatterMin); RecycleMotionBlurRenderTargets(preppedMotionVec, minMaxTileVel, maxTileNeigbourhood, tileToScatterMax, tileToScatterMin); PoolSource(ref source, destination); @@ -636,7 +648,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.PaniniProjection))) { var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - DoPaniniProjection(PreparePaniniProjectionParameters(camera), cmd, camera, source, destination); + DoPaniniProjection(PreparePaniniProjectionParameters(camera), cmd, source, destination); PoolSource(ref source, destination); } } @@ -655,7 +667,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) { ComputeBloomMipSizesAndScales(camera); AllocateBloomMipTextures(); - DoBloom(PrepareBloomParameters(camera), cmd, camera, source, m_BloomMipsDown, m_BloomMipsUp, uberPostParams.uberPostCS, uberPostParams.uberPostKernel); + DoBloom(PrepareBloomParameters(camera), cmd, source, m_BloomMipsDown, m_BloomMipsUp); RecycleUnusedBloomMips(); } } @@ -702,7 +714,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.FXAA))) { var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - DoFXAA(PrepareFXAAParameters(), cmd, camera, source, destination); + DoFXAA(PrepareFXAAParameters(camera), cmd, source, destination); PoolSource(ref source, destination); } } @@ -714,31 +726,7 @@ void PoolSource(ref RTHandle src, RTHandle dst) using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.ContrastAdaptiveSharpen))) { var destination = m_Pool.Get(Vector2.one, m_ColorFormat); - - var cs = m_Resources.shaders.contrastAdaptiveSharpenCS; - int kInit = cs.FindKernel("KInitialize"); - int kMain = cs.FindKernel("KMain"); - if (kInit >= 0 && kMain >= 0) - { - cmd.SetComputeFloatParam(cs, HDShaderIDs._Sharpness, 1); - cmd.SetComputeTextureParam(cs, kMain, HDShaderIDs._InputTexture, source); - cmd.SetComputeVectorParam(cs, HDShaderIDs._InputTextureDimensions, new Vector4(source.rt.width, source.rt.height)); - cmd.SetComputeTextureParam(cs, kMain, HDShaderIDs._OutputTexture, destination); - cmd.SetComputeVectorParam(cs, HDShaderIDs._OutputTextureDimensions, new Vector4(destination.rt.width, destination.rt.height)); - - ValidateComputeBuffer(ref m_ContrastAdaptiveSharpen, 2, sizeof(uint) * 4); - - cmd.SetComputeBufferParam(cs, kInit, "CasParameters", m_ContrastAdaptiveSharpen); - cmd.SetComputeBufferParam(cs, kMain, "CasParameters", m_ContrastAdaptiveSharpen); - - cmd.DispatchCompute(cs, kInit, 1, 1, 1); - - int dispatchX = (int)System.Math.Ceiling(destination.rt.width / 16.0f); - int dispatchY = (int)System.Math.Ceiling(destination.rt.height / 16.0f); - - cmd.DispatchCompute(cs, kMain, dispatchX, dispatchY, camera.viewCount); - } - + DoContrastAdaptiveSharpening(PrepareContrastAdaptiveSharpeningParameters(camera), cmd, source, destination); PoolSource(ref source, destination); } } @@ -900,23 +888,30 @@ struct StopNaNParameters { public ComputeShader nanKillerCS; public int nanKillerKernel; + + public int width; + public int height; + public int viewCount; } - StopNaNParameters PrepareStopNaNParameters() + StopNaNParameters PrepareStopNaNParameters(HDCamera camera) { StopNaNParameters stopNanParams = new StopNaNParameters(); stopNanParams.nanKillerCS = m_Resources.shaders.nanKillerCS; stopNanParams.nanKillerKernel = stopNanParams.nanKillerCS.FindKernel("KMain"); + stopNanParams.width = camera.actualWidth; + stopNanParams.height = camera.actualHeight; + stopNanParams.viewCount = camera.viewCount; return stopNanParams; } - static void DoStopNaNs(in StopNaNParameters stopNanParameters, CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination) + static void DoStopNaNs(in StopNaNParameters stopNanParameters, CommandBuffer cmd, RTHandle source, RTHandle destination) { var cs = stopNanParameters.nanKillerCS; int kernel = stopNanParameters.nanKillerKernel; cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination); - cmd.DispatchCompute(cs, kernel, (camera.actualWidth + 7) / 8, (camera.actualHeight + 7) / 8, camera.viewCount); + cmd.DispatchCompute(cs, kernel, (stopNanParameters.width + 7) / 8, (stopNanParameters.height + 7) / 8, stopNanParameters.viewCount); } #endregion @@ -951,7 +946,46 @@ static void DoCopyAlpha(in DoCopyAlphaParameters parameters, RTHandle source, RT #region Exposure - struct ExposureParameter + struct ApplyExposureParameters + { + public ComputeShader applyExposureCS; + public int applyExposureKernel; + + public int width; + public int height; + public int viewCount; + } + + ApplyExposureParameters PrepareApplyExposureParameters(HDCamera camera) + { + ApplyExposureParameters parameters = new ApplyExposureParameters(); + parameters.applyExposureCS = m_Resources.shaders.applyExposureCS; + parameters.applyExposureKernel = parameters.applyExposureCS.FindKernel("KMain"); + + parameters.width = camera.actualWidth; + parameters.height = camera.actualHeight; + parameters.viewCount = camera.viewCount; + + return parameters; + } + + static void ApplyExposure(in ApplyExposureParameters parameters, CommandBuffer cmd, RTHandle source, RTHandle destination, RTHandle prevExposure) + { + var cs = parameters.applyExposureCS; + int kernel = parameters.applyExposureKernel; + + // Note: we use previous instead of current because the textures + // are swapped internally as the system expects the texture will be used + // on the next frame. So the actual "current" for this frame is in + // "previous". + cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._ExposureTexture, prevExposure); + cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source); + cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination); + cmd.DispatchCompute(cs, kernel, (parameters.width + 7) / 8, (parameters.height + 7) / 8, parameters.viewCount); + + } + + struct ExposureParameters { public ComputeShader exposureCS; public ComputeShader histogramExposureCS; @@ -961,6 +995,8 @@ struct ExposureParameter public Texture textureMeteringMask; public Texture exposureCurve; + public HDCamera camera; + public ComputeBuffer histogramBuffer; public ExposureMode exposureMode; @@ -976,21 +1012,33 @@ struct ExposureParameter public Vector4 adaptationParams; } - ExposureParameter PrepareExposureParameters(HDCamera hdCamera) + ExposureParameters PrepareExposureParameters(HDCamera hdCamera) { - var parameters = new ExposureParameter(); + var parameters = new ExposureParameters(); parameters.exposureCS = m_Resources.shaders.exposureCS; parameters.histogramExposureCS = m_Resources.shaders.histogramExposureCS; parameters.histogramExposureCS.shaderKeywords = null; + parameters.camera = hdCamera; + bool isFixed = IsExposureFixed(hdCamera); if (isFixed) { parameters.exposureParams2 = new Vector4(0.0f, 0.0f, ColorUtils.lensImperfectionExposureScale, ColorUtils.s_LightMeterCalibrationConstant); - if (m_Exposure.mode.value == ExposureMode.Fixed) + if (m_Exposure.mode.value == ExposureMode.Fixed +#if UNITY_EDITOR + || HDAdditionalSceneViewSettings.sceneExposureOverriden && hdCamera.camera.cameraType == CameraType.SceneView +#endif + ) { parameters.exposureReductionKernel = parameters.exposureCS.FindKernel("KFixedExposure"); parameters.exposureParams = new Vector4(m_Exposure.compensation.value + m_DebugExposureCompensation, m_Exposure.fixedExposure.value, 0f, 0f); +#if UNITY_EDITOR + if (HDAdditionalSceneViewSettings.sceneExposureOverriden && hdCamera.camera.cameraType == CameraType.SceneView) + { + parameters.exposureParams = new Vector4(0.0f, HDAdditionalSceneViewSettings.sceneExposure, 0f, 0f); + } +#endif } else if (m_Exposure.mode == ExposureMode.UsePhysicalCamera) { @@ -1161,37 +1209,13 @@ internal ComputeBuffer GetDebugImageHistogramBuffer() return m_DebugImageHistogramBuffer; } - void DoFixedExposure(CommandBuffer cmd, HDCamera camera) + void DoFixedExposure(in ExposureParameters parameters, CommandBuffer cmd, RTHandle prevExposure) { - var cs = m_Resources.shaders.exposureCS; - - cmd.SetComputeVectorParam(cs, HDShaderIDs._ExposureParams2, new Vector4(0.0f, 0.0f, ColorUtils.lensImperfectionExposureScale, ColorUtils.s_LightMeterCalibrationConstant)); + var cs = parameters.exposureCS; + int kernel = parameters.exposureReductionKernel; - GrabExposureHistoryTextures(camera, out var prevExposure, out _); - - int kernel = 0; - - if (m_Exposure.mode.value == ExposureMode.Fixed - #if UNITY_EDITOR - || (HDAdditionalSceneViewSettings.sceneExposureOverriden && camera.camera.cameraType == CameraType.SceneView) - #endif - ) - { - kernel = cs.FindKernel("KFixedExposure"); - var exposureParam = new Vector4(m_Exposure.compensation.value + m_DebugExposureCompensation, m_Exposure.fixedExposure.value, 0f, 0f); - #if UNITY_EDITOR - if (HDAdditionalSceneViewSettings.sceneExposureOverriden) - { - exposureParam = new Vector4(0.0f, HDAdditionalSceneViewSettings.sceneExposure, 0f, 0f); - } - #endif - cmd.SetComputeVectorParam(cs, HDShaderIDs._ExposureParams, exposureParam); - } - else if (m_Exposure.mode == ExposureMode.UsePhysicalCamera) - { - kernel = cs.FindKernel("KManualCameraExposure"); - cmd.SetComputeVectorParam(cs, HDShaderIDs._ExposureParams, new Vector4(m_Exposure.compensation.value + m_DebugExposureCompensation, m_PhysicalCamera.aperture, m_PhysicalCamera.shutterSpeed, m_PhysicalCamera.iso)); - } + cmd.SetComputeVectorParam(cs, HDShaderIDs._ExposureParams, parameters.exposureParams); + cmd.SetComputeVectorParam(cs, HDShaderIDs._ExposureParams2, parameters.exposureParams2); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, prevExposure); cmd.DispatchCompute(cs, kernel, 1, 1, 1); @@ -1267,44 +1291,18 @@ void PrepareExposureCurveData(out float min, out float max) m_ExposureCurveTexture.Apply(); } - void GrabExposureRequiredTextures(HDCamera camera, out RTHandle prevExposure, out RTHandle nextExposure, out RTHandle tmpRenderTarget1024, out RTHandle tmpRenderTarget32) - { - GrabExposureHistoryTextures(camera, out prevExposure, out nextExposure); - if (camera.resetPostProcessingHistory) - { - // For Dynamic Exposure, we need to undo the pre-exposure from the color buffer to calculate the correct one - // When we reset history we must setup neutral value - prevExposure = m_EmptyExposureTexture; // Use neutral texture - } - - tmpRenderTarget1024 = m_TempTexture1024; - tmpRenderTarget32 = m_TempTexture32; - } - - void DynamicExposureSetup(CommandBuffer cmd, HDCamera camera, out RTHandle prevExposure, out RTHandle nextExposure) + void GrabExposureRequiredTextures(HDCamera camera, out RTHandle prevExposure, out RTHandle nextExposure) { GrabExposureHistoryTextures(camera, out prevExposure, out nextExposure); - - // Setup variants - var adaptationMode = m_Exposure.adaptationMode.value; - - if (!Application.isPlaying || camera.resetPostProcessingHistory) - adaptationMode = AdaptationMode.Fixed; - if (camera.resetPostProcessingHistory) { // For Dynamic Exposure, we need to undo the pre-exposure from the color buffer to calculate the correct one // When we reset history we must setup neutral value prevExposure = m_EmptyExposureTexture; // Use neutral texture } - - m_ExposureVariants[0] = 1; // (int)exposureSettings.luminanceSource.value; - m_ExposureVariants[1] = (int)m_Exposure.meteringMode.value; - m_ExposureVariants[2] = (int)adaptationMode; - m_ExposureVariants[3] = 0; } - static void DoDynamicExposure(in ExposureParameter exposureParameters, CommandBuffer cmd, HDCamera camera, RTHandle colorBuffer, RTHandle prevExposure, RTHandle nextExposure, RTHandle tmpRenderTarget1024, RTHandle tmpRenderTarget32) + static void DoDynamicExposure(in ExposureParameters exposureParameters, CommandBuffer cmd, RTHandle colorBuffer, RTHandle prevExposure, RTHandle nextExposure, RTHandle tmpRenderTarget1024, RTHandle tmpRenderTarget32) { var cs = exposureParameters.exposureCS; int kernel; @@ -1353,7 +1351,7 @@ static void DoDynamicExposure(in ExposureParameter exposureParameters, CommandBu cmd.DispatchCompute(cs, kernel, 1, 1, 1); } - static void DoHistogramBasedExposure(in ExposureParameter exposureParameters, CommandBuffer cmd, HDCamera camera, RTHandle sourceTexture, RTHandle prevExposure, RTHandle nextExposure, RTHandle debugData) + static void DoHistogramBasedExposure(in ExposureParameters exposureParameters, CommandBuffer cmd, RTHandle sourceTexture, RTHandle prevExposure, RTHandle nextExposure, RTHandle debugData) { var cs = exposureParameters.histogramExposureCS; int kernel; @@ -1375,9 +1373,8 @@ static void DoHistogramBasedExposure(in ExposureParameter exposureParameters, Co int threadGroupSizeX = 16; int threadGroupSizeY = 8; - int dispatchSizeX = HDUtils.DivRoundUp(camera.actualWidth / 2, threadGroupSizeX); - int dispatchSizeY = HDUtils.DivRoundUp(camera.actualHeight / 2, threadGroupSizeY); - int totalPixels = camera.actualWidth * camera.actualHeight; + int dispatchSizeX = HDUtils.DivRoundUp(exposureParameters.camera.actualWidth / 2, threadGroupSizeX); + int dispatchSizeY = HDUtils.DivRoundUp(exposureParameters.camera.actualHeight / 2, threadGroupSizeY); cmd.DispatchCompute(cs, kernel, dispatchSizeX, dispatchSizeY, 1); // Now read the histogram @@ -1405,6 +1402,7 @@ static void DoHistogramBasedExposure(in ExposureParameter exposureParameters, Co cmd.DispatchCompute(cs, kernel, 1, 1, 1); } + // TODO_FCC: TODO ADD! MISSING! internal void GenerateDebugImageHistogram(CommandBuffer cmd, HDCamera camera, RTHandle sourceTexture) { var cs = m_Resources.shaders.debugImageHistogramCS; @@ -1430,10 +1428,11 @@ internal void GenerateDebugImageHistogram(CommandBuffer cmd, HDCamera camera, RT struct TemporalAntiAliasingParameters { public Material temporalAAMaterial; - public MaterialPropertyBlock taaHistoryPropertyBlock; public MaterialPropertyBlock taaPropertyBlock; + public HDCamera camera; + public Vector4 taaParameters; public Vector4 taaFilterWeights; } @@ -1441,6 +1440,9 @@ struct TemporalAntiAliasingParameters TemporalAntiAliasingParameters PrepareTAAParameters(HDCamera camera) { TemporalAntiAliasingParameters parameters = new TemporalAntiAliasingParameters(); + + parameters.camera = camera; + float minAntiflicker = 0.0f; float maxAntiflicker = 3.5f; float motionRejectionMultiplier = Mathf.Lerp(0.0f, 250.0f, camera.taaMotionVectorRejection * camera.taaMotionVectorRejection * camera.taaMotionVectorRejection); @@ -1511,9 +1513,9 @@ TemporalAntiAliasingParameters PrepareTAAParameters(HDCamera camera) static void DoTemporalAntialiasing(in TemporalAntiAliasingParameters taaParams, CommandBuffer cmd, - HDCamera camera, RTHandle source, RTHandle destination, + RTHandle motionVecTexture, RTHandle depthBuffer, RTHandle depthMipChain, RTHandle prevHistory, @@ -1521,7 +1523,7 @@ static void DoTemporalAntialiasing(in TemporalAntiAliasingParameters taaParams, RTHandle prevMVLen, RTHandle nextMVLen) { - if (camera.resetPostProcessingHistory) + if (taaParams.camera.resetPostProcessingHistory) { taaParams.taaHistoryPropertyBlock.SetTexture(HDShaderIDs._BlitTexture, source); var rtScaleSource = source.rtHandleProperties.rtHandleScale; @@ -1533,6 +1535,7 @@ static void DoTemporalAntialiasing(in TemporalAntiAliasingParameters taaParams, taaParams.taaPropertyBlock.SetInt(HDShaderIDs._StencilMask, (int)StencilUsage.ExcludeFromTAA); taaParams.taaPropertyBlock.SetInt(HDShaderIDs._StencilRef, (int)StencilUsage.ExcludeFromTAA); + taaParams.taaPropertyBlock.SetTexture(HDShaderIDs._CameraMotionVectorsTexture, motionVecTexture); taaParams.taaPropertyBlock.SetTexture(HDShaderIDs._InputTexture, source); taaParams.taaPropertyBlock.SetTexture(HDShaderIDs._InputHistoryTexture, prevHistory); taaParams.taaPropertyBlock.SetTexture(HDShaderIDs._InputVelocityMagnitudeHistory, prevMVLen); @@ -2330,6 +2333,8 @@ struct MotionBlurParameters public int tileMergeKernel; public int motionBlurKernel; + public HDCamera camera; + public Vector4 tileTargetSize; public Vector4 motionBlurParams0; public Vector4 motionBlurParams1; @@ -2341,6 +2346,9 @@ struct MotionBlurParameters MotionBlurParameters PrepareMotionBlurParameters(HDCamera camera) { MotionBlurParameters parameters = new MotionBlurParameters(); + + parameters.camera = camera; + int tileSize = 32; if (m_MotionBlurSupportsScattering) @@ -2441,7 +2449,7 @@ void RecycleMotionBlurRenderTargets(RTHandle preppedMotionVec, RTHandle minMaxTi } } - static void DoMotionBlur(in MotionBlurParameters motionBlurParams, CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination, + static void DoMotionBlur(in MotionBlurParameters motionBlurParams, CommandBuffer cmd, RTHandle source, RTHandle destination, RTHandle motionVectorTexture, RTHandle preppedMotionVec, RTHandle minMaxTileVel, RTHandle maxTileNeigbourhood, RTHandle tileToScatterMax, RTHandle tileToScatterMin) @@ -2473,11 +2481,13 @@ static void DoMotionBlur(in MotionBlurParameters motionBlurParams, CommandBuffer cmd.SetComputeVectorParam(cs, HDShaderIDs._MotionBlurParams1, motionBlurParams.motionBlurParams1); cmd.SetComputeVectorParam(cs, HDShaderIDs._MotionBlurParams2, motionBlurParams.motionBlurParams2); - cmd.SetComputeMatrixParam(cs, HDShaderIDs._PrevVPMatrixNoTranslation, camera.mainViewConstants.prevViewProjMatrixNoCameraTrans); + cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._CameraMotionVectorsTexture, motionVectorTexture); - threadGroupX = (camera.actualWidth + (groupSizeX - 1)) / groupSizeX; - threadGroupY = (camera.actualHeight + (groupSizeY - 1)) / groupSizeY; - cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, camera.viewCount); + cmd.SetComputeMatrixParam(cs, HDShaderIDs._PrevVPMatrixNoTranslation, motionBlurParams.camera.mainViewConstants.prevViewProjMatrixNoCameraTrans); + + threadGroupX = (motionBlurParams.camera.actualWidth + (groupSizeX - 1)) / groupSizeX; + threadGroupY = (motionBlurParams.camera.actualHeight + (groupSizeY - 1)) / groupSizeY; + cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, motionBlurParams.camera.viewCount); } @@ -2503,9 +2513,9 @@ static void DoMotionBlur(in MotionBlurParameters motionBlurParams, CommandBuffer cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._TileToScatterMin, tileToScatterMin); } - threadGroupX = (camera.actualWidth + (tileSize - 1)) / tileSize; - threadGroupY = (camera.actualHeight + (tileSize - 1)) / tileSize; - cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, camera.viewCount); + threadGroupX = (motionBlurParams.camera.actualWidth + (tileSize - 1)) / tileSize; + threadGroupY = (motionBlurParams.camera.actualHeight + (tileSize - 1)) / tileSize; + cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, motionBlurParams.camera.viewCount); } // ----------------------------------------------------------------------------- @@ -2533,7 +2543,7 @@ static void DoMotionBlur(in MotionBlurParameters motionBlurParams, CommandBuffer groupSizeY = 8; threadGroupX = ((int)motionBlurParams.tileTargetSize.x + (groupSizeX - 1)) / groupSizeX; threadGroupY = ((int)motionBlurParams.tileTargetSize.y + (groupSizeY - 1)) / groupSizeY; - cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, camera.viewCount); + cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, motionBlurParams.camera.viewCount); } // ----------------------------------------------------------------------------- @@ -2551,7 +2561,7 @@ static void DoMotionBlur(in MotionBlurParameters motionBlurParams, CommandBuffer cmd.SetComputeVectorParam(cs, HDShaderIDs._MotionBlurParams1, motionBlurParams.motionBlurParams1); cmd.SetComputeVectorParam(cs, HDShaderIDs._MotionBlurParams2, motionBlurParams.motionBlurParams2); - cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, camera.viewCount); + cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, motionBlurParams.camera.viewCount); } // ----------------------------------------------------------------------------- @@ -2572,9 +2582,9 @@ static void DoMotionBlur(in MotionBlurParameters motionBlurParams, CommandBuffer groupSizeX = 16; groupSizeY = 16; - threadGroupX = (camera.actualWidth + (groupSizeX - 1)) / groupSizeX; - threadGroupY = (camera.actualHeight + (groupSizeY - 1)) / groupSizeY; - cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, camera.viewCount); + threadGroupX = (motionBlurParams.camera.actualWidth + (groupSizeX - 1)) / groupSizeX; + threadGroupY = (motionBlurParams.camera.actualHeight + (groupSizeY - 1)) / groupSizeY; + cmd.DispatchCompute(cs, kernel, threadGroupX, threadGroupY, motionBlurParams.camera.viewCount); } } @@ -2588,11 +2598,20 @@ struct PaniniProjectionParameters public int paniniProjectionKernel; public Vector4 paniniParams; + + public int width; + public int height; + public int viewCount; } PaniniProjectionParameters PreparePaniniProjectionParameters(HDCamera camera) { PaniniProjectionParameters parameters = new PaniniProjectionParameters(); + + parameters.width = camera.actualWidth; + parameters.height = camera.actualHeight; + parameters.viewCount = camera.viewCount; + parameters.paniniProjectionCS = m_Resources.shaders.paniniProjectionCS; parameters.paniniProjectionCS.shaderKeywords = null; @@ -2623,7 +2642,7 @@ PaniniProjectionParameters PreparePaniniProjectionParameters(HDCamera camera) } // Back-ported & adapted from the work of the Stockholm demo team - thanks Lasse! - static void DoPaniniProjection(in PaniniProjectionParameters parameters, CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination) + static void DoPaniniProjection(in PaniniProjectionParameters parameters, CommandBuffer cmd, RTHandle source, RTHandle destination) { var cs = parameters.paniniProjectionCS; int kernel = parameters.paniniProjectionKernel; @@ -2631,7 +2650,7 @@ static void DoPaniniProjection(in PaniniProjectionParameters parameters, Command cmd.SetComputeVectorParam(cs, HDShaderIDs._Params, parameters.paniniParams); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination); - cmd.DispatchCompute(cs, kernel, (camera.actualWidth + 7) / 8, (camera.actualHeight + 7) / 8, camera.viewCount); + cmd.DispatchCompute(cs, kernel, (parameters.width + 7) / 8, (parameters.height + 7) / 8, parameters.viewCount); } Vector2 CalcViewExtents(HDCamera camera) @@ -2695,18 +2714,19 @@ struct BloomParameters public int bloomBlurKernel; public int bloomDownsampleKernel; public int bloomUpsampleKernel; + + public int viewCount; public int bloomMipCount; public float bloomScatterParam; - public Vector4 thresholdParams; - public Vector4[] bloomMipInfo; } BloomParameters PrepareBloomParameters(HDCamera camera) { BloomParameters parameters = new BloomParameters(); + parameters.viewCount = camera.viewCount; parameters.bloomMipCount = m_BloomMipCount; parameters.bloomMipInfo = m_BloomMipsInfo; @@ -2856,12 +2876,12 @@ void RecycleUnusedBloomMips() } } - static void DoBloom(in BloomParameters bloomParameters, CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle[] bloomMipsDown, RTHandle[] bloomMipsUp, ComputeShader uberCS, int uberKernel) + static void DoBloom(in BloomParameters bloomParameters, CommandBuffer cmd, RTHandle source, RTHandle[] bloomMipsDown, RTHandle[] bloomMipsUp) { // All the computes for this effect use the same group size so let's use a local // function to simplify dispatches // Make sure the thread group count is sufficient to draw the guard bands - void DispatchWithGuardBands(ComputeShader shader, int kernelId, in Vector2Int size) + void DispatchWithGuardBands(ComputeShader shader, int kernelId, in Vector2Int size, in int viewCount) { int w = size.x; int h = size.y; @@ -2871,7 +2891,7 @@ void DispatchWithGuardBands(ComputeShader shader, int kernelId, in Vector2Int si if (h < source.rt.height && h % 8 < k_RTGuardBandSize) h += k_RTGuardBandSize; - cmd.DispatchCompute(shader, kernelId, (w + 7) / 8, (h + 7) / 8, camera.viewCount); + cmd.DispatchCompute(shader, kernelId, (w + 7) / 8, (h + 7) / 8, viewCount); } // Pre-filtering @@ -2887,7 +2907,7 @@ void DispatchWithGuardBands(ComputeShader shader, int kernelId, in Vector2Int si cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, bloomMipsUp[0]); // Use m_BloomMipsUp as temp target cmd.SetComputeVectorParam(cs, HDShaderIDs._TexelSize, new Vector4(size.x, size.y, 1f / size.x, 1f / size.y)); cmd.SetComputeVectorParam(cs, HDShaderIDs._BloomThreshold, bloomParameters.thresholdParams); - DispatchWithGuardBands(cs, kernel, size); + DispatchWithGuardBands(cs, kernel, size, bloomParameters.viewCount); cs = bloomParameters.bloomBlurCS; kernel = bloomParameters.bloomBlurKernel; @@ -2895,7 +2915,7 @@ void DispatchWithGuardBands(ComputeShader shader, int kernelId, in Vector2Int si cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, bloomMipsUp[0]); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, bloomMipsDown[0]); cmd.SetComputeVectorParam(cs, HDShaderIDs._TexelSize, new Vector4(size.x, size.y, 1f / size.x, 1f / size.y)); - DispatchWithGuardBands(cs, kernel, size); + DispatchWithGuardBands(cs, kernel, size, bloomParameters.viewCount); } // Blur pyramid @@ -2910,7 +2930,7 @@ void DispatchWithGuardBands(ComputeShader shader, int kernelId, in Vector2Int si cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, src); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, dst); cmd.SetComputeVectorParam(cs, HDShaderIDs._TexelSize, new Vector4(size.x, size.y, 1f / size.x, 1f / size.y)); - DispatchWithGuardBands(cs, kernel, size); + DispatchWithGuardBands(cs, kernel, size, bloomParameters.viewCount); } // Upsample & combine @@ -2932,7 +2952,7 @@ void DispatchWithGuardBands(ComputeShader shader, int kernelId, in Vector2Int si cmd.SetComputeVectorParam(cs, HDShaderIDs._Params, new Vector4(bloomParameters.bloomScatterParam, 0f, 0f, 0f)); cmd.SetComputeVectorParam(cs, HDShaderIDs._BloomBicubicParams, new Vector4(lowSize.x, lowSize.y, 1f / lowSize.x, 1f / lowSize.y)); cmd.SetComputeVectorParam(cs, HDShaderIDs._TexelSize, new Vector4(highSize.x, highSize.y, 1f / highSize.x, 1f / highSize.y)); - DispatchWithGuardBands(cs, kernel, highSize); + DispatchWithGuardBands(cs, kernel, highSize, bloomParameters.viewCount); } } @@ -3336,24 +3356,32 @@ struct FXAAParameters { public ComputeShader fxaaCS; public int fxaaKernel; + + public int width; + public int height; + public int viewCount; } - FXAAParameters PrepareFXAAParameters() + FXAAParameters PrepareFXAAParameters(HDCamera camera) { FXAAParameters parameters = new FXAAParameters(); parameters.fxaaCS = m_Resources.shaders.FXAACS; parameters.fxaaKernel = parameters.fxaaCS.FindKernel("FXAA"); + parameters.width = camera.actualWidth; + parameters.height = camera.actualHeight; + parameters.viewCount = camera.viewCount; + return parameters; } - void DoFXAA(in FXAAParameters parameters, CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination) + void DoFXAA(in FXAAParameters parameters, CommandBuffer cmd, RTHandle source, RTHandle destination) { var cs = parameters.fxaaCS; int kernel = parameters.fxaaKernel; cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source); cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination); - cmd.DispatchCompute(cs, kernel, (camera.actualWidth + 7) / 8, (camera.actualHeight + 7) / 8, camera.viewCount); + cmd.DispatchCompute(cs, kernel, (parameters.width + 7) / 8, (parameters.height + 7) / 8, parameters.viewCount); } #endregion @@ -3410,7 +3438,7 @@ void RecycleSMAARenderTargets(RTHandle smaaEdgeTex, RTHandle smaaBlendTex) m_Pool.Recycle(smaaBlendTex); } - static void DoSMAA(in SMAAParameters parameters, CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle smaaEdgeTex, RTHandle smaaBlendTex, RTHandle destination, RTHandle depthBuffer) + static void DoSMAA(in SMAAParameters parameters, CommandBuffer cmd, RTHandle source, RTHandle smaaEdgeTex, RTHandle smaaBlendTex, RTHandle destination, RTHandle depthBuffer) { parameters.smaaMaterial.SetVector(HDShaderIDs._SMAARTMetrics, parameters.smaaRTMetrics); parameters.smaaMaterial.SetTexture(HDShaderIDs._SMAAAreaTex, parameters.smaaAreaTex); @@ -3442,6 +3470,61 @@ static void DoSMAA(in SMAAParameters parameters, CommandBuffer cmd, HDCamera cam #endregion + #region CAS + struct CASParameters + { + public ComputeShader casCS; + public int initKernel; + public int mainKernel; + + public ComputeBuffer casParametersBuffer; + + public int viewCount; + } + + CASParameters PrepareContrastAdaptiveSharpeningParameters(HDCamera camera) + { + CASParameters parameters = new CASParameters(); + + parameters.casCS = m_Resources.shaders.contrastAdaptiveSharpenCS; + parameters.initKernel = parameters.casCS.FindKernel("KInitialize"); + parameters.mainKernel = parameters.casCS.FindKernel("KMain"); + + ValidateComputeBuffer(ref m_ContrastAdaptiveSharpen, 2, sizeof(uint) * 4); + parameters.casParametersBuffer = m_ContrastAdaptiveSharpen; + + parameters.viewCount = camera.viewCount; + + return parameters; + } + + static void DoContrastAdaptiveSharpening(in CASParameters parameters, CommandBuffer cmd, RTHandle source, RTHandle destination) + { + var cs = parameters.casCS; + int kInit = parameters.initKernel; + int kMain = parameters.mainKernel; + if (kInit >= 0 && kMain >= 0) + { + cmd.SetComputeFloatParam(cs, HDShaderIDs._Sharpness, 1); + cmd.SetComputeTextureParam(cs, kMain, HDShaderIDs._InputTexture, source); + cmd.SetComputeVectorParam(cs, HDShaderIDs._InputTextureDimensions, new Vector4(source.rt.width, source.rt.height)); + cmd.SetComputeTextureParam(cs, kMain, HDShaderIDs._OutputTexture, destination); + cmd.SetComputeVectorParam(cs, HDShaderIDs._OutputTextureDimensions, new Vector4(destination.rt.width, destination.rt.height)); + + cmd.SetComputeBufferParam(cs, kInit, "CasParameters", parameters.casParametersBuffer); + cmd.SetComputeBufferParam(cs, kMain, "CasParameters", parameters.casParametersBuffer); + + cmd.DispatchCompute(cs, kInit, 1, 1, 1); + + int dispatchX = (int)System.Math.Ceiling(destination.rt.width / 16.0f); + int dispatchY = (int)System.Math.Ceiling(destination.rt.height / 16.0f); + + cmd.DispatchCompute(cs, kMain, dispatchX, dispatchY, parameters.viewCount); + } + + } + #endregion + #region Final Pass struct FinalPassParameters diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs index 0187f373785..ae885cb4cef 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDProfileId.cs @@ -156,10 +156,12 @@ internal enum HDProfileId UpsampleLowResTransparent, // Post-processing + GuardBandClear, AlphaCopy, StopNaNs, FixedExposure, DynamicExposure, + ApplyExposure, TemporalAntialiasing, DepthOfField, DepthOfFieldKernel, diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs index 2c6aac34fb9..040fec11e4d 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.PostProcess.cs @@ -15,8 +15,8 @@ class AfterPostProcessPassData } TextureHandle RenderPostProcess( RenderGraph renderGraph, + PrepassOutput prepassOutput, TextureHandle inputColor, - TextureHandle depthBuffer, TextureHandle backBuffer, CullingResults cullResults, HDCamera hdCamera) @@ -36,7 +36,7 @@ TextureHandle RenderPostProcess( RenderGraph renderGraph, passData.afterPostProcessBuffer = builder.UseColorBuffer(renderGraph.CreateTexture( new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R8G8B8A8_SRGB, clearBuffer = true, clearColor = Color.black, name = "OffScreen AfterPostProcess" }), 0); if (passData.parameters.useDepthBuffer) - passData.depthStencilBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.ReadWrite); + passData.depthStencilBuffer = builder.UseDepthBuffer(prepassOutput.depthBuffer, DepthAccess.ReadWrite); passData.opaqueAfterPostprocessRL = builder.UseRendererList(renderGraph.CreateRendererList(passData.parameters.opaqueAfterPPDesc)); passData.transparentAfterPostprocessRL = builder.UseRendererList(renderGraph.CreateRendererList(passData.parameters.transparentAfterPPDesc)); @@ -60,7 +60,9 @@ TextureHandle RenderPostProcess( RenderGraph renderGraph, parameters.blueNoise, inputColor, afterPostProcessBuffer, - depthBuffer, + prepassOutput.resolvedDepthBuffer, + prepassOutput.depthPyramidTexture, + prepassOutput.resolvedMotionVectorsBuffer, dest, parameters.flipYInPostProcess ); 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 2e47a0fb08f..5f95b6e5786 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 @@ -222,7 +222,7 @@ void ExecuteWithRenderGraph( RenderRequest renderRequest, aovRequest.PushCameraTexture(m_RenderGraph, AOVBuffers.Color, hdCamera, colorBuffer, aovBuffers); - TextureHandle postProcessDest = RenderPostProcess(m_RenderGraph, colorBuffer, prepassOutput.resolvedDepthBuffer, backBuffer, cullingResults, hdCamera); + TextureHandle postProcessDest = RenderPostProcess(m_RenderGraph, prepassOutput, colorBuffer, backBuffer, cullingResults, hdCamera); // TODO RENDERGRAPH //// If requested, compute histogram of the very final image 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 6816f23eeee..ea364157343 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.cs @@ -5342,6 +5342,7 @@ void RenderPostProcess(CullingResults cullResults, HDCamera hdCamera, RenderTarg finalRT: destination, depthBuffer: m_SharedRTManager.GetDepthStencilBuffer(), depthMipChain: m_SharedRTManager.GetDepthTexture(), + motionVecTexture: m_SharedRTManager.GetMotionVectorsBuffer(), flipY: parameters.flipYInPostProcess ); }