Compare commits

...

3 Commits

Author SHA1 Message Date
Max Barashev
46a383e36d Added RpcFunctions
- Added RpcFunction.cs with init static functions
 - Extend BlendShaderController for getting needed data
 - Added CrpcExtensions for server api
2026-06-05 21:02:56 +03:00
Max Barashev
0749c2fbe7 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
2026-06-03 21:48:43 +03:00
Max Barashev
a2f9328f5f Made color and dapth calculations in parallel
- Edited RenderDepth.sahder to 2 sapces calculations
 - In DepthRenderPassFeature.cs changes passEvent to rendering after post-processing
 - Remove side cutting merged image in BlendShader.compute
2026-06-03 15:37:10 +03:00
10 changed files with 577 additions and 118 deletions

View File

@ -252,7 +252,7 @@ PrefabInstance:
- target: {fileID: 919132149155446097, guid: cadef6a45e22b304aafd4c21eb84340f, - target: {fileID: 919132149155446097, guid: cadef6a45e22b304aafd4c21eb84340f,
type: 3} type: 3}
propertyPath: m_IsActive propertyPath: m_IsActive
value: 1 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: cadef6a45e22b304aafd4c21eb84340f, - target: {fileID: 919132149155446097, guid: cadef6a45e22b304aafd4c21eb84340f,
type: 3} type: 3}
@ -658,7 +658,7 @@ Transform:
m_GameObject: {fileID: 365053774} m_GameObject: {fileID: 365053774}
serializedVersion: 2 serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0.12557845, y: 0.64992166, z: -10.212498} m_LocalPosition: {x: 0.37, y: -9.73, z: -0.46}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
@ -748,7 +748,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!4 &409312061 --- !u!4 &409312061
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -1424,7 +1424,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
FrameRes: 256 FrameRes: 256
Offset: 0.02 Offset: -0.07
texture2D: {fileID: 0} texture2D: {fileID: 0}
--- !u!1 &686694433 --- !u!1 &686694433
GameObject: GameObject:
@ -1444,7 +1444,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &686694434 --- !u!224 &686694434
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -1591,6 +1591,7 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
testDistance: 0.08 testDistance: 0.08
DepthShader: {fileID: 4800000, guid: 38575fbac906d53499789597d61d2fa4, type: 3} DepthShader: {fileID: 4800000, guid: 38575fbac906d53499789597d61d2fa4, type: 3}
depthMaterial: {fileID: 0}
BlendShader: {fileID: 7200000, guid: 5bf2857e309eda648b826d75af82d1ab, type: 3} BlendShader: {fileID: 7200000, guid: 5bf2857e309eda648b826d75af82d1ab, type: 3}
camera1: {fileID: 146129744} camera1: {fileID: 146129744}
camera2: {fileID: 73635654} camera2: {fileID: 73635654}
@ -1623,7 +1624,7 @@ MonoBehaviour:
m_GameObject: {fileID: 763126624} m_GameObject: {fileID: 763126624}
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c61b6ef6bca767e42a8ec8ea380a4ac6, type: 3} m_Script: {fileID: 11500000, guid: b06971fce09a875489a2898f4f2cbaec, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
--- !u!1 &858903265 --- !u!1 &858903265
@ -1725,7 +1726,7 @@ Transform:
m_GameObject: {fileID: 858903265} m_GameObject: {fileID: 858903265}
serializedVersion: 2 serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 1.5} m_LocalPosition: {x: 0, y: 0, z: 2}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
@ -1748,7 +1749,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!114 &867358639 --- !u!114 &867358639
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -2120,7 +2121,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &1682170431 --- !u!224 &1682170431
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -2302,9 +2303,9 @@ RectTransform:
m_Children: [] m_Children: []
m_Father: {fileID: 2034953397} m_Father: {fileID: 2034953397}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: 0, y: -160} m_AnchoredPosition: {x: -300, y: 200}
m_SizeDelta: {x: 500, y: 300} m_SizeDelta: {x: 500, y: 300}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &2034953393 --- !u!1 &2034953393

View File

@ -6,6 +6,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal.Internal; using UnityEngine.Rendering.Universal.Internal;
using UnityEngine.UI; using UnityEngine.UI;
@ -18,6 +19,9 @@ public class BlendShaderController : MonoBehaviour
private static int resXProp = Shader.PropertyToID("ResX"); private static int resXProp = Shader.PropertyToID("ResX");
private static int farClipPlaneProp = Shader.PropertyToID("FarClipPlane"); private static int farClipPlaneProp = Shader.PropertyToID("FarClipPlane");
private static int monoChanelResProp = Shader.PropertyToID("MonoChannelResult"); private static int monoChanelResProp = Shader.PropertyToID("MonoChannelResult");
private static int Depths1Id = Shader.PropertyToID("Depths1");
private static int Depths2Id = Shader.PropertyToID("Depths2");
private static int ResDepthsId = Shader.PropertyToID("MergedDepths");
private static string savePath = Application.streamingAssetsPath + '\\'; private static string savePath = Application.streamingAssetsPath + '\\';
private const string filename = "dsitMap"; private const string filename = "dsitMap";
@ -37,6 +41,7 @@ public class BlendShaderController : MonoBehaviour
[Range(0.0f, 2.0f)] [Range(0.0f, 2.0f)]
public float testDistance = 0.08f; public float testDistance = 0.08f;
public Shader DepthShader; public Shader DepthShader;
public Material depthMaterial;
public ComputeShader BlendShader; public ComputeShader BlendShader;
public Camera camera1; public Camera camera1;
public Camera camera2; public Camera camera2;
@ -57,11 +62,16 @@ public class BlendShaderController : MonoBehaviour
private bool flag = false; private bool flag = false;
private ComputeBuffer computeBuffer; private ComputeBuffer computeBuffer;
private ComputeBuffer depthBuffer;
private float[] resultArray; private float[] resultArray;
Thread savingThread; Thread savingThread;
Task<string> task1; Task<string> task1;
Task task2; Task task2;
private ComputeBuffer depthsBuffer1;
private ComputeBuffer depthsBuffer2;
private ComputeBuffer resDepthsBuffer;
private int uvOffset; private int uvOffset;
// Start is called before the first frame update // Start is called before the first frame update
@ -74,6 +84,14 @@ public class BlendShaderController : MonoBehaviour
void InitializeComputeBuffer() void InitializeComputeBuffer()
{ {
computeBuffer = new ComputeBuffer(currentRes * currentRes, 1 * sizeof(float));//2 dimensional array of 1 value type of float computeBuffer = new ComputeBuffer(currentRes * currentRes, 1 * sizeof(float));//2 dimensional array of 1 value type of float
depthBuffer = new ComputeBuffer(currentRes * currentRes, 1 * sizeof(float));
depthMaterial = CoreUtils.CreateEngineMaterial(DepthShader);
depthMaterial.SetBuffer("distBuffer", depthBuffer);
depthsBuffer1 = new ComputeBuffer(currentRes * currentRes, 1 * sizeof(float));
depthsBuffer2 = new ComputeBuffer(currentRes * currentRes, 1 * sizeof(float));
resDepthsBuffer = new ComputeBuffer(currentRes * currentRes, 1 * sizeof(float));
} }
void InitializeTextures() void InitializeTextures()
@ -113,27 +131,7 @@ public class BlendShaderController : MonoBehaviour
SetCameraDistance(testDistance); SetCameraDistance(testDistance);
ComputeUVOffset(); ComputeUVOffset();
if (Input.GetKeyDown(KeyCode.F))
{
SetFlag();
}
if (flag)
{
GenerateDepth();
}
UpdateShader(cameraTexture1, cameraTexture2); UpdateShader(cameraTexture1, cameraTexture2);
if(Input.GetKeyDown(KeyCode.S))
{
SaveTextureAsync();
}
if (Input.GetKeyDown(KeyCode.A))
{
SaveTexture();
}
} }
void UpdateShader(RenderTexture tex1, RenderTexture tex2) void UpdateShader(RenderTexture tex1, RenderTexture tex2)
@ -148,6 +146,21 @@ public class BlendShaderController : MonoBehaviour
BlendShader.Dispatch(0, Result.width / 8, Result.height / 8, 1); BlendShader.Dispatch(0, Result.width / 8, Result.height / 8, 1);
} }
void UpdateShader(float[] depths1, float[] depths2)
{
depthsBuffer1.SetData(depths1);
depthsBuffer2.SetData(depths2);
BlendShader.SetFloat(offsetProp, uvOffset);
BlendShader.SetFloat(resXProp, currentRes);
BlendShader.SetBuffer(1, Depths1Id, depthsBuffer1);
BlendShader.SetBuffer(1, Depths2Id, depthsBuffer2);
BlendShader.SetBuffer(1, ResDepthsId, resDepthsBuffer);
BlendShader.Dispatch(1, currentRes / 8, currentRes / 8, 1);
}
void ComputeUVOffset() void ComputeUVOffset()
{ {
if (camera1 && camera2) if (camera1 && camera2)
@ -166,15 +179,6 @@ public class BlendShaderController : MonoBehaviour
uvOffset = (int)(camera2.transform.localPosition.x * OffsetMultiplier); uvOffset = (int)(camera2.transform.localPosition.x * OffsetMultiplier);
} }
void GenerateDepth()
{
//camera1.RenderWithShader(DepthShader, "RenderType");
//camera2.RenderWithShader(DepthShader, "RenderType");
Graphics.Blit(depth1, cameraTexture1); //Depth generated due to format of render texture
Graphics.Blit(depth2, cameraTexture2);
}
void SwapRenderTargets() void SwapRenderTargets()
{ {
if (flag) if (flag)
@ -222,9 +226,20 @@ public class BlendShaderController : MonoBehaviour
Save(result); Save(result);
} }
public void GetDistArray() public async void GetDistArray(TaskCompletionSource<string> tcs)
{ {
int cameraId1 = camera1.GetInstanceID();
int cameraId2 = camera2.GetInstanceID();
float[] depths1 = await DepthRenderPassFeature.DepthRenderPass.RequestDepthDataAsync(cameraId1);
float[] depths2 = await DepthRenderPassFeature.DepthRenderPass.RequestDepthDataAsync(cameraId2);
UpdateShader(depths1, depths2);
float[] depths = new float[currentRes * currentRes];
resDepthsBuffer.GetData(depths);
byte[] bytes = new byte[depths.Length * sizeof(float)];
Buffer.BlockCopy(depths, 0, bytes, 0, bytes.Length);
string base64 = Convert.ToBase64String(bytes);
string result = "{\"width\":" + currentRes + ",\"height\":" + currentRes + ",\"data\":\"" + base64 + "\"}";
tcs.SetResult(result);
} }
private async Task SavingProcessAsync(string data) private async Task SavingProcessAsync(string data)
@ -243,12 +258,17 @@ public class BlendShaderController : MonoBehaviour
} }
private string SerializeArray() private string SerializeArray()
{
return SerializeArray(resultArray);
}
private string SerializeArray(float[] arr)
{ {
string result = string.Empty; string result = string.Empty;
Debug.Log("StartSerializing"); Debug.Log("StartSerializing");
for (int i = 0; i < resultArray.Length; i += currentRes) for (int i = 0; i < resultArray.Length; i += currentRes)
{ {
result += string.Join(", ", resultArray[i..(i + currentRes)]) + '\n'; result += string.Join("; ", arr[i..(i + currentRes)]) + '\n';
} }
Debug.Log("EndSerializing"); Debug.Log("EndSerializing");
return result; return result;
@ -288,6 +308,54 @@ public class BlendShaderController : MonoBehaviour
return new double[] { fx, 0, cx, 0, fy, cy, 0, 0, 1 }; return new double[] { fx, 0, cx, 0, fy, cy, 0, 0, 1 };
} }
public string GetIntrinsicParametersAsBase64(Camera camera)
{
double[] intrinsics = GetIntrinsicParameters(camera);
byte[] bytes = new byte[intrinsics.Length * sizeof(double)];
Buffer.BlockCopy(intrinsics, 0, bytes, 0, bytes.Length);
return Convert.ToBase64String(bytes);
}
public string GetLeftIntrinsicParametersAsBase64()
{
return GetIntrinsicParametersAsBase64(camera1);
}
public string GetRightIntrinsicParametersAsBase64()
{
return GetIntrinsicParametersAsBase64(camera2);
}
public double[] GetExtrinsicParameters(Camera camera)
{
Matrix4x4 m = camera.worldToCameraMatrix;
return new double[]
{
m.m00, m.m01, m.m02, m.m03,
m.m10, m.m11, m.m12, m.m13,
m.m20, m.m21, m.m22, m.m23,
m.m30, m.m31, m.m32, m.m33
};
}
public string GetExtrinsicParametersAsBase64(Camera camera)
{
double[] extrinsics = GetExtrinsicParameters(camera);
byte[] bytes = new byte[extrinsics.Length * sizeof(double)];
Buffer.BlockCopy(extrinsics, 0, bytes, 0, bytes.Length);
return Convert.ToBase64String(bytes);
}
public string GetLeftExtrinsicParametersAsBase64()
{
return GetExtrinsicParametersAsBase64(camera1);
}
public string GetRightExtrinsicParametersAsBase64()
{
return GetExtrinsicParametersAsBase64(camera2);
}
public float GetCameraDistance() public float GetCameraDistance()
{ {
if (camera1 == null || camera2 == null) if (camera1 == null || camera2 == null)
@ -307,9 +375,72 @@ public class BlendShaderController : MonoBehaviour
camera1.transform.position = center - direction * distance * 0.5f; camera1.transform.position = center - direction * distance * 0.5f;
} }
public RenderTexture CombineTexturesSideBySide(RenderTexture left, RenderTexture right)
{
if (left == null || right == null)
{
Debug.LogError("Both render textures must be provided");
return null;
}
if (left.width != right.width || left.height != right.height)
{
Debug.LogError("Both render textures must have the same dimensions");
return null;
}
int w = left.width;
int h = left.height;
RenderTexture combined = new RenderTexture(w * 2, h, 0, RenderTextureFormat.ARGBFloat);
combined.Create();
Graphics.CopyTexture(left, 0, 0, 0, 0, w, h, combined, 0, 0, 0, 0);
Graphics.CopyTexture(right, 0, 0, 0, 0, w, h, combined, 0, 0, w, 0);
return combined;
}
public string GetCombinedTexturesAsBase64Json()
{
RenderTexture combined = CombineTexturesSideBySide(cameraTexture1, cameraTexture2);
if (combined == null) return null;
int w = combined.width;
int h = combined.height;
RenderTexture activeRT = RenderTexture.active;
RenderTexture.active = combined;
Texture2D tex = new Texture2D(w, h, TextureFormat.RGBAFloat, false);
tex.ReadPixels(new Rect(0, 0, w, h), 0, 0);
tex.Apply();
RenderTexture.active = activeRT;
byte[] rawData = tex.GetRawTextureData();
Destroy(tex);
combined.Release();
string base64 = Convert.ToBase64String(rawData);
return "{\"width\":" + w + ",\"height\":" + h + ",\"data\":\"" + base64 + "\"}";
}
private void OnDisable() private void OnDisable()
{ {
computeBuffer.Release(); computeBuffer.Release();
computeBuffer = null; computeBuffer = null;
depthBuffer.Release();
depthBuffer = null;
depthsBuffer1.Release();
depthsBuffer1 = null;
depthsBuffer2.Release();
depthsBuffer2 = null;
resDepthsBuffer.Release();
resDepthsBuffer = null;
Destroy(depthMaterial);
depthMaterial = null;
} }
} }

View File

@ -71,7 +71,7 @@ namespace CloudPointRpc
public RpcString(string data) public RpcString(string data)
{ {
var bytes = Encoding.UTF8.GetBytes(data); var bytes = Encoding.ASCII.GetBytes(data);
_handle = CrpcServerApi.crpc_str_create(bytes, (ulong)bytes.Length); _handle = CrpcServerApi.crpc_str_create(bytes, (ulong)bytes.Length);
} }
@ -113,6 +113,51 @@ namespace CloudPointRpc
} }
} }
public static class CrpcExtensions
{
public static string CrpcStrGetData(IntPtr rpcString)
{
var dataPtr = CrpcServerApi.crpc_str_get_data(rpcString);
var size = CrpcServerApi.crpc_str_get_size(rpcString);
if (dataPtr == IntPtr.Zero || size == 0)
return string.Empty;
return Marshal.PtrToStringAnsi(dataPtr, (int)size) ?? string.Empty;
}
public static ulong CrpcStrGetSize(IntPtr rpcString)
{
return CrpcServerApi.crpc_str_get_size(rpcString);
}
public static IntPtr CrpcStrCreate(string data)
{
var bytes = Encoding.UTF8.GetBytes(data);
return CrpcServerApi.crpc_str_create(bytes, (ulong)bytes.Length);
}
public static void CrpcStrDestroy(IntPtr rpcString)
{
CrpcServerApi.crpc_str_destroy(rpcString);
}
public static void CrpcInit(string configPath)
{
var bytes = Encoding.UTF8.GetBytes(configPath + '\0');
CrpcServerApi.crpc_init(bytes);
}
public static void CrpcDeinit()
{
CrpcServerApi.crpc_deinit();
}
public static void CrpcAddMethod(CrpcTestApi.RpcStringCallback cb, string name)
{
using var nameRpc = new RpcString(name);
CrpcServerApi.crpc_add_method(cb, nameRpc.Handle);
}
}
public static class CrpcTestExtensions public static class CrpcTestExtensions
{ {
public static void CrpcTestAddMethod(CrpcTestApi.RpcStringCallback cb, string name) public static void CrpcTestAddMethod(CrpcTestApi.RpcStringCallback cb, string name)

View File

@ -1,28 +1,48 @@
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;
using UnityEngine.Rendering.Universal; using UnityEngine.Rendering.Universal;
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 Queue<bool> Requests; public static Task<float[]> RequestDepthDataAsync(int id, TaskCompletionSource<float[]> tcs)
public static Queue<float[]> Answers; {
if(m_PendingRequests == null)
m_PendingRequests = new Dictionary<int, Queue<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;
}
public static Task<float[]> RequestDepthDataAsync(int id)
{
var tcs = new TaskCompletionSource<float[]>();
return RequestDepthDataAsync(id, tcs);
}
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)
@ -38,12 +58,15 @@ public class DepthRenderPassFeature : ScriptableRendererFeature
{ {
material.SetBuffer("distBuffer", computeBuffer); material.SetBuffer("distBuffer", computeBuffer);
material.SetFloat("res", rt.height); material.SetFloat("res", rt.height);
material.SetInt("_RenderDepth", this.depth ? 1 : 0);
} }
} }
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.
@ -52,25 +75,32 @@ public class DepthRenderPassFeature : ScriptableRendererFeature
// You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline. // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline.
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{ {
if (!depth) return;
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.
@ -98,18 +128,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()
@ -132,7 +150,7 @@ public class DepthRenderPassFeature : ScriptableRendererFeature
m_ScriptablePass = new DepthRenderPass(material); m_ScriptablePass = new DepthRenderPass(material);
// Configures where the render pass should be injected. // Configures where the render pass should be injected.
m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
} }
// Here you can inject one or multiple render passes in the renderer. // Here you can inject one or multiple render passes in the renderer.
@ -167,8 +185,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();
}
} }
} }

View File

@ -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;

View File

@ -0,0 +1,218 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using CloudPointRpc;
using UnityEngine;
public class RpcFunctions : MonoBehaviour
{
private static Queue<Task> _callbackTasks = new Queue<Task>();
private static BlendShaderController controller;
private static CancellationTokenSource cts;
void Start()
{
controller = GetComponent<BlendShaderController>();
cts = new CancellationTokenSource();
CrpcExtensions.CrpcInit("config.json");
CrpcExtensions.CrpcAddMethod(RpcGetCloudPoint, "get_cloud_point");
CrpcExtensions.CrpcAddMethod(RpcGetImage, "get_image");
CrpcExtensions.CrpcAddMethod(RpcGetIntrinsicsLeft, "get_intrinsics_left");
CrpcExtensions.CrpcAddMethod(RpcGetIntrinsicsRight, "get_intrinsics_right");
CrpcExtensions.CrpcAddMethod(RpcGetExtrinsicsLeft, "get_extrinsics_left");
CrpcExtensions.CrpcAddMethod(RpcGetExtrinsicsRight, "get_extrinsics_right");
Debug.Log("[RpcFunctions] Initialized and methods added");
}
private void OnDestroy()
{
lock (_callbackTasks)
{
_callbackTasks.Clear();
}
cts.Cancel();
CrpcServerApi.crpc_deinit();
}
private void Update()
{
lock (_callbackTasks)
{
while (_callbackTasks.Count > 0)
{
var task = _callbackTasks.Dequeue();
task.RunSynchronously();
}
}
}
public static IntPtr RpcGetCloudPoint(IntPtr rpcString)
{
var rpc = new RpcString(rpcString);
var message = rpc.Data;
rpc.Dispose();
var tcs = new TaskCompletionSource<string>();
var task = new Task(() => {
Debug.Log($"[RpcTest] Callback received: {message}");
controller.GetDistArray(tcs);
}, cts.Token);
lock (_callbackTasks)
{
_callbackTasks.Enqueue(task);
}
try
{
task.Wait(cts.Token);
tcs.Task.Wait(cts.Token);
}
catch (OperationCanceledException)
{
Debug.Log("Waiting was canceled");
}
var responce = new RpcString(tcs.Task.Result);
return responce.Handle;
}
public static IntPtr RpcGetImage(IntPtr rpcString)
{
var rpc = new RpcString(rpcString);
var message = rpc.Data;
rpc.Dispose();
var tcs = new TaskCompletionSource<string>();
var task = new Task(() =>
{
string result = controller.GetCombinedTexturesAsBase64Json();
tcs.SetResult(result);
});
try
{
task.Wait(cts.Token);
tcs.Task.Wait(cts.Token);
}
catch (OperationCanceledException)
{
Debug.Log("Waiting was canceled");
}
var responce = new RpcString(tcs.Task.Result);
return responce.Handle;
}
public static IntPtr RpcGetIntrinsicsLeft(IntPtr rpcString)
{
var rpc = new RpcString(rpcString);
var message = rpc.Data;
rpc.Dispose();
var tcs = new TaskCompletionSource<string>();
var task = new Task(() =>
{
string result = controller.GetLeftIntrinsicParametersAsBase64();
tcs.SetResult(result);
});
try
{
task.Wait(cts.Token);
tcs.Task.Wait(cts.Token);
}
catch (OperationCanceledException)
{
Debug.Log("Waiting was canceled");
}
var responce = new RpcString(tcs.Task.Result);
return responce.Handle;
}
public static IntPtr RpcGetIntrinsicsRight(IntPtr rpcString)
{
var rpc = new RpcString(rpcString);
var message = rpc.Data;
rpc.Dispose();
var tcs = new TaskCompletionSource<string>();
var task = new Task(() =>
{
string result = controller.GetRightIntrinsicParametersAsBase64();
tcs.SetResult(result);
});
try
{
task.Wait(cts.Token);
tcs.Task.Wait(cts.Token);
}
catch (OperationCanceledException)
{
Debug.Log("Waiting was canceled");
}
var responce = new RpcString(tcs.Task.Result);
return responce.Handle;
}
public static IntPtr RpcGetExtrinsicsLeft(IntPtr rpcString)
{
var rpc = new RpcString(rpcString);
var message = rpc.Data;
rpc.Dispose();
var tcs = new TaskCompletionSource<string>();
var task = new Task(() =>
{
string result = controller.GetLeftExtrinsicParametersAsBase64();
tcs.SetResult(result);
});
try
{
task.Wait(cts.Token);
tcs.Task.Wait(cts.Token);
}
catch (OperationCanceledException)
{
Debug.Log("Waiting was canceled");
}
var responce = new RpcString(tcs.Task.Result);
return responce.Handle;
}
public static IntPtr RpcGetExtrinsicsRight(IntPtr rpcString)
{
var rpc = new RpcString(rpcString);
var message = rpc.Data;
rpc.Dispose();
var tcs = new TaskCompletionSource<string>();
var task = new Task(() =>
{
string result = controller.GetRightExtrinsicParametersAsBase64();
tcs.SetResult(result);
});
try
{
task.Wait(cts.Token);
tcs.Task.Wait(cts.Token);
}
catch (OperationCanceledException)
{
Debug.Log("Waiting was canceled");
}
var responce = new RpcString(tcs.Task.Result);
return responce.Handle;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b06971fce09a875489a2898f4f2cbaec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -14,7 +14,7 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_Active: 1 m_Active: 1
shader: {fileID: 4800000, guid: 38575fbac906d53499789597d61d2fa4, type: 3} shader: {fileID: 4800000, guid: 38575fbac906d53499789597d61d2fa4, type: 3}
Depth: 1 Depth: 0
--- !u!114 &-1878332245247344467 --- !u!114 &-1878332245247344467
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -108,7 +108,7 @@ MonoBehaviour:
zFailOperation: 0 zFailOperation: 0
m_ShadowTransparentReceive: 1 m_ShadowTransparentReceive: 1
m_RenderingMode: 1 m_RenderingMode: 1
m_DepthPrimingMode: 0 m_DepthPrimingMode: 1
m_CopyDepthMode: 0 m_CopyDepthMode: 0
m_AccurateGbufferNormals: 0 m_AccurateGbufferNormals: 0
m_IntermediateTextureMode: 1 m_IntermediateTextureMode: 1

View File

@ -1,5 +1,6 @@
// Each #kernel tells which function to compile; you can have many kernels // Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain #pragma kernel CSMain
#pragma kernel CSBlendDepths
// Create a RenderTexture with enableRandomWrite flag and set it // Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture // with cs.SetTexture
@ -7,6 +8,11 @@ RWTexture2D<float4> Camera1;
RWTexture2D<float4> Camera2; RWTexture2D<float4> Camera2;
RWTexture2D<float4> Result; RWTexture2D<float4> Result;
RWStructuredBuffer<float> MonoChannelResult; RWStructuredBuffer<float> MonoChannelResult;
StructuredBuffer<float> Depths1;
StructuredBuffer<float> Depths2;
RWStructuredBuffer<float> MergedDepths;
float ResX; float ResX;
float Offset; float Offset;
float FarClipPlane; float FarClipPlane;
@ -16,8 +22,29 @@ void CSMain (uint3 id : SV_DispatchThreadID)
{ {
int2 idxy1 = int2(clamp(id.x + Offset, 0, ResX), id.y); int2 idxy1 = int2(clamp(id.x + Offset, 0, ResX), id.y);
int2 idxy2 = int2(clamp(id.x - Offset, 0, ResX), id.y); int2 idxy2 = int2(clamp(id.x - Offset, 0, ResX), id.y);
float diffFactor = saturate(id.x - Offset) * saturate(ResX - (id.x + Offset)); float3 col1 = Camera1[idxy1].xyz;
float4 resVal = float4(((Camera1[idxy1] * diffFactor + Camera2[idxy2] * diffFactor) / 2).xyz, 1); float3 col2 = Camera1[idxy2].xyz;
float diffFactorL = saturate(id.x - Offset);
float diffFactorR = saturate(ResX - (id.x + Offset));
float4 resVal = 0;
//if(diffFactorL && diffFactorR > 0)
resVal = float4(((col1 * diffFactorR + col2 * diffFactorL) / ((diffFactorL && diffFactorR) == false ? 1 : 2)).xyz, 1);
//else
//resVal = float4(max(col1, col2), 1);
Result[id.xy] = resVal; Result[id.xy] = resVal;
MonoChannelResult[id.x + id.y * ResX] = resVal.r * FarClipPlane; MonoChannelResult[id.x + id.y * ResX] = resVal.r * FarClipPlane;
} }
[numthreads(8, 8, 1)]
void CSBlendDepths(uint3 id : SV_DispatchThreadID)
{
int2 idx1 = int2(clamp(id.x + Offset, 0, ResX), id.y);
int2 idx2 = int2(clamp(id.x - Offset, 0, ResX), id.y);
float col1 = Depths1[idx1.x + ResX * idx1.y];
float col2 = Depths1[idx2.x + ResX * idx2.y];
float diffFactorL = saturate(id.x - Offset);
float diffFactorR = saturate(ResX - (id.x + Offset));
float resCol = (col1 * diffFactorR + col2 * diffFactorL) / ((diffFactorL && diffFactorR) == false ? 1 : 2);
MergedDepths[id.x + id.y * ResX] = resCol;
}

View File

@ -14,54 +14,36 @@ Shader "Hidden/RenderDepth"
Pass Pass
{ {
HLSLPROGRAM HLSLPROGRAM
#pragma target 5.0
#pragma vertex Vert #pragma vertex Vert
#pragma fragment frag #pragma fragment frag
//#include "UnityCG.cginc"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
// v2f vert (appdata v)
// {
// v2f o;
// o.vertex = UnityObjectToClipPos(v.vertex);
// o.uv = v.uv;
// return o;
// }
sampler2D _MainTex; sampler2D _MainTex;
TEXTURE2D_X(_CameraOpaqueTexture);
SAMPLER(sampler_CameraOpaqueTexture);
RWStructuredBuffer<float> distBuffer; RWStructuredBuffer<float> distBuffer : register(u1);
int res; int res;
bool _RenderDepth;
float4 frag (Varyings i) : SV_Target float4 frag (Varyings i) : SV_Target
{ {
float2 UV = i.positionCS.xy / _ScaledScreenParams.xy; uint2 pixelIdx = uint2(i.positionCS.xy);
float3 color = SampleSceneColor(i.texcoord);
#if UNITY_REVERSED_Z #if UNITY_REVERSED_Z
real depth = SampleSceneDepth(UV); real depth = SampleSceneDepth(i.texcoord);
#else #else
// Adjust z to match NDC for OpenGL // Adjust z to match NDC for OpenGL
real depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(UV)); real depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(i.texcoord));
#endif #endif
depth = Linear01Depth(depth, _ZBufferParams); depth = Linear01Depth(depth, _ZBufferParams);
distBuffer[pixelIdx.y * (uint)_ScaledScreenParams.x + pixelIdx.x] = depth * _ProjectionParams.z;
return float4(depth, depth, depth, 1); return _RenderDepth ? float4(depth, depth, depth, 1) : float4(color, 1);
} }
ENDHLSL ENDHLSL
} }