diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index e84b0d7956..fe0124f171 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -382,8 +382,12 @@ FrameGraphId PostProcessManager::structure(FrameGraph& fg, }, [=, renderPass = pass](FrameGraphResources const& resources, auto const& data, DriverApi& driver) mutable { + Variant structureVariant(Variant::DEPTH_VARIANT); + structureVariant.setPicking(config.picking); + auto out = resources.getRenderPassInfo(); renderPass.setRenderFlags(structureRenderFlags); + renderPass.setVariant(structureVariant); renderPass.appendCommands(RenderPass::CommandTypeFlags::SSAO); renderPass.sortCommands(); renderPass.execute(resources.getPassName(), out.target, out.params); diff --git a/filament/src/RenderPass.cpp b/filament/src/RenderPass.cpp index b30dd5dab6..f789c67810 100644 --- a/filament/src/RenderPass.cpp +++ b/filament/src/RenderPass.cpp @@ -94,6 +94,7 @@ void RenderPass::appendCommands(CommandTypeFlags const commandTypeFlags) noexcep FEngine& engine = mEngine; JobSystem& js = engine.getJobSystem(); const RenderFlags renderFlags = mFlags; + const Variant variant = mVariant; const FScene::VisibleMaskType visibilityMask = mVisibilityMask; CameraInfo const& camera = mCamera; @@ -113,11 +114,11 @@ void RenderPass::appendCommands(CommandTypeFlags const commandTypeFlags) noexcep // we extract camera position/forward outside of the loop, because these are not cheap. const float3 cameraPosition(camera.getPosition()); const float3 cameraForwardVector(camera.getForwardVector()); - auto work = [commandTypeFlags, curr, &soa, renderFlags, visibilityMask, cameraPosition, + auto work = [commandTypeFlags, curr, &soa, variant, renderFlags, visibilityMask, cameraPosition, cameraForwardVector] (uint32_t startIndex, uint32_t indexCount) { RenderPass::generateCommands(commandTypeFlags, curr, - soa, { startIndex, startIndex + indexCount }, renderFlags, visibilityMask, + soa, { startIndex, startIndex + indexCount }, variant, renderFlags, visibilityMask, cameraPosition, cameraForwardVector); }; @@ -211,8 +212,10 @@ void RenderPass::setupColorCommand(Command& cmdDraw, /* static */ UTILS_NOINLINE void RenderPass::generateCommands(uint32_t commandTypeFlags, Command* const commands, - FScene::RenderableSoa const& soa, Range range, RenderFlags renderFlags, - FScene::VisibleMaskType visibilityMask, float3 cameraPosition, float3 cameraForward) noexcept { + FScene::RenderableSoa const& soa, Range range, + Variant variant, RenderFlags renderFlags, + FScene::VisibleMaskType visibilityMask, + float3 cameraPosition, float3 cameraForward) noexcept { // generateCommands() writes both the draw and depth commands simultaneously such that // we go throw the list of renderables just once. @@ -239,11 +242,11 @@ void RenderPass::generateCommands(uint32_t commandTypeFlags, Command* const comm switch (commandTypeFlags & (CommandTypeFlags::COLOR | CommandTypeFlags::DEPTH)) { case CommandTypeFlags::COLOR: generateCommandsImpl(commandTypeFlags, curr, - soa, range, renderFlags, visibilityMask, cameraPosition, cameraForward); + soa, range, variant, renderFlags, visibilityMask, cameraPosition, cameraForward); break; case CommandTypeFlags::DEPTH: generateCommandsImpl(commandTypeFlags, curr, - soa, range, renderFlags, visibilityMask, cameraPosition, cameraForward); + soa, range, variant, renderFlags, visibilityMask, cameraPosition, cameraForward); break; default: // we should never end-up here @@ -257,7 +260,7 @@ UTILS_NOINLINE void RenderPass::generateCommandsImpl(uint32_t extraFlags, Command* UTILS_RESTRICT curr, FScene::RenderableSoa const& UTILS_RESTRICT soa, Range range, - RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask, + Variant variant, RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask, float3 cameraPosition, float3 cameraForward) noexcept { // generateCommands() writes both the draw and depth commands simultaneously such that @@ -283,23 +286,13 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags, const bool hasShadowing = renderFlags & HAS_SHADOWING; const bool viewInverseFrontFaces = renderFlags & HAS_INVERSE_FRONT_FACES; - Variant materialVariant; - materialVariant.setDirectionalLighting(renderFlags & HAS_DIRECTIONAL_LIGHT); - materialVariant.setDynamicLighting(renderFlags & HAS_DYNAMIC_LIGHTING); - materialVariant.setFog(renderFlags & HAS_FOG); - // DPCF and PCSS uses the same color pass shader as VSM (but not for depth) - materialVariant.setVsm(((renderFlags & HAS_VSM) || (renderFlags & HAS_DPCF_OR_PCSS)) && hasShadowing); - materialVariant.setShadowReceiver(false); // this is set per Renderable - Command cmdColor; Command cmdDepth; if constexpr (isDepthPass) { - cmdDepth.primitive.materialVariant = Variant{ Variant::DEPTH_VARIANT }; - cmdDepth.primitive.materialVariant.setPicking(renderFlags & HAS_PICKING); - cmdDepth.primitive.materialVariant.setVsm(renderFlags & HAS_VSM); + cmdDepth.primitive.materialVariant = variant; cmdDepth.primitive.rasterState = {}; - cmdDepth.primitive.rasterState.colorWrite = renderFlags & (HAS_VSM | HAS_PICKING); + cmdDepth.primitive.rasterState.colorWrite = variant.hasPicking() || variant.hasVsm(); cmdDepth.primitive.rasterState.depthWrite = true; cmdDepth.primitive.rasterState.depthFunc = RasterState::DepthFunc::GE; cmdDepth.primitive.rasterState.alphaToCoverage = false; @@ -355,8 +348,8 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags, cmdColor.key = makeField(soaVisibility[i].priority, PRIORITY_MASK, PRIORITY_SHIFT); cmdColor.primitive.index = (uint16_t)i; - materialVariant.setShadowReceiver(soaVisibility[i].receiveShadows & hasShadowing); - materialVariant.setSkinning(soaVisibility[i].skinning || soaVisibility[i].morphing); + variant.setShadowReceiver(soaVisibility[i].receiveShadows & hasShadowing); + variant.setSkinning(soaVisibility[i].skinning || soaVisibility[i].morphing); if constexpr (isDepthPass) { cmdDepth.key = uint64_t(Pass::DEPTH); @@ -384,7 +377,7 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags, FMorphTargetBuffer const* const morphTargetBuffer = primitive.getMorphTargetBuffer(); if constexpr (isColorPass) { cmdColor.primitive.primitiveHandle = primitive.getHwHandle(); - cmdColor.primitive.materialVariant = materialVariant; + cmdColor.primitive.materialVariant = variant; RenderPass::setupColorCommand(cmdColor, mi, inverseFrontFaces); cmdColor.primitive.morphWeightBuffer = morphing.handle; diff --git a/filament/src/RenderPass.h b/filament/src/RenderPass.h index 53962ddcd3..7e7b0c2427 100644 --- a/filament/src/RenderPass.h +++ b/filament/src/RenderPass.h @@ -238,13 +238,7 @@ public: using RenderFlags = uint8_t; static constexpr RenderFlags HAS_SHADOWING = 0x01; - static constexpr RenderFlags HAS_DIRECTIONAL_LIGHT = 0x02; - static constexpr RenderFlags HAS_DYNAMIC_LIGHTING = 0x04; - static constexpr RenderFlags HAS_INVERSE_FRONT_FACES = 0x08; - static constexpr RenderFlags HAS_FOG = 0x10; - static constexpr RenderFlags HAS_VSM = 0x20; - static constexpr RenderFlags HAS_PICKING = 0x40; - static constexpr RenderFlags HAS_DPCF_OR_PCSS = 0x80; + static constexpr RenderFlags HAS_INVERSE_FRONT_FACES = 0x02; // Arena used for commands using Arena = utils::Arena< @@ -279,6 +273,9 @@ public: // flags controlling how commands are generated void setRenderFlags(RenderFlags flags) noexcept { mFlags = flags; } + // variant to use + void setVariant(Variant variant) noexcept { mVariant = variant; } + // Sets the visibility mask, which is AND-ed against each Renderable's VISIBLE_MASK to determine // if the renderable is visible for this pass. // Defaults to all 1's, which means all renderables in this render pass will be rendered. @@ -369,13 +366,15 @@ private: "Size of Commands jobs must be multiple of a cache-line size"); static inline void generateCommands(uint32_t commandTypeFlags, Command* commands, - FScene::RenderableSoa const& soa, utils::Range range, RenderFlags renderFlags, - FScene::VisibleMaskType visibilityMask, math::float3 cameraPosition, math::float3 cameraForward) noexcept; + FScene::RenderableSoa const& soa, utils::Range range, + Variant variant, RenderFlags renderFlags, + FScene::VisibleMaskType visibilityMask, + math::float3 cameraPosition, math::float3 cameraForward) noexcept; template static inline void generateCommandsImpl(uint32_t, Command* commands, FScene::RenderableSoa const& soa, utils::Range range, - RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask, + Variant variant, RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask, math::float3 cameraPosition, math::float3 cameraForward) noexcept; static void setupColorCommand(Command& cmdDraw, @@ -415,6 +414,9 @@ private: // info about the scene features (e.g.: has shadows, lighting, etc...) RenderFlags mFlags{}; + // Variant to use + Variant mVariant{}; + // Additional visibility mask FScene::VisibleMaskType mVisibilityMask = std::numeric_limits::max(); diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index 744a0a40ca..a02ad79eee 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -285,23 +285,16 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { RenderPass::Arena commandArena("Command Arena", { arenaBegin, arenaEnd }); RenderPass pass(engine, commandArena); - RenderPass::RenderFlags baseRenderFlags = 0; - if (view.hasShadowing()) baseRenderFlags |= RenderPass::HAS_SHADOWING; - if (view.hasDirectionalLight()) baseRenderFlags |= RenderPass::HAS_DIRECTIONAL_LIGHT; - if (view.hasDynamicLighting()) baseRenderFlags |= RenderPass::HAS_DYNAMIC_LIGHTING; - if (view.hasFog()) baseRenderFlags |= RenderPass::HAS_FOG; - if (view.isFrontFaceWindingInverted()) baseRenderFlags |= RenderPass::HAS_INVERSE_FRONT_FACES; - RenderPass::RenderFlags colorRenderFlags = baseRenderFlags; - switch (view.getShadowType()) { - case ShadowType::PCF: break; - case ShadowType::VSM: colorRenderFlags |= RenderPass::HAS_VSM; break; - case ShadowType::DPCF: colorRenderFlags |= RenderPass::HAS_DPCF_OR_PCSS; break; - case ShadowType::PCSS: colorRenderFlags |= RenderPass::HAS_DPCF_OR_PCSS; break; - } + RenderPass::RenderFlags renderFlags = 0; + if (view.hasShadowing()) renderFlags |= RenderPass::HAS_SHADOWING; + if (view.isFrontFaceWindingInverted()) renderFlags |= RenderPass::HAS_INVERSE_FRONT_FACES; - RenderPass::RenderFlags structureRenderFlags = baseRenderFlags; - if (view.hasPicking()) structureRenderFlags |= RenderPass::HAS_PICKING; + Variant variant; + variant.setDirectionalLighting(view.hasDirectionalLight()); + variant.setDynamicLighting(view.hasDynamicLighting()); + variant.setFog(view.hasFog()); + variant.setVsm(view.hasShadowing() && view.getShadowType() != ShadowType::PCF); /* * Frame graph @@ -314,8 +307,12 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { */ if (view.needsShadowMap()) { + Variant shadowVariant(Variant::DEPTH_VARIANT); + shadowVariant.setVsm(view.getShadowType() == ShadowType::VSM); + RenderPass shadowPass(pass); - shadowPass.setRenderFlags(colorRenderFlags); + shadowPass.setRenderFlags(renderFlags); + shadowPass.setVariant(shadowVariant); view.renderShadowMaps(fg, engine, driver, shadowPass); } @@ -436,7 +433,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { // This is normally used by SSAO and contact-shadows // TODO: the scaling should depends on all passes that need the structure pass - ppm.structure(fg, pass, structureRenderFlags, svp.width, svp.height, { + ppm.structure(fg, pass, renderFlags, svp.width, svp.height, { .scale = aoOptions.resolution, .picking = view.hasPicking() }); @@ -503,7 +500,8 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { // This one doesn't need to be a FrameGraph pass because it always happens by construction // (i.e. it won't be culled, unless everything is culled), so no need to complexify things. - pass.setRenderFlags(colorRenderFlags); + pass.setRenderFlags(renderFlags); + pass.setVariant(variant); pass.appendCommands(RenderPass::COLOR); pass.sortCommands(); diff --git a/libs/filabridge/include/private/filament/Variant.h b/libs/filabridge/include/private/filament/Variant.h index 3069fbab77..c8457b0d04 100644 --- a/libs/filabridge/include/private/filament/Variant.h +++ b/libs/filabridge/include/private/filament/Variant.h @@ -34,6 +34,8 @@ namespace filament { using type_t = uint8_t; Variant() noexcept = default; + Variant(Variant const& rhs) noexcept = default; + Variant& operator=(Variant const& rhs) noexcept = default; constexpr explicit Variant(type_t key) noexcept : key(key) { }