Skip to content

Commit

Permalink
wip: picking
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelflinger committed Sep 21, 2021
1 parent 0744876 commit c638593
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 82 deletions.
5 changes: 3 additions & 2 deletions filament/src/Material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder)
if (UTILS_UNLIKELY(!mIsDefaultMaterial && !mHasCustomDepthShader)) {
auto& cachedPrograms = mCachedPrograms;
for (uint8_t i = 0, n = cachedPrograms.size(); i < n; ++i) {
if (Variant(i).isDepthPass()) {
const Variant v{ i };
if (v.isDepthPass() && !Variant::isReserved(i)) {
cachedPrograms[i] = engine.getDefaultMaterial()->getProgram(i);
}
}
Expand Down Expand Up @@ -430,7 +431,7 @@ Program FMaterial::getProgramBuilderWithVariants(

ASSERT_POSTCONDITION(isNoop || (fsOK && fsBuilder.size() > 0),
"The material '%s' has not been compiled to include the required "
"GLSL or SPIR-V chunks for the fragment shader (variant=0x%x, filterer=0x%x).",
"GLSL or SPIR-V chunks for the fragment shader (variant=0x%x, filtered=0x%x).",
mName.c_str(), variantKey, fragmentVariantKey);

Program pb;
Expand Down
19 changes: 16 additions & 3 deletions filament/src/PostProcessManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,15 +313,18 @@ void PostProcessManager::commitAndRender(FrameGraphResources::RenderPassInfo con
// ------------------------------------------------------------------------------------------------

FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,
RenderPass const& pass, uint32_t width, uint32_t height, float scale) noexcept {
RenderPass const& pass, uint32_t width, uint32_t height,
StructurePassConfig const& config) noexcept {

const float scale = config.scale;

// 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;
FrameGraphId<FrameGraphTexture> picking;
};

// sanitize a bit the user provided scaling factor
Expand All @@ -342,9 +345,18 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,

data.depth = builder.write(data.depth, FrameGraphTexture::Usage::DEPTH_ATTACHMENT);

if (config.picking) {
data.picking = builder.createTexture("Picking Buffer", {
.width = width, .height = height,
.format = TextureFormat::R32UI });

data.picking = builder.write(data.picking,
FrameGraphTexture::Usage::COLOR_ATTACHMENT);
}

builder.declareRenderPass("Structure Target", {
.attachments = { .depth = data.depth },
.clearFlags = TargetBufferFlags::DEPTH
.attachments = { .color = { data.picking }, .depth = data.depth },
.clearFlags = TargetBufferFlags::COLOR0 | TargetBufferFlags::DEPTH
});
},
[=](FrameGraphResources const& resources,
Expand Down Expand Up @@ -393,6 +405,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,
});

fg.getBlackboard().put("structure", depth);
fg.getBlackboard().put("picking", structurePass->picking);
return depth;
}

Expand Down
9 changes: 7 additions & 2 deletions filament/src/PostProcessManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,18 @@ struct CameraInfo;
class PostProcessManager {
public:
struct ColorGradingConfig {
bool asSubpass = false;
bool asSubpass{};
bool translucent{};
bool fxaa{};
bool dithering{};
backend::TextureFormat ldrFormat{};
};

struct StructurePassConfig {
float scale = 0.5f;
bool picking{};
};

explicit PostProcessManager(FEngine& engine) noexcept;

void init() noexcept;
Expand All @@ -65,7 +70,7 @@ class PostProcessManager {

// structure (depth) pass
FrameGraphId<FrameGraphTexture> structure(FrameGraph& fg, RenderPass const& pass,
uint32_t width, uint32_t height, float scale) noexcept;
uint32_t width, uint32_t height, StructurePassConfig const& config) noexcept;

// SSAO
FrameGraphId<FrameGraphTexture> screenSpaceAmbientOcclusion(FrameGraph& fg,
Expand Down
46 changes: 25 additions & 21 deletions filament/src/RenderPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
// (in principle, we could have split this method into two, at the cost of going through
// the list twice)

const bool isColorPass = bool(commandTypeFlags & CommandTypeFlags::COLOR);
const bool isDepthPass = bool(commandTypeFlags & CommandTypeFlags::DEPTH);
constexpr bool isColorPass = bool(commandTypeFlags & CommandTypeFlags::COLOR);
constexpr bool isDepthPass = bool(commandTypeFlags & CommandTypeFlags::DEPTH);

static_assert(isColorPass != isDepthPass, "only color or depth pass supported");

Expand All @@ -292,13 +292,16 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
Command cmdColor;

Command cmdDepth;
cmdDepth.primitive.materialVariant = Variant{ Variant::DEPTH_VARIANT };
cmdDepth.primitive.materialVariant.setVsm(renderFlags & HAS_VSM);
cmdDepth.primitive.rasterState = {};
cmdDepth.primitive.rasterState.colorWrite = renderFlags & HAS_VSM;
cmdDepth.primitive.rasterState.depthWrite = true;
cmdDepth.primitive.rasterState.depthFunc = RasterState::DepthFunc::GE;
cmdDepth.primitive.rasterState.alphaToCoverage = false;
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.rasterState = {};
cmdDepth.primitive.rasterState.colorWrite = renderFlags & (HAS_VSM | HAS_PICKING);
cmdDepth.primitive.rasterState.depthWrite = true;
cmdDepth.primitive.rasterState.depthFunc = RasterState::DepthFunc::GE;
cmdDepth.primitive.rasterState.alphaToCoverage = false;
}

for (uint32_t i = range.first; i < range.last; ++i) {
// Check if this renderable passes the visibilityMask. If it doesn't, encode SENTINEL
Expand Down Expand Up @@ -353,15 +356,16 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
materialVariant.setShadowReceiver(soaVisibility[i].receiveShadows & hasShadowing);
materialVariant.setSkinning(soaVisibility[i].skinning || soaVisibility[i].morphing);

// we're assuming we're always doing the depth (either way, it's correct)
// this will generate front to back rendering
cmdDepth.key = uint64_t(Pass::DEPTH);
cmdDepth.key |= uint64_t(CustomCommand::PASS);
cmdDepth.key |= makeField(soaVisibility[i].priority, PRIORITY_MASK, PRIORITY_SHIFT);
cmdDepth.key |= makeField(distanceBits, DISTANCE_BITS_MASK, DISTANCE_BITS_SHIFT);
cmdDepth.primitive.index = (uint16_t)i;
cmdDepth.primitive.materialVariant.setSkinning(soaVisibility[i].skinning || soaVisibility[i].morphing);
cmdDepth.primitive.rasterState.inverseFrontFaces = inverseFrontFaces;
if constexpr (isDepthPass) {
cmdDepth.key = uint64_t(Pass::DEPTH);
cmdDepth.key |= uint64_t(CustomCommand::PASS);
cmdDepth.key |= makeField(soaVisibility[i].priority, PRIORITY_MASK, PRIORITY_SHIFT);
cmdDepth.key |= makeField(distanceBits, DISTANCE_BITS_MASK, DISTANCE_BITS_SHIFT);
cmdDepth.primitive.index = (uint16_t)i;
cmdDepth.primitive.materialVariant.setSkinning(
soaVisibility[i].skinning || soaVisibility[i].morphing);
cmdDepth.primitive.rasterState.inverseFrontFaces = inverseFrontFaces;
}

const bool shadowCaster = soaVisibility[i].castShadows & hasShadowing;
const bool writeDepthForShadowCasters = depthContainsShadowCasters & shadowCaster;
Expand All @@ -374,7 +378,7 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
*/
for (auto const& primitive : primitives) {
FMaterialInstance const* const mi = primitive.getMaterialInstance();
if (isColorPass) {
if constexpr (isColorPass) {
cmdColor.primitive.primitiveHandle = primitive.getHwHandle();
cmdColor.primitive.materialVariant = materialVariant;
RenderPass::setupColorCommand(cmdColor, mi, inverseFrontFaces);
Expand Down Expand Up @@ -454,13 +458,13 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
++curr;
}

if (isDepthPass) {
if constexpr (isDepthPass) {
FMaterial const* const ma = mi->getMaterial();
const RasterState rs = ma->getRasterState();
const TransparencyMode mode = mi->getTransparencyMode();
const BlendingMode blendingMode = ma->getBlendingMode();
const bool translucent = (blendingMode != BlendingMode::OPAQUE
&& blendingMode != BlendingMode::MASKED);
&& blendingMode != BlendingMode::MASKED);

// unconditionally write the command
cmdDepth.primitive.primitiveHandle = primitive.getHwHandle();
Expand Down
3 changes: 2 additions & 1 deletion filament/src/RenderPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ class RenderPass {
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;

// Arena used for commands
using Arena = utils::Arena<
Expand Down Expand Up @@ -270,7 +271,7 @@ class RenderPass {
// specifies camera information (e.g. used for sorting commands)
void setCamera(const CameraInfo& camera) noexcept { mCamera = camera; }

// flags controling how commands are generated
// flags controlling how commands are generated
void setRenderFlags(RenderFlags flags) noexcept { mFlags = flags; }

// Sets the visibility mask, which is AND-ed against each Renderable's VISIBLE_MASK to determine
Expand Down
31 changes: 21 additions & 10 deletions filament/src/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,14 +280,18 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
RenderPass::Arena commandArena("Command Arena", { arenaBegin, arenaEnd });

RenderPass pass(engine, commandArena);
RenderPass::RenderFlags renderFlags = 0;
if (view.hasShadowing()) renderFlags |= RenderPass::HAS_SHADOWING;
if (view.hasDirectionalLight()) renderFlags |= RenderPass::HAS_DIRECTIONAL_LIGHT;
if (view.hasDynamicLighting()) renderFlags |= RenderPass::HAS_DYNAMIC_LIGHTING;
if (view.hasFog()) renderFlags |= RenderPass::HAS_FOG;
if (view.isFrontFaceWindingInverted()) renderFlags |= RenderPass::HAS_INVERSE_FRONT_FACES;
if (view.hasVsm()) renderFlags |= RenderPass::HAS_VSM;
pass.setRenderFlags(renderFlags);
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;
if (view.hasVsm()) colorRenderFlags |= RenderPass::HAS_VSM;

RenderPass::RenderFlags structureRenderFlags = baseRenderFlags;
if (view.hasPicking()) structureRenderFlags |= RenderPass::HAS_PICKING;

/*
* Frame graph
Expand All @@ -300,7 +304,9 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
*/

if (view.needsShadowMap()) {
view.renderShadowMaps(fg, engine, driver, pass);
RenderPass shadowPass(pass);
shadowPass.setRenderFlags(colorRenderFlags);
view.renderShadowMaps(fg, engine, driver, shadowPass);
}

// When we don't have a custom RenderTarget, currentRenderTarget below is nullptr and is
Expand Down Expand Up @@ -414,11 +420,15 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {

// TODO: ideally this should be a FrameGraph pass to participate to automatic culling
RenderPass structurePass(pass);
structurePass.setRenderFlags(structureRenderFlags);
structurePass.appendCommands(RenderPass::CommandTypeFlags::SSAO);
structurePass.sortCommands();

// TODO: the scaling should depends on all passes that need the structure pass
ppm.structure(fg, structurePass, svp.width, svp.height, aoOptions.resolution);
ppm.structure(fg, structurePass, svp.width, svp.height, {
.scale = aoOptions.resolution,
.picking = view.hasPicking()
});

// Apply the TAA jitter to everything after the structure pass, starting with the color pass.
if (taaOptions.enabled) {
Expand Down Expand Up @@ -448,6 +458,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
// Color passes

// TODO: ideally this should be a FrameGraph pass to participate to automatic culling
pass.setRenderFlags(colorRenderFlags);
pass.appendCommands(RenderPass::COLOR);
pass.sortCommands();

Expand Down
8 changes: 8 additions & 0 deletions filament/src/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ void FScene::prepare(const mat4& worldOriginTransform, bool shadowReceiversAreCa

void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Handle<backend::HwBufferObject> renderableUbh) noexcept {
FEngine::DriverApi& driver = mEngine.getDriverApi();
FRenderableManager& rcm = mEngine.getRenderableManager();

const size_t size = visibleRenderables.size() * sizeof(PerRenderableUib);

// allocate space into the command stream directly
Expand All @@ -208,6 +210,8 @@ void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Hand
for (uint32_t i : visibleRenderables) {
mat4f const& model = sceneData.elementAt<WORLD_TRANSFORM>(i);
FRenderableManager::Visibility visibility = sceneData.elementAt<VISIBILITY_STATE>(i);
auto ri = sceneData.elementAt<RENDERABLE_INSTANCE>(i);

const size_t offset = i * sizeof(PerRenderableUib);

UniformBuffer::setUniform(buffer,
Expand Down Expand Up @@ -257,6 +261,10 @@ void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Hand
offset + offsetof(PerRenderableUib, channels),
(uint32_t)sceneData.elementAt<CHANNELS>(i));

UniformBuffer::setUniform(buffer,
offset + offsetof(PerRenderableUib, objectId),
rcm.getEntity(ri).getId()); // we could also store the entity in sceneData

// TODO: We need to find a better way to provide the scale information per object
UniformBuffer::setUniform(buffer,
offset + offsetof(PerRenderableUib, userData),
Expand Down
2 changes: 0 additions & 2 deletions filament/src/ShadowMapManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,13 @@ void ShadowMapManager::render(FrameGraph& fg, FEngine& engine, backend::DriverAp
auto depth = builder.createTexture("Temporary VSM Depth Texture", {
.width = textureRequirements.size, .height = textureRequirements.size,
.samples = options->vsm.msaaSamples,
.type = SamplerType::SAMPLER_2D,
.format = mTextureFormat,
});

// Temporary (resolved) texture used to render the shadowmap when blurring
// is needed -- it'll be used as the source of the blur.
data.tempBlurSrc = builder.createTexture("Temporary Shadowmap", {
.width = textureRequirements.size, .height = textureRequirements.size,
.type = SamplerType::SAMPLER_2D,
.format = vsmTextureFormat
});

Expand Down
4 changes: 4 additions & 0 deletions filament/src/components/RenderableManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ class FRenderableManager : public RenderableManager {
inline uint32_t getBoneCount(Instance instance) const noexcept;


utils::Entity getEntity(Instance instance) const noexcept {
return mManager.getEntity(instance);
}

inline size_t getLevelCount(Instance instance) const noexcept { return 1; }
inline size_t getPrimitiveCount(Instance instance, uint8_t level) const noexcept;
void setMaterialInstanceAt(Instance instance, uint8_t level,
Expand Down
1 change: 1 addition & 0 deletions filament/src/details/View.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ class FView : public View {
bool needsShadowMap() const noexcept { return mNeedsShadowMap; }
bool hasFog() const noexcept { return mFogOptions.enabled && mFogOptions.density > 0.0f; }
bool hasVsm() const noexcept { return mShadowType == ShadowType::VSM; }
bool hasPicking() const noexcept { return false; /* TODO: implement this */ }

void renderShadowMaps(FrameGraph& fg, FEngine& engine, FEngine::DriverApi& driver,
RenderPass const& pass) noexcept;
Expand Down
6 changes: 3 additions & 3 deletions libs/filabridge/include/private/filament/UibStructs.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ struct alignas(256) PerRenderableUib {
math::mat4f worldFromModelMatrix;
math::mat3f worldFromModelNormalMatrix; // this gets expanded to 48 bytes during the copy to the UBO
alignas(16) math::float4 morphWeights; // morph weights (we could easily have 8 using half)
uint32_t flags; // see packFlags() below
uint32_t channels; // 0x000000ll
uint32_t reserved1; // 0
uint32_t flags; // see packFlags() below
uint32_t channels; // 0x000000ll
uint32_t objectId; // used for picking
// TODO: We need a better solution, this currently holds the average local scale for the renderable
float userData;

Expand Down
Loading

0 comments on commit c638593

Please sign in to comment.