make sure "structure" pass is culled when not needed
the structure (depth path) wasn't culled even if both ssao and contact-shadows were disabled.
This commit is contained in:
committed by
Mathias Agopian
parent
e43466d2bc
commit
968dbdb847
@@ -602,10 +602,11 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::screenSpaceAmbientOclusion(
|
||||
FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,
|
||||
const RenderPass& pass, uint32_t width, uint32_t height, float scale) noexcept {
|
||||
|
||||
// structure pass -- automatically culled if not used
|
||||
// used for SSAO currently. It consists of a mipmapped depth path
|
||||
// mipmapping is tunned for SSAO
|
||||
struct DepthPassData {
|
||||
// structure pass -- automatically culled if not used, currently used by:
|
||||
// - ssao
|
||||
// - contact shadows
|
||||
// It consists of a mipmapped depth pass, tuned for SSAO
|
||||
struct StructurePassData {
|
||||
FrameGraphId<FrameGraphTexture> depth;
|
||||
FrameGraphRenderTargetHandle rt;
|
||||
};
|
||||
@@ -618,8 +619,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,
|
||||
const size_t levelCount = FTexture::maxLevelCount(width, height) - 5;
|
||||
assert(levelCount >= 1);
|
||||
|
||||
// SSAO generates its own depth pass at the requested resolution
|
||||
auto& ssaoDepthPass = fg.addPass<DepthPassData>("SSAO Depth Pass",
|
||||
// generate depth pass at the requested resolution
|
||||
auto& structurePass = fg.addPass<StructurePassData>("Structure Pass",
|
||||
[&](FrameGraph::Builder& builder, auto& data) {
|
||||
data.depth = builder.createTexture("Depth Buffer", {
|
||||
.width = width, .height = height,
|
||||
@@ -628,7 +629,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,
|
||||
|
||||
data.depth = builder.write(builder.read(data.depth));
|
||||
|
||||
data.rt = builder.createRenderTarget("SSAO Depth Target", {
|
||||
data.rt = builder.createRenderTarget("Structure Target", {
|
||||
.attachments = {{}, data.depth },
|
||||
.clearFlags = TargetBufferFlags::DEPTH
|
||||
});
|
||||
@@ -638,7 +639,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,
|
||||
pass.execute(resources.getPassName(), out.target, out.params);
|
||||
});
|
||||
|
||||
auto depth = ssaoDepthPass.getData().depth;
|
||||
auto depth = structurePass.getData().depth;
|
||||
|
||||
/*
|
||||
* create depth mipmap chain
|
||||
|
||||
@@ -315,7 +315,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// structure pass -- automatically culled if not used
|
||||
// Currently it consists of a simple depth pass.
|
||||
// This is normally used by SSAO
|
||||
// This is normally used by SSAO and contact-shadows
|
||||
|
||||
// TODO: this should be a FrameGraph pass to participate to automatic culling
|
||||
pass.newCommandBuffer();
|
||||
@@ -348,7 +348,8 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
.hdrFormat = hdrFormat,
|
||||
.msaa = msaa,
|
||||
.clearFlags = clearFlags,
|
||||
.clearColor = clearColor
|
||||
.clearColor = clearColor,
|
||||
.hasContactShadows = scene.hasContactShadows()
|
||||
};
|
||||
|
||||
// We use a framegraph pass to wait for froxelization to finish (so it can be done
|
||||
@@ -576,7 +577,8 @@ FrameGraphId<FrameGraphTexture> FRenderer::colorPass(FrameGraph& fg, const char*
|
||||
data.color = blackboard.get<FrameGraphTexture>("color");
|
||||
data.structure = blackboard.get<FrameGraphTexture>("structure");
|
||||
|
||||
if (data.structure.isValid()) {
|
||||
if (config.hasContactShadows) {
|
||||
assert(data.structure.isValid());
|
||||
data.structure = builder.sample(data.structure);
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@ void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Hand
|
||||
// allocate space into the command stream directly
|
||||
void* const buffer = driver.allocate(size);
|
||||
|
||||
bool hasContactShadows = false;
|
||||
auto& sceneData = mRenderableData;
|
||||
for (uint32_t i : visibleRenderables) {
|
||||
mat4f const& model = sceneData.elementAt<WORLD_TRANSFORM>(i);
|
||||
@@ -206,20 +207,27 @@ void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Hand
|
||||
// Note that we cast bools to uint32. Booleans are byte-sized in C++, but we need to
|
||||
// initialize all 32 bits in the UBO field.
|
||||
|
||||
UniformBuffer::setUniform(buffer, offset + offsetof(PerRenderableUib, skinningEnabled),
|
||||
uint32_t(sceneData.elementAt<VISIBILITY_STATE>(i).skinning));
|
||||
|
||||
UniformBuffer::setUniform(buffer, offset + offsetof(PerRenderableUib, morphingEnabled),
|
||||
uint32_t(sceneData.elementAt<VISIBILITY_STATE>(i).morphing));
|
||||
|
||||
UniformBuffer::setUniform(buffer, offset + offsetof(PerRenderableUib, screenSpaceContactShadows),
|
||||
uint32_t(sceneData.elementAt<VISIBILITY_STATE>(i).screenSpaceContactShadows));
|
||||
FRenderableManager::Visibility visibility = sceneData.elementAt<VISIBILITY_STATE>(i);
|
||||
hasContactShadows = hasContactShadows || visibility.screenSpaceContactShadows;
|
||||
UniformBuffer::setUniform(buffer,
|
||||
offset + offsetof(PerRenderableUib, skinningEnabled),
|
||||
uint32_t(visibility.skinning));
|
||||
|
||||
UniformBuffer::setUniform(buffer,
|
||||
offset + offsetof(PerRenderableUib, morphWeights), sceneData.elementAt<MORPH_WEIGHTS>(i));
|
||||
offset + offsetof(PerRenderableUib, morphingEnabled),
|
||||
uint32_t(visibility.morphing));
|
||||
|
||||
UniformBuffer::setUniform(buffer,
|
||||
offset + offsetof(PerRenderableUib, screenSpaceContactShadows),
|
||||
uint32_t(visibility.screenSpaceContactShadows));
|
||||
|
||||
UniformBuffer::setUniform(buffer,
|
||||
offset + offsetof(PerRenderableUib, morphWeights),
|
||||
sceneData.elementAt<MORPH_WEIGHTS>(i));
|
||||
}
|
||||
|
||||
// TODO: handle static objects separately
|
||||
mHasContactShadows = hasContactShadows;
|
||||
mRenderableViewUbh = renderableUbh;
|
||||
driver.loadUniformBuffer(renderableUbh, { buffer, size });
|
||||
}
|
||||
@@ -390,6 +398,17 @@ void FScene::setSkybox(FSkybox const* skybox) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
bool FScene::hasContactShadows() const noexcept {
|
||||
bool hasContactShadows = mHasContactShadows;
|
||||
auto& lcm = mEngine.getLightManager();
|
||||
FLightManager::Instance directionalLight = mLightData.elementAt<LIGHT_INSTANCE>(0);
|
||||
if (directionalLight.isValid()) {
|
||||
auto const& shadowOoptions = lcm.getShadowOptions(directionalLight);
|
||||
hasContactShadows = hasContactShadows && shadowOoptions.screenSpaceContactShadows;
|
||||
}
|
||||
return hasContactShadows;
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -109,6 +109,7 @@ private:
|
||||
backend::TargetBufferFlags clearFlags;
|
||||
math::float4 clearColor = {};
|
||||
float refractionLodOffset;
|
||||
bool hasContactShadows;
|
||||
};
|
||||
|
||||
FrameGraphId<FrameGraphTexture> colorPass(FrameGraph& fg, const char* name,
|
||||
|
||||
@@ -194,6 +194,8 @@ public:
|
||||
|
||||
void updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Handle<backend::HwUniformBuffer> renderableUbh) noexcept;
|
||||
|
||||
bool hasContactShadows() const noexcept;
|
||||
|
||||
private:
|
||||
static inline void computeLightRanges(math::float2* zrange,
|
||||
CameraInfo const& camera, const math::float4* spheres, size_t count) noexcept;
|
||||
@@ -215,13 +217,14 @@ private:
|
||||
|
||||
/*
|
||||
* The data below is valid only during a view pass. i.e. if a scene is used in multiple
|
||||
* views, the data below is update for each view.
|
||||
* views, the data below is updated for each view.
|
||||
* In essence, this data should be owned by View, but it's so scene-specific, that for now
|
||||
* we store it here.
|
||||
*/
|
||||
RenderableSoa mRenderableData;
|
||||
LightSoa mLightData;
|
||||
backend::Handle<backend::HwUniformBuffer> mRenderableViewUbh; // This is actually owned by the view.
|
||||
bool mHasContactShadows = false;
|
||||
};
|
||||
|
||||
FILAMENT_UPCAST(Scene)
|
||||
|
||||
Reference in New Issue
Block a user