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);