Add gaussian splat integration baseline

This commit is contained in:
2026-04-11 05:37:31 +08:00
parent 3622bf3aa2
commit 39632e1a04
11 changed files with 6813 additions and 175 deletions

View File

@@ -13,23 +13,26 @@ Shader "Builtin Gaussian Splat"
float4x4 gModelMatrix;
float4 gCameraRight;
float4 gCameraUp;
float4 gScreenParams;
float4 gSplatParams;
};
cbuffer MaterialConstants
{
float4 gSplatParams;
float4 gPointScaleParams;
float4 gOpacityScaleParams;
};
struct GaussianSplatOtherData
struct GaussianSplatViewData
{
float4 rotation;
float4 scaleReserved;
float4 clipCenter;
float4 ellipseAxisU;
float4 ellipseAxisV;
float4 colorOpacity;
};
StructuredBuffer<uint> GaussianSplatOrderBuffer;
StructuredBuffer<float3> GaussianSplatPositions;
StructuredBuffer<GaussianSplatOtherData> GaussianSplatOther;
StructuredBuffer<float4> GaussianSplatColor;
StructuredBuffer<GaussianSplatViewData> GaussianSplatViewDataBuffer;
struct VSOutput
{
@@ -53,39 +56,35 @@ Shader "Builtin Gaussian Splat"
VSOutput MainVS(uint vertexId : SV_VertexID, uint instanceId : SV_InstanceID)
{
VSOutput output;
const float2 corner = ResolveQuadCorner(vertexId);
VSOutput output = (VSOutput)0;
const uint splatIndex = GaussianSplatOrderBuffer[instanceId];
const float3 localCenter = GaussianSplatPositions[splatIndex];
const GaussianSplatOtherData otherData = GaussianSplatOther[splatIndex];
const float4 colorOpacity = GaussianSplatColor[splatIndex];
const GaussianSplatViewData viewData = GaussianSplatViewDataBuffer[splatIndex];
const float3 worldCenter = mul(gModelMatrix, float4(localCenter, 1.0)).xyz;
const float maxAxisScale =
max(max(otherData.scaleReserved.x, otherData.scaleReserved.y), otherData.scaleReserved.z);
const float radius = max(maxAxisScale * gSplatParams.x, 0.0001);
const float3 worldPosition =
worldCenter +
gCameraRight.xyz * (corner.x * radius) +
gCameraUp.xyz * (corner.y * radius);
if (viewData.clipCenter.w <= 0.0)
{
const float nanValue = asfloat(0x7fc00000u);
output.position = float4(nanValue, nanValue, nanValue, nanValue);
return output;
}
output.position = mul(gProjectionMatrix, mul(gViewMatrix, float4(worldPosition, 1.0)));
output.localUv = corner;
output.colorOpacity = colorOpacity;
const float2 quadPos = ResolveQuadCorner(vertexId) * 2.0;
const float2 ellipseOffsetPixels =
(quadPos.x * viewData.ellipseAxisU.xy + quadPos.y * viewData.ellipseAxisV.xy) * gPointScaleParams.x;
const float2 clipOffset =
ellipseOffsetPixels * (2.0 / max(gScreenParams.xy, float2(1.0, 1.0))) * viewData.clipCenter.w;
output.position = viewData.clipCenter;
output.position.xy += clipOffset;
output.localUv = quadPos;
output.colorOpacity = viewData.colorOpacity;
return output;
}
float4 MainPS(VSOutput input) : SV_TARGET
{
const float radiusSq = dot(input.localUv, input.localUv);
if (radiusSq > 1.0)
{
discard;
}
const float gaussianFalloff = exp(-radiusSq * 2.5);
const float alpha = saturate(input.colorOpacity.a * gSplatParams.y * gaussianFalloff);
if (alpha <= 0.001)
const float alpha =
saturate(exp(-dot(input.localUv, input.localUv)) * input.colorOpacity.a * gOpacityScaleParams.x);
if (alpha <= (1.0 / 255.0))
{
discard;
}