diff --git a/Source/Engine/Graphics/Materials/DecalMaterialShader.cpp b/Source/Engine/Graphics/Materials/DecalMaterialShader.cpp index e93338604..dc510f331 100644 --- a/Source/Engine/Graphics/Materials/DecalMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/DecalMaterialShader.cpp @@ -47,7 +47,9 @@ void DecalMaterialShader::Bind(BindParameters& params) MaterialParams::Bind(params.ParamsLink, bindMeta); // Decals use depth buffer to draw on top of the objects - context->BindSR(0, GET_TEXTURE_VIEW_SAFE(params.RenderContext.Buffers->DepthBuffer)); + GPUTexture* depthBuffer = params.RenderContext.Buffers->DepthBuffer; + GPUTextureView* depthBufferView = EnumHasAnyFlags(depthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView) ? depthBuffer->ViewReadOnlyDepth() : depthBuffer->View(); + context->BindSR(0, depthBufferView); // Setup material constants { @@ -90,16 +92,20 @@ void DecalMaterialShader::Unload() bool DecalMaterialShader::Load() { GPUPipelineState::Description psDesc0 = GPUPipelineState::Description::DefaultNoDepth; - psDesc0.VS = _shader->GetVS("VS_Decal"); + psDesc0.VS = _shader->GetVS("VS_Decal"); // TODO: move VS_Decal to be shared (eg. in GBuffer.shader) if (psDesc0.VS == nullptr) return true; psDesc0.PS = _shader->GetPS("PS_Decal"); psDesc0.CullMode = CullMode::Normal; + if (GPUDevice::Instance->Limits.HasReadOnlyDepth) + { + psDesc0.DepthEnable = true; + psDesc0.DepthWriteEnable = false; + } switch (_info.DecalBlendingMode) { case MaterialDecalBlendingMode::Translucent: - { psDesc0.BlendMode.BlendEnable = true; psDesc0.BlendMode.SrcBlend = BlendingMode::Blend::SrcAlpha; psDesc0.BlendMode.DestBlend = BlendingMode::Blend::InvSrcAlpha; @@ -107,9 +113,7 @@ bool DecalMaterialShader::Load() psDesc0.BlendMode.DestBlendAlpha = BlendingMode::Blend::One; psDesc0.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RGB; break; - } case MaterialDecalBlendingMode::Stain: - { psDesc0.BlendMode.BlendEnable = true; psDesc0.BlendMode.SrcBlend = BlendingMode::Blend::DestColor; psDesc0.BlendMode.DestBlend = BlendingMode::Blend::InvSrcAlpha; @@ -117,9 +121,7 @@ bool DecalMaterialShader::Load() psDesc0.BlendMode.DestBlendAlpha = BlendingMode::Blend::One; psDesc0.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RGB; break; - } case MaterialDecalBlendingMode::Normal: - { psDesc0.BlendMode.BlendEnable = true; psDesc0.BlendMode.SrcBlend = BlendingMode::Blend::SrcAlpha; psDesc0.BlendMode.DestBlend = BlendingMode::Blend::InvSrcAlpha; @@ -127,13 +129,10 @@ bool DecalMaterialShader::Load() psDesc0.BlendMode.DestBlendAlpha = BlendingMode::Blend::One; psDesc0.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::RGB; break; - } case MaterialDecalBlendingMode::Emissive: - { psDesc0.BlendMode = BlendingMode::Additive; break; } - } _cache.Outside = GPUDevice::Instance->CreatePipelineState(); if (_cache.Outside->Init(psDesc0)) @@ -143,6 +142,7 @@ bool DecalMaterialShader::Load() } psDesc0.CullMode = CullMode::Inverted; + psDesc0.DepthEnable = false; _cache.Inside = GPUDevice::Instance->CreatePipelineState(); if (_cache.Inside->Init(psDesc0)) { diff --git a/Source/Engine/Renderer/GBufferPass.cpp b/Source/Engine/Renderer/GBufferPass.cpp index ee021d0ea..9d3684010 100644 --- a/Source/Engine/Renderer/GBufferPass.cpp +++ b/Source/Engine/Renderer/GBufferPass.cpp @@ -434,6 +434,7 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light PROFILE_GPU_CPU("Decals"); auto context = GPUDevice::Instance->GetMainContext(); auto buffers = renderContext.Buffers; + GPUTextureView* depthBuffer = EnumHasAnyFlags(buffers->DepthBuffer->Flags(), GPUTextureFlags::ReadOnlyDepthView) ? buffers->DepthBuffer->ViewReadOnlyDepth() : nullptr; // Sort decals from the lowest order to the highest order Sorting::QuickSort(decals.Get(), decals.Count(), &SortDecal); @@ -484,22 +485,22 @@ void GBufferPass::DrawDecals(RenderContext& renderContext, GPUTextureView* light count++; targetBuffers[2] = buffers->GBuffer1->View(); } - context->SetRenderTarget(nullptr, ToSpan(targetBuffers, count)); + context->SetRenderTarget(depthBuffer, ToSpan(targetBuffers, count)); break; } case MaterialDecalBlendingMode::Stain: { - context->SetRenderTarget(buffers->GBuffer0->View()); + context->SetRenderTarget(depthBuffer, buffers->GBuffer0->View()); break; } case MaterialDecalBlendingMode::Normal: { - context->SetRenderTarget(buffers->GBuffer1->View()); + context->SetRenderTarget(depthBuffer, buffers->GBuffer1->View()); break; } case MaterialDecalBlendingMode::Emissive: { - context->SetRenderTarget(lightBuffer); + context->SetRenderTarget(depthBuffer, lightBuffer); break; } }