421 lines
21 KiB
C#

//pipelinedefine
#define H_URP
using HTraceWSGI.Scripts.Data.Private;
using HTraceWSGI.Scripts.Extensions;
using HTraceWSGI.Scripts.Globals;
using HTraceWSGI.Scripts.Passes.Shared;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
#if UNITY_2023_3_OR_NEWER
using UnityEngine.Rendering.RenderGraphModule;
#endif
namespace HTraceWSGI.Scripts.Passes.URP
{
internal class FinalPassURP : ScriptableRenderPass
{
const string _OutputTarget = "_OutputTarget";
private static string s_motionVectorsKeyword = "MOTION_VECTORS";
// Shader properties
private static readonly int AmbientOcclusionParam = Shader.PropertyToID("_AmbientOcclusionParam");
private static readonly int DebugSwitch = Shader.PropertyToID("_DebugSwitch");
private static readonly int BuffersSwitch = Shader.PropertyToID("_BuffersSwitch");
private static readonly int Debug_Output = Shader.PropertyToID("_Debug_Output");
internal static ComputeShader VoxelVisualization;
internal static Material VoxelVisualizationMaterial;
internal static ComputeShader HLightCluster;
internal static Material LightClusterVisualizationMaterial;
// Buffers & etc
internal static ComputeShader HDebug = null;
// Textures
internal static RTHandle OutputTarget;
private static void SetUrpAdditionalLightShadowKeywords(ComputeShader ComputeShader)
{
if (ComputeShader == null)
return;
bool UseAdditionalLightShadows = HSettings.LightingSettings.EvaluatePunctualLights && HRendererURP.UrpAsset != null && HRendererURP.UrpAsset.supportsAdditionalLightShadows;
if (UseAdditionalLightShadows)
ComputeShader.EnableKeyword(VoxelizationShared.ADDITIONAL_LIGHT_SHADOWS);
else
ComputeShader.DisableKeyword(VoxelizationShared.ADDITIONAL_LIGHT_SHADOWS);
}
#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 (HDebug == null) HDebug = HExtensions.LoadComputeShader("HDebug");
//
// 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;
// desc.enableRandomWrite = true;
//
// ExtensionsURP.ReAllocateIfNeeded(_OutputTarget, ref OutputTarget, ref desc);
}
#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_FINAL_PASS_NAME);
int width = (int)(camera.scaledPixelWidth * renderingData.cameraData.renderScale);
int height = (int)(camera.scaledPixelHeight * renderingData.cameraData.renderScale);
if (DebugModule(cmd, width, height, OutputTarget))
return;
Blitter.BlitCameraTexture(cmd, OutputTarget, _renderer.cameraColorTargetHandle);
context.ExecuteCommandBuffer(cmd);
cmd.Clear();
CommandBufferPool.Release(cmd);
}
#endif
#endregion --------------------------- Non Render Graph ---------------------------
#region --------------------------- Render Graph ---------------------------
#if UNITY_2023_3_OR_NEWER
private class VoxelVisPassData
{
public UniversalCameraData UniversalCameraData;
public TextureHandle VoxelVisualizationRayDirections;
public TextureHandle VoxelVisualizationDebugOutput;
}
private class LightClusterVisPassData
{
public UniversalCameraData UniversalCameraData;
public TextureHandle LightClusterDebugColor;
public TextureHandle LightClusterDebugDepth;
}
private class DebugPassData
{
public TextureHandle ColorTexture;
public TextureHandle DebugColorTexture;
public TextureHandle DebugDepthTexture;
public TextureHandle DebugGBuffer0Texture;
public TextureHandle DebugGBuffer1Texture;
public TextureHandle DebugGBuffer2Texture;
public TextureHandle DebugMotionVectorsTexture;
public TextureHandle DebugMotionMaskTexture;
public UniversalCameraData UniversalCameraData;
public TextureHandle OutputTarget;
}
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedLighting || HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedColor)
{
using (var builder = renderGraph.AddUnsafePass<VoxelVisPassData>(HNames.HTRACE_VOXEL_VISUALIZATION_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_VOXEL_VISUALIZATION_PASS_NAME)))
{
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
UniversalCameraData universalCameraData = frameData.Get<UniversalCameraData>();
UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
UniversalLightData lightData = frameData.Get<UniversalLightData>();
builder.AllowGlobalStateModification(true);
builder.AllowPassCulling(false);
passData.UniversalCameraData = universalCameraData;
TextureHandle colorTextureHandle = resourceData.activeColorTexture;
TextureDesc textureDesc = colorTextureHandle.GetDescriptor(renderGraph);
textureDesc.colorFormat = GraphicsFormat.R16G16B16A16_SFloat;
textureDesc.name = "_VoxelVisualizationRayDirections";
passData.VoxelVisualizationRayDirections = renderGraph.CreateTexture(textureDesc);
builder.UseTexture(passData.VoxelVisualizationRayDirections, AccessFlags.ReadWrite);
textureDesc.colorFormat = GraphicsFormat.R32G32B32A32_SFloat;
textureDesc.name = "_VoxelVisualizationDebugOutput";
textureDesc.enableRandomWrite = true;
passData.VoxelVisualizationDebugOutput = renderGraph.CreateTexture(textureDesc);
builder.UseTexture(passData.VoxelVisualizationDebugOutput, AccessFlags.ReadWrite);
if (VoxelVisualization == null) VoxelVisualization = HExtensions.LoadComputeShader("VoxelVisualization");
if (VoxelVisualizationMaterial == null) VoxelVisualizationMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/HTraceWSGI/VoxelVisualizationURP"));
builder.SetRenderFunc((VoxelVisPassData data, UnsafeGraphContext context) =>
{
var cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.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);
// Disable visualization keywords by default
VoxelVisualization.EnableKeyword(VoxelizationShared.VISUALIZE_OFF); VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_LIGHTING); VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_COLOR);
if (HSettings.LightingSettings.EvaluatePunctualLights) VoxelVisualization.EnableKeyword(VoxelizationShared.EVALUATE_PUNCTUAL_LIGHTS);
else VoxelVisualization.DisableKeyword(VoxelizationShared.EVALUATE_PUNCTUAL_LIGHTS);
SetUrpAdditionalLightShadowKeywords(VoxelVisualization);
using (new HTraceProfilingScope(cmd, VoxelizationShared.s_VisualizeVoxelsProfilingSampler))
{
if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedLighting)
{VoxelizationShared.VoxelVisualization.EnableKeyword(VoxelizationShared.VISUALIZE_LIGHTING); VoxelizationShared.VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_COLOR); VoxelizationShared.VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_OFF);}
if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedColor)
{VoxelizationShared.VoxelVisualization.EnableKeyword(VoxelizationShared.VISUALIZE_COLOR); VoxelizationShared.VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_LIGHTING); VoxelizationShared.VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_OFF);}
Vector2Int runningRes = new Vector2Int(width, height);
Vector2 probeAtlasRes = runningRes * Vector2.one / HSettings.GeneralSettings.RayCountMode.ParseToProbeSize() * HConstants.OCTAHEDRAL_SIZE;
//Dispatch resolutions
int fullResX_8 = Mathf.CeilToInt((float)runningRes.x / 8);
int fullResY_8 = Mathf.CeilToInt((float)runningRes.y / 8);
// Calculate rays in camera frustum
// var debugCameraFrustum = HMath.ComputeFrustumCorners(camera);
// // Interpolate rays in vf shader
// CoreUtils.SetRenderTarget(cmd, data.VoxelVisualizationRayDirections);
// VoxelVisualizationMaterial.SetMatrix(HShaderParams._DebugCameraFrustum, debugCameraFrustum);
// CoreUtils.DrawFullScreen(cmd, VoxelVisualizationMaterial, VoxelizationShared.VoxelVisualizationRayDirections.rt, shaderPassId: 0);
// Trace into voxels for debug
cmd.SetComputeTextureParam(VoxelVisualization, (int)VoxelizationShared.VoxelVisualizationKernel.VisualizeVoxels, HShaderParams._DebugRayDirection, data.VoxelVisualizationRayDirections);
cmd.SetComputeTextureParam(VoxelVisualization, (int)VoxelizationShared.VoxelVisualizationKernel.VisualizeVoxels, HShaderParams._Visualization_Output, data.VoxelVisualizationDebugOutput);
cmd.SetComputeIntParam(VoxelVisualization, HShaderParams._MultibounceMode, (int)HSettings.GeneralSettings.Multibounce);
cmd.DispatchCompute(VoxelVisualization, (int)VoxelizationShared.VoxelVisualizationKernel.VisualizeVoxels, fullResX_8, fullResY_8, TextureXR.slices);
cmd.SetGlobalTexture(HShaderParams.g_HTraceBufferGI, data.VoxelVisualizationDebugOutput);
}
});
}
}
if (HSettings.LightingSettings.EvaluatePunctualLights && (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.LightClusterColor || HSettings.GeneralSettings.DebugModeWS == DebugModeWS.LightClusterHeatmap))
{
using (var builder = renderGraph.AddUnsafePass<LightClusterVisPassData>(HNames.HTRACE_LIGHT_CLUSTER_VISUALIZATION_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_LIGHT_CLUSTER_VISUALIZATION_PASS_NAME)))
{
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
UniversalCameraData universalCameraData = frameData.Get<UniversalCameraData>();
builder.AllowGlobalStateModification(true);
builder.AllowPassCulling(false);
passData.UniversalCameraData = universalCameraData;
TextureHandle colorTextureHandle = resourceData.activeColorTexture;
TextureDesc textureDesc = colorTextureHandle.GetDescriptor(renderGraph);
textureDesc.clearBuffer = false;
passData.LightClusterDebugColor = ExtensionsURP.CreateTexture("_LightClusterDebugColor", renderGraph, ref textureDesc, GraphicsFormat.R16G16B16A16_SFloat);
builder.UseTexture(passData.LightClusterDebugColor, AccessFlags.ReadWrite);
// Match the dedicated sampleable debug target used by the shared/HDRP path
// instead of inheriting the camera depth texture descriptor.
passData.LightClusterDebugDepth = ExtensionsURP.CreateTexture("_LightClusterDebugDepth", renderGraph, ref textureDesc, GraphicsFormat.R8_UNorm,
depthBufferBits: DepthBits.Depth32, enableRandomWrite: false);
builder.UseTexture(passData.LightClusterDebugDepth, AccessFlags.ReadWrite);
if (HLightCluster == null) HLightCluster = HExtensions.LoadComputeShader($"HLightClusterURP", HRenderPipeline.URP);;
if (LightClusterVisualizationMaterial == null) LightClusterVisualizationMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/HTraceWSGI/LightClusterVisualizationURP"));
builder.SetRenderFunc((LightClusterVisPassData data, UnsafeGraphContext context) =>
{
var cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.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);
if (HSettings.LightingSettings.EvaluatePunctualLights == true)
{
// Draw 2D debug light cluster view on visible surfaces
cmd.SetComputeTextureParam(HLightCluster, (int)LightClusterShared.LightClusterKernels.DebugLightCluster, LightClusterShared._LightClusterDebug_Output, passData.LightClusterDebugColor);
cmd.DispatchCompute(HLightCluster, (int)LightClusterShared.LightClusterKernels.DebugLightCluster, Mathf.CeilToInt(width / 8.0f), Mathf.CeilToInt(height / 8.0f), TextureXR.slices);
}
if (HSettings.LightingSettings.EvaluatePunctualLights && HSettings.GeneralSettings.VolumetricDebug)
{
// Find all edge cells relative to each light's radius
cmd.DispatchCompute(HLightCluster, (int)LightClusterShared.LightClusterKernels.FillLightClusterDebugBuffer, HSettings.LightingSettings.LightClusterCellDensity / 4, HSettings.LightingSettings.LightClusterCellDensity / 4, HSettings.LightingSettings.LightClusterCellDensity / 4);
LightClusterVisualizationMaterial.SetTexture(LightClusterShared._LightClusterDebugColor, passData.LightClusterDebugColor);
LightClusterVisualizationMaterial.SetTexture(LightClusterShared._LightClusterDebugDepth, passData.LightClusterDebugDepth);
// Set our own Color and Depth render targets
CoreUtils.SetRenderTarget(cmd, passData.LightClusterDebugColor, passData.LightClusterDebugDepth, ClearFlag.Depth, Color.clear,
0, CubemapFace.Unknown, -1);
// Draw cubes first to Color and then to Depth
cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 0, MeshTopology.Triangles, 36,
HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity);
cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 1, MeshTopology.Triangles, 36,
HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity);
// Set only Color
CoreUtils.SetRenderTarget(cmd, passData.LightClusterDebugColor, ClearFlag.None);
// Draw lines testing against the Depth filled by Cubes
cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 2, MeshTopology.Lines, 48,
HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity);
}
cmd.SetGlobalTexture(HShaderParams.g_LightClusterDebug, passData.LightClusterDebugColor);
});
}
}
using (var builder = renderGraph.AddUnsafePass<DebugPassData>(HNames.HTRACE_FINAL_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_FINAL_PASS_NAME)))
{
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
UniversalCameraData universalCameraData = frameData.Get<UniversalCameraData>();
UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
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;
passData.ColorTexture = colorTexture;
passData.DebugColorTexture = GBufferPassURP.DebugColorTextureRG;
passData.DebugDepthTexture = GBufferPassURP.DebugDepthTextureRG;
passData.DebugGBuffer0Texture = GBufferPassURP.DebugGBuffer0TextureRG;
passData.DebugGBuffer1Texture = GBufferPassURP.DebugGBuffer1TextureRG;
passData.DebugGBuffer2Texture = GBufferPassURP.DebugGBuffer2TextureRG;
passData.DebugMotionVectorsTexture = MotionVectorsPassURP.DebugMotionVectorsTextureRG;
passData.DebugMotionMaskTexture = MotionVectorsPassURP.DebugMotionMaskTextureRG;
passData.UniversalCameraData = universalCameraData;
if (passData.DebugColorTexture.IsValid()) builder.UseTexture(passData.DebugColorTexture, AccessFlags.Read);
if (passData.DebugDepthTexture.IsValid()) builder.UseTexture(passData.DebugDepthTexture, AccessFlags.Read);
if (passData.DebugGBuffer0Texture.IsValid()) builder.UseTexture(passData.DebugGBuffer0Texture, AccessFlags.Read);
if (passData.DebugGBuffer1Texture.IsValid()) builder.UseTexture(passData.DebugGBuffer1Texture, AccessFlags.Read);
if (passData.DebugGBuffer2Texture.IsValid()) builder.UseTexture(passData.DebugGBuffer2Texture, AccessFlags.Read);
if (passData.DebugMotionVectorsTexture.IsValid()) builder.UseTexture(passData.DebugMotionVectorsTexture, AccessFlags.Read);
if (passData.DebugMotionMaskTexture.IsValid()) builder.UseTexture(passData.DebugMotionMaskTexture, AccessFlags.Read);
if (HDebug == null) HDebug = HExtensions.LoadComputeShader("HDebug");
TextureHandle colorTextureHandle = resourceData.cameraColor;
TextureDesc desc = colorTextureHandle.GetDescriptor(renderGraph);
desc.colorFormat = GraphicsFormat.R16G16B16A16_SFloat;
desc.clearBuffer = false;
desc.name = _OutputTarget;
desc.enableRandomWrite = true;
passData.OutputTarget = renderGraph.CreateTexture(desc);
builder.UseTexture(passData.OutputTarget, AccessFlags.ReadWrite);
builder.SetRenderFunc((DebugPassData data, UnsafeGraphContext context) => ExecutePass(data, context));
}
}
private static void ExecutePass(DebugPassData 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);
if (data.DebugColorTexture.IsValid())
cmd.SetGlobalTexture(HShaderParams.g_HTraceColor, data.DebugColorTexture);
if (data.DebugDepthTexture.IsValid())
cmd.SetGlobalTexture(HShaderParams.g_HTraceDepth, data.DebugDepthTexture);
if (data.DebugGBuffer0Texture.IsValid())
cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, data.DebugGBuffer0Texture);
if (data.DebugGBuffer1Texture.IsValid())
cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, data.DebugGBuffer1Texture);
if (data.DebugGBuffer2Texture.IsValid())
cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, data.DebugGBuffer2Texture);
if (data.DebugMotionVectorsTexture.IsValid())
cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionVectors, data.DebugMotionVectorsTexture);
if (data.DebugMotionMaskTexture.IsValid())
cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionMask, data.DebugMotionMaskTexture);
if (DebugModule(cmd, width, height, data.OutputTarget))
return;
Blitter.BlitCameraTexture(cmd, data.OutputTarget, data.ColorTexture);
}
#endif
#endregion --------------------------- Render Graph ---------------------------
#region --------------------------- Shared ---------------------------
private static bool DebugModule(CommandBuffer cmd, int width, int height, RTHandle outputTarget)
{
if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.None || HSettings.GeneralSettings.DebugModeWS == DebugModeWS.DirectLighting)
return true;
using (new HTraceProfilingScope(cmd, new ProfilingSamplerHTrace("Debug")))
{
cmd.SetComputeIntParams(HDebug, DebugSwitch, (int)HSettings.GeneralSettings.DebugModeWS);
cmd.SetComputeIntParams(HDebug, BuffersSwitch, (int)HSettings.GeneralSettings.HBuffer);
int debug_kernel = 0;
cmd.SetComputeTextureParam(HDebug, debug_kernel, Debug_Output, outputTarget.rt);
cmd.DispatchCompute(HDebug, debug_kernel, Mathf.CeilToInt(width / 8.0f), Mathf.CeilToInt(height / 8.0f), HRenderer.TextureXrSlices);
}
return false;
}
protected internal void Dispose()
{
Object.DestroyImmediate(LightClusterVisualizationMaterial);
//HLightCluster
}
#endregion --------------------------- Shared ---------------------------
}
}