Added reading of depth independent of mode
- Added writing distances in buffer in RenderDepth.shader - Added reading distances directly from render pass in DepthRenderPassFeature.cs - Added example depth reading in DepthTester.cs
This commit is contained in:
parent
a2f9328f5f
commit
0749c2fbe7
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
@ -8,24 +9,36 @@ using UnityEngine.XR;
|
||||
|
||||
public class DepthRenderPassFeature : ScriptableRendererFeature
|
||||
{
|
||||
class DepthRenderPass : ScriptableRenderPass
|
||||
private static Dictionary<int, Queue<TaskCompletionSource<float[]>>> m_PendingRequests = new();
|
||||
|
||||
internal class DepthRenderPass : ScriptableRenderPass
|
||||
{
|
||||
public static Action<float[]> OnDepthReady;
|
||||
public static Queue<bool> Requests;
|
||||
public static Queue<float[]> Answers;
|
||||
public static Task<float[]> RequestDepthDataAsync(int id)
|
||||
{
|
||||
if(m_PendingRequests == null)
|
||||
m_PendingRequests = new Dictionary<int, Queue<TaskCompletionSource<float[]>>>();
|
||||
|
||||
var tcs = new TaskCompletionSource<float[]>();
|
||||
int key = id;
|
||||
if (!m_PendingRequests.TryGetValue(key, out var queue))
|
||||
{
|
||||
queue = new Queue<TaskCompletionSource<float[]>>();
|
||||
m_PendingRequests.Add(key, queue);
|
||||
}
|
||||
queue.Enqueue(tcs);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
ProfilingSampler m_ProfilingSampler = new ProfilingSampler("ColorBlit");
|
||||
private Material material;
|
||||
private RTHandle rtHandle;
|
||||
private RTHandle copyRtHandle;
|
||||
private bool depth = false;
|
||||
private ComputeBuffer computeBuffer;
|
||||
|
||||
public DepthRenderPass(Material material)
|
||||
{
|
||||
this.material = material;
|
||||
|
||||
Requests = new Queue<bool>();
|
||||
Answers = new Queue<float[]>();
|
||||
}
|
||||
|
||||
public void SetTarget(RTHandle handle, bool depth)
|
||||
@ -48,6 +61,8 @@ public class DepthRenderPassFeature : ScriptableRendererFeature
|
||||
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
ConfigureTarget(rtHandle);
|
||||
var desc = renderingData.cameraData.cameraTargetDescriptor;
|
||||
RenderingUtils.ReAllocateIfNeeded(ref copyRtHandle, desc, FilterMode.Bilinear, TextureWrapMode.Clamp);
|
||||
}
|
||||
|
||||
// Here you can implement the rendering logic.
|
||||
@ -57,22 +72,31 @@ public class DepthRenderPassFeature : ScriptableRendererFeature
|
||||
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
//RTHandle rt = renderingData.cameraData.renderer.cameraColorTargetHandle;
|
||||
|
||||
using (new ProfilingScope(cmd, m_ProfilingSampler))
|
||||
{
|
||||
Blitter.BlitCameraTexture(cmd, rtHandle, rtHandle, material, 0);
|
||||
if(Requests.Count > 0)
|
||||
{
|
||||
Requests.Dequeue();
|
||||
float[] resultArray = new float[computeBuffer.count];
|
||||
computeBuffer.GetData(resultArray);
|
||||
Answers.Enqueue(resultArray);
|
||||
}
|
||||
}
|
||||
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
|
||||
lock(m_PendingRequests)
|
||||
{
|
||||
if (m_PendingRequests.Count > 0)
|
||||
{
|
||||
int key = renderingData.cameraData.camera.GetInstanceID();
|
||||
if (m_PendingRequests.TryGetValue(key, out var queue) && queue.Count > 0)
|
||||
{
|
||||
float[] result = new float[computeBuffer.count];
|
||||
material.SetBuffer("distBuffer", computeBuffer);
|
||||
Graphics.SetRandomWriteTarget(1, computeBuffer,false);
|
||||
computeBuffer.GetData(result);
|
||||
while (queue.TryDequeue(out var tcs))
|
||||
tcs.TrySetResult(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup any allocated resources that were created during the execution of this render pass.
|
||||
@ -100,18 +124,6 @@ public class DepthRenderPassFeature : ScriptableRendererFeature
|
||||
{
|
||||
DestroyComputeBuffer();
|
||||
}
|
||||
|
||||
if (Requests != null)
|
||||
{
|
||||
Requests.Clear();
|
||||
Requests = null;
|
||||
}
|
||||
|
||||
if (Answers != null)
|
||||
{
|
||||
Answers.Clear();
|
||||
Answers = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void DestroyComputeBuffer()
|
||||
@ -169,8 +181,16 @@ public class DepthRenderPassFeature : ScriptableRendererFeature
|
||||
Destroy(material);
|
||||
#endif
|
||||
m_ScriptablePass.Dispose();
|
||||
|
||||
if (m_PendingRequests != null)
|
||||
{
|
||||
foreach (var queue in m_PendingRequests.Values)
|
||||
{
|
||||
while (queue.TryDequeue(out var tcs))
|
||||
tcs.TrySetCanceled();
|
||||
}
|
||||
m_PendingRequests.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
@ -14,15 +16,20 @@ public class DepthTester : MonoBehaviour
|
||||
private Camera camera;
|
||||
private float farPlane;
|
||||
private float nearPlane;
|
||||
private int id;
|
||||
private Task<float[]> task;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
camera = GetComponent<Camera>();
|
||||
id = camera.GetInstanceID();
|
||||
farPlane = camera.farClipPlane;
|
||||
nearPlane = camera.nearClipPlane;
|
||||
texture = BlendShaderController.CreateTextures(1, FrameRes, FrameRes, false)[0];
|
||||
camera.targetTexture = texture;
|
||||
texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGBAFloat, false);
|
||||
task = DepthRenderPassFeature.DepthRenderPass.RequestDepthDataAsync(id);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
@ -40,18 +47,29 @@ public class DepthTester : MonoBehaviour
|
||||
|
||||
private void Update()
|
||||
{
|
||||
lock(task)
|
||||
{
|
||||
if(task != null)
|
||||
{
|
||||
if(task.IsCompletedSuccessfully)
|
||||
{
|
||||
float[] depths = task.Result;
|
||||
int centerIndex = (FrameRes / 2) * FrameRes + (FrameRes / 2);
|
||||
float depth = depths[centerIndex];
|
||||
Vector3 depthPos = transform.position + transform.right * Offset;
|
||||
RenderTexture.active = texture;
|
||||
texture2D.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
|
||||
texture2D.Apply();
|
||||
Color pixel = texture2D.GetPixel(texture.width / 2, texture2D.height / 2);
|
||||
float depth = pixel.r;
|
||||
float depthDist = depth * farPlane;
|
||||
Debug.DrawLine(depthPos, depthPos + transform.forward * depthDist, Color.green);
|
||||
Debug.DrawLine(depthPos, depthPos + transform.forward * depth, Color.green);
|
||||
Debug.Log($"chto to risuet: dist:{depth}; depthsCount: {depths.Length}");
|
||||
task = DepthRenderPassFeature.DepthRenderPass.RequestDepthDataAsync(id);
|
||||
}
|
||||
else if(task.IsCanceled)
|
||||
{
|
||||
task = DepthRenderPassFeature.DepthRenderPass.RequestDepthDataAsync(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 raycastPos = transform.position - transform.right * Offset;
|
||||
float rayDistance = 0;
|
||||
|
||||
if(Physics.Raycast(transform.position, transform.forward, out var hit, 100))
|
||||
{
|
||||
rayDistance = hit.distance;
|
||||
|
||||
@ -26,7 +26,7 @@ Shader "Hidden/RenderDepth"
|
||||
|
||||
sampler2D _MainTex;
|
||||
|
||||
RWStructuredBuffer<float> distBuffer;
|
||||
RWStructuredBuffer<float> distBuffer : register(u1);
|
||||
int res;
|
||||
bool _RenderDepth;
|
||||
|
||||
@ -42,7 +42,7 @@ Shader "Hidden/RenderDepth"
|
||||
real depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(i.texcoord));
|
||||
#endif
|
||||
depth = Linear01Depth(depth, _ZBufferParams);
|
||||
distBuffer[pixelIdx.y * _ScaledScreenParams.x + pixelIdx.x] = depth * _ProjectionParams.z;
|
||||
distBuffer[pixelIdx.y * (uint)_ScaledScreenParams.x + pixelIdx.x] = depth * _ProjectionParams.z;
|
||||
return _RenderDepth ? float4(depth, depth, depth, 1) : float4(color, 1);
|
||||
}
|
||||
ENDHLSL
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user