224 lines
6.4 KiB
C#
224 lines
6.4 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering.Universal.Internal;
|
|
using UnityEngine.UI;
|
|
|
|
public class BlendShaderController : MonoBehaviour
|
|
{
|
|
private static string savePath = Application.streamingAssetsPath + '\\';
|
|
private const string filename = "dsitMap";
|
|
private const string ext = ".txt";
|
|
|
|
public Shader DepthShader;
|
|
public ComputeShader BlendShader;
|
|
public Camera camera1;
|
|
public Camera camera2;
|
|
public int QuadResolution = 256;
|
|
public float Multiplier;
|
|
public RawImage Reciever;
|
|
[Range(0, 1000)] public float OffsetMultiplier = 1000;
|
|
|
|
public RenderTexture test;
|
|
|
|
private RenderTexture depth1;
|
|
private RenderTexture depth2;
|
|
private RenderTexture cameraTexture1;
|
|
private RenderTexture cameraTexture2;
|
|
private RenderTexture Result;
|
|
private int currentRes;
|
|
|
|
private bool flag = false;
|
|
|
|
private ComputeBuffer computeBuffer;
|
|
private float[] resultArray;
|
|
Thread savingThread;
|
|
Task<string> task1;
|
|
Task task2;
|
|
|
|
// Start is called before the first frame update
|
|
void Start()
|
|
{
|
|
InitializeTextures();
|
|
InitializeComputeBuffer();
|
|
}
|
|
|
|
void InitializeComputeBuffer()
|
|
{
|
|
computeBuffer = new ComputeBuffer(currentRes * currentRes, 1 * sizeof(float));//2 dimensional array of 1 value type of double
|
|
}
|
|
|
|
void InitializeTextures()
|
|
{
|
|
currentRes = QuadResolution;
|
|
RenderTexture[] defaultTextures = CreateTextures(2, currentRes, currentRes);
|
|
cameraTexture1 = defaultTextures[0];
|
|
cameraTexture2 = defaultTextures[1];
|
|
|
|
RenderTexture[] depthTextures = CreateTextures(2, currentRes, currentRes, true);
|
|
depth1 = depthTextures[0];
|
|
depth2 = depthTextures[1];
|
|
|
|
Result = CreateTextures(1, currentRes, currentRes)[0];
|
|
|
|
Reciever.texture = Result;
|
|
|
|
camera1.targetTexture = cameraTexture1;
|
|
camera2.targetTexture = cameraTexture2;
|
|
}
|
|
|
|
public static RenderTexture[] CreateTextures(int count, int resX, int resY, bool depth = false)
|
|
{
|
|
RenderTexture[] result = new RenderTexture[count];
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
result[i] = new RenderTexture(resX, resY, 32, depth ? RenderTextureFormat.Depth : RenderTextureFormat.ARGBFloat);
|
|
result[i].enableRandomWrite = !depth;
|
|
result[i].Create();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.F))
|
|
{
|
|
SetFlag();
|
|
}
|
|
|
|
if (flag)
|
|
{
|
|
GenerateDepth();
|
|
}
|
|
|
|
UpdateShader(cameraTexture1, cameraTexture2);
|
|
|
|
if(Input.GetKeyDown(KeyCode.S))
|
|
{
|
|
SaveTexture();
|
|
}
|
|
|
|
if (Input.GetKeyDown(KeyCode.J))
|
|
{
|
|
Debug.Log(GetDistanceByDepth());
|
|
}
|
|
if (Input.GetKeyDown(KeyCode.K))
|
|
{
|
|
Debug.Log(GetDistanceByRayCast());
|
|
}
|
|
|
|
if (Input.GetKeyDown(KeyCode.T))
|
|
{
|
|
camera1.targetTexture = test;
|
|
camera1.RenderWithShader(DepthShader, "fragment");
|
|
camera1.targetTexture = cameraTexture1;
|
|
}
|
|
}
|
|
|
|
void UpdateShader(RenderTexture tex1, RenderTexture tex2)
|
|
{
|
|
BlendShader.SetTexture(0, "Camera1", tex1);
|
|
BlendShader.SetTexture(0, "Camera2", tex2);
|
|
BlendShader.SetTexture(0, "Result", Result);
|
|
BlendShader.SetFloat(Shader.PropertyToID("Offset"), (int)(camera2.transform.localPosition.x * OffsetMultiplier));
|
|
BlendShader.SetFloat(Shader.PropertyToID("ResX"), Result.width);
|
|
BlendShader.SetBuffer(0, "MonoChannelResult", computeBuffer);
|
|
//BlendShader.SetTexture(0, "Test", test);
|
|
BlendShader.Dispatch(0, Result.width / 8, Result.height / 8, 1);
|
|
}
|
|
|
|
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()
|
|
{
|
|
if (flag)
|
|
{
|
|
camera1.targetTexture = depth1;
|
|
camera2.targetTexture = depth2;
|
|
}
|
|
else
|
|
{
|
|
camera1.targetTexture = cameraTexture1;
|
|
camera2.targetTexture = cameraTexture2;
|
|
}
|
|
}
|
|
|
|
public void SetFlag()
|
|
{
|
|
flag = !flag;
|
|
SwapRenderTargets();
|
|
}
|
|
|
|
private async void SaveTexture()
|
|
{
|
|
Debug.Log("Start Saving");
|
|
resultArray = new float[currentRes * currentRes];
|
|
computeBuffer.GetData(resultArray);
|
|
Debug.Log("Data copied");
|
|
task1 = Task.Run(() => SerializeArray());
|
|
await task1;
|
|
string result = task1.Result;
|
|
|
|
task2 = SavingProcessAsync(result);
|
|
await task2;
|
|
}
|
|
|
|
private async Task SavingProcessAsync(string data)
|
|
{
|
|
int filesCount = Directory.EnumerateFiles(savePath, filename + '*' + ext).Count();
|
|
await File.WriteAllTextAsync(savePath + filename + filesCount.ToString() + ext, data);
|
|
Debug.Log("File saved");
|
|
}
|
|
|
|
private string SerializeArray()
|
|
{
|
|
string result = string.Empty;
|
|
for (int i = 0; i < resultArray.Length; i += currentRes)
|
|
{
|
|
result += string.Join(", ", resultArray[i..(i + currentRes)]) + '\n';
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private float GetDistanceByDepth()
|
|
{
|
|
resultArray = new float[currentRes * currentRes];
|
|
computeBuffer.GetData(resultArray);
|
|
int idx = (int)(currentRes * (0.5f + currentRes * 0.5f));
|
|
Matrix4x4 porjMat = camera1.projectionMatrix;
|
|
float zDepth = resultArray[idx];
|
|
float far = camera1.farClipPlane;
|
|
float near = camera1.nearClipPlane;
|
|
return zDepth * (far - near) + near;
|
|
}
|
|
|
|
private float GetDistanceByRayCast()
|
|
{
|
|
Vector3 position = camera1.transform.position + camera1.transform.right * camera2.transform.localPosition.x * 0.5f;
|
|
if (Physics.Raycast(position, camera1.transform.forward, out var hit, 100))
|
|
{
|
|
return hit.distance;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
computeBuffer.Release();
|
|
computeBuffer = null;
|
|
}
|
|
}
|