Skip to content

Commit

Permalink
VR support (PR #146 from ninjamode/vr-support)
Browse files Browse the repository at this point in the history
- Replace projection and view-projection matrices with Unity built-ins
- Update DeviceRadixSort to an newer version that has better GPU support (needed for Quest 3)
- Uses the eye texture size in screen size calculations when available

Reportedly this makes the URP version work on Desktop Steam VR (HTC Vive), Varjo devices (Aero), Quest 3 and Quest Pro via link and standalone. Note that Apple Vision Pro is not supported due to lack of single pass instanced rendering.
  • Loading branch information
aras-p authored Nov 28, 2024
2 parents 5d2dc7a + ab1028b commit d1ad241
Show file tree
Hide file tree
Showing 6 changed files with 1,405 additions and 691 deletions.
10 changes: 3 additions & 7 deletions package/Runtime/GaussianSplatRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.XR;

namespace GaussianSplatting.Runtime
{
Expand Down Expand Up @@ -301,9 +302,7 @@ internal static class Props
public static readonly int SrcBuffer = Shader.PropertyToID("_SrcBuffer");
public static readonly int DstBuffer = Shader.PropertyToID("_DstBuffer");
public static readonly int BufferSize = Shader.PropertyToID("_BufferSize");
public static readonly int MatrixVP = Shader.PropertyToID("_MatrixVP");
public static readonly int MatrixMV = Shader.PropertyToID("_MatrixMV");
public static readonly int MatrixP = Shader.PropertyToID("_MatrixP");
public static readonly int MatrixObjectToWorld = Shader.PropertyToID("_MatrixObjectToWorld");
public static readonly int MatrixWorldToObject = Shader.PropertyToID("_MatrixWorldToObject");
public static readonly int VecScreenParams = Shader.PropertyToID("_VecScreenParams");
Expand Down Expand Up @@ -552,15 +551,14 @@ internal void CalcViewData(CommandBuffer cmb, Camera cam, Matrix4x4 matrix)
Matrix4x4 matO2W = tr.localToWorldMatrix;
Matrix4x4 matW2O = tr.worldToLocalMatrix;
int screenW = cam.pixelWidth, screenH = cam.pixelHeight;
Vector4 screenPar = new Vector4(screenW, screenH, 0, 0);
int eyeW = XRSettings.eyeTextureWidth, eyeH = XRSettings.eyeTextureHeight;
Vector4 screenPar = new Vector4(eyeW != 0 ? eyeW : screenW, eyeH != 0 ? eyeH : screenH, 0, 0);
Vector4 camPos = cam.transform.position;

// calculate view dependent data for each splat
SetAssetDataOnCS(cmb, KernelIndices.CalcViewData);

cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixVP, matProj * matView);
cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixMV, matView * matO2W);
cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixP, matProj);
cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixObjectToWorld, matO2W);
cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixWorldToObject, matW2O);

Expand Down Expand Up @@ -784,9 +782,7 @@ public void EditUpdateSelection(Vector2 rectMin, Vector2 rectMax, Camera cam, bo
using var cmb = new CommandBuffer { name = "SplatSelectionUpdate" };
SetAssetDataOnCS(cmb, KernelIndices.SelectionUpdate);

cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixVP, matProj * matView);
cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixMV, matView * matO2W);
cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixP, matProj);
cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixObjectToWorld, matO2W);
cmb.SetComputeMatrixParam(m_CSSplatUtilities, Props.MatrixWorldToObject, matW2O);

Expand Down
24 changes: 23 additions & 1 deletion package/Runtime/GpuSorting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace GaussianSplatting.Runtime
{
// GPU (uint key, uint payload) 8 bit-LSD radix sort, using reduce-then-scan
// Copyright Thomas Smith 2023, MIT license
// Copyright Thomas Smith 2024, MIT license
// https://github.com/b0nes164/GPUSorting

public class GpuSorting
Expand All @@ -22,6 +22,13 @@ public class GpuSorting
//Number of sorting passes required to sort a 32bit key, KEY_BITS / DEVICE_RADIX_SORT_BITS
const uint DEVICE_RADIX_SORT_PASSES = 4;

//Keywords to enable for the shader
private LocalKeyword m_keyUintKeyword;
private LocalKeyword m_payloadUintKeyword;
private LocalKeyword m_ascendKeyword;
private LocalKeyword m_sortPairKeyword;
private LocalKeyword m_vulkanKeyword;

public struct Args
{
public uint count;
Expand Down Expand Up @@ -104,6 +111,21 @@ public GpuSorting(ComputeShader cs)
m_Valid = false;
}
}

m_keyUintKeyword = new LocalKeyword(cs, "KEY_UINT");
m_payloadUintKeyword = new LocalKeyword(cs, "PAYLOAD_UINT");
m_ascendKeyword = new LocalKeyword(cs, "SHOULD_ASCEND");
m_sortPairKeyword = new LocalKeyword(cs, "SORT_PAIRS");
m_vulkanKeyword = new LocalKeyword(cs, "VULKAN");

cs.EnableKeyword(m_keyUintKeyword);
cs.EnableKeyword(m_payloadUintKeyword);
cs.EnableKeyword(m_ascendKeyword);
cs.EnableKeyword(m_sortPairKeyword);
if (SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Vulkan)
cs.EnableKeyword(m_vulkanKeyword);
else
cs.DisableKeyword(m_vulkanKeyword);
}

static uint DivRoundUp(uint x, uint y) => (x + y - 1) / y;
Expand Down
Loading

0 comments on commit d1ad241

Please sign in to comment.