Fixed stamped decals not rendering correctly

This commit is contained in:
Justin Marshall
2026-05-22 08:12:09 -07:00
parent f2e8b0b45e
commit 686422ec83
4 changed files with 36 additions and 7 deletions
+2 -1
View File
@@ -4088,7 +4088,8 @@ static classVariableInfo_t glScreenSpaceDecal_t_typeInfo[] = {
{ "float", "pad0", (intptr_t)(&((glScreenSpaceDecal_t *)0)->pad0), sizeof( ((glScreenSpaceDecal_t *)0)->pad0 ) },
{ "float[4]", "color", (intptr_t)(&((glScreenSpaceDecal_t *)0)->color), sizeof( ((glScreenSpaceDecal_t *)0)->color ) },
{ "uint32_t", "textureId", (intptr_t)(&((glScreenSpaceDecal_t *)0)->textureId), sizeof( ((glScreenSpaceDecal_t *)0)->textureId ) },
{ "float[3]", "pad1", (intptr_t)(&((glScreenSpaceDecal_t *)0)->pad1), sizeof( ((glScreenSpaceDecal_t *)0)->pad1 ) },
{ "uint32_t", "blendMode", (intptr_t)(&((glScreenSpaceDecal_t *)0)->blendMode), sizeof( ((glScreenSpaceDecal_t *)0)->blendMode ) },
{ "float[2]", "pad1", (intptr_t)(&((glScreenSpaceDecal_t *)0)->pad1), sizeof( ((glScreenSpaceDecal_t *)0)->pad1 ) },
{ NULL, 0 }
};
+23 -5
View File
@@ -1705,6 +1705,7 @@ struct GLState
ComPtr<ID3D12PipelineState> postDepthResolveMsaaPSO;
ComPtr<ID3D12PipelineState> postGBufferPointResolveMsaaPSO;
ComPtr<ID3D12PipelineState> postScreenDecalPSO;
ComPtr<ID3D12PipelineState> postScreenDecalStainPSO;
ComPtr<ID3DBlob> vsMainBlob;
ComPtr<ID3DBlob> hsMainBlob;
@@ -4407,7 +4408,8 @@ struct ScreenSpaceDecal
float pad0;
float4 color;
uint textureId;
float3 pad1;
uint blendMode;
float2 pad1;
};
StructuredBuffer<ScreenSpaceDecal> gScreenDecals : register(t13);
@@ -4542,8 +4544,16 @@ float4 PSScreenDecals(VSOut i) : SV_Target0
float4 texel = gTex0.Sample(gSamp0, texUv);
float edge = smoothstep(1.0, 0.75, max(abs(uv.x), abs(uv.y)));
float mask = saturate(d.opacity) * facing * depthFade * edge * saturate(d.color.a) * saturate(texel.a);
decalColor = texel.rgb * saturate(d.color.rgb);
decalAlpha = mask;
if (d.blendMode == 1u)
{
decalColor = saturate(texel.rgb * mask);
decalAlpha = 1.0;
}
else
{
decalColor = texel.rgb * saturate(d.color.rgb);
decalAlpha = mask;
}
return float4(decalColor, decalAlpha);
}
@@ -4842,7 +4852,8 @@ float PSDepthResolveMS(VSOut i) : SV_Depth
return depth;
}
)HLSL"
R"HLSL(
struct PSGBufferPointResolveOut
{
float4 normal : SV_Target0;
@@ -8049,7 +8060,6 @@ void APIENTRY glDrawScreenSpaceDecalsQD3D12(void)
cl->SetDescriptorHeaps(_countof(heaps), heaps);
cl->SetGraphicsRootSignature(g_gl.postRootSig.Get());
QD3D12_SetPostConstants(cl, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, false, (float)g_gl.screenSpaceDecalCount);
cl->SetPipelineState(g_gl.postScreenDecalPSO.Get());
D3D12_CPU_DESCRIPTOR_HANDLE sceneColorRtv = CurrentResolvedSceneColorRTV();
cl->OMSetRenderTargets(1, &sceneColorRtv, FALSE, nullptr);
cl->RSSetViewports(1, &viewport);
@@ -8059,6 +8069,8 @@ void APIENTRY glDrawScreenSpaceDecalsQD3D12(void)
{
D3D12_GPU_DESCRIPTOR_HANDLE decalTextureSrv = g_gl.whiteTexture.srvGpu;
const glScreenSpaceDecal_t& decal = g_gl.screenSpaceDecals[decalIndex];
ID3D12PipelineState* decalPSO = (decal.blendMode == 1 && g_gl.postScreenDecalStainPSO.Get() != nullptr) ? g_gl.postScreenDecalStainPSO.Get() : g_gl.postScreenDecalPSO.Get();
cl->SetPipelineState(decalPSO);
TextureResource* decalTexture = decal.textureId ? QD3D12_FindTextureResource(decal.textureId) : nullptr;
if (decalTexture)
{
@@ -9795,6 +9807,12 @@ static void QD3D12_CreatePSOs()
d.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
QD3D12_CHECK(g_gl.device->CreateGraphicsPipelineState(&d, IID_PPV_ARGS(&g_gl.postScreenDecalPSO)));
d.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ZERO;
d.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_COLOR;
d.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ZERO;
d.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ONE;
QD3D12_CHECK(g_gl.device->CreateGraphicsPipelineState(&d, IID_PPV_ARGS(&g_gl.postScreenDecalStainPSO)));
D3D12_GRAPHICS_PIPELINE_STATE_DESC depthDesc{};
depthDesc.pRootSignature = g_gl.postRootSig.Get();
depthDesc.VS = { g_gl.postVsBlob->GetBufferPointer(), g_gl.postVsBlob->GetBufferSize() };
+2 -1
View File
@@ -1740,7 +1740,8 @@ typedef struct glScreenSpaceDecal_s
float pad0;
float color[4];
uint32_t textureId;
float pad1[3];
uint32_t blendMode; // 0 = alpha blend, 1 = multiplicative stain
float pad1[2];
} glScreenSpaceDecal_t;
int glRaytracingInit(void);
+9
View File
@@ -187,9 +187,18 @@ void idRenderWorldLocal::SubmitWorldDecalsToScreenSpace() const {
dst.color[2] = src.color.z;
dst.color[3] = src.color.w;
dst.textureId = 0;
dst.blendMode = 0;
const idMaterial* mat = declManager->FindMaterial(src.material.c_str());
idImage* image = mat ? mat->GetEditorImage() : NULL;
if (mat && mat->GetNumStages() > 0) {
const shaderStage_t* stage = mat->GetStage(0);
const int srcBlend = stage->drawStateBits & GLS_SRCBLEND_BITS;
const int dstBlend = stage->drawStateBits & GLS_DSTBLEND_BITS;
if (srcBlend == GLS_SRCBLEND_ZERO && dstBlend == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR) {
dst.blendMode = 1;
}
}
#ifndef QUAKE4
if (mat && src.color.x == 1.0f && src.color.y == 1.0f && src.color.z == 1.0f && src.color.w == 1.0f) {
decalInfo_t decalInfo = mat->GetDecalInfo();