Add support for sampling Scene Color in transparent materials (forward pass)

This commit is contained in:
Wojtek Figat
2022-04-12 21:48:52 +02:00
parent c99793d2a4
commit e32ad93020
6 changed files with 17 additions and 21 deletions

View File

@@ -70,7 +70,7 @@ void ForwardMaterialShader::Bind(BindParameters& params)
MaterialParameter::BindMeta bindMeta; MaterialParameter::BindMeta bindMeta;
bindMeta.Context = context; bindMeta.Context = context;
bindMeta.Constants = cb; 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.Buffers = params.RenderContext.Buffers;
bindMeta.CanSampleDepth = GPUDevice::Instance->Limits.HasReadOnlyDepth; bindMeta.CanSampleDepth = GPUDevice::Instance->Limits.HasReadOnlyDepth;
bindMeta.CanSampleGBuffer = true; bindMeta.CanSampleGBuffer = true;

View File

@@ -400,11 +400,13 @@ void MaterialParameter::Bind(BindMeta& meta) const
{ {
case MaterialSceneTextures::SceneDepth: case MaterialSceneTextures::SceneDepth:
view = meta.CanSampleDepth 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(); : GPUDevice::Instance->GetDefaultWhiteTexture()->View();
break; break;
case MaterialSceneTextures::AmbientOcclusion: case MaterialSceneTextures::AmbientOcclusion:
case MaterialSceneTextures::BaseColor: case MaterialSceneTextures::BaseColor:
case MaterialSceneTextures::DiffuseColor:
case MaterialSceneTextures::SpecularColor:
view = meta.CanSampleGBuffer ? meta.Buffers->GBuffer0->View() : nullptr; view = meta.CanSampleGBuffer ? meta.Buffers->GBuffer0->View() : nullptr;
break; break;
case MaterialSceneTextures::WorldNormal: case MaterialSceneTextures::WorldNormal:

View File

@@ -74,10 +74,7 @@ void ForwardPass::Dispose()
void ForwardPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output) void ForwardPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output)
{ {
PROFILE_GPU_CPU("Forward"); PROFILE_GPU_CPU("Forward");
auto context = GPUDevice::Instance->GetMainContext();
// Cache data
auto device = GPUDevice::Instance;
auto context = device->GetMainContext();
auto& view = renderContext.View; auto& view = renderContext.View;
auto mainCache = renderContext.List; auto mainCache = renderContext.List;
@@ -141,6 +138,6 @@ void ForwardPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTex
// Run forward pass // Run forward pass
view.Pass = DrawPass::Forward; view.Pass = DrawPass::Forward;
context->SetRenderTarget(depthBufferHandle, output->View()); context->SetRenderTarget(depthBufferHandle, output->View());
mainCache->ExecuteDrawCalls(renderContext, forwardList); mainCache->ExecuteDrawCalls(renderContext, forwardList, input->View());
} }
} }

View File

@@ -553,7 +553,7 @@ bool CanUseInstancing(DrawPass pass)
return pass == DrawPass::GBuffer || pass == DrawPass::Depth; 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()) if (list.IsEmpty())
return; return;
@@ -625,6 +625,7 @@ DRAW:
// Execute draw calls // Execute draw calls
MaterialBase::BindParameters bindParams(context, renderContext); MaterialBase::BindParameters bindParams(context, renderContext);
bindParams.Input = input;
if (useInstancing) if (useInstancing)
{ {
int32 instanceBufferOffset = 0; int32 instanceBufferOffset = 0;

View File

@@ -564,9 +564,10 @@ public:
/// </summary> /// </summary>
/// <param name="renderContext">The rendering context.</param> /// <param name="renderContext">The rendering context.</param>
/// <param name="listType">The collected draw calls list type.</param> /// <param name="listType">The collected draw calls list type.</param>
API_FUNCTION() FORCE_INLINE void ExecuteDrawCalls(API_PARAM(Ref) const RenderContext& renderContext, DrawCallsListType listType) /// <param name="input">The input scene color. It's optional and used in forward/postFx rendering.</param>
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);
} }
/// <summary> /// <summary>
@@ -574,7 +575,8 @@ public:
/// </summary> /// </summary>
/// <param name="renderContext">The rendering context.</param> /// <param name="renderContext">The rendering context.</param>
/// <param name="list">The collected draw calls list.</param> /// <param name="list">The collected draw calls list.</param>
void ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsList& list); /// <param name="input">The input scene color. It's optional and used in forward/postFx rendering.</param>
void ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsList& list, GPUTextureView* input = nullptr);
}; };
/// <summary> /// <summary>

View File

@@ -45,7 +45,6 @@ Array<RendererPassBase*> PassList(64);
class RendererService : public EngineService class RendererService : public EngineService
{ {
public: public:
RendererService() RendererService()
: EngineService(TEXT("Renderer"), 20) : EngineService(TEXT("Renderer"), 20)
{ {
@@ -429,8 +428,9 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext)
} }
// Run forward pass // Run forward pass
auto forwardPassResult = renderContext.Buffers->RT1_FloatRGB; GPUTexture* frameBuffer = renderContext.Buffers->RT1_FloatRGB;
ForwardPass::Instance()->Render(renderContext, lightBuffer, forwardPassResult); GPUTexture* tempBuffer = renderContext.Buffers->RT2_FloatRGB;
ForwardPass::Instance()->Render(renderContext, lightBuffer, frameBuffer);
// Cleanup // Cleanup
context->ResetRenderTarget(); context->ResetRenderTarget();
@@ -443,16 +443,10 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext)
{ {
context->SetRenderTarget(task->GetOutputView()); context->SetRenderTarget(task->GetOutputView());
context->SetViewportAndScissors(task->GetOutputViewport()); context->SetViewportAndScissors(task->GetOutputViewport());
context->Draw(forwardPassResult); context->Draw(frameBuffer);
return; 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 // Material and Custom PostFx
renderContext.List->RunMaterialPostFxPass(context, renderContext, MaterialPostFxLocation::BeforePostProcessingPass, frameBuffer, tempBuffer); renderContext.List->RunMaterialPostFxPass(context, renderContext, MaterialPostFxLocation::BeforePostProcessingPass, frameBuffer, tempBuffer);
renderContext.List->RunCustomPostFxPass(context, renderContext, PostProcessEffectLocation::BeforePostProcessingPass, frameBuffer, tempBuffer); renderContext.List->RunCustomPostFxPass(context, renderContext, PostProcessEffectLocation::BeforePostProcessingPass, frameBuffer, tempBuffer);