Handle shadow receivers w/ VSM more robustly

VSM requires shadow receivers to be in the shadowmap, instead of
handling this in the shadow mapping code, we're handling it in 
FScene::prepare(), which guarantees it'll ripple everywhere it needs to.
This commit is contained in:
Mathias Agopian
2021-06-23 18:08:57 -07:00
committed by Mathias Agopian
parent 1b53e78ea7
commit 4b3a983b23
3 changed files with 17 additions and 14 deletions
+7 -2
View File
@@ -47,7 +47,7 @@ FScene::FScene(FEngine& engine) :
FScene::~FScene() noexcept = default;
void FScene::prepare(const mat4f& worldOriginTransform) {
void FScene::prepare(const mat4f& worldOriginTransform, bool shadowReceiversAreCasters) noexcept {
// TODO: can we skip this in most cases? Since we rely on indices staying the same,
// we could only skip, if nothing changed in the RCM.
@@ -119,12 +119,17 @@ void FScene::prepare(const mat4f& worldOriginTransform) {
// compute the world AABB so we can perform culling
const Box worldAABB = rigidTransform(rcm.getAABB(ri), worldTransform);
auto visibility = rcm.getVisibility(ri);
if (shadowReceiversAreCasters && visibility.receiveShadows) {
visibility.castShadows = true;
}
// we know there is enough space in the array
sceneData.push_back_unsafe(
ri, // RENDERABLE_INSTANCE
worldTransform, // WORLD_TRANSFORM
reversedWindingOrder, // REVERSED_WINDING_ORDER
rcm.getVisibility(ri), // VISIBILITY_STATE
visibility, // VISIBILITY_STATE
rcm.getBonesUbh(ri), // BONES_UBH
worldAABB.center, // WORLD_AABB_CENTER
0, // VISIBLE_MASK
+7 -10
View File
@@ -414,7 +414,7 @@ void FView::prepare(FEngine& engine, backend::DriverApi& driver, ArenaScope& are
* Gather all information needed to render this scene. Apply the world origin to all
* objects in the scene.
*/
scene->prepare(worldOriginScene);
scene->prepare(worldOriginScene, hasVsm());
/*
* Light culling: runs in parallel with Renderable culling (below)
@@ -594,20 +594,17 @@ void FView::computeVisibilityMasks(
//
// It is written without if statements to avoid branches, which allows it to be vectorized 16x.
const bool visRenderables = (!v.culling || (mask & VISIBLE_RENDERABLE)) && inVisibleLayer;
const bool vvsmRenderShadow = hasVsm && v.receiveShadows;
const bool visShadowParticipant = v.castShadows || vvsmRenderShadow;
const bool visShadowRenderable =
(!v.culling || (mask & VISIBLE_DIR_SHADOW_RENDERABLE)) && inVisibleLayer && visShadowParticipant;
const bool visRenderables = (!v.culling || (mask & VISIBLE_RENDERABLE)) && inVisibleLayer;
const bool visShadowParticipant = v.castShadows;
const bool visShadowRenderable = (!v.culling || (mask & VISIBLE_DIR_SHADOW_RENDERABLE))
&& inVisibleLayer && visShadowParticipant;
visibleMask[i] = Culler::result_type(visRenderables) |
Culler::result_type(visShadowRenderable << 1u);
// this loop gets fully unrolled
for (size_t j = 0; j < CONFIG_MAX_SHADOW_CASTING_SPOTS; ++j) {
const bool vvsmSpotRenderShadow = hasVsm && v.receiveShadows;
const bool visSpotShadowParticipant = v.castShadows || vvsmSpotRenderShadow;
const bool visSpotShadowRenderable =
(!v.culling || (mask & VISIBLE_SPOT_SHADOW_RENDERABLE_N(j))) &&
inVisibleLayer && visSpotShadowParticipant;
(!v.culling || (mask & VISIBLE_SPOT_SHADOW_RENDERABLE_N(j))) &&
inVisibleLayer && visShadowParticipant;
visibleMask[i] |=
Culler::result_type(visSpotShadowRenderable << VISIBLE_SPOT_SHADOW_RENDERABLE_N_BIT(j));
}
+3 -2
View File
@@ -84,8 +84,9 @@ public:
~FScene() noexcept;
void terminate(FEngine& engine);
void prepare(const math::mat4f& worldOriginTransform);
void prepareDynamicLights(const CameraInfo& camera, ArenaScope& arena, backend::Handle<backend::HwUniformBuffer> lightUbh) noexcept;
void prepare(const math::mat4f& worldOriginTransform, bool shadowReceiversAreCasters) noexcept;
void prepareDynamicLights(const CameraInfo& camera, ArenaScope& arena,
backend::Handle<backend::HwUniformBuffer> lightUbh) noexcept;
filament::backend::Handle<backend::HwUniformBuffer> getRenderableUBO() const noexcept {