//pipelinedefine #define H_URP using HTraceWSGI.Scripts.Data.Private; using HTraceWSGI.Scripts.Extensions; using HTraceWSGI.Scripts.Globals; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; using UnityEngine.Rendering.RendererUtils; using UnityEngine.Rendering.Universal; #if UNITY_2023_3_OR_NEWER using UnityEngine.Rendering.RenderGraphModule; #endif namespace HTraceWSGI.Scripts.Passes.URP { internal class GBufferPassURP : ScriptableRenderPass { private enum HDepthPyramidKernel { GenerateDepthPyramid_1 = 0, GenerateDepthPyramid_2 = 1, } // Texture Names private const string _Dummy = "_Dummy"; private const string _DepthPyramid = "_DepthPyramid"; private const string _DepthIntermediate_Pyramid = "_DepthIntermediate_Pyramid"; private const string _ForwardGBuffer0 = "_ForwardGBuffer0"; private const string _ForwardGBuffer1 = "_ForwardGBuffer1"; private const string _ForwardGBuffer2 = "_ForwardGBuffer2"; private const string _ForwardGBuffer3 = "_ForwardGBuffer3"; private const string _ForwardRenderLayerMask = "_ForwardRenderLayerMask"; private const string _ForwardGBufferDepth = "_ForwardGBufferDepth"; // Materials & Computes internal static ComputeShader HDepthPyramid = null; // Samplers internal static readonly ProfilingSamplerHTrace GBufferProfilingSampler = new("GBuffer", HNames.HTRACE_PRE_PASS_NAME, 0); private static readonly ProfilingSamplerHTrace DepthPyramidGenerationProfilingSampler = new ProfilingSamplerHTrace("Depth Pyramid Generation", parentName: HNames.HTRACE_PRE_PASS_NAME); // Textures internal static RTHandle Dummy; internal static RTHandle ForwardGBuffer0; internal static RTHandle ForwardGBuffer1; internal static RTHandle ForwardGBuffer2; internal static RTHandle ForwardGBuffer3; internal static RTHandle ForwardRenderLayerMask; internal static RTHandle ForwardGBufferDepth; internal static RTHandle DepthPyramidRT; internal static RTHandle DepthIntermediate_Pyramid; internal static TextureHandle DebugGBuffer0TextureRG; internal static TextureHandle DebugGBuffer1TextureRG; internal static TextureHandle DebugGBuffer2TextureRG; internal static TextureHandle DebugDepthTextureRG; internal static TextureHandle DebugColorTextureRG; // MRT Arrays internal static RenderTargetIdentifier[] GBufferMRT = null; // Misc internal static RenderStateBlock ForwardGBufferRenderStateBlock = new RenderStateBlock(RenderStateMask.Nothing); #region --------------------------- Non Render Graph --------------------------- #if !UNITY_6000_4_OR_NEWER private ScriptableRenderer _renderer; protected internal void Initialize(ScriptableRenderer renderer) { _renderer = renderer; } #if UNITY_2023_3_OR_NEWER [System.Obsolete] #endif public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { // SetupShared(renderingData.cameraData.camera, renderingData.cameraData.renderScale, renderingData.cameraData.cameraTargetDescriptor); // if (HDepthPyramid == null) HDepthPyramid = HExtensions.LoadComputeShader("HDepthPyramid"); // // int width = (int)(camera.scaledPixelWidth * renderScale); // int height = (int)(camera.scaledPixelHeight * renderScale); // // if (desc.width != width || desc.height != height) // desc = new RenderTextureDescriptor(width, height); // desc.depthBufferBits = 0; // Color and depth cannot be combined in RTHandles // desc.stencilFormat = GraphicsFormat.None; // desc.depthStencilFormat = GraphicsFormat.None; // desc.msaaSamples = 1; // desc.bindMS = false; // // var graphicsFormatRenderingLayerMask = GraphicsFormat.R8G8B8A8_UNorm; // // #if UNITY_6000_2_OR_NEWER // graphicsFormatRenderingLayerMask = GraphicsFormat.R8G8_UInt; // #endif // // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBuffer0, ref ForwardGBuffer0, ref desc, graphicsFormat: GraphicsFormat.R8G8B8A8_SRGB); // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBuffer1, ref ForwardGBuffer1, ref desc, graphicsFormat: GraphicsFormat.R8G8B8A8_UNorm); // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBuffer2, ref ForwardGBuffer2, ref desc, graphicsFormat: GraphicsFormat.R8G8B8A8_UNorm); // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBuffer3, ref ForwardGBuffer3, ref desc, graphicsFormat: GraphicsFormat.B10G11R11_UFloatPack32); // ExtensionsURP.ReAllocateIfNeeded(_ForwardRenderLayerMask, ref ForwardRenderLayerMask, ref desc, graphicsFormat: graphicsFormatRenderingLayerMask); // ExtensionsURP.ReAllocateIfNeeded(_DepthPyramid, ref DepthPyramidRT, ref desc, graphicsFormat: GraphicsFormat.R16_SFloat, useMipMap: true); // desc.width = width / 16; // desc.height = height / 16; // ExtensionsURP.ReAllocateIfNeeded(_DepthIntermediate_Pyramid, ref DepthIntermediate_Pyramid, ref desc, graphicsFormat: GraphicsFormat.R16_SFloat, useMipMap: true); // // RenderTextureDescriptor depthDesc = desc; // depthDesc.depthBufferBits = 32; // depthDesc.depthStencilFormat = GraphicsFormat.None; // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBufferDepth, ref ForwardGBufferDepth, ref depthDesc, graphicsFormat: GraphicsFormat.R16_SFloat, useMipMap: false, enableRandomWrite: false); } #if UNITY_2023_3_OR_NEWER [System.Obsolete] #endif public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { } #if UNITY_2023_3_OR_NEWER [System.Obsolete] #endif public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { Camera camera = renderingData.cameraData.camera; var cmd = CommandBufferPool.Get(HNames.HTRACE_GBUFFER_PASS_NAME); int width = (int)(camera.scaledPixelWidth * renderingData.cameraData.renderScale); int height = (int)(camera.scaledPixelHeight * renderingData.cameraData.renderScale); // Set Depth and Color to HTrace passes cmd.SetGlobalTexture(HShaderParams.g_HTraceColor, _renderer.cameraColorTargetHandle); cmd.SetGlobalTexture(HShaderParams.g_HTraceDepth, _renderer.cameraDepthTargetHandle); var nativeGBuffer0 = Shader.GetGlobalTexture(HShaderParams._GBuffer0); var nativeGBuffer1 = Shader.GetGlobalTexture(HShaderParams._GBuffer1); var nativeGBuffer2 = Shader.GetGlobalTexture(HShaderParams._GBuffer2); var renderLayerMaskTexture = Shader.GetGlobalTexture(HShaderParams._CameraRenderingLayersTexture); GBufferGenerationNonRenderGraph(cmd, width, height, nativeGBuffer0, nativeGBuffer1, nativeGBuffer2, renderLayerMaskTexture, _renderer.cameraColorTargetHandle, _renderer.cameraDepthTargetHandle, ref context, ref renderingData); using (new HTraceProfilingScope(cmd, DepthPyramidGenerationProfilingSampler)) { // Generate 0-4 mip levels cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP0, DepthPyramidRT.rt, 0); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP1, DepthPyramidRT.rt, 1); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP2, DepthPyramidRT.rt, 2); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP3, DepthPyramidRT.rt, 3); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP4, DepthPyramidRT.rt, 4); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthIntermediate_Output, DepthIntermediate_Pyramid.rt); cmd.DispatchCompute(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, Mathf.CeilToInt(width / 16.0f), Mathf.CeilToInt(height / 16.0f), TextureXR.slices); // Generate 5-7 mip levels cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthIntermediate, DepthIntermediate_Pyramid.rt); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP5, DepthPyramidRT.rt, 5); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP6, DepthPyramidRT.rt, 6); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP7, DepthPyramidRT.rt, 7); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP8, DepthPyramidRT.rt, 8); cmd.DispatchCompute(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, Mathf.CeilToInt(width / 16.0f / 8.0f), Mathf.CeilToInt(height / 16.0f / 8.0f), TextureXR.slices); cmd.SetGlobalTexture(HShaderParams.g_HTraceDepthPyramidWSGI, DepthPyramidRT.rt); } context.ExecuteCommandBuffer(cmd); cmd.Clear(); CommandBufferPool.Release(cmd); } private static void GBufferGenerationNonRenderGraph(CommandBuffer cmd, int width, int height, Texture nativeGBuffer0, Texture nativeGBuffer1, Texture nativeGBuffer2, Texture renderLayerMask, RTHandle cameraColorBuffer, RTHandle cameraDepthBuffer, ref ScriptableRenderContext context, ref RenderingData renderingData) { var camera = renderingData.cameraData.camera; using (new HTraceProfilingScope(cmd, GBufferProfilingSampler)) { // Set sky probe management SphericalHarmonicsL2 ambientProbe = RenderSettings.ambientProbe; cmd.SetGlobalVector(HShaderParams.H_SHAr, new Vector4(ambientProbe[0, 3], ambientProbe[0, 1], ambientProbe[0, 2], ambientProbe[0, 0] - ambientProbe[0, 6])); cmd.SetGlobalVector(HShaderParams.H_SHAg, new Vector4(ambientProbe[1, 3], ambientProbe[1, 1], ambientProbe[1, 2], ambientProbe[1, 0] - ambientProbe[1, 6])); cmd.SetGlobalVector(HShaderParams.H_SHAb, new Vector4(ambientProbe[2, 3], ambientProbe[2, 1], ambientProbe[2, 2], ambientProbe[2, 0] - ambientProbe[2, 6])); cmd.SetGlobalVector(HShaderParams.H_SHBr, new Vector4(ambientProbe[0, 4], ambientProbe[0, 5], ambientProbe[0, 6] * 3, ambientProbe[0, 7])); cmd.SetGlobalVector(HShaderParams.H_SHBg, new Vector4(ambientProbe[1, 4], ambientProbe[1, 5], ambientProbe[1, 6] * 3, ambientProbe[1, 7])); cmd.SetGlobalVector(HShaderParams.H_SHBb, new Vector4(ambientProbe[2, 4], ambientProbe[2, 5], ambientProbe[2, 6] * 3, ambientProbe[2, 7])); cmd.SetGlobalVector(HShaderParams.H_SHC, new Vector4(ambientProbe[0, 8], ambientProbe[1, 8], ambientProbe[2, 8], 1)); // Check if GBuffer is valid (e.g. Forward / wrong scale / is not set, etc.) bool RequestForwardGBufferRender = false; if (nativeGBuffer0 == null || nativeGBuffer1 == null || nativeGBuffer2 == null) { RequestForwardGBufferRender = true; } else if ( nativeGBuffer0.width != width || nativeGBuffer0.height != height) // CameraDepthBuffer.rtHandleProperties.currentViewportSize.x { RequestForwardGBufferRender = true; } // Set Render Layer Mask to black dummy in case it's disabled as a feature and we can't render it if (renderLayerMask == null) renderLayerMask = HRenderer.EmptyTexture;// Dummy.rt; //RequestForwardGBufferRender = true; // GBuffer can't be rendered because its resolution doesn't match the resolution of Unity's depth buffer. Happens when switching between Scene and Game windows if (ForwardGBuffer0.rt.width != cameraDepthBuffer.rt.width || ForwardGBuffer0.rt.height != cameraDepthBuffer.rt.height) { cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, ForwardGBuffer0.rt); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, ForwardGBuffer1.rt); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, ForwardGBuffer2.rt); cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, ForwardRenderLayerMask.rt); return; } // Set GBuffer to HTrace passes if valid or render it otherwise if (RequestForwardGBufferRender == false) { cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, nativeGBuffer0); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, nativeGBuffer1); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, nativeGBuffer2); cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, renderLayerMask); } else { if (HRendererURP.RenderGraphEnabled) GBufferMRT = new RenderTargetIdentifier[] { ForwardGBuffer0.rt, ForwardGBuffer1.rt, ForwardGBuffer2.rt, ForwardGBuffer3.rt, ForwardGBufferDepth.rt, ForwardRenderLayerMask.rt }; else GBufferMRT = new RenderTargetIdentifier[] { ForwardGBuffer0.rt, ForwardGBuffer1.rt, ForwardGBuffer2.rt, ForwardGBuffer3.rt, ForwardRenderLayerMask.rt }; // If CameraDepthBuffer.rt doesn't work for any reason - we can replace it with our ForwardGBufferDepth.rt, but GBuffer rendering performance will suffer. CoreUtils.SetRenderTarget(cmd, GBufferMRT, cameraDepthBuffer.rt); CoreUtils.SetKeyword(cmd, HShaderParams._GBUFFER_NORMALS_OCT, true); CoreUtils.SetKeyword(cmd, HShaderParams._WRITE_RENDERING_LAYERS, true); // ---------------------------------- Non Render Graph Version CullingResults cullingResults = renderingData.cullResults; int layerMask = camera.cullingMask; ForwardGBufferRenderStateBlock.depthState = new DepthState(false, CompareFunction.LessEqual); ForwardGBufferRenderStateBlock.mask |= RenderStateMask.Depth; var renderList = new UnityEngine.Rendering.RendererUtils.RendererListDesc(HShaderParams.UniversalGBufferTag, cullingResults, camera) { rendererConfiguration = PerObjectData.None, renderQueueRange = RenderQueueRange.opaque, sortingCriteria = SortingCriteria.OptimizeStateChanges, layerMask = layerMask, stateBlock = ForwardGBufferRenderStateBlock, }; #if UNITY_6000_3_OR_NEWER CoreUtils.DrawRendererList(cmd, context.CreateRendererList(renderList)); #else CoreUtils.DrawRendererList(context, cmd, context.CreateRendererList(renderList)); #endif cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, ForwardGBuffer0.rt); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, ForwardGBuffer1.rt); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, ForwardGBuffer2.rt); cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, ForwardRenderLayerMask.rt); } } } #endif #endregion --------------------------- Non Render Graph --------------------------- #region --------------------------- Render Graph --------------------------- #if UNITY_2023_3_OR_NEWER private class PassData { public TextureHandle[] GBufferTextures; public TextureHandle ColorTexture; public TextureHandle DepthTexture; public TextureHandle NormalsTexture; public RendererListHandle ForwardGBufferRendererListHandle; public UniversalCameraData UniversalCameraData; public TextureHandle ForwardGBuffer0Texture; public TextureHandle ForwardGBuffer1Texture; public TextureHandle ForwardGBuffer2Texture; public TextureHandle ForwardGBuffer3Texture; public TextureHandle ForwardRenderLayerMaskTexture; public TextureHandle DepthPyramidTexture; public TextureHandle DepthPyramidIntermediateTexture; public TextureHandle ForwardGBufferDepthTexture; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { DebugGBuffer0TextureRG = default(TextureHandle); DebugGBuffer1TextureRG = default(TextureHandle); DebugGBuffer2TextureRG = default(TextureHandle); DebugDepthTextureRG = default(TextureHandle); DebugColorTextureRG = default(TextureHandle); using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_GBUFFER_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_GBUFFER_PASS_NAME))) { UniversalResourceData resourceData = frameData.Get(); UniversalCameraData universalCameraData = frameData.Get(); UniversalRenderingData universalRenderingData = frameData.Get(); UniversalLightData lightData = frameData.Get(); builder.AllowGlobalStateModification(true); builder.AllowPassCulling(false); TextureHandle colorTexture = universalRenderingData.renderingMode == RenderingMode.Deferred #if UNITY_6000_1_OR_NEWER || universalRenderingData.renderingMode == RenderingMode.DeferredPlus #endif ? resourceData.activeColorTexture : resourceData.cameraColor; TextureHandle depthTexture = universalRenderingData.renderingMode == RenderingMode.Deferred #if UNITY_6000_1_OR_NEWER || universalRenderingData.renderingMode == RenderingMode.DeferredPlus #endif ? resourceData.activeDepthTexture : resourceData.cameraDepth; TextureHandle normalsTexture = resourceData.cameraNormalsTexture; builder.UseTexture(depthTexture, AccessFlags.Read); builder.UseTexture(normalsTexture, AccessFlags.Read); passData.ColorTexture = colorTexture; passData.DepthTexture = depthTexture; passData.NormalsTexture = normalsTexture; passData.UniversalCameraData = universalCameraData; passData.GBufferTextures = resourceData.gBuffer; DebugColorTextureRG = colorTexture; DebugDepthTextureRG = depthTexture; DebugGBuffer2TextureRG = normalsTexture; if (HDepthPyramid == null) HDepthPyramid = HExtensions.LoadComputeShader("HDepthPyramid"); TextureHandle colorTextureHandle = resourceData.cameraColor; TextureDesc desc = colorTextureHandle.GetDescriptor(renderGraph); desc.clearBuffer = false; TextureHandle depthTextureHandle = resourceData.cameraDepthTexture; TextureDesc descDepth = depthTextureHandle.GetDescriptor(renderGraph); descDepth.clearBuffer = false; var graphicsFormatRenderingLayerMask = GraphicsFormat.R8G8B8A8_UNorm; #if UNITY_6000_2_OR_NEWER graphicsFormatRenderingLayerMask = GraphicsFormat.R8G8_UInt; #endif passData.ForwardGBuffer0Texture = ExtensionsURP.CreateTexture(_ForwardGBuffer0, renderGraph, ref desc, format: GraphicsFormat.R8G8B8A8_SRGB); builder.UseTexture(passData.ForwardGBuffer0Texture, AccessFlags.Write); passData.ForwardGBuffer1Texture = ExtensionsURP.CreateTexture(_ForwardGBuffer1, renderGraph, ref desc, format: GraphicsFormat.R8G8B8A8_UNorm); builder.UseTexture(passData.ForwardGBuffer1Texture, AccessFlags.Write); passData.ForwardGBuffer2Texture = ExtensionsURP.CreateTexture(_ForwardGBuffer2, renderGraph, ref desc, format: GraphicsFormat.R8G8B8A8_SNorm); builder.UseTexture(passData.ForwardGBuffer2Texture, AccessFlags.Write); passData.ForwardGBuffer3Texture = ExtensionsURP.CreateTexture(_ForwardGBuffer3, renderGraph, ref desc, format: GraphicsFormat.B10G11R11_UFloatPack32); builder.UseTexture(passData.ForwardGBuffer3Texture, AccessFlags.Write); passData.ForwardRenderLayerMaskTexture = ExtensionsURP.CreateTexture(_ForwardRenderLayerMask, renderGraph, ref desc, format: graphicsFormatRenderingLayerMask); builder.UseTexture(passData.ForwardRenderLayerMaskTexture, AccessFlags.Write); passData.DepthPyramidTexture = ExtensionsURP.CreateTexture(_DepthPyramid, renderGraph, ref desc, format: GraphicsFormat.R16_SFloat, useMipMap: true); builder.UseTexture(passData.DepthPyramidTexture, AccessFlags.Write); desc.width /= 16; desc.height /= 16; passData.DepthPyramidIntermediateTexture = ExtensionsURP.CreateTexture(_DepthIntermediate_Pyramid, renderGraph, ref desc, format: GraphicsFormat.R16_SFloat, useMipMap: true); builder.UseTexture(passData.DepthPyramidIntermediateTexture, AccessFlags.Write); passData.ForwardGBufferDepthTexture = ExtensionsURP.CreateTexture(_ForwardGBufferDepth, renderGraph, ref descDepth, format: GraphicsFormat.R16_SFloat, useMipMap: false, enableRandomWrite: false); builder.UseTexture(passData.ForwardGBufferDepthTexture, AccessFlags.Write); bool useNativeDeferredGBuffer = universalRenderingData.renderingMode == RenderingMode.Deferred #if UNITY_6000_1_OR_NEWER || universalRenderingData.renderingMode == RenderingMode.DeferredPlus #endif ; DebugGBuffer0TextureRG = useNativeDeferredGBuffer ? resourceData.gBuffer[0] : passData.ForwardGBuffer0Texture; DebugGBuffer1TextureRG = useNativeDeferredGBuffer ? resourceData.gBuffer[1] : passData.ForwardGBuffer1Texture; if (useNativeDeferredGBuffer) { builder.UseTexture(resourceData.gBuffer[0], AccessFlags.Read); builder.UseTexture(resourceData.gBuffer[1], AccessFlags.Read); builder.UseTexture(resourceData.gBuffer[2], AccessFlags.Read); builder.UseTexture(resourceData.gBuffer[3], AccessFlags.Read); if (resourceData.gBuffer.Length >= 6 && resourceData.gBuffer[5].IsValid()) builder.UseTexture(resourceData.gBuffer[5], AccessFlags.Read); } CullingResults cullingResults = universalRenderingData.cullResults; ShaderTagId tags = new ShaderTagId("UniversalGBuffer"); int layerMask = universalCameraData.camera.cullingMask; ForwardGBufferRenderStateBlock.depthState = new DepthState(false, CompareFunction.LessEqual); ForwardGBufferRenderStateBlock.mask |= RenderStateMask.Depth; RendererListDesc rendererListDesc = new RendererListDesc(tags, cullingResults, universalCameraData.camera) { rendererConfiguration = PerObjectData.None, renderQueueRange = RenderQueueRange.opaque, sortingCriteria = SortingCriteria.OptimizeStateChanges, layerMask = layerMask, stateBlock = ForwardGBufferRenderStateBlock, }; passData.ForwardGBufferRendererListHandle = renderGraph.CreateRendererList(rendererListDesc); builder.UseRendererList(passData.ForwardGBufferRendererListHandle); builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); } } private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) { var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); // Set Depth and Color to HTrace passes cmd.SetGlobalTexture(HShaderParams.g_HTraceColor, data.ColorTexture); cmd.SetGlobalTexture(HShaderParams.g_HTraceDepth, data.DepthTexture); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, data.NormalsTexture); var nativeGBuffer0 = data.GBufferTextures[0]; var nativeGBuffer1 = data.GBufferTextures[1]; var nativeGBuffer2 = data.GBufferTextures[2]; Texture renderLayerMaskTexture = data.GBufferTextures.Length >= 6 ? data.GBufferTextures[5] : null; GBufferGenerationRenderGraph(cmd, data, width, height, nativeGBuffer0, nativeGBuffer1, nativeGBuffer2, renderLayerMaskTexture, data.ColorTexture,data.DepthTexture, data.ForwardGBufferRendererListHandle); using (new HTraceProfilingScope(cmd, DepthPyramidGenerationProfilingSampler)) { // Generate 0-4 mip levels cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP0, data.DepthPyramidTexture, 0); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP1, data.DepthPyramidTexture, 1); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP2, data.DepthPyramidTexture, 2); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP3, data.DepthPyramidTexture, 3); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP4, data.DepthPyramidTexture, 4); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthIntermediate_Output, data.DepthPyramidIntermediateTexture); cmd.DispatchCompute(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, Mathf.CeilToInt(width / 16.0f), Mathf.CeilToInt(height / 16.0f), TextureXR.slices); // Generate 5-7 mip levels cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthIntermediate, data.DepthPyramidIntermediateTexture); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP5, data.DepthPyramidTexture, 5); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP6, data.DepthPyramidTexture, 6); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP7, data.DepthPyramidTexture, 7); cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP8, data.DepthPyramidTexture, 8); cmd.DispatchCompute(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, Mathf.CeilToInt(width / 16.0f / 8.0f), Mathf.CeilToInt(height / 16.0f / 8.0f), TextureXR.slices); cmd.SetGlobalTexture(HShaderParams.g_HTraceDepthPyramidWSGI, data.DepthPyramidTexture); } } private static void GBufferGenerationRenderGraph(CommandBuffer cmd, PassData data, int width, int height, Texture nativeGBuffer0, Texture nativeGBuffer1, Texture nativeGBuffer2, Texture renderLayerMask, RTHandle cameraColorBuffer, RTHandle cameraDepthBuffer, RendererListHandle forwardGBufferRendererListHandle) { using (new HTraceProfilingScope(cmd, GBufferProfilingSampler)) { // Sky probe management SphericalHarmonicsL2 ambientProbe = RenderSettings.ambientProbe; cmd.SetGlobalVector(HShaderParams.H_SHAr, new Vector4(ambientProbe[0, 3], ambientProbe[0, 1], ambientProbe[0, 2], ambientProbe[0, 0] - ambientProbe[0, 6])); cmd.SetGlobalVector(HShaderParams.H_SHAg, new Vector4(ambientProbe[1, 3], ambientProbe[1, 1], ambientProbe[1, 2], ambientProbe[1, 0] - ambientProbe[1, 6])); cmd.SetGlobalVector(HShaderParams.H_SHAb, new Vector4(ambientProbe[2, 3], ambientProbe[2, 1], ambientProbe[2, 2], ambientProbe[2, 0] - ambientProbe[2, 6])); cmd.SetGlobalVector(HShaderParams.H_SHBr, new Vector4(ambientProbe[0, 4], ambientProbe[0, 5], ambientProbe[0, 6] * 3, ambientProbe[0, 7])); cmd.SetGlobalVector(HShaderParams.H_SHBg, new Vector4(ambientProbe[1, 4], ambientProbe[1, 5], ambientProbe[1, 6] * 3, ambientProbe[1, 7])); cmd.SetGlobalVector(HShaderParams.H_SHBb, new Vector4(ambientProbe[2, 4], ambientProbe[2, 5], ambientProbe[2, 6] * 3, ambientProbe[2, 7])); cmd.SetGlobalVector(HShaderParams.H_SHC, new Vector4(ambientProbe[0, 8], ambientProbe[1, 8], ambientProbe[2, 8], 1)); // Check if GBuffer is valid (e.g. Forward / wrong scale / is not set, etc.) bool requestForwardGBufferRender = false; if (nativeGBuffer0 == null || nativeGBuffer1 == null || nativeGBuffer2 == null) { requestForwardGBufferRender = true; } else if ( nativeGBuffer0.width != width || nativeGBuffer0.height != height) // CameraDepthBuffer.rtHandleProperties.currentViewportSize.x { requestForwardGBufferRender = true; } // Set Render Layer Mask to black dummy in case it's disabled as a feature and we can't render it if (renderLayerMask == null) renderLayerMask = HRenderer.EmptyTexture;// Dummy.rt; // RequestForwardGBufferRender = true; // GBuffer can't be rendered because its resolution doesn't match the resolution of Unity's depth buffer. Happens when switching between Scene and Game windows // NOT actual in new RG allocation? // if (data.ForwardGBuffer0Texture.width != cameraDepthBuffer.rt.width || ForwardGBuffer0.rt.height != cameraDepthBuffer.rt.height) // { // cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, ForwardGBuffer0.rt); // cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, ForwardGBuffer1.rt); // cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, ForwardGBuffer2.rt); // cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, ForwardRenderLayerMask.rt); // return; // } // Set GBuffer to HTrace passes if valid or render it otherwise if (requestForwardGBufferRender == false) { cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, nativeGBuffer0); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, nativeGBuffer1); cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, renderLayerMask); } else { if (HRendererURP.RenderGraphEnabled) GBufferMRT = new RenderTargetIdentifier[] { data.ForwardGBuffer0Texture, data.ForwardGBuffer1Texture, data.ForwardGBuffer2Texture, data.ForwardGBuffer3Texture, data.ForwardGBufferDepthTexture, data.ForwardRenderLayerMaskTexture }; else GBufferMRT = new RenderTargetIdentifier[] { data.ForwardGBuffer0Texture, data.ForwardGBuffer1Texture, data.ForwardGBuffer2Texture, data.ForwardGBuffer3Texture, data.ForwardRenderLayerMaskTexture }; // If CameraDepthBuffer.rt doesn't work for any reason - we can replace it with our ForwardGBufferDepth.rt, but GBuffer rendering performance will suffer. CoreUtils.SetRenderTarget(cmd, GBufferMRT, cameraDepthBuffer.rt, ClearFlag.Color); bool gbufferNormalsOctKeywordState = Shader.IsKeywordEnabled(HShaderParams._GBUFFER_NORMALS_OCT); bool renderLayerKeywordState = Shader.IsKeywordEnabled(HShaderParams._WRITE_RENDERING_LAYERS); CoreUtils.SetKeyword(cmd, HShaderParams._GBUFFER_NORMALS_OCT, true); CoreUtils.SetKeyword(cmd, HShaderParams._WRITE_RENDERING_LAYERS, true); // ---------------------------------- Render Graph Version cmd.DrawRendererList(forwardGBufferRendererListHandle); CoreUtils.SetKeyword(cmd, HShaderParams._GBUFFER_NORMALS_OCT, gbufferNormalsOctKeywordState); CoreUtils.SetKeyword(cmd, HShaderParams._WRITE_RENDERING_LAYERS, renderLayerKeywordState); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, data.ForwardGBuffer0Texture); cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, data.ForwardGBuffer1Texture); cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, data.ForwardRenderLayerMaskTexture); } } } #endif #endregion --------------------------- Render Graph --------------------------- #region --------------------------- Shared --------------------------- protected internal void Dispose() { Dummy?.Release(); ForwardGBuffer0?.Release(); ForwardGBuffer1?.Release(); ForwardGBuffer2?.Release(); ForwardGBuffer3?.Release(); ForwardRenderLayerMask?.Release(); ForwardGBufferDepth?.Release(); DepthPyramidRT?.Release(); } #endregion --------------------------- Shared --------------------------- } }