using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using UnityEngine.Experimental.Rendering; using UnityEngine.Experimental.Rendering.RenderGraphModule; namespace UnityEngine.Rendering.Universal { /// /// Uses a compute shader to capture the depth and normal of the pixel under the cursor. /// internal partial class ProbeVolumeDebugPass : ScriptableRenderPass { ComputeShader m_ComputeShader; RTHandle m_DepthTexture; RTHandle m_NormalTexture; /// /// Creates a new ProbeVolumeDebugPass instance. /// public ProbeVolumeDebugPass(RenderPassEvent evt, ComputeShader computeShader) { base.profilingSampler = new ProfilingSampler(nameof(ProbeVolumeDebugPass)); renderPassEvent = evt; m_ComputeShader = computeShader; } public void Setup(RTHandle depthBuffer, RTHandle normalBuffer) { m_DepthTexture = depthBuffer; m_NormalTexture = normalBuffer; } /// public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (!ProbeReferenceVolume.instance.isInitialized) return; ref CameraData cameraData = ref renderingData.cameraData; if (ProbeReferenceVolume.instance.GetProbeSamplingDebugResources(cameraData.camera, out var resultBuffer, out Vector2 coords)) { OutputPositionAndNormal(renderingData.commandBuffer, m_ComputeShader, resultBuffer, coords, m_DepthTexture, m_NormalTexture); } } class WriteApvData { public ComputeShader computeShader; public BufferHandle resultBuffer; public Vector2 clickCoordinates; public TextureHandle depthBuffer; public TextureHandle normalBuffer; } /// /// Render graph entry point /// /// /// /// /// internal void Render(RenderGraph renderGraph, ref RenderingData renderingData, TextureHandle depthPyramidBuffer, TextureHandle normalBuffer) { if (!ProbeReferenceVolume.instance.isInitialized) return; ref CameraData cameraData = ref renderingData.cameraData; if (ProbeReferenceVolume.instance.GetProbeSamplingDebugResources(cameraData.camera, out var resultBuffer, out Vector2 coords)) { using (var builder = renderGraph.AddRenderPass("Debug", out var passData, base.profilingSampler)) { passData.resultBuffer = renderGraph.ImportBuffer(resultBuffer); passData.clickCoordinates = coords; passData.depthBuffer = builder.ReadTexture(depthPyramidBuffer); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.computeShader = m_ComputeShader; builder.SetRenderFunc((WriteApvData data, RenderGraphContext ctx) => { OutputPositionAndNormal(ctx.cmd, data.computeShader, data.resultBuffer, data.clickCoordinates, data.depthBuffer, data.normalBuffer); }); } } } static void OutputPositionAndNormal(CommandBuffer cmd, ComputeShader compute, GraphicsBuffer resultBuffer, Vector2 clickCoordinates, RenderTargetIdentifier depthBuffer, RenderTargetIdentifier normalBuffer) { int kernel = compute.FindKernel("ComputePositionNormal"); cmd.SetComputeTextureParam(compute, kernel, "_CameraDepthTexture", depthBuffer); cmd.SetComputeTextureParam(compute, kernel, "_NormalBufferTexture", normalBuffer); cmd.SetComputeVectorParam(compute, "_positionSS", new Vector4(clickCoordinates.x, clickCoordinates.y, 0.0f, 0.0f)); cmd.SetComputeBufferParam(compute, kernel, "_ResultBuffer", resultBuffer); cmd.DispatchCompute(compute, kernel, 1, 1, 1); } } }