remove fake dependencies on the PER_VIEW UBO
The PER_VIEW UBO was updated by different render passes at different times, which created synchronizations on the GPU, between unrelated passes and prevented the vertex shader to run on parallel with another pass for instance. In the PR, we fix this by moving ALL the UBO set-up outside of render passes. It's now done early, just before creating the framegraph. The PER_VIEW UBO is shared between several passes, themselves using different descriptor sets; so we need to make sure all the data necessary for these passes is computed and set in the UBO (e.g. SSR passes). The passes themselves (like the color pass) still set the textures and UBOs in their descriptor sets, but then no longer updated the content of the UBO itself. In this PR we also remove some "fake" dependencies between passes due to descriptor sets straddling between passes. This is done by unbinding all descriptor sets at the end of each pass. The PER_MATERIAL descriptor set is a bit special because it should be unbound between full screen quads draws. Additionally, there some places in the code attempting to update UBOs only when the content was dirty were missing a "clean" call, to reset the dirty bit to the unset state. The main change here is to move the code that set the UBO content out of the ColorPassDescriptorSet (and a few other) into View and instead of updating the content in the color pass (and a few other), do that at the beginning of Renderer::render().
This commit is contained in:
committed by
Mathias Agopian
parent
b4c9b9f489
commit
ee8d0e6ebf
@@ -421,6 +421,12 @@ void PostProcessManager::resetForRender() {
|
||||
mFixedMaterialInstanceIndex = {};
|
||||
}
|
||||
|
||||
void PostProcessManager::unbindAllDescriptorSets(DriverApi& driver) noexcept {
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_VIEW);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_RENDERABLE);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
PipelineState PostProcessManager::getPipelineState(
|
||||
FMaterial const* const ma, PostProcessVariant variant) const noexcept {
|
||||
@@ -484,6 +490,7 @@ void PostProcessManager::commitAndRenderFullScreenQuad(DriverApi& driver,
|
||||
driver.beginRenderPass(out.target, out.params);
|
||||
driver.draw(pipeline, mFullScreenQuadRph, 0, 3, 1);
|
||||
driver.endRenderPass();
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -556,11 +563,7 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
|
||||
driver.beginRenderPass(out.target, out.params);
|
||||
pass.getExecutor().execute(mEngine, driver);
|
||||
driver.endRenderPass();
|
||||
|
||||
// unbind all descriptor sets to avoid false dependencies with the next pass
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_VIEW);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_RENDERABLE);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
auto const depth = structurePass->depth;
|
||||
@@ -607,8 +610,10 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
|
||||
mi->commit(driver);
|
||||
mi->use(driver);
|
||||
renderFullScreenQuad(out, pipeline, driver);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
driver.destroyTexture(th);
|
||||
}
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return { depth, structurePass->picking };
|
||||
@@ -666,11 +671,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::transparentPicking(FrameGrap
|
||||
driver.beginRenderPass(target, params);
|
||||
pass.getExecutor().execute(mEngine, driver);
|
||||
driver.endRenderPass();
|
||||
|
||||
// unbind all descriptor sets to avoid false dependencies with the next pass
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_VIEW);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_RENDERABLE);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return pickingRenderPass->picking;
|
||||
@@ -681,9 +682,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::transparentPicking(FrameGrap
|
||||
FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,
|
||||
RenderPassBuilder const& passBuilder,
|
||||
FrameHistory const& frameHistory,
|
||||
CameraInfo const& cameraInfo,
|
||||
FrameGraphId<FrameGraphTexture> const structure,
|
||||
ScreenSpaceReflectionsOptions const& options,
|
||||
FrameGraphTexture::Descriptor const& desc) noexcept {
|
||||
|
||||
struct SSRPassData {
|
||||
@@ -704,8 +703,6 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,
|
||||
|
||||
FrameGraphId<FrameGraphTexture> const history = fg.import("SSR history", previous.desc,
|
||||
FrameGraphTexture::Usage::SAMPLEABLE, previous.color);
|
||||
mat4 const& historyProjection = previous.projection;
|
||||
auto const& uvFromClipMatrix = mEngine.getUvFromClipMatrix();
|
||||
|
||||
auto const& ssrPass = fg.addPass<SSRPassData>("SSR Pass",
|
||||
[&](FrameGraph::Builder& builder, auto& data) {
|
||||
@@ -739,23 +736,16 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,
|
||||
data.history = builder.sample(history);
|
||||
}
|
||||
},
|
||||
[this, projection = cameraInfo.projection,
|
||||
userViewMatrix = cameraInfo.getUserViewMatrix(), uvFromClipMatrix, historyProjection,
|
||||
options, passBuilder = passBuilder]
|
||||
(FrameGraphResources const& resources, auto const& data, DriverApi& driver) mutable {
|
||||
[this, passBuilder = passBuilder](FrameGraphResources const& resources,
|
||||
auto const& data, DriverApi& driver) mutable {
|
||||
// set structure sampler
|
||||
mSsrPassDescriptorSet.prepareStructure(mEngine, data.structure ?
|
||||
resources.getTexture(data.structure) : getOneTexture());
|
||||
|
||||
// set screen-space reflections and screen-space refractions
|
||||
mat4f const uvFromViewMatrix = uvFromClipMatrix * projection;
|
||||
mat4f const reprojection = uvFromClipMatrix *
|
||||
mat4f{ historyProjection * inverse(userViewMatrix) };
|
||||
|
||||
// the history sampler is a regular texture2D
|
||||
TextureHandle const history = data.history ?
|
||||
resources.getTexture(data.history) : getZeroTexture();
|
||||
mSsrPassDescriptorSet.prepareHistorySSR(mEngine, history, reprojection, uvFromViewMatrix, options);
|
||||
mSsrPassDescriptorSet.prepareHistorySSR(mEngine, history);
|
||||
|
||||
mSsrPassDescriptorSet.commit(mEngine);
|
||||
|
||||
@@ -777,11 +767,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,
|
||||
driver.beginRenderPass(out.target, out.params);
|
||||
pass.getExecutor().execute(mEngine, driver);
|
||||
driver.endRenderPass();
|
||||
|
||||
// unbind all descriptor sets to avoid false dependencies with the next pass
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_VIEW);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_RENDERABLE);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return ssrPass->reflections;
|
||||
@@ -1047,6 +1033,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::screenSpaceAmbientOcclusion(
|
||||
pipeline.rasterState.depthFunc = RasterState::DepthFunc::L;
|
||||
assert_invariant(ssao.params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH);
|
||||
renderFullScreenQuad(ssao, pipeline, driver);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
FrameGraphId<FrameGraphTexture> ssao = SSAOPass->ssao;
|
||||
@@ -1165,6 +1152,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::bilateralBlurPass(FrameGraph
|
||||
auto pipeline = getPipelineState(ma);
|
||||
pipeline.rasterState.depthFunc = RasterState::DepthFunc::L;
|
||||
renderFullScreenQuad(blurred, pipeline, driver);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return blurPass->blurred;
|
||||
@@ -1381,6 +1369,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::gaussianBlurPass(FrameGraph&
|
||||
|
||||
commitAndRenderFullScreenQuad(driver, hwOutRT, mi);
|
||||
}
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return blurPass->out;
|
||||
@@ -1783,6 +1772,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
|
||||
1.0f / float(colorDesc.width),
|
||||
1.0f / float(colorDesc.height) });
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
/*
|
||||
@@ -1849,10 +1839,12 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
|
||||
mi->use(driver);
|
||||
|
||||
renderFullScreenQuad(out, pipeline, driver);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
|
||||
driver.destroyTexture(inColor);
|
||||
driver.destroyTexture(inCoc);
|
||||
}
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
/*
|
||||
@@ -1908,6 +1900,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
|
||||
mi->setParameter("cocMinMax", inCocMinMax, { .filterMin = SamplerMinFilter::NEAREST });
|
||||
mi->setParameter("texelSize", float2{ 1.0f / inputDesc.width, 1.0f / inputDesc.height });
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
inTilesCocMinMax = ppDoFTiling->outTilesCocMinMax;
|
||||
}
|
||||
@@ -1940,6 +1933,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
|
||||
FMaterialInstance* const mi = getMaterialInstance(mEngine, material);
|
||||
mi->setParameter("tiles", inTilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST });
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
return ppDoFDilate->outTilesCocMinMax;
|
||||
};
|
||||
@@ -2019,6 +2013,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
|
||||
});
|
||||
mi->setParameter("bokehAngle", bokehAngle);
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
/*
|
||||
@@ -2062,6 +2057,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
|
||||
mi->setParameter("alpha", inAlpha, { .filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST });
|
||||
mi->setParameter("tiles", tilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST });
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
|
||||
@@ -2111,6 +2107,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
|
||||
mi->setParameter("alpha", alpha, { .filterMag = SamplerMagFilter::NEAREST });
|
||||
mi->setParameter("tiles", tilesCocMinMax, { .filterMin = SamplerMinFilter::NEAREST });
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return ppDoFCombine->output;
|
||||
@@ -2145,7 +2142,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::downscalePass(FrameGraph& fg
|
||||
mi->setParameter("fireflies", fireflies ? 1.0f : 0.0f);
|
||||
mi->setParameter("invHighlight", std::isinf(highlight) ? 0.0f : 1.0f / highlight);
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
return downsamplePass->output;
|
||||
}
|
||||
@@ -2301,6 +2298,7 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
|
||||
commitAndRenderFullScreenQuad(driver, hwDstRT, mi);
|
||||
driver.destroyTexture(hwOutView);
|
||||
}
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
// output of bloom downsample pass becomes input of next (flare) pass
|
||||
@@ -2348,8 +2346,10 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
|
||||
mi->commit(driver);
|
||||
mi->use(driver);
|
||||
renderFullScreenQuad(hwDstRT, pipeline, driver);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
driver.destroyTexture(hwOutView);
|
||||
}
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return { bloomUpsamplePass->out, flare };
|
||||
@@ -2403,6 +2403,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::flarePass(FrameGraph& fg,
|
||||
mi->setParameter("haloThickness", bloomOptions.haloThickness);
|
||||
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
constexpr float kernelWidth = 9;
|
||||
@@ -2661,6 +2662,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::colorGrading(FrameGraph& fg,
|
||||
commitAndRenderFullScreenQuad(driver, out, mi,
|
||||
colorGradingConfig.translucent
|
||||
? PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE);
|
||||
|
||||
unbindAllDescriptorSets(driver);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2713,6 +2716,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::fxaa(FrameGraph& fg,
|
||||
mi->setParameter("texelSize", 1.0f / float2{ inDesc.width, inDesc.height });
|
||||
|
||||
commitAndRenderFullScreenQuad(driver, out, mi, variant);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return ppFXAA->output;
|
||||
@@ -2997,6 +3001,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
|
||||
colorGradingSubpass(driver, colorGradingConfig);
|
||||
}
|
||||
driver.endRenderPass();
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
input = colorGradingConfig.asSubpass ? taaPass->tonemappedOutput : taaPass->output;
|
||||
@@ -3066,6 +3071,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::rcas(
|
||||
outputDesc.width, outputDesc.height,
|
||||
1.0f / outputDesc.width, 1.0f / outputDesc.height });
|
||||
commitAndRenderFullScreenQuad(driver, out, mi, variant);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return ppFsrRcas->output;
|
||||
@@ -3145,6 +3151,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscaleBilinear(FrameGraph&
|
||||
|
||||
auto pipeline = getPipelineState(material.getMaterial(mEngine));
|
||||
renderFullScreenQuad(out, pipeline, driver);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
auto output = ppQuadBlit->output;
|
||||
@@ -3219,9 +3226,9 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscaleSGSR1(FrameGraph& fg,
|
||||
mi->commit(driver);
|
||||
mi->use(driver);
|
||||
|
||||
auto out = resources.getRenderPassInfo();
|
||||
auto const out = resources.getRenderPassInfo();
|
||||
commitAndRenderFullScreenQuad(driver, out, mi, variant);
|
||||
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
auto output = ppQuadBlit->output;
|
||||
@@ -3358,6 +3365,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscaleFSR1(FrameGraph& fg,
|
||||
auto pipeline = getPipelineState(easuMaterial->getMaterial(mEngine));
|
||||
renderFullScreenQuad(out, pipeline, driver);
|
||||
}
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
auto output = ppQuadBlit->output;
|
||||
@@ -3432,6 +3440,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::blit(FrameGraph& fg, bool co
|
||||
pipeline.rasterState.blendFunctionDstAlpha = BlendFunction::ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
renderFullScreenQuad(out, pipeline, driver);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return ppQuadBlit->output;
|
||||
@@ -3515,6 +3524,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::blitDepth(FrameGraph& fg,
|
||||
float(vp.bottom) / inputDesc.height, float(vp.width) / inputDesc.width,
|
||||
float(vp.height) / inputDesc.height});
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return ppQuadBlit->output;
|
||||
@@ -3619,6 +3629,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::resolveDepth(FrameGraph& fg,
|
||||
getMaterialInstance(mEngine, material);
|
||||
mi->setParameter("depth", input, {}); // NEAREST
|
||||
commitAndRenderFullScreenQuad(driver, resources.getRenderPassInfo(), mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return ppResolve->output;
|
||||
@@ -3678,6 +3689,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::vsmMipmapPass(FrameGraph& fg
|
||||
mi->use(driver);
|
||||
|
||||
renderFullScreenQuadWithScissor(out, pipeline, scissor, driver);
|
||||
unbindAllDescriptorSets(driver);
|
||||
|
||||
driver.destroyTexture(in); // `in` is just a view on `data.in`
|
||||
});
|
||||
@@ -3714,6 +3726,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugShadowCascades(FrameGra
|
||||
mi->setParameter("color", color, {}); // nearest
|
||||
mi->setParameter("depth", depth, {}); // nearest
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return debugShadowCascadePass->output;
|
||||
@@ -3791,11 +3804,13 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(Fra
|
||||
mi->setParameter("layerIndex", i);
|
||||
mi->commit(driver);
|
||||
renderFullScreenQuad(out, pipeline, driver);
|
||||
DescriptorSet::unbind(driver, DescriptorSetBindingPoints::PER_MATERIAL);
|
||||
// From the second draw, don't clear the targetbuffer.
|
||||
out.params.flags.clear = TargetBufferFlags::NONE;
|
||||
out.params.flags.discardStart = TargetBufferFlags::NONE;
|
||||
out.params.viewport.left += out.params.viewport.width;
|
||||
}
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
|
||||
return ppQuadBlit->output;
|
||||
@@ -3842,6 +3857,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugDisplayShadowTexture(
|
||||
mi->setParameter("channel", (uint32_t)channel);
|
||||
mi->setParameter("power", power);
|
||||
commitAndRenderFullScreenQuad(driver, out, mi);
|
||||
unbindAllDescriptorSets(driver);
|
||||
});
|
||||
input = shadomapDebugPass->color;
|
||||
}
|
||||
|
||||
@@ -114,9 +114,7 @@ public:
|
||||
FrameGraphId<FrameGraphTexture> ssr(FrameGraph& fg,
|
||||
RenderPassBuilder const& passBuilder,
|
||||
FrameHistory const& frameHistory,
|
||||
CameraInfo const& cameraInfo,
|
||||
FrameGraphId<FrameGraphTexture> structure,
|
||||
ScreenSpaceReflectionsOptions const& options,
|
||||
FrameGraphTexture::Descriptor const& desc) noexcept;
|
||||
|
||||
// SSAO
|
||||
@@ -395,6 +393,7 @@ public:
|
||||
void resetForRender();
|
||||
|
||||
private:
|
||||
static void unbindAllDescriptorSets(backend::DriverApi& driver) noexcept;
|
||||
|
||||
// Helper to get a MaterialInstance from a FMaterial
|
||||
// This currently just call FMaterial::getDefaultInstance().
|
||||
|
||||
@@ -208,37 +208,23 @@ RendererUtils::ColorPassOutput RendererUtils::colorPass(
|
||||
view.prepareSSAO(data.ssao ?
|
||||
resources.getTexture(data.ssao) : engine.getOneTextureArray());
|
||||
|
||||
view.prepareShadowMapping(engine, view.getVsmShadowOptions().highPrecision);
|
||||
|
||||
// set shadow sampler
|
||||
view.prepareShadow(data.shadows ?
|
||||
resources.getTexture(data.shadows) :
|
||||
(view.getShadowType() != ShadowType::PCF ?
|
||||
engine.getOneTextureArray() : engine.getOneTextureArrayDepth()));
|
||||
// set screen-space reflections and screen-space refractions
|
||||
view.prepareSSR(data.ssr ?
|
||||
resources.getTexture(data.ssr) : engine.getOneTextureArray());
|
||||
|
||||
// set structure sampler
|
||||
view.prepareStructure(data.structure ?
|
||||
resources.getTexture(data.structure) : engine.getOneTexture());
|
||||
|
||||
// set screen-space reflections and screen-space refractions
|
||||
TextureHandle const ssr = data.ssr ?
|
||||
resources.getTexture(data.ssr) : engine.getOneTextureArray();
|
||||
// set shadow sampler
|
||||
view.prepareShadowMapping(engine,
|
||||
data.shadows
|
||||
? resources.getTexture(data.shadows)
|
||||
: (view.getShadowType() != ShadowType::PCF
|
||||
? engine.getOneTextureArray()
|
||||
: engine.getOneTextureArrayDepth()));
|
||||
|
||||
view.prepareSSR(ssr, config.screenSpaceReflectionHistoryNotReady,
|
||||
config.ssrLodOffset, view.getScreenSpaceReflectionsOptions());
|
||||
|
||||
// Note: here we can't use data.color's descriptor for the viewport because
|
||||
// the actual viewport might be offset when the target is the swapchain.
|
||||
// However, the width/height should be the same.
|
||||
assert_invariant(
|
||||
out.params.viewport.width == resources.getDescriptor(data.color).width);
|
||||
assert_invariant(
|
||||
out.params.viewport.height == resources.getDescriptor(data.color).height);
|
||||
|
||||
view.prepareViewport(static_cast<filament::Viewport&>(out.params.viewport),
|
||||
config.logicalViewport);
|
||||
|
||||
view.commitUniformsAndSamplers(driver);
|
||||
view.commitDescriptorSet(driver);
|
||||
|
||||
// TODO: this should be a parameter of FrameGraphRenderPass::Descriptor
|
||||
out.params.clearStencil = config.clearStencil;
|
||||
|
||||
@@ -65,16 +65,12 @@ public:
|
||||
math::float4 clearColor = {};
|
||||
// Clear stencil
|
||||
uint8_t clearStencil = 0u;
|
||||
// Lod offset for the SSR passes
|
||||
float ssrLodOffset;
|
||||
// Contact shadow enabled?
|
||||
bool hasContactShadows;
|
||||
// Screen space reflections enabled
|
||||
bool hasScreenSpaceReflectionsOrRefractions;
|
||||
// Use a depth format with a stencil component.
|
||||
bool enabledStencilBuffer;
|
||||
// whether the screenspace reflections history buffer is initialized
|
||||
bool screenSpaceReflectionHistoryNotReady;
|
||||
};
|
||||
|
||||
struct ColorPassInput {
|
||||
|
||||
@@ -436,6 +436,7 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FEngine& engine, FrameG
|
||||
|
||||
// Finally update our UBO in one batch
|
||||
if (mShadowUb.isDirty()) {
|
||||
mShadowUb.clean();
|
||||
driver.updateBufferObject(mShadowUbh,
|
||||
mShadowUb.toBufferDescriptor(driver), 0);
|
||||
}
|
||||
|
||||
@@ -222,6 +222,7 @@ void FMaterialInstance::commit(FEngine& engine) const {
|
||||
void FMaterialInstance::commit(DriverApi& driver) const {
|
||||
// update uniforms if needed
|
||||
if (mUniforms.isDirty() || mHasStreamUniformAssociations) {
|
||||
mUniforms.clean();
|
||||
driver.updateBufferObject(mUbHandle, mUniforms.toBufferDescriptor(driver), 0);
|
||||
}
|
||||
if (!mTextureParameters.empty()) {
|
||||
|
||||
@@ -830,29 +830,57 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
xvp.bottom = int32_t(guardBand);
|
||||
}
|
||||
|
||||
/*
|
||||
* Frame graph
|
||||
*/
|
||||
FrameGraph fg(*mResourceAllocator,
|
||||
isProtectedContent ? FrameGraph::Mode::PROTECTED : FrameGraph::Mode::UNPROTECTED);
|
||||
auto& blackboard = fg.getBlackboard();
|
||||
|
||||
PostProcessManager::ScreenSpaceRefConfig const ssrConfig = PostProcessManager::prepareMipmapSSR(
|
||||
fg, svp.width, svp.height,
|
||||
ssReflectionsOptions.enabled ? TextureFormat::RGBA16F : TextureFormat::R11F_G11F_B10F,
|
||||
view.getCameraUser().getFieldOfView(Camera::Fov::VERTICAL), scale);
|
||||
|
||||
/*
|
||||
* Update the PER_VIEW UBO used for the color, ssr and postfx passes. This UBO is never
|
||||
* updated again during the frame.
|
||||
*/
|
||||
|
||||
auto [bias, derivativeScale] = prepareUpscaler(scale, taaOptions, dsrOptions);
|
||||
|
||||
view.prepare(engine, driver, rootArenaScope, svp, cameraInfo, getShaderUserTime(), needsAlphaChannel);
|
||||
|
||||
view.prepareLodBias(bias, derivativeScale);
|
||||
view.prepareSSAO(aoOptions);
|
||||
view.prepareSSR(engine, cameraInfo, ssrConfig.lodOffset, ssReflectionsOptions);
|
||||
view.prepareShadowMapping();
|
||||
// There might be a bug here with svp's origin; normally the origin could offset when the
|
||||
// target is the swapchain (width/height are the same though). This would mean that we'd have
|
||||
// to wait for the color pass to execute to set the viewport. For now, I wasn't able to
|
||||
// get into such a case though.
|
||||
view.prepareViewport(svp, xvp);
|
||||
view.commitUniforms(driver);
|
||||
|
||||
/*
|
||||
* Update the PER_VIEW UBO use for the structure pass. It never updated again after this point.
|
||||
*/
|
||||
|
||||
// Set the PER_VIEW UBO for the passes that use the user materials, but are not the color pass
|
||||
// (e.g. structure, ssao). The PER_VIEW UBO may be different because these passes don't run
|
||||
// at the same resolution. We set only the values that are relevant to both user-materials
|
||||
// and the concerned passes. The PER_VIEW UBO contains data that is needed by the user
|
||||
// materials public APIs.
|
||||
StructureDescriptorSet& descriptorSet = ppm.getStructureDescriptorSet();
|
||||
descriptorSet.prepareCamera(engine, cameraInfo);
|
||||
descriptorSet.prepareTime(engine, getShaderUserTime());
|
||||
descriptorSet.prepareViewport(svp, {
|
||||
{ // the scope helps to guarantee that we're not modifying the descriptor-set later
|
||||
StructureDescriptorSet& ds = ppm.getStructureDescriptorSet();
|
||||
ds.prepareCamera(engine, cameraInfo);
|
||||
ds.prepareTime(engine, getShaderUserTime());
|
||||
ds.prepareViewport(svp, {
|
||||
int32_t(float(xvp.left) * aoOptions.resolution),
|
||||
int32_t(float(xvp.bottom) * aoOptions.resolution),
|
||||
uint32_t(float(xvp.width) * aoOptions.resolution),
|
||||
uint32_t(float(xvp.height) * aoOptions.resolution) });
|
||||
descriptorSet.prepareLodBias(bias, derivativeScale);
|
||||
descriptorSet.prepareMaterialGlobals(view.getMaterialGlobals());
|
||||
descriptorSet.commit(driver);
|
||||
|
||||
ds.prepareLodBias(bias, derivativeScale);
|
||||
ds.prepareMaterialGlobals(view.getMaterialGlobals());
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate command buffer
|
||||
@@ -886,14 +914,6 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
variant.setVsm(view.hasShadowing() && view.getShadowType() != ShadowType::PCF);
|
||||
variant.setStereo(view.hasStereo());
|
||||
|
||||
/*
|
||||
* Frame graph
|
||||
*/
|
||||
|
||||
FrameGraph fg(*mResourceAllocator,
|
||||
isProtectedContent ? FrameGraph::Mode::PROTECTED : FrameGraph::Mode::UNPROTECTED);
|
||||
auto& blackboard = fg.getBlackboard();
|
||||
|
||||
/*
|
||||
* Shadow pass
|
||||
*/
|
||||
@@ -969,7 +989,7 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
// the clearFlags and clearColor specified below will only apply when rendering into the
|
||||
// temporary color buffer. In particular, they won't apply when rendering into the main
|
||||
// swapchain (imported render target above)
|
||||
RendererUtils::ColorPassConfig config{
|
||||
RendererUtils::ColorPassConfig const config{
|
||||
.physicalViewport = svp,
|
||||
.logicalViewport = xvp,
|
||||
.scale = scale,
|
||||
@@ -978,7 +998,6 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
.clearFlags = getClearFlags(),
|
||||
.clearColor = clearColor,
|
||||
.clearStencil = clearStencil,
|
||||
.ssrLodOffset = 0.0f,
|
||||
.hasContactShadows = scene.hasContactShadows(),
|
||||
// at this point we don't know if we have refraction, but that's handled later
|
||||
.hasScreenSpaceReflectionsOrRefractions = ssReflectionsOptions.enabled,
|
||||
@@ -1064,23 +1083,12 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
blackboard["ssao"] = ssao;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// prepare screen-space reflection/refraction passes
|
||||
|
||||
PostProcessManager::ScreenSpaceRefConfig const ssrConfig = PostProcessManager::prepareMipmapSSR(
|
||||
fg, svp.width, svp.height,
|
||||
ssReflectionsOptions.enabled ? TextureFormat::RGBA16F : TextureFormat::R11F_G11F_B10F,
|
||||
view.getCameraUser().getFieldOfView(Camera::Fov::VERTICAL), config.scale);
|
||||
config.ssrLodOffset = ssrConfig.lodOffset;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// screen-space reflections pass
|
||||
|
||||
if (ssReflectionsOptions.enabled) {
|
||||
auto reflections = ppm.ssr(fg, passBuilder,
|
||||
view.getFrameHistory(), cameraInfo,
|
||||
structure,
|
||||
ssReflectionsOptions,
|
||||
view.getFrameHistory(), structure,
|
||||
{ .width = svp.width, .height = svp.height });
|
||||
|
||||
if (UTILS_LIKELY(reflections)) {
|
||||
@@ -1088,7 +1096,6 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
PostProcessManager::generateMipmapSSR(ppm, fg,
|
||||
reflections, ssrConfig.reflection, false, ssrConfig);
|
||||
}
|
||||
config.screenSpaceReflectionHistoryNotReady = !reflections;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -948,54 +948,137 @@ void FView::prepareSSAO(Handle<HwTexture> ssao) const noexcept {
|
||||
getColorPassDescriptorSet().prepareSSAO(ssao, mAmbientOcclusionOptions);
|
||||
}
|
||||
|
||||
void FView::prepareSSR(Handle<HwTexture> ssr,
|
||||
bool const disableSSR,
|
||||
float const refractionLodOffset,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) const noexcept {
|
||||
getColorPassDescriptorSet().prepareSSR(ssr, disableSSR, refractionLodOffset, ssrOptions);
|
||||
void FView::prepareSSAO(AmbientOcclusionOptions const& options) const noexcept {
|
||||
// High quality sampling is enabled only if AO itself is enabled and upsampling quality is at
|
||||
// least set to high and of course only if upsampling is needed.
|
||||
const bool highQualitySampling = options.upsampling >= QualityLevel::HIGH
|
||||
&& options.resolution < 1.0f;
|
||||
|
||||
const float edgeDistance = 1.0f / options.bilateralThreshold;
|
||||
auto& s = mUniforms.edit();
|
||||
s.aoSamplingQualityAndEdgeDistance =
|
||||
options.enabled ? (highQualitySampling ? edgeDistance : 0.0f) : -1.0f;
|
||||
s.aoBentNormals = options.enabled && options.bentNormals ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
void FView::prepareSSR(Handle<HwTexture> ssr) const noexcept {
|
||||
getColorPassDescriptorSet().prepareScreenSpaceRefraction(ssr);
|
||||
}
|
||||
|
||||
void FView::prepareSSR(FEngine& engine, CameraInfo const& cameraInfo,
|
||||
float const refractionLodOffset,
|
||||
ScreenSpaceReflectionsOptions const& options) const noexcept {
|
||||
|
||||
auto const& ssr = getFrameHistory().getPrevious().ssr;
|
||||
|
||||
bool const disableSSR = !ssr.color.handle;
|
||||
mat4 const& historyProjection = ssr.projection;
|
||||
mat4f const& uvFromClipMatrix = engine.getUvFromClipMatrix();
|
||||
mat4f const projection = cameraInfo.projection;
|
||||
mat4 const userViewMatrix = cameraInfo.getUserViewMatrix();
|
||||
|
||||
// set screen-space reflections and screen-space refractions
|
||||
mat4f const uvFromViewMatrix = uvFromClipMatrix * projection;
|
||||
mat4f const reprojection = uvFromClipMatrix *
|
||||
mat4f{ historyProjection * inverse(userViewMatrix) };
|
||||
|
||||
auto& s = mUniforms.edit();
|
||||
s.ssrReprojection = reprojection;
|
||||
s.ssrUvFromViewMatrix = uvFromViewMatrix;
|
||||
s.ssrThickness = options.thickness;
|
||||
s.ssrBias = options.bias;
|
||||
s.ssrStride = options.stride;
|
||||
s.refractionLodOffset = refractionLodOffset;
|
||||
s.ssrDistance = (options.enabled && !disableSSR) ? options.maxDistance : 0.0f;
|
||||
}
|
||||
|
||||
|
||||
void FView::prepareStructure(Handle<HwTexture> structure) const noexcept {
|
||||
// sampler must be NEAREST
|
||||
getColorPassDescriptorSet().prepareStructure(structure);
|
||||
}
|
||||
|
||||
void FView::prepareShadow(Handle<HwTexture> texture) const noexcept {
|
||||
void FView::prepareShadowMapping(FEngine const& engine, Handle<HwTexture> texture) const noexcept {
|
||||
// when needsShadowMap() is not set, this method only just sets a dummy texture
|
||||
// in the needed samplers (in that case `texture` is actually a dummy texture).
|
||||
ShadowMapManager::ShadowMappingUniforms uniforms;
|
||||
if (needsShadowMap()) {
|
||||
uniforms = mShadowMapManager->getShadowMappingUniforms();
|
||||
}
|
||||
switch (mShadowType) {
|
||||
case ShadowType::PCF:
|
||||
getColorPassDescriptorSet().prepareShadowPCF(texture, uniforms);
|
||||
break;
|
||||
case ShadowType::VSM:
|
||||
getColorPassDescriptorSet().prepareShadowVSM(texture, uniforms, mVsmShadowOptions);
|
||||
break;
|
||||
case ShadowType::DPCF:
|
||||
getColorPassDescriptorSet().prepareShadowDPCF(texture, uniforms, mSoftShadowOptions);
|
||||
break;
|
||||
case ShadowType::PCSS:
|
||||
getColorPassDescriptorSet().prepareShadowPCSS(texture, uniforms, mSoftShadowOptions);
|
||||
break;
|
||||
case ShadowType::PCFd:
|
||||
getColorPassDescriptorSet().prepareShadowPCFDebug(texture, uniforms);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FView::prepareShadowMapping(FEngine const& engine, bool const highPrecision) const noexcept {
|
||||
BufferObjectHandle ubo{ engine.getDummyUniformBuffer() };
|
||||
if (mHasShadowing) {
|
||||
assert_invariant(mShadowMapManager);
|
||||
ubo = mShadowMapManager->getShadowUniformsHandle();
|
||||
}
|
||||
getColorPassDescriptorSet().prepareShadowMapping(ubo, highPrecision);
|
||||
getColorPassDescriptorSet().prepareShadowMapping(ubo);
|
||||
|
||||
switch (mShadowType) {
|
||||
case ShadowType::PCF:
|
||||
getColorPassDescriptorSet().prepareShadowPCF(texture);
|
||||
break;
|
||||
case ShadowType::VSM:
|
||||
getColorPassDescriptorSet().prepareShadowVSM(texture, mVsmShadowOptions);
|
||||
break;
|
||||
case ShadowType::DPCF:
|
||||
getColorPassDescriptorSet().prepareShadowDPCF(texture);
|
||||
break;
|
||||
case ShadowType::PCSS:
|
||||
getColorPassDescriptorSet().prepareShadowPCSS(texture);
|
||||
break;
|
||||
case ShadowType::PCFd:
|
||||
getColorPassDescriptorSet().prepareShadowPCFDebug(texture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FView::commitUniformsAndSamplers(DriverApi& driver) const noexcept {
|
||||
void FView::prepareShadowMapping() const noexcept {
|
||||
|
||||
ShadowMapManager::ShadowMappingUniforms uniforms{};
|
||||
if (needsShadowMap()) {
|
||||
uniforms = mShadowMapManager->getShadowMappingUniforms();
|
||||
}
|
||||
|
||||
constexpr float low = 5.54f; // ~ std::log(std::numeric_limits<math::half>::max()) * 0.5f;
|
||||
constexpr float high = 42.0f; // ~ std::log(std::numeric_limits<float>::max()) * 0.5f;
|
||||
constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCF = 0u;
|
||||
constexpr uint32_t SHADOW_SAMPLING_RUNTIME_EVSM = 1u;
|
||||
constexpr uint32_t SHADOW_SAMPLING_RUNTIME_DPCF = 2u;
|
||||
constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCSS = 3u;
|
||||
auto& s = mUniforms.edit();
|
||||
s.cascadeSplits = uniforms.cascadeSplits;
|
||||
s.ssContactShadowDistance = uniforms.ssContactShadowDistance;
|
||||
s.directionalShadows = int32_t(uniforms.directionalShadows);
|
||||
s.cascades = int32_t(uniforms.cascades);
|
||||
switch (mShadowType) {
|
||||
case ShadowType::PCF:
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCF;
|
||||
break;
|
||||
case ShadowType::VSM:
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_EVSM;
|
||||
s.vsmExponent = mVsmShadowOptions.highPrecision ? high : low;
|
||||
s.vsmDepthScale = mVsmShadowOptions.minVarianceScale * 0.01f * s.vsmExponent;
|
||||
s.vsmLightBleedReduction = mVsmShadowOptions.lightBleedReduction;
|
||||
break;
|
||||
case ShadowType::DPCF:
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_DPCF;
|
||||
s.shadowPenumbraRatioScale = mSoftShadowOptions.penumbraRatioScale;
|
||||
break;
|
||||
case ShadowType::PCSS:
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCSS;
|
||||
s.shadowPenumbraRatioScale = mSoftShadowOptions.penumbraRatioScale;
|
||||
break;
|
||||
case ShadowType::PCFd:
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FView::commitUniforms(DriverApi& driver) const noexcept {
|
||||
if (mUniforms.isDirty()) {
|
||||
mUniforms.clean();
|
||||
driver.updateBufferObject(mUniforms.getUboHandle(),
|
||||
mUniforms.toBufferDescriptor(driver), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void FView::commitDescriptorSet(DriverApi& driver) const noexcept {
|
||||
getColorPassDescriptorSet().commit(driver);
|
||||
}
|
||||
|
||||
|
||||
@@ -173,15 +173,19 @@ public:
|
||||
void prepareLighting(FEngine& engine, CameraInfo const& cameraInfo) noexcept;
|
||||
|
||||
void prepareSSAO(backend::Handle<backend::HwTexture> ssao) const noexcept;
|
||||
void prepareSSR(backend::Handle<backend::HwTexture> ssr, bool disableSSR,
|
||||
float refractionLodOffset,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) const noexcept;
|
||||
void prepareSSAO(AmbientOcclusionOptions const& options) const noexcept;
|
||||
|
||||
void prepareSSR(backend::Handle<backend::HwTexture> ssr) const noexcept;
|
||||
void prepareSSR(FEngine& engine, CameraInfo const& cameraInfo,
|
||||
float refractionLodOffset, ScreenSpaceReflectionsOptions const& options) const noexcept;
|
||||
|
||||
void prepareStructure(backend::Handle<backend::HwTexture> structure) const noexcept;
|
||||
void prepareShadow(backend::Handle<backend::HwTexture> structure) const noexcept;
|
||||
void prepareShadowMapping(FEngine const& engine, bool highPrecision) const noexcept;
|
||||
void prepareShadowMapping(FEngine const& engine, backend::Handle<backend::HwTexture> structure) const noexcept;
|
||||
void prepareShadowMapping() const noexcept;
|
||||
|
||||
void commitFroxels(backend::DriverApi& driverApi) const noexcept;
|
||||
void commitUniformsAndSamplers(backend::DriverApi& driver) const noexcept;
|
||||
void commitUniforms(backend::DriverApi& driver) const noexcept;
|
||||
void commitDescriptorSet(backend::DriverApi& driver) const noexcept;
|
||||
|
||||
utils::JobSystem::Job* getFroxelizerSync() const noexcept { return mFroxelizerSync; }
|
||||
void setFroxelizerSync(utils::JobSystem::Job* sync) noexcept { mFroxelizerSync = sync; }
|
||||
|
||||
@@ -257,7 +257,6 @@ void ColorPassDescriptorSet::prepareFog(FEngine& engine, const CameraInfo& camer
|
||||
|
||||
void ColorPassDescriptorSet::prepareSSAO(Handle<HwTexture> ssao,
|
||||
AmbientOcclusionOptions const& options) noexcept {
|
||||
|
||||
// High quality sampling is enabled only if AO itself is enabled and upsampling quality is at
|
||||
// least set to high and of course only if upsampling is needed.
|
||||
const bool highQualitySampling = options.upsampling >= QualityLevel::HIGH
|
||||
@@ -268,12 +267,6 @@ void ColorPassDescriptorSet::prepareSSAO(Handle<HwTexture> ssao,
|
||||
.filterMag = options.enabled && !highQualitySampling ?
|
||||
SamplerMagFilter::LINEAR : SamplerMagFilter::NEAREST
|
||||
});
|
||||
|
||||
const float edgeDistance = 1.0f / options.bilateralThreshold;
|
||||
auto& s = mUniforms.edit();
|
||||
s.aoSamplingQualityAndEdgeDistance =
|
||||
options.enabled ? (highQualitySampling ? edgeDistance : 0.0f) : -1.0f;
|
||||
s.aoBentNormals = options.enabled && options.bentNormals ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareBlending(bool const needsAlphaChannel) noexcept {
|
||||
@@ -285,19 +278,11 @@ void ColorPassDescriptorSet::prepareMaterialGlobals(
|
||||
PerViewDescriptorSetUtils::prepareMaterialGlobals(mUniforms.edit(), materialGlobals);
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareSSR(Handle<HwTexture> ssr,
|
||||
bool const disableSSR,
|
||||
float const refractionLodOffset,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) noexcept {
|
||||
|
||||
void ColorPassDescriptorSet::prepareScreenSpaceRefraction(Handle<HwTexture> ssr) noexcept {
|
||||
setSampler(+PerViewBindingPoints::SSR, ssr, {
|
||||
.filterMag = SamplerMagFilter::LINEAR,
|
||||
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR
|
||||
});
|
||||
|
||||
auto& s = mUniforms.edit();
|
||||
s.refractionLodOffset = refractionLodOffset;
|
||||
s.ssrDistance = (ssrOptions.enabled && !disableSSR) ? ssrOptions.maxDistance : 0.0f;
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareStructure(Handle<HwTexture> structure) noexcept {
|
||||
@@ -379,27 +364,12 @@ void ColorPassDescriptorSet::prepareDynamicLights(Froxelizer& froxelizer) noexce
|
||||
s.lightFarAttenuationParams = 0.5f * float2{ 10.0f, 10.0f / (f * f) };
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareShadowMapping(BufferObjectHandle shadowUniforms, bool const highPrecision) noexcept {
|
||||
auto& s = mUniforms.edit();
|
||||
constexpr float low = 5.54f; // ~ std::log(std::numeric_limits<math::half>::max()) * 0.5f;
|
||||
constexpr float high = 42.0f; // ~ std::log(std::numeric_limits<float>::max()) * 0.5f;
|
||||
s.vsmExponent = highPrecision ? high : low;
|
||||
void ColorPassDescriptorSet::prepareShadowMapping(BufferObjectHandle shadowUniforms) noexcept {
|
||||
setBuffer(+PerViewBindingPoints::SHADOWS, shadowUniforms, 0, sizeof(ShadowUib));
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareShadowSampling(PerViewUib& uniforms,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms) noexcept {
|
||||
uniforms.cascadeSplits = shadowMappingUniforms.cascadeSplits;
|
||||
uniforms.ssContactShadowDistance = shadowMappingUniforms.ssContactShadowDistance;
|
||||
uniforms.directionalShadows = int32_t(shadowMappingUniforms.directionalShadows);
|
||||
uniforms.cascades = int32_t(shadowMappingUniforms.cascades);
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareShadowVSM(Handle<HwTexture> texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms,
|
||||
VsmShadowOptions const& options) noexcept {
|
||||
constexpr float low = 5.54f; // ~ std::log(std::numeric_limits<math::half>::max()) * 0.5f;
|
||||
constexpr float high = 42.0f; // ~ std::log(std::numeric_limits<float>::max()) * 0.5f;
|
||||
SamplerMinFilter filterMin = SamplerMinFilter::LINEAR;
|
||||
if (options.anisotropy > 0 || options.mipmapping) {
|
||||
filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR;
|
||||
@@ -410,16 +380,9 @@ void ColorPassDescriptorSet::prepareShadowVSM(Handle<HwTexture> texture,
|
||||
.filterMin = filterMin,
|
||||
.anisotropyLog2 = options.anisotropy,
|
||||
});
|
||||
auto& s = mUniforms.edit();
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_EVSM;
|
||||
s.vsmExponent = options.highPrecision ? high : low;
|
||||
s.vsmDepthScale = options.minVarianceScale * 0.01f * s.vsmExponent;
|
||||
s.vsmLightBleedReduction = options.lightBleedReduction;
|
||||
prepareShadowSampling(s, shadowMappingUniforms);
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareShadowPCF(Handle<HwTexture> texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms) noexcept {
|
||||
void ColorPassDescriptorSet::prepareShadowPCF(Handle<HwTexture> texture) noexcept {
|
||||
setSampler(+PerViewBindingPoints::SHADOW_MAP,
|
||||
texture, {
|
||||
.filterMag = SamplerMagFilter::LINEAR,
|
||||
@@ -427,49 +390,24 @@ void ColorPassDescriptorSet::prepareShadowPCF(Handle<HwTexture> texture,
|
||||
.compareMode = SamplerCompareMode::COMPARE_TO_TEXTURE,
|
||||
.compareFunc = SamplerCompareFunc::GE
|
||||
});
|
||||
auto& s = mUniforms.edit();
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCF;
|
||||
prepareShadowSampling(s, shadowMappingUniforms);
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareShadowDPCF(Handle<HwTexture> texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms,
|
||||
SoftShadowOptions const& options) noexcept {
|
||||
void ColorPassDescriptorSet::prepareShadowDPCF(Handle<HwTexture> texture) noexcept {
|
||||
setSampler(+PerViewBindingPoints::SHADOW_MAP, texture, {});
|
||||
auto& s = mUniforms.edit();
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_DPCF;
|
||||
s.shadowPenumbraRatioScale = options.penumbraRatioScale;
|
||||
prepareShadowSampling(s, shadowMappingUniforms);
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareShadowPCSS(Handle<HwTexture> texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms,
|
||||
SoftShadowOptions const& options) noexcept {
|
||||
void ColorPassDescriptorSet::prepareShadowPCSS(Handle<HwTexture> texture) noexcept {
|
||||
setSampler(+PerViewBindingPoints::SHADOW_MAP, texture, {});
|
||||
auto& s = mUniforms.edit();
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCSS;
|
||||
s.shadowPenumbraRatioScale = options.penumbraRatioScale;
|
||||
prepareShadowSampling(s, shadowMappingUniforms);
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareShadowPCFDebug(Handle<HwTexture> texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms) noexcept {
|
||||
void ColorPassDescriptorSet::prepareShadowPCFDebug(Handle<HwTexture> texture) noexcept {
|
||||
setSampler(+PerViewBindingPoints::SHADOW_MAP, texture, {
|
||||
.filterMag = SamplerMagFilter::NEAREST,
|
||||
.filterMin = SamplerMinFilter::NEAREST
|
||||
});
|
||||
auto& s = mUniforms.edit();
|
||||
s.shadowSamplingType = SHADOW_SAMPLING_RUNTIME_PCF;
|
||||
prepareShadowSampling(s, shadowMappingUniforms);
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::commit(DriverApi& driver) noexcept {
|
||||
if (mUniforms.isDirty()) {
|
||||
driver.updateBufferObject(mUniforms.getUboHandle(),
|
||||
mUniforms.toBufferDescriptor(driver), 0);
|
||||
}
|
||||
|
||||
|
||||
for (size_t i = 0; i < DESCRIPTOR_LAYOUT_COUNT; i++) {
|
||||
mDescriptorSet[i].commit(mDescriptorSetLayout[i], driver);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "TypedUniformBuffer.h"
|
||||
|
||||
#include <private/filament/EngineEnums.h>
|
||||
#include <private/filament/UibStructs.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
@@ -66,11 +67,6 @@ class ColorPassDescriptorSet {
|
||||
using LightManagerInstance = utils::EntityInstance<LightManager>;
|
||||
using TextureHandle = backend::Handle<backend::HwTexture>;
|
||||
|
||||
static constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCF = 0u;
|
||||
static constexpr uint32_t SHADOW_SAMPLING_RUNTIME_EVSM = 1u;
|
||||
static constexpr uint32_t SHADOW_SAMPLING_RUNTIME_DPCF = 2u;
|
||||
static constexpr uint32_t SHADOW_SAMPLING_RUNTIME_PCSS = 3u;
|
||||
|
||||
public:
|
||||
|
||||
static uint8_t getIndex(bool lit, bool ssr, bool fog) noexcept;
|
||||
@@ -112,12 +108,9 @@ public:
|
||||
void prepareMaterialGlobals(std::array<math::float4, 4> const& materialGlobals) noexcept;
|
||||
|
||||
// screen-space reflection and/or refraction (SSR)
|
||||
void prepareSSR(TextureHandle ssr,
|
||||
bool disableSSR,
|
||||
float refractionLodOffset,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) noexcept;
|
||||
void prepareScreenSpaceRefraction(TextureHandle ssr) noexcept;
|
||||
|
||||
void prepareShadowMapping(backend::BufferObjectHandle shadowUniforms, bool highPrecision) noexcept;
|
||||
void prepareShadowMapping(backend::BufferObjectHandle shadowUniforms) noexcept;
|
||||
|
||||
void prepareDirectionalLight(FEngine& engine, float exposure,
|
||||
math::float3 const& sceneSpaceDirection, LightManagerInstance instance) noexcept;
|
||||
@@ -128,22 +121,15 @@ public:
|
||||
void prepareDynamicLights(Froxelizer& froxelizer) noexcept;
|
||||
|
||||
void prepareShadowVSM(TextureHandle texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms,
|
||||
VsmShadowOptions const& options) noexcept;
|
||||
|
||||
void prepareShadowPCF(TextureHandle texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms) noexcept;
|
||||
void prepareShadowPCF(TextureHandle texture) noexcept;
|
||||
|
||||
void prepareShadowDPCF(TextureHandle texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms,
|
||||
SoftShadowOptions const& options) noexcept;
|
||||
void prepareShadowDPCF(TextureHandle texture) noexcept;
|
||||
|
||||
void prepareShadowPCSS(TextureHandle texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms,
|
||||
SoftShadowOptions const& options) noexcept;
|
||||
void prepareShadowPCSS(TextureHandle texture) noexcept;
|
||||
|
||||
void prepareShadowPCFDebug(TextureHandle texture,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms) noexcept;
|
||||
void prepareShadowPCFDebug(TextureHandle texture) noexcept;
|
||||
|
||||
// update local data into GPU UBO
|
||||
void commit(backend::DriverApi& driver) noexcept;
|
||||
@@ -164,9 +150,6 @@ private:
|
||||
void setBuffer(backend::descriptor_binding_t binding,
|
||||
backend::BufferObjectHandle boh, uint32_t offset, uint32_t size) noexcept;
|
||||
|
||||
static void prepareShadowSampling(PerViewUib& uniforms,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms) noexcept;
|
||||
|
||||
TypedUniformBuffer<PerViewUib>& mUniforms;
|
||||
std::array<DescriptorSetLayout, DESCRIPTOR_LAYOUT_COUNT> mDescriptorSetLayout;
|
||||
std::array<DescriptorSet, DESCRIPTOR_LAYOUT_COUNT> mDescriptorSet;
|
||||
|
||||
@@ -66,29 +66,14 @@ void SsrPassDescriptorSet::setFrameUniforms(FEngine const& engine,
|
||||
// and GL would be okay without this, but Vulkan's validation layer would complain.
|
||||
mDescriptorSet.setBuffer(engine.getPerViewDescriptorSetLayoutSsrVariant(),
|
||||
+PerViewBindingPoints::SHADOWS, mShadowUbh, 0, sizeof(ShadowUib));
|
||||
|
||||
mUniforms = std::addressof(uniforms);
|
||||
}
|
||||
|
||||
void SsrPassDescriptorSet::prepareHistorySSR(FEngine const& engine, Handle<HwTexture> ssr,
|
||||
mat4f const& historyProjection,
|
||||
mat4f const& uvFromViewMatrix,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) noexcept {
|
||||
|
||||
void SsrPassDescriptorSet::prepareHistorySSR(FEngine const& engine, Handle<HwTexture> ssr) noexcept {
|
||||
mDescriptorSet.setSampler(engine.getPerViewDescriptorSetLayoutSsrVariant(),
|
||||
+PerViewBindingPoints::SSR_HISTORY, ssr, {
|
||||
.filterMag = SamplerMagFilter::LINEAR,
|
||||
.filterMin = SamplerMinFilter::LINEAR
|
||||
});
|
||||
|
||||
assert_invariant(mUniforms);
|
||||
auto& s = mUniforms->edit();
|
||||
s.ssrReprojection = historyProjection;
|
||||
s.ssrUvFromViewMatrix = uvFromViewMatrix;
|
||||
s.ssrThickness = ssrOptions.thickness;
|
||||
s.ssrBias = ssrOptions.bias;
|
||||
s.ssrDistance = ssrOptions.enabled ? ssrOptions.maxDistance : 0.0f;
|
||||
s.ssrStride = ssrOptions.stride;
|
||||
}
|
||||
|
||||
void SsrPassDescriptorSet::prepareStructure(FEngine const& engine,
|
||||
@@ -99,12 +84,7 @@ void SsrPassDescriptorSet::prepareStructure(FEngine const& engine,
|
||||
}
|
||||
|
||||
void SsrPassDescriptorSet::commit(FEngine& engine) noexcept {
|
||||
assert_invariant(mUniforms);
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
if (mUniforms->isDirty()) {
|
||||
driver.updateBufferObject(mUniforms->getUboHandle(),
|
||||
mUniforms->toBufferDescriptor(driver), 0);
|
||||
}
|
||||
mDescriptorSet.commit(engine.getPerViewDescriptorSetLayoutSsrVariant(), driver);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include "DescriptorSet.h"
|
||||
|
||||
#include "DescriptorSetLayout.h"
|
||||
|
||||
#include "TypedUniformBuffer.h"
|
||||
|
||||
#include <private/filament/UibStructs.h>
|
||||
@@ -28,8 +26,6 @@
|
||||
#include <backend/DriverApiForward.h>
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
|
||||
namespace filament {
|
||||
|
||||
class FEngine;
|
||||
@@ -51,11 +47,7 @@ public:
|
||||
|
||||
void prepareStructure(FEngine const& engine, TextureHandle structure) noexcept;
|
||||
|
||||
void prepareHistorySSR(FEngine const& engine, TextureHandle ssr,
|
||||
math::mat4f const& historyProjection,
|
||||
math::mat4f const& uvFromViewMatrix,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) noexcept;
|
||||
|
||||
void prepareHistorySSR(FEngine const& engine, TextureHandle ssr) noexcept;
|
||||
|
||||
// update local data into GPU UBO
|
||||
void commit(FEngine& engine) noexcept;
|
||||
@@ -64,7 +56,6 @@ public:
|
||||
void bind(backend::DriverApi& driver) noexcept;
|
||||
|
||||
private:
|
||||
TypedUniformBuffer<PerViewUib>* mUniforms = nullptr;
|
||||
DescriptorSet mDescriptorSet;
|
||||
backend::BufferObjectHandle mShadowUbh;
|
||||
};
|
||||
|
||||
@@ -63,14 +63,14 @@ void StructureDescriptorSet::terminate(DriverApi& driver) {
|
||||
mUniforms.terminate(driver);
|
||||
}
|
||||
|
||||
void StructureDescriptorSet::commit(DriverApi& driver) noexcept {
|
||||
assert_invariant(mDescriptorSetLayout);
|
||||
driver.updateBufferObject(mUniforms.getUboHandle(),
|
||||
mUniforms.toBufferDescriptor(driver), 0);
|
||||
mDescriptorSet.commit(*mDescriptorSetLayout, driver);
|
||||
}
|
||||
|
||||
void StructureDescriptorSet::bind(DriverApi& driver) const noexcept {
|
||||
assert_invariant(mDescriptorSetLayout);
|
||||
if (mUniforms.isDirty()) {
|
||||
mUniforms.clean();
|
||||
driver.updateBufferObject(mUniforms.getUboHandle(),
|
||||
mUniforms.toBufferDescriptor(driver), 0);
|
||||
mDescriptorSet.commit(*mDescriptorSetLayout, driver);
|
||||
}
|
||||
mDescriptorSet.bind(driver, DescriptorSetBindingPoints::PER_VIEW);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,8 +45,7 @@ public:
|
||||
|
||||
void terminate(backend::DriverApi& driver);
|
||||
|
||||
void commit(backend::DriverApi& driver) noexcept;
|
||||
|
||||
// this commits the UBO if needed and binds the descriptor set
|
||||
void bind(backend::DriverApi& driver) const noexcept;
|
||||
|
||||
|
||||
@@ -65,7 +64,7 @@ public:
|
||||
|
||||
private:
|
||||
DescriptorSetLayout const* mDescriptorSetLayout = nullptr;
|
||||
DescriptorSet mDescriptorSet;
|
||||
mutable DescriptorSet mDescriptorSet;
|
||||
TypedUniformBuffer<PerViewUib> mUniforms;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user