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));
m_ComputeShader = computeShader;
renderPassEvent = evt;
}
///
/// Disposes used resources.
///
public void Dispose()
{
}
public void Setup(RTHandle depthBuffer, RTHandle normalBuffer)
{
m_DepthTexture = depthBuffer;
m_NormalTexture = normalBuffer;
}
public bool NeedsNormal()
{
return ProbeReferenceVolume.probeSamplingDebugData.update != ProbeSamplingDebugUpdate.Never;
}
///
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (ProbeReferenceVolume.instance.isInitialized)
{
#if UNITY_EDITOR
ref CameraData cameraData = ref renderingData.cameraData;
if (ProbeReferenceVolume.probeSamplingDebugData.camera != cameraData.camera)
return;
#endif
if (ProbeReferenceVolume.probeSamplingDebugData.update != ProbeSamplingDebugUpdate.Never)
{
var cmd = renderingData.commandBuffer;
int kernelHandle = m_ComputeShader.FindKernel("ComputePositionNormal");
cmd.SetComputeTextureParam(m_ComputeShader, kernelHandle, "_CameraDepthTexture", m_DepthTexture);
cmd.SetComputeTextureParam(m_ComputeShader, kernelHandle, "_NormalBufferTexture", m_NormalTexture);
cmd.SetComputeVectorParam(m_ComputeShader, "_positionSS", new Vector4(ProbeReferenceVolume.probeSamplingDebugData.coordinates.x, ProbeReferenceVolume.probeSamplingDebugData.coordinates.y, 0.0f, 0.0f));
cmd.SetComputeBufferParam(m_ComputeShader, kernelHandle, "_ResultBuffer", ProbeReferenceVolume.probeSamplingDebugData.positionNormalBuffer);
cmd.DispatchCompute(m_ComputeShader, kernelHandle, 1, 1, 1);
if (ProbeReferenceVolume.probeSamplingDebugData.update == ProbeSamplingDebugUpdate.Once)
{
ProbeReferenceVolume.probeSamplingDebugData.update = ProbeSamplingDebugUpdate.Never;
ProbeReferenceVolume.probeSamplingDebugData.forceScreenCenterCoordinates = false;
}
}
}
}
///
/// Render graph entry point
///
///
///
///
///
internal void Render(RenderGraph renderGraph, ref RenderingData renderingData, TextureHandle depthPyramidBuffer, TextureHandle normalBuffer)
{
if (ProbeReferenceVolume.instance.isInitialized)
{
#if UNITY_EDITOR
ref CameraData cameraData = ref renderingData.cameraData;
if (ProbeReferenceVolume.probeSamplingDebugData.camera != cameraData.camera)
return;
#endif
if (ProbeReferenceVolume.probeSamplingDebugData.update != ProbeSamplingDebugUpdate.Never)
{
WriteApvPositionNormalDebugBuffer(renderGraph, ProbeReferenceVolume.probeSamplingDebugData.positionNormalBuffer, ProbeReferenceVolume.probeSamplingDebugData.coordinates, depthPyramidBuffer, normalBuffer);
if (ProbeReferenceVolume.probeSamplingDebugData.update == ProbeSamplingDebugUpdate.Once)
{
ProbeReferenceVolume.probeSamplingDebugData.update = ProbeSamplingDebugUpdate.Never;
ProbeReferenceVolume.probeSamplingDebugData.forceScreenCenterCoordinates = false;
}
}
}
}
class WriteApvData
{
public ComputeShader computeShader;
public BufferHandle resultBuffer;
public Vector2 clickCoordinates;
public TextureHandle depthBuffer;
public TextureHandle normalBuffer;
}
// Compute worldspace position and normal at given screenspace clickCoordinates, and write it into given ResultBuffer.
void WriteApvPositionNormalDebugBuffer(RenderGraph renderGraph, GraphicsBuffer resultBuffer, Vector2 clickCoordinates, TextureHandle depthBuffer, TextureHandle normalBuffer)
{
using (var builder = renderGraph.AddRenderPass("Debug", out var passData, base.profilingSampler))
{
passData.resultBuffer = renderGraph.ImportBuffer(resultBuffer);
passData.clickCoordinates = clickCoordinates;
passData.depthBuffer = builder.ReadTexture(depthBuffer);
passData.normalBuffer = builder.ReadTexture(normalBuffer);
passData.computeShader = m_ComputeShader;
builder.SetRenderFunc(
(WriteApvData data, RenderGraphContext ctx) =>
{
int kernelHandle = data.computeShader.FindKernel("ComputePositionNormal");
ctx.cmd.SetComputeTextureParam(data.computeShader, kernelHandle, "_CameraDepthTexture", data.depthBuffer);
ctx.cmd.SetComputeTextureParam(data.computeShader, kernelHandle, "_NormalBufferTexture", data.normalBuffer);
ctx.cmd.SetComputeVectorParam(data.computeShader, "_positionSS", new Vector4(data.clickCoordinates.x, data.clickCoordinates.y, 0.0f, 0.0f));
ctx.cmd.SetComputeBufferParam(data.computeShader, kernelHandle, "_ResultBuffer", data.resultBuffer);
ctx.cmd.DispatchCompute(data.computeShader, kernelHandle, 1, 1, 1);
});
}
}
}
}