From 2c5528e691b502673b16723205c83add62317734 Mon Sep 17 00:00:00 2001 From: Aleksandar Stojiljkovic Date: Sun, 7 Jul 2019 13:40:22 +0300 Subject: Fix layers rendering after fill-extrusion This fixes following issues: * Fix some false passing combinations/fill-extrusion-translucent--XXXX tests * Fix and enable other, failing but ignored, combinations/fill-extrusion-translucent--XXXX tests * Fix rendering of layers that are on top of fill-extrusion layers state.getProjMatrix(nearClippedProjMatrix, 100) caused that tests with size 64x64 were not rendering fill extrusions: far plane calculated as 96.9 and near plane set to 100 was the cause. near plane is changed from hardcoded 100 to depend on state.getCameraToCenterDistance() - producing similar value but one that follows max zoom. This caused that e.g. combinations/fill-extrusion-translucent--fill-opaque was falsely passing as only fill-opaque layer got rendered. combinations/fill-extrusion-translucent--XXXX tests expose regression https://github.com/mapbox/mapbox-gl-native/issues/14844#issuecomment-503600034 in #14844, #14779. Fix (opaquePassCutoff, is3D) is ported from https://github.com/mapbox/mapbox-gl-js/pull/7821 Fixes: #14844, #14779, #15039 --- platform/node/test/ignores.json | 18 ------------------ .../renderer/layers/render_fill_extrusion_layer.cpp | 4 ++++ .../renderer/layers/render_fill_extrusion_layer.hpp | 1 + src/mbgl/renderer/layers/render_fill_layer.cpp | 9 ++++----- src/mbgl/renderer/paint_parameters.cpp | 12 ++++++++---- src/mbgl/renderer/paint_parameters.hpp | 3 +-- src/mbgl/renderer/render_layer.hpp | 3 +++ src/mbgl/renderer/render_orchestrator.cpp | 10 +++++++--- src/mbgl/renderer/render_tile.cpp | 2 +- src/mbgl/renderer/render_tree.hpp | 1 + src/mbgl/renderer/renderer_impl.cpp | 1 + 11 files changed, 31 insertions(+), 33 deletions(-) diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json index 63b9764f22..4b2ed7fd3f 100644 --- a/platform/node/test/ignores.json +++ b/platform/node/test/ignores.json @@ -87,25 +87,7 @@ "render-tests/text-rotate/with-offset": "https://github.com/mapbox/mapbox-gl-native/issues/11872", "render-tests/video/default": "skip - https://github.com/mapbox/mapbox-gl-native/issues/601", "render-tests/background-color/colorSpace-hcl": "needs issue", - "render-tests/combinations/fill-extrusion-translucent--heatmap-translucent": "needs investigation", "render-tests/combinations/heatmap-translucent--background-opaque": "needs investigation", - "render-tests/combinations/heatmap-translucent--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/background-opaque--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/background-translucent--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/circle-translucent--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/fill-extrusion-translucent--background-translucent": "needs investigation", - "render-tests/combinations/fill-extrusion-translucent--circle-translucent": "needs investigation", - "render-tests/combinations/fill-extrusion-translucent--hillshade-translucent": "needs investigation", - "render-tests/combinations/fill-extrusion-translucent--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/fill-extrusion-translucent--fill-translucent": "needs investigation", - "render-tests/combinations/fill-extrusion-translucent--line-translucent": "needs investigation", - "render-tests/combinations/fill-extrusion-translucent--symbol-translucent": "needs investigation", - "render-tests/combinations/hillshade-translucent--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/fill-opaque--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/fill-translucent--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/line-translucent--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/raster-translucent--fill-extrusion-translucent": "needs investigation", - "render-tests/combinations/symbol-translucent--fill-extrusion-translucent": "needs investigation", "render-tests/feature-state/composite-expression": "https://github.com/mapbox/mapbox-gl-native/issues/12613", "render-tests/feature-state/data-expression": "https://github.com/mapbox/mapbox-gl-native/issues/12613", "render-tests/feature-state/vector-source": "https://github.com/mapbox/mapbox-gl-native/issues/12613", diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index b8d195cfa1..5ad2e53a5b 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -55,6 +55,10 @@ bool RenderFillExtrusionLayer::hasCrossfade() const { return getCrossfade(evaluatedProperties).t != 1; } +bool RenderFillExtrusionLayer::is3D() const { + return true; +} + void RenderFillExtrusionLayer::render(PaintParameters& parameters) { assert(renderTiles); if (parameters.pass != RenderPass::Translucent) { diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp index 9118601581..8bd1f52adf 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp @@ -17,6 +17,7 @@ private: void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; bool hasCrossfade() const override; + bool is3D() const override; void render(PaintParameters&) override; bool queryIntersectsFeature( diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 6a3c247fbb..c2bf149582 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -130,11 +130,10 @@ void RenderFillLayer::render(PaintParameters& parameters) { ); }; - // Only draw the fill when it's opaque and we're drawing opaque fragments, - // or when it's translucent and we're drawing translucent fragments. - if (bucket.triangleIndexBuffer && - (evaluated.get().constantOr(Color()).a >= 1.0f && - evaluated.get().constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) { + auto fillRenderPass = (evaluated.get().constantOr(Color()).a >= 1.0f + && evaluated.get().constantOr(0) >= 1.0f + && parameters.currentLayer >= parameters.opaquePassCutoff) ? RenderPass::Opaque : RenderPass::Translucent; + if (bucket.triangleIndexBuffer && parameters.pass == fillRenderPass) { draw(parameters.programs.getFillLayerPrograms().fill, gfx::Triangles(), parameters.depthModeForSublayer(1, parameters.pass == RenderPass::Opaque diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp index 1539c0fbcb..6c6abc008b 100644 --- a/src/mbgl/renderer/paint_parameters.cpp +++ b/src/mbgl/renderer/paint_parameters.cpp @@ -19,10 +19,11 @@ TransformParameters::TransformParameters(const TransformState& state_) // odd viewport sizes. state.getProjMatrix(alignedProjMatrix, 1, true); - // Calculate a second projection matrix with the near plane clipped to 100 so as - // not to waste lots of depth buffer precision on very close empty space, for layer - // types (fill-extrusion) that use the depth buffer to emulate real-world space. - state.getProjMatrix(nearClippedProjMatrix, 100); + // Calculate a second projection matrix with the near plane moved further, + // to a tenth of the far value, so as not to waste depth buffer precision on + // very close empty space, for layer types (fill-extrusion) that use the + // depth buffer to emulate real-world space. + state.getProjMatrix(nearClippedProjMatrix, 0.1 * state.getCameraToCenterDistance()); } PaintParameters::PaintParameters(gfx::Context& context_, @@ -72,6 +73,9 @@ mat4 PaintParameters::matrixForTile(const UnwrappedTileID& tileID, bool aligned) } gfx::DepthMode PaintParameters::depthModeForSublayer(uint8_t n, gfx::DepthMaskType mask) const { + if (currentLayer < opaquePassCutoff) { + return gfx::DepthMode::disabled(); + } float depth = depthRangeSize + ((1 + currentLayer) * numSublayers + n) * depthEpsilon; return gfx::DepthMode { gfx::DepthFunctionType::LessEqual, mask, { depth, depth } }; } diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp index a0d26df7c5..a043ad5578 100644 --- a/src/mbgl/renderer/paint_parameters.hpp +++ b/src/mbgl/renderer/paint_parameters.hpp @@ -104,8 +104,7 @@ public: uint32_t currentLayer; float depthRangeSize; const float depthEpsilon = 1.0f / (1 << 16); - - + uint32_t opaquePassCutoff = 0; float symbolFadeChange; }; diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index c7efdceab4..fe8b7c6529 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -66,6 +66,9 @@ public: // Returns true if the layer has a pattern property and is actively crossfading. virtual bool hasCrossfade() const = 0; + // Returns true if layer writes to depth buffer by drawing using PaintParameters::depthModeFor3D(). + virtual bool is3D() const { return false; } + // Returns true is the layer is subject to placement. bool needsPlacement() const; diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index 7df74cda71..c70ce63c76 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -342,12 +342,16 @@ std::unique_ptr RenderOrchestrator::createRenderTree(const UpdatePar } } - for (auto& renderItem : layerRenderItems) { - RenderLayer& renderLayer = renderItem.layer; - renderLayer.prepare({renderItem.source, *imageManager, *patternAtlas, *lineAtlas, updateParameters.transformState}); + uint32_t i = static_cast(layerRenderItems.size()) - 1; + for (auto it = layerRenderItems.begin(); it != layerRenderItems.end(); ++it, --i) { + RenderLayer& renderLayer = it->layer; + renderLayer.prepare({it->source, *imageManager, *patternAtlas, *lineAtlas, updateParameters.transformState}); if (renderLayer.needsPlacement()) { layersNeedPlacement.emplace_back(renderLayer); } + if (renderLayer.is3D() && renderTreeParameters->opaquePassCutOff == 0) { + renderTreeParameters->opaquePassCutOff = i; + } } // Symbol placement. { diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index fbb2ae81de..65a6cb9f30 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -121,7 +121,7 @@ void RenderTile::prepare(const SourcePrepareParameters& parameters) { } // Calculate two matrices for this tile: matrix is the standard tile matrix; nearClippedMatrix - // clips the near plane to 100 to save depth buffer precision + // has near plane moved further, to enhance depth buffer precision const auto& transform = parameters.transform; transform.state.matrixFor(matrix, id); transform.state.matrixFor(nearClippedMatrix, id); diff --git a/src/mbgl/renderer/render_tree.hpp b/src/mbgl/renderer/render_tree.hpp index 4266ddec6d..cf62ccb03e 100644 --- a/src/mbgl/renderer/render_tree.hpp +++ b/src/mbgl/renderer/render_tree.hpp @@ -47,6 +47,7 @@ public: TimePoint timePoint; EvaluatedLight light; bool has3D = false; + uint32_t opaquePassCutOff = 0; Color backgroundColor; float symbolFadeChange = 0.0f; bool needsRepaint = false; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index c536497c30..990d9cd3ab 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -77,6 +77,7 @@ void Renderer::Impl::render(const RenderTree& renderTree) { }; parameters.symbolFadeChange = renderTreeParameters.symbolFadeChange; + parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff; const auto& sourceRenderItems = renderTree.getSourceRenderItems(); const auto& layerRenderItems = renderTree.getLayerRenderItems(); -- cgit v1.2.1