Double renderbins for renderables (#2520)

This commit is contained in:
Emma Broman
2023-03-08 10:59:32 +01:00
committed by GitHub
parent 5e7b67e077
commit 4a50c4cbc0
5 changed files with 58 additions and 19 deletions

View File

@@ -82,8 +82,9 @@ public:
std::string_view typeAsString() const;
virtual void render(const RenderData& data, RendererTasks& rendererTask);
virtual void update(const UpdateData& data);
virtual void render(const RenderData& data, RendererTasks& rendererTask);
virtual void renderSecondary(const RenderData& data, RendererTasks& rendererTask);
// The 'surface' in this case is the interaction sphere of this renderable. In some
// cases (i.e., planets) this corresponds directly to the physical surface, but in
@@ -97,7 +98,9 @@ public:
RenderBin renderBin() const;
void setRenderBin(RenderBin bin);
bool matchesRenderBinMask(int binMask);
bool matchesRenderBinMask(int binMask) const noexcept;
bool matchesSecondaryRenderBin(int binMask) const noexcept;
void setFade(float fade);
@@ -129,6 +132,10 @@ protected:
bool _shouldUpdateIfDisabled = false;
RenderBin _renderBin = RenderBin::Opaque;
// An optional renderbin that renderables can use for certain components, in cases
// where all parts of the renderable should not be rendered in the same bin
std::optional<RenderBin> _secondaryRenderBin;
private:
// We only want the SceneGraphNode to be able manipulate the parent, so we don't want
// to provide a set method for this. Otherwise, anyone might mess around with our

View File

@@ -64,6 +64,8 @@ namespace std {
#endif
namespace {
constexpr std::string_view _loggerCat = "RenderableGlobe";
// Global flags to modify the RenderableGlobe
constexpr bool LimitLevelByAvailableData = true;
constexpr bool PerformFrustumCulling = true;
@@ -664,6 +666,10 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
_generalProperties.shadowMapping = true;
}
_generalProperties.shadowMapping.onChange(notifyShaderRecompilation);
// Use a secondary renderbin for labels, and other things that we want to be able to
// render with transparency, on top of the globe, after the atmosphere step
_secondaryRenderBin = RenderBin::PostDeferredTransparent;
}
void RenderableGlobe::initializeGL() {
@@ -735,9 +741,6 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
if ((distanceToCamera < distance) || (_generalProperties.renderAtDistance)) {
try {
// Before Shadows
_globeLabelsComponent.draw(data);
if (_hasShadows && _shadowComponent.isEnabled()) {
// Set matrices and other GL states
RenderData lightRenderData(_shadowComponent.begin(data));
@@ -806,6 +809,15 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
_lastChangedLayer = nullptr;
}
void RenderableGlobe::renderSecondary(const RenderData& data, RendererTasks&) {
try {
_globeLabelsComponent.draw(data);
}
catch (const ghoul::opengl::TextureUnit::TextureUnitError& e) {
LERROR(fmt::format("Error on drawing globe labels: '{}'", e.message));
}
}
void RenderableGlobe::update(const UpdateData& data) {
ZoneScoped;

View File

@@ -103,6 +103,7 @@ public:
bool isReady() const override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
void renderSecondary(const RenderData& data, RendererTasks&) override;
void update(const UpdateData& data) override;
SurfacePositionHandle calculateSurfacePositionHandle(

View File

@@ -224,6 +224,8 @@ void Renderable::update(const UpdateData&) {}
void Renderable::render(const RenderData&, RendererTasks&) {}
void Renderable::renderSecondary(const RenderData&, RendererTasks&) {}
void Renderable::setBoundingSphere(double boundingSphere) {
_boundingSphere = boundingSphere;
}
@@ -267,8 +269,15 @@ void Renderable::setRenderBin(RenderBin bin) {
_renderBin = bin;
}
bool Renderable::matchesRenderBinMask(int binMask) {
return binMask & static_cast<int>(renderBin());
bool Renderable::matchesRenderBinMask(int binMask) const noexcept {
return binMask & static_cast<int>(_renderBin);
}
bool Renderable::matchesSecondaryRenderBin(int binMask) const noexcept {
if (!_secondaryRenderBin.has_value()) {
return false;
}
return binMask & static_cast<int>(*_secondaryRenderBin);
}
void Renderable::setFade(float fade) {

View File

@@ -737,7 +737,7 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) {
}
const bool visible = _renderable && _renderable->isVisible() &&
_renderable->isReady() && _renderable->matchesRenderBinMask(data.renderBinMask);
_renderable->isReady();
if (!visible) {
return;
@@ -747,21 +747,31 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) {
return;
}
RenderData newData = {
.camera = data.camera,
.time = data.time,
.renderBinMask = data.renderBinMask,
.modelTransform = {
.translation = _worldPositionCached,
.rotation = _worldRotationCached,
.scale = _worldScaleCached
}
};
if (_renderable->matchesSecondaryRenderBin(data.renderBinMask)) {
TracyGpuZone("Render Secondary Bin")
_renderable->renderSecondary(newData, tasks);
}
if (!_renderable->matchesRenderBinMask(data.renderBinMask)) {
return;
}
{
TracyGpuZone("Render")
RenderData newData = {
.camera = data.camera,
.time = data.time,
.renderBinMask = data.renderBinMask,
.modelTransform = {
.translation = _worldPositionCached,
.rotation = _worldRotationCached,
.scale = _worldScaleCached
}
};
_renderable->render(newData, tasks);
if (_computeScreenSpaceValues) {
computeScreenSpaceData(newData);
}