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:
committed by
Mathias Agopian
parent
1b53e78ea7
commit
4b3a983b23
@@ -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
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user