Streamingle_URP/Assets/External/HTraceWSGI/Scripts/Passes/URP/DirectionalShadowmapPassURP.cs

431 lines
19 KiB
C#

//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<PassData>(HNames.HTRACE_SHADOWMAP_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_SHADOWMAP_PASS_NAME)))
{
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
UniversalCameraData universalCameraData = frameData.Get<UniversalCameraData>();
UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
UniversalLightData lightData = frameData.Get<UniversalLightData>();
CullContextData cullContextData = frameData.Get<CullContextData>();
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 ---------------------------
}
}