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