From e32ad93020567868415e7a37f3f186290ba24f51 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 12 Apr 2022 21:48:52 +0200 Subject: [PATCH] Add support for sampling Scene Color in transparent materials (forward pass) --- .../Graphics/Materials/ForwardMaterialShader.cpp | 2 +- .../Engine/Graphics/Materials/MaterialParams.cpp | 4 +++- Source/Engine/Renderer/ForwardPass.cpp | 7 ++----- Source/Engine/Renderer/RenderList.cpp | 3 ++- Source/Engine/Renderer/RenderList.h | 8 +++++--- Source/Engine/Renderer/Renderer.cpp | 14 ++++---------- 6 files changed, 17 insertions(+), 21 deletions(-) diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index 5f9c385d4..a62ab9014 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -70,7 +70,7 @@ void ForwardMaterialShader::Bind(BindParameters& params) MaterialParameter::BindMeta bindMeta; bindMeta.Context = context; bindMeta.Constants = cb; - bindMeta.Input = nullptr; // forward pass materials cannot sample scene color for now + bindMeta.Input = params.Input; bindMeta.Buffers = params.RenderContext.Buffers; bindMeta.CanSampleDepth = GPUDevice::Instance->Limits.HasReadOnlyDepth; bindMeta.CanSampleGBuffer = true; diff --git a/Source/Engine/Graphics/Materials/MaterialParams.cpp b/Source/Engine/Graphics/Materials/MaterialParams.cpp index 7386343b5..c99d358e3 100644 --- a/Source/Engine/Graphics/Materials/MaterialParams.cpp +++ b/Source/Engine/Graphics/Materials/MaterialParams.cpp @@ -400,11 +400,13 @@ void MaterialParameter::Bind(BindMeta& meta) const { case MaterialSceneTextures::SceneDepth: view = meta.CanSampleDepth - ? (GPUDevice::Instance->Limits.HasReadOnlyDepth ? meta.Buffers->DepthBuffer->ViewReadOnlyDepth() : meta.Buffers->DepthBuffer->View()) + ? meta.Buffers->DepthBuffer->GetDescription().Flags & GPUTextureFlags::ReadOnlyDepthView ? meta.Buffers->DepthBuffer->ViewReadOnlyDepth() : meta.Buffers->DepthBuffer->View() : GPUDevice::Instance->GetDefaultWhiteTexture()->View(); break; case MaterialSceneTextures::AmbientOcclusion: case MaterialSceneTextures::BaseColor: + case MaterialSceneTextures::DiffuseColor: + case MaterialSceneTextures::SpecularColor: view = meta.CanSampleGBuffer ? meta.Buffers->GBuffer0->View() : nullptr; break; case MaterialSceneTextures::WorldNormal: diff --git a/Source/Engine/Renderer/ForwardPass.cpp b/Source/Engine/Renderer/ForwardPass.cpp index bf607ea6b..b853b71c4 100644 --- a/Source/Engine/Renderer/ForwardPass.cpp +++ b/Source/Engine/Renderer/ForwardPass.cpp @@ -74,10 +74,7 @@ void ForwardPass::Dispose() void ForwardPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output) { PROFILE_GPU_CPU("Forward"); - - // Cache data - auto device = GPUDevice::Instance; - auto context = device->GetMainContext(); + auto context = GPUDevice::Instance->GetMainContext(); auto& view = renderContext.View; auto mainCache = renderContext.List; @@ -141,6 +138,6 @@ void ForwardPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTex // Run forward pass view.Pass = DrawPass::Forward; context->SetRenderTarget(depthBufferHandle, output->View()); - mainCache->ExecuteDrawCalls(renderContext, forwardList); + mainCache->ExecuteDrawCalls(renderContext, forwardList, input->View()); } } diff --git a/Source/Engine/Renderer/RenderList.cpp b/Source/Engine/Renderer/RenderList.cpp index 09e6bc6b2..5df281aae 100644 --- a/Source/Engine/Renderer/RenderList.cpp +++ b/Source/Engine/Renderer/RenderList.cpp @@ -553,7 +553,7 @@ bool CanUseInstancing(DrawPass pass) return pass == DrawPass::GBuffer || pass == DrawPass::Depth; } -void RenderList::ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsList& list) +void RenderList::ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsList& list, GPUTextureView* input) { if (list.IsEmpty()) return; @@ -625,6 +625,7 @@ DRAW: // Execute draw calls MaterialBase::BindParameters bindParams(context, renderContext); + bindParams.Input = input; if (useInstancing) { int32 instanceBufferOffset = 0; diff --git a/Source/Engine/Renderer/RenderList.h b/Source/Engine/Renderer/RenderList.h index 1b514f824..7ff47014b 100644 --- a/Source/Engine/Renderer/RenderList.h +++ b/Source/Engine/Renderer/RenderList.h @@ -564,9 +564,10 @@ public: /// /// The rendering context. /// The collected draw calls list type. - API_FUNCTION() FORCE_INLINE void ExecuteDrawCalls(API_PARAM(Ref) const RenderContext& renderContext, DrawCallsListType listType) + /// The input scene color. It's optional and used in forward/postFx rendering. + API_FUNCTION() FORCE_INLINE void ExecuteDrawCalls(API_PARAM(Ref) const RenderContext& renderContext, DrawCallsListType listType, GPUTextureView* input = nullptr) { - ExecuteDrawCalls(renderContext, DrawCallsLists[(int32)listType]); + ExecuteDrawCalls(renderContext, DrawCallsLists[(int32)listType], input); } /// @@ -574,7 +575,8 @@ public: /// /// The rendering context. /// The collected draw calls list. - void ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsList& list); + /// The input scene color. It's optional and used in forward/postFx rendering. + void ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsList& list, GPUTextureView* input = nullptr); }; /// diff --git a/Source/Engine/Renderer/Renderer.cpp b/Source/Engine/Renderer/Renderer.cpp index d529447d9..7758e824e 100644 --- a/Source/Engine/Renderer/Renderer.cpp +++ b/Source/Engine/Renderer/Renderer.cpp @@ -45,7 +45,6 @@ Array PassList(64); class RendererService : public EngineService { public: - RendererService() : EngineService(TEXT("Renderer"), 20) { @@ -429,8 +428,9 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext) } // Run forward pass - auto forwardPassResult = renderContext.Buffers->RT1_FloatRGB; - ForwardPass::Instance()->Render(renderContext, lightBuffer, forwardPassResult); + GPUTexture* frameBuffer = renderContext.Buffers->RT1_FloatRGB; + GPUTexture* tempBuffer = renderContext.Buffers->RT2_FloatRGB; + ForwardPass::Instance()->Render(renderContext, lightBuffer, frameBuffer); // Cleanup context->ResetRenderTarget(); @@ -443,16 +443,10 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext) { context->SetRenderTarget(task->GetOutputView()); context->SetViewportAndScissors(task->GetOutputViewport()); - context->Draw(forwardPassResult); + context->Draw(frameBuffer); return; } - // Prepare buffers for post processing frame - GPUTexture* frameBuffer = renderContext.Buffers->RT1_FloatRGB; - GPUTexture* tempBuffer = renderContext.Buffers->RT2_FloatRGB; - if (forwardPassResult == tempBuffer) - Swap(frameBuffer, tempBuffer); - // Material and Custom PostFx renderContext.List->RunMaterialPostFxPass(context, renderContext, MaterialPostFxLocation::BeforePostProcessingPass, frameBuffer, tempBuffer); renderContext.List->RunCustomPostFxPass(context, renderContext, PostProcessEffectLocation::BeforePostProcessingPass, frameBuffer, tempBuffer);