Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 96 additions & 4 deletions package/Runtime/GaussianSplatURPFeature.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,104 @@
// SPDX-License-Identifier: MIT
#if GS_ENABLE_URP

#if !UNITY_6000_0_OR_NEWER
#error Unity Gaussian Splatting URP support only works in Unity 6 or later
#endif

using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

#if !UNITY_6000_0_OR_NEWER

namespace GaussianSplatting.Runtime
{
// Note: I have no idea what is the purpose of ScriptableRendererFeature vs ScriptableRenderPass, which one of those
// is supposed to do resource management vs logic, etc. etc. Code below "seems to work" but I'm just fumbling along,
// without understanding any of it.
//
// ReSharper disable once InconsistentNaming
class GaussianSplatURPFeature : ScriptableRendererFeature
{
class GSRenderPass : ScriptableRenderPass
{
RTHandle m_RenderTarget;
internal ScriptableRenderer m_Renderer = null;
internal CommandBuffer m_Cmb = null;

public void Dispose()
{
m_RenderTarget?.Release();
}

public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
RenderTextureDescriptor rtDesc = renderingData.cameraData.cameraTargetDescriptor;
rtDesc.depthBufferBits = 0;
rtDesc.msaaSamples = 1;
rtDesc.graphicsFormat = GraphicsFormat.R16G16B16A16_SFloat;
RenderingUtils.ReAllocateIfNeeded(ref m_RenderTarget, rtDesc, FilterMode.Point, TextureWrapMode.Clamp, name: "_GaussianSplatRT");
cmd.SetGlobalTexture(m_RenderTarget.name, m_RenderTarget.nameID);

ConfigureTarget(m_RenderTarget, m_Renderer.cameraDepthTargetHandle);
ConfigureClear(ClearFlag.Color, new Color(0,0,0,0));
}

public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (m_Cmb == null)
return;

// add sorting, view calc and drawing commands for each splat object
Material matComposite = GaussianSplatRenderSystem.instance.SortAndRenderSplats(renderingData.cameraData.camera, m_Cmb);

// compose
m_Cmb.BeginSample(GaussianSplatRenderSystem.s_ProfCompose);
Blitter.BlitCameraTexture(m_Cmb, m_RenderTarget, m_Renderer.cameraColorTargetHandle, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store, matComposite, 0);
m_Cmb.EndSample(GaussianSplatRenderSystem.s_ProfCompose);
context.ExecuteCommandBuffer(m_Cmb);
}
}

GSRenderPass m_Pass;
bool m_HasCamera;

public override void Create()
{
m_Pass = new GSRenderPass
{
renderPassEvent = RenderPassEvent.BeforeRenderingTransparents
};
}

public override void OnCameraPreCull(ScriptableRenderer renderer, in CameraData cameraData)
{
m_HasCamera = false;
var system = GaussianSplatRenderSystem.instance;
if (!system.GatherSplatsForCamera(cameraData.camera))
return;

CommandBuffer cmb = system.InitialClearCmdBuffer(cameraData.camera);
m_Pass.m_Cmb = cmb;
m_HasCamera = true;
}

public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if (!m_HasCamera)
return;
m_Pass.m_Renderer = renderer;
renderer.EnqueuePass(m_Pass);
}

protected override void Dispose(bool disposing)
{
m_Pass?.Dispose();
m_Pass = null;
}
}
}


#else

using UnityEngine.Rendering.RenderGraphModule;

namespace GaussianSplatting.Runtime
Expand Down Expand Up @@ -107,4 +197,6 @@ protected override void Dispose(bool disposing)
}
}

#endif

#endif // #if GS_ENABLE_URP