Render 3DGS debug splats as quads

This commit is contained in:
2026-04-13 13:38:41 +08:00
parent 8ba05216fb
commit a0d5e84516
3 changed files with 41 additions and 10 deletions

View File

@@ -1,4 +1,19 @@
float4 MainPS(float4 position : SV_Position, float4 color : COLOR0) : SV_Target0
struct PixelInput
{
return color;
float4 position : SV_Position;
float4 color : COLOR0;
float2 localPosition : TEXCOORD0;
};
float4 MainPS(PixelInput input) : SV_Target0
{
float alpha = exp(-dot(input.localPosition, input.localPosition));
alpha = saturate(alpha * input.color.a);
if (alpha < (1.0 / 255.0))
{
discard;
}
return float4(input.color.rgb * alpha, alpha);
}

View File

@@ -17,23 +17,34 @@ struct VertexOutput
{
float4 position : SV_Position;
float4 color : COLOR0;
float2 localPosition : TEXCOORD0;
};
VertexOutput MainVS(uint vertexId : SV_VertexID, uint instanceId : SV_InstanceID)
{
VertexOutput output;
VertexOutput output = (VertexOutput)0;
uint splatIndex = gOrderBuffer[instanceId];
PreparedSplatView view = gPreparedViews[splatIndex];
float4 color = UnpackPreparedColor(view);
if (view.clipPosition.w <= 0.0)
{
output.position = float4(2.0, 2.0, 2.0, 1.0);
output.color = 0.0;
const float nanValue = asfloat(0x7fc00000);
output.position = float4(nanValue, nanValue, nanValue, nanValue);
return output;
}
float2 quadPosition = float2(vertexId & 1, (vertexId >> 1) & 1) * 2.0 - 1.0;
quadPosition *= 2.0;
float2 scaledAxis1 = view.axis1 * gSettings.w;
float2 scaledAxis2 = view.axis2 * gSettings.w;
float2 deltaScreenPosition =
(quadPosition.x * scaledAxis1 + quadPosition.y * scaledAxis2) * 2.0 / gScreenParams.xy;
output.position = view.clipPosition;
output.color = float4(color.rgb, 1.0);
output.position.xy += deltaScreenPosition * view.clipPosition.w;
output.color = color;
output.localPosition = quadPosition;
return output;
}

View File

@@ -209,7 +209,7 @@ FrameConstants BuildFrameConstants(uint32_t width, uint32_t height, uint32_t spl
constants.settings[0] = static_cast<float>(splatCount);
constants.settings[1] = 1.0f; // opacity scale
constants.settings[2] = 3.0f; // SH order
constants.settings[3] = 1.0f;
constants.settings[3] = 0.9f;
return constants;
}
@@ -1108,7 +1108,7 @@ bool App::InitializeDebugDrawResources() {
GraphicsPipelineDesc pipelineDesc = {};
pipelineDesc.pipelineLayout = m_debugPipelineLayout;
pipelineDesc.topologyType = static_cast<uint32_t>(PrimitiveTopologyType::Point);
pipelineDesc.topologyType = static_cast<uint32_t>(PrimitiveTopologyType::Triangle);
pipelineDesc.renderTargetCount = 1;
pipelineDesc.renderTargetFormats[0] = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
pipelineDesc.depthStencilFormat = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
@@ -1117,6 +1117,11 @@ bool App::InitializeDebugDrawResources() {
pipelineDesc.rasterizerState.cullMode = static_cast<uint32_t>(CullMode::None);
pipelineDesc.depthStencilState.depthTestEnable = false;
pipelineDesc.depthStencilState.depthWriteEnable = false;
pipelineDesc.blendState.blendEnable = true;
pipelineDesc.blendState.srcBlend = static_cast<uint32_t>(BlendFactor::One);
pipelineDesc.blendState.dstBlend = static_cast<uint32_t>(BlendFactor::InvSrcAlpha);
pipelineDesc.blendState.srcBlendAlpha = static_cast<uint32_t>(BlendFactor::One);
pipelineDesc.blendState.dstBlendAlpha = static_cast<uint32_t>(BlendFactor::InvSrcAlpha);
pipelineDesc.vertexShader.fileName = ResolveShaderPath(L"DebugPointsVS.hlsl").wstring();
pipelineDesc.vertexShader.entryPoint = L"MainVS";
@@ -1908,8 +1913,8 @@ void App::RenderFrame(bool captureScreenshot) {
m_commandList.SetPipelineState(m_debugPipelineState);
RHIDescriptorSet* debugSets[] = { m_debugDescriptorSet };
m_commandList.SetGraphicsDescriptorSets(0, 1, debugSets, m_debugPipelineLayout);
m_commandList.SetPrimitiveTopology(PrimitiveTopology::PointList);
m_commandList.Draw(1u, m_gaussianSceneData.splatCount, 0u, 0u);
m_commandList.SetPrimitiveTopology(PrimitiveTopology::TriangleStrip);
m_commandList.Draw(4u, m_gaussianSceneData.splatCount, 0u, 0u);
if (captureScreenshot) {
AppendTrace("RenderFrame: close+execute capture pre-screenshot");