soundvision/UnityProject/Assets/ThridParty/Keijiro/PointCloudBaker.cs

100 lines
3.1 KiB
C#
Raw Normal View History

2019-12-12 12:08:41 +00:00
using UnityEngine;
2019-12-13 15:14:22 +00:00
using UnityEngine.Events;
2019-12-12 12:08:41 +00:00
using GraphicsFormat = UnityEngine.Experimental.Rendering.GraphicsFormat;
namespace Akvfx
{
2019-12-13 15:14:22 +00:00
2019-12-12 12:08:41 +00:00
public sealed class PointCloudBaker : MonoBehaviour
{
2019-12-13 15:14:22 +00:00
2019-12-12 12:08:41 +00:00
#region Editable attributes
[SerializeField] DeviceSettings _deviceSettings = null;
[SerializeField] RenderTexture _colorTexture = null;
[SerializeField] RenderTexture _positionTexture = null;
[SerializeField] Shader _shader = null;
2019-12-13 15:14:22 +00:00
[SerializeField] UnityEvent azureDataUpdated;
2019-12-12 12:08:41 +00:00
#endregion
#region Internal objects
ThreadedDriver _driver;
Material _material;
ComputeBuffer _xyTable;
(Texture2D color, Texture2D depth) _temporaries;
#endregion
#region MonoBehaviour implementation
void Start()
{
// Start capturing via the threaded driver.
_driver = new ThreadedDriver(_deviceSettings);
// Temporary objects for convertion shader
_material = new Material(_shader);
_temporaries = (
new Texture2D(2048, 1536, GraphicsFormat.B8G8R8A8_SRGB, 0),
new Texture2D(2048 * 2, 1536, GraphicsFormat.R8_UNorm, 0)
);
}
void OnDestroy()
{
if (_material != null) Destroy(_material);
_xyTable?.Dispose();
if (_temporaries.color != null) Destroy(_temporaries.color);
if (_temporaries.depth != null) Destroy(_temporaries.depth);
_driver?.Dispose();
}
RenderBuffer[] _mrt = new RenderBuffer[2];
unsafe void Update()
{
// Try initializing XY table if it's not ready.
if (_xyTable == null)
{
var data = _driver.XYTable;
if (data.IsEmpty) return; // Table is not ready.
// Allocate and initialize the XY table.
_xyTable = new ComputeBuffer(data.Length, sizeof(float));
_xyTable.SetData(data);
}
// Try retrieving the last frame.
var (color, depth) = _driver.LockLastFrame();
if (color.IsEmpty || depth.IsEmpty) return;
// Load the frame data into the temporary textures.
_temporaries.color.LoadRawTextureData(color.Span);
_temporaries.depth.LoadRawTextureData(depth.Span);
_temporaries.color.Apply();
_temporaries.depth.Apply();
// We don't need the last frame any more.
_driver.ReleaseLastFrame();
// Invoke the unprojection shader.
_material.SetTexture("_ColorTexture", _temporaries.color);
_material.SetTexture("_DepthTexture", _temporaries.depth);
_material.SetBuffer("_XYTable", _xyTable);
_material.SetFloat("_MaxDepth", _deviceSettings.maxDepth);
var prevRT = RenderTexture.active;
GraphicsExtensions.SetRenderTarget(_colorTexture, _positionTexture);
Graphics.Blit(null, _material, 0);
RenderTexture.active = prevRT;
2019-12-13 15:14:22 +00:00
azureDataUpdated.Invoke();
2019-12-12 12:08:41 +00:00
}
#endregion
}
}