//pipelinedefine #define H_URP using HTraceWSGI.Scripts.Data.Private; using HTraceWSGI.Scripts.Extensions; using HTraceWSGI.Scripts.Extensions.CameraHistorySystem; using HTraceWSGI.Scripts.Globals; using HTraceWSGI.Scripts.Services.DirectionalShadowmap; using HTraceWSGI.Scripts.Wrappers; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; #if UNITY_2023_3_OR_NEWER using HTraceWSGI.Scripts.Services.VoxelCameras; using UnityEngine.Rendering.RendererUtils; using UnityEngine.Rendering.RenderGraphModule; #endif namespace HTraceWSGI.Scripts.Passes.URP { internal class DirectionalShadowmapPassURP : ScriptableRenderPass { private enum HShadowmapKernel { ShadowmapMerge = 0, } // Shader properties internal static readonly int g_DirLightMatrix = Shader.PropertyToID("g_DirLightMatrix"); internal static readonly int g_DirLightPlanes = Shader.PropertyToID("g_DirLightPlanes"); internal static readonly int g_HTraceShadowmap = Shader.PropertyToID("g_HTraceShadowmap"); internal static readonly int _DirectionalShadowmapStatic = Shader.PropertyToID("_DirectionalShadowmapStatic"); internal static readonly int _Shadowmap = Shader.PropertyToID("_Shadowmap"); internal static readonly int _Shadowmap_Output = Shader.PropertyToID("_Shadowmap_Output"); internal static readonly int _OctantShadowOffset = Shader.PropertyToID("_OctantShadowOffset"); // Samplers internal static readonly ProfilingSamplerHTrace s_RenderShadowmapProfilingSampler = new ProfilingSamplerHTrace("Render Shadowmap", parentName: HNames.HTRACE_SHADOWMAP_PASS_NAME, priority: 0); internal static readonly ProfilingSamplerHTrace s_RenderShadowmapDrawRendererListProfilingSampler = new ProfilingSamplerHTrace("Render Shadowmap DrawRendererList"); internal static readonly ProfilingSamplerHTrace s_MergeShadowmapStaticProfilingSampler = new ProfilingSamplerHTrace("Merge Shadowmap Static"); // Buffers & etc // Materials and Shaders internal static Material ShadowmapMaterial; //Partial internal static ComputeShader HShadowmap; //Textures internal static RTWrapper DirectionalDepthTarget = new RTWrapper(); //Partial internal static RTWrapper DirectionalDepthTargetCombined = new RTWrapper(); internal static RTWrapper DirectionalDepthTargetStatic = new RTWrapper(); internal static RTWrapper DirectionalShadowmapStatic = new RTWrapper(); internal struct HistoryData : IHistoryData { public VoxelizationUpdateMode VoxelizationUpdateMode; public void Update() { VoxelizationUpdateMode = HSettings.VoxelizationSettings.VoxelizationUpdateMode; } } internal static HistoryData History = new HistoryData(); #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) { //ResourcesRG(renderingData.cameraData.camera, renderingData.cameraData.renderScale, renderingData.cameraData.cameraTargetDescriptor); } #if UNITY_2023_3_OR_NEWER [System.Obsolete] #endif public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { ConfigureInput(ScriptableRenderPassInput.Depth); // | ScriptableRenderPassInput.Normal); } #if UNITY_2023_3_OR_NEWER [System.Obsolete] #endif public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { var cmd = CommandBufferPool.Get(HNames.HTRACE_SHADOWMAP_PASS_NAME); Camera camera = renderingData.cameraData.camera; int width = (int)(camera.scaledPixelWidth * renderingData.cameraData.renderScale); int height = (int)(camera.scaledPixelHeight * renderingData.cameraData.renderScale); DirectionalShadowmapService.Instance.DirectionalCamera.ExecuteUpdate(); switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) { case VoxelizationUpdateMode.Constant: using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) //ExecuteConstant(cmd, camera, width, height, ref renderingData.cullResults); break; case VoxelizationUpdateMode.Partial: using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) //ExecutePartial(cmd, camera, width, height); break; } History.Update(); context.ExecuteCommandBuffer(cmd); cmd.Clear(); CommandBufferPool.Release(cmd); } #endif #endregion --------------------------- Non Render Graph --------------------------- #region --------------------------- Render Graph --------------------------- #if UNITY_2023_3_OR_NEWER private class PassData { public RendererListHandle RendererListHandle; public UniversalCameraData UniversalCameraData; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_SHADOWMAP_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_SHADOWMAP_PASS_NAME))) { UniversalResourceData resourceData = frameData.Get(); UniversalCameraData universalCameraData = frameData.Get(); UniversalRenderingData universalRenderingData = frameData.Get(); UniversalLightData lightData = frameData.Get(); CullContextData cullContextData = frameData.Get(); ConfigureInput(ScriptableRenderPassInput.Depth); builder.AllowGlobalStateModification(true); builder.AllowPassCulling(true); passData.UniversalCameraData = universalCameraData; ResourcesRG(renderGraph, universalCameraData); DirectionalShadowmapService.Instance.DirectionalCamera.ExecuteUpdate(); AddRendererList(renderGraph, universalCameraData, universalRenderingData, lightData, passData, builder, cullContextData); builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); } } private static void ResourcesRG(RenderGraph renderGraph, UniversalCameraData universalCameraData) { if (ShadowmapMaterial == null) { ShadowmapMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/HTraceWSGI/ShadowmapURP")); ShadowmapMaterial.enableInstancing = true; } if (HShadowmap == null) HShadowmap = HExtensions.LoadComputeShader("Shadowmap"); int width = (int)(universalCameraData.camera.scaledPixelWidth * universalCameraData.renderScale); int height = (int)(universalCameraData.camera.scaledPixelHeight * universalCameraData.renderScale); RenderTextureDescriptor desc = universalCameraData.cameraTargetDescriptor; RenderTextureDescriptor depthDesc = universalCameraData.cameraTargetDescriptor; switch (HSettings.GeneralSettings.TracingMode) { case Globals.TracingMode.SoftwareTracing: switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) { case VoxelizationUpdateMode.Constant: desc.width = (int)HConstants.ShadowmapResolution.x; desc.height = (int)HConstants.ShadowmapResolution.y; desc.depthBufferBits = 0; // Color and depth cannot be combined in RTHandles desc.dimension = TextureDimension.Tex2D; desc.stencilFormat = GraphicsFormat.None; desc.depthStencilFormat = GraphicsFormat.None; DirectionalShadowmapStatic.ReAllocateIfNeeded("_DirectionalShadowmapStatic", ref desc, graphicsFormat: GraphicsFormat.R32_SFloat, enableRandomWrite: false); depthDesc.width = (int)HConstants.ShadowmapResolution.x; depthDesc.height = (int)HConstants.ShadowmapResolution.y; depthDesc.depthBufferBits = 32; depthDesc.colorFormat = RenderTextureFormat.Depth; DirectionalDepthTarget.ReAllocateIfNeeded(name: "_DirectionalDepthTargetCombined", ref depthDesc, enableRandomWrite: false); renderGraph.ImportTexture(DirectionalShadowmapStatic.rt); renderGraph.ImportTexture(DirectionalDepthTarget.rt); DirectionalDepthTargetStatic?.HRelease(); DirectionalDepthTargetCombined?.HRelease(); break; case VoxelizationUpdateMode.Partial: desc.width = (int)HConstants.ShadowmapResolution.x; desc.height = (int)HConstants.ShadowmapResolution.y; desc.depthBufferBits = 0; // Color and depth cannot be combined in RTHandles desc.dimension = TextureDimension.Tex2D; desc.stencilFormat = GraphicsFormat.None; desc.depthStencilFormat = GraphicsFormat.None; DirectionalShadowmapStatic.ReAllocateIfNeeded(name: "_DirectionalShadowmapStatic", ref desc, GraphicsFormat.R32_SFloat); depthDesc.width = (int)HConstants.ShadowmapResolution.x / 2; depthDesc.height = (int)HConstants.ShadowmapResolution.y / 2; depthDesc.dimension = TextureDimension.Tex2D; depthDesc.depthBufferBits = 32; depthDesc.colorFormat = RenderTextureFormat.Depth; depthDesc.useDynamicScale = false; DirectionalDepthTargetStatic.ReAllocateIfNeeded("_DirectionalDepthTargetStatic", ref depthDesc, enableRandomWrite: false); depthDesc.width = (int)HConstants.ShadowmapResolution.x; depthDesc.height = (int)HConstants.ShadowmapResolution.y; DirectionalDepthTargetCombined.ReAllocateIfNeeded("_DirectionalDepthTargetCombined", ref depthDesc, enableRandomWrite: false); renderGraph.ImportTexture(DirectionalShadowmapStatic.rt); renderGraph.ImportTexture(DirectionalDepthTargetStatic.rt); renderGraph.ImportTexture(DirectionalDepthTargetCombined.rt); DirectionalDepthTarget?.HRelease(); break; } break; } } private static void AddRendererList(RenderGraph renderGraph, UniversalCameraData universalCameraData, UniversalRenderingData universalRenderingData, UniversalLightData lightData, PassData passData, IUnsafeRenderGraphBuilder builder, CullContextData cullContextData) { LayerMask voxelizationLayer = HSettings.VoxelizationSettings.VoxelizationMask; if (HSettings.VoxelizationSettings.VoxelizationUpdateMode == VoxelizationUpdateMode.Partial) { voxelizationLayer = HSettings.VoxelizationSettings.VoxelizationMask & ~HSettings.VoxelizationSettings.DynamicObjectsMask; if (VoxelizationRuntimeData.OctantIndex == OctantIndex.DynamicObjects) voxelizationLayer = HSettings.VoxelizationSettings.VoxelizationMask & HSettings.VoxelizationSettings.DynamicObjectsMask; } SortingCriteria sortFlags = universalCameraData.defaultOpaqueSortFlags; RenderQueueRange renderQueueRange = RenderQueueRange.opaque; FilteringSettings filterSettings = new FilteringSettings(renderQueueRange, voxelizationLayer); ShaderTagId tag = new ShaderTagId("ShadowCaster"); // Create drawing settings DrawingSettings drawSettings = RenderingUtils.CreateDrawingSettings(tag, universalRenderingData, universalCameraData, lightData, sortFlags); //drawSettings.perObjectData = PerObjectData.MotionVectors; //drawSettings.overrideMaterial = materialToUse; var voxelizationCamera = VoxelizationRuntimeData.VoxelCamera.Camera; var directionalLightCamera = DirectionalShadowmapService.Instance.DirectionalCamera.GetDirectionalCamera; var maximumLODLevelBackup = QualitySettings.maximumLODLevel; var lodBiasBackup = QualitySettings.lodBias; QualitySettings.SetLODSettings(1, HSettings.VoxelizationSettings.LODMax, false); if (directionalLightCamera.TryGetCullingParameters(out ScriptableCullingParameters shadowCullingParams)) { shadowCullingParams.cullingOptions = CullingOptions.None; shadowCullingParams.isOrthographic = true; //LayerMask shadowmapLayer = HSettings.VoxelizationSettings.VoxelizationMask; LODParameters lodParameters = shadowCullingParams.lodParameters; lodParameters.cameraPosition = voxelizationCamera.transform.position; lodParameters.isOrthographic = true; lodParameters.orthoSize = 0; shadowCullingParams.lodParameters = lodParameters; shadowCullingParams.cullingMask = (uint)voxelizationLayer.value; var directionalLightCullResults = cullContextData.Cull(ref shadowCullingParams); var rendererListParameters = new RendererListParams(directionalLightCullResults, drawSettings, filterSettings); passData.RendererListHandle = renderGraph.CreateRendererList(rendererListParameters); builder.UseRendererList(passData.RendererListHandle); } QualitySettings.SetLODSettings(lodBiasBackup, maximumLODLevelBackup, false); } private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) { var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); Camera camera = data.UniversalCameraData.camera; int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) { case VoxelizationUpdateMode.Constant: using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) ExecuteConstant(cmd, camera, width, height, data); break; case VoxelizationUpdateMode.Partial: using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) ExecutePartial(cmd, camera, width, height, data); VoxelizationRuntimeData.UpdateOctantIndex(); break; } } #endif #endregion --------------------------- Render Graph --------------------------- #region --------------------------- Shared --------------------------- private static void ExecuteConstant(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight, PassData data) { var viewMatrixCached = camera.worldToCameraMatrix; var projectionMatrixCached = camera.projectionMatrix; var directionalLightCamera = DirectionalShadowmapService.Instance.DirectionalCamera.GetDirectionalCamera; cmd.SetViewProjectionMatrices(directionalLightCamera.worldToCameraMatrix, directionalLightCamera.projectionMatrix); var viewMatrix = directionalLightCamera.worldToCameraMatrix; var projectionMatrix = directionalLightCamera.projectionMatrix; projectionMatrix = GL.GetGPUProjectionMatrix(projectionMatrix, false); cmd.SetGlobalMatrix(g_DirLightMatrix, projectionMatrix * viewMatrix); cmd.SetGlobalVector(g_DirLightPlanes, new Vector2(directionalLightCamera.nearClipPlane, directionalLightCamera.farClipPlane)); // Render shadowmap cmd.SetRenderTarget(DirectionalShadowmapStatic.rt, DirectionalDepthTarget.rt); //TODO: Why we use DirectionalShadowmapStatic here? cmd.ClearRenderTarget(true, true, Color.black); cmd.DrawRendererList(data.RendererListHandle); cmd.SetGlobalTexture(g_HTraceShadowmap, DirectionalDepthTarget.rt); cmd.SetViewProjectionMatrices(viewMatrixCached, projectionMatrixCached); History.Update(); } private static void ExecutePartial(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight, PassData data) { var viewMatrixCached = camera.worldToCameraMatrix; var projectionMatrixCached = camera.projectionMatrix; var directionalLightCamera = DirectionalShadowmapService.Instance.DirectionalCamera.GetDirectionalCamera; cmd.SetViewProjectionMatrices(directionalLightCamera.worldToCameraMatrix, directionalLightCamera.projectionMatrix); var shadowmapRenderTarget = DirectionalDepthTargetStatic; ClearFlag clearDepthFlag = ClearFlag.Depth; var viewMatrix = directionalLightCamera.worldToCameraMatrix; var projectionMatrix = directionalLightCamera.projectionMatrix; projectionMatrix = GL.GetGPUProjectionMatrix(projectionMatrix, false); if ((int)VoxelizationRuntimeData.OctantIndex == 5) { cmd.SetGlobalMatrix(g_DirLightMatrix, projectionMatrix * viewMatrix); // Copy merged static depth to the final depth render target where dynamic objects will be added ShadowmapMaterial.SetTexture(_DirectionalShadowmapStatic, DirectionalShadowmapStatic.rt); CoreUtils.SetRenderTarget(cmd, DirectionalDepthTargetCombined.rt, ClearFlag.Depth, 0, CubemapFace.Unknown, -1); CoreUtils.DrawFullScreen(cmd, ShadowmapMaterial, DirectionalDepthTargetCombined.rt, DirectionalDepthTargetCombined.rt, shaderPassId: 0); shadowmapRenderTarget = DirectionalDepthTargetCombined; clearDepthFlag = ClearFlag.None; } var maximumLODLevelBackup = QualitySettings.maximumLODLevel; var lodBiasBackup = QualitySettings.lodBias; QualitySettings.SetLODSettings(1, HSettings.VoxelizationSettings.LODMax, false); // Render shadowmap CoreUtils.SetRenderTarget(cmd, shadowmapRenderTarget.rt, shadowmapRenderTarget.rt, clearDepthFlag); cmd.DrawRendererList(data.RendererListHandle); // Restore matrices and culling of the main camera QualitySettings.SetLODSettings(lodBiasBackup, maximumLODLevelBackup, false); cmd.SetViewProjectionMatrices(viewMatrixCached, projectionMatrixCached); // Merge shadowmap octants with static objects into a single texture using (new HTraceProfilingScope(cmd, s_MergeShadowmapStaticProfilingSampler)) { if ((int)VoxelizationRuntimeData.OctantIndex != 5) { Vector2 octantShadowOffset = Vector2.zero; int octantIndex = (int)VoxelizationRuntimeData.OctantIndex; if (octantIndex == 1) octantShadowOffset = new Vector2(0, HConstants.ShadowmapResolution.y / 2); if (octantIndex == 2) octantShadowOffset = new Vector2(HConstants.ShadowmapResolution.x / 2, HConstants.ShadowmapResolution.y / 2); if (octantIndex == 3) octantShadowOffset = new Vector2(0, 0); if (octantIndex == 4) octantShadowOffset = new Vector2(HConstants.ShadowmapResolution.x / 2, 0); cmd.SetComputeTextureParam(HShadowmap, (int)HShadowmapKernel.ShadowmapMerge, _Shadowmap, DirectionalDepthTargetStatic.rt); cmd.SetComputeTextureParam(HShadowmap, (int)HShadowmapKernel.ShadowmapMerge, _Shadowmap_Output, DirectionalShadowmapStatic.rt); cmd.SetComputeVectorParam(HShadowmap, _OctantShadowOffset, octantShadowOffset); cmd.DispatchCompute(HShadowmap, (int)HShadowmapKernel.ShadowmapMerge, (int)HConstants.ShadowmapResolution.x / 2 / 8, (int)HConstants.ShadowmapResolution.y / 2 / 8, 1); } } // Pass rendered shadowmap to shaders cmd.SetGlobalTexture(g_HTraceShadowmap, DirectionalDepthTargetCombined.rt); History.Update(); } protected internal void Dispose() { DirectionalDepthTargetStatic?.HRelease(); DirectionalDepthTargetCombined?.HRelease(); DirectionalShadowmapStatic?.HRelease(); DirectionalDepthTarget?.HRelease(); } #endregion --------------------------- Shared --------------------------- } }