Skip to content

Commit

Permalink
Disable sky after maximum projection transition to mercator (#11215)
Browse files Browse the repository at this point in the history
* Disable sky below maximum projection transition to mercator

* Revert change

* Better naming

* Apply Ansis suggestion

* Renaming
  • Loading branch information
karimnaaji authored Nov 4, 2021
1 parent 302e679 commit 92284d3
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 11 deletions.
10 changes: 8 additions & 2 deletions src/geo/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -1915,7 +1915,8 @@ class Transform {
}

// Check if any of the four corners are off the edge of the rendered map
isCornerOffEdge(p0: Point, p1: Point): boolean {
// This function will return `false` for all non-mercator projection
anyCornerOffEdge(p0: Point, p1: Point): boolean {
const minX = Math.min(p0.x, p1.x);
const maxX = Math.max(p0.x, p1.x);
const minY = Math.min(p0.y, p1.y);
Expand All @@ -1924,6 +1925,10 @@ class Transform {
const horizon = this.horizonLineFromTop(false);
if (minY < horizon) return true;

if (this.projection.name !== 'mercator') {
return false;
}

const min = new Point(minX, minY);
const max = new Point(maxX, maxY);

Expand Down Expand Up @@ -1958,14 +1963,15 @@ class Transform {
// Checks the four corners of the frustum to see if they lie in the map's quad.
//
isHorizonVisible(): boolean {

// we consider the horizon as visible if the angle between
// a the top plane of the frustum and the map plane is smaller than this threshold.
const horizonAngleEpsilon = 2;
if (this.pitch + radToDeg(this.fovAboveCenter) > (90 - horizonAngleEpsilon)) {
return true;
}

return this.isCornerOffEdge(new Point(0, 0), new Point(this.width, this.height));
return this.anyCornerOffEdge(new Point(0, 0), new Point(this.width, this.height));
}

/**
Expand Down
11 changes: 10 additions & 1 deletion src/render/draw_sky.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import CullFaceMode from '../gl/cull_face_mode.js';
import Context from '../gl/context.js';
import Texture from './texture.js';
import Program from './program.js';
import {smoothstep} from '../util/util.js';
import type SourceCache from '../source/source_cache.js';
import SkyboxGeometry from './skybox_geometry.js';
import {skyboxUniformValues, skyboxGradientUniformValues} from './program/skybox_program.js';
Expand All @@ -18,8 +19,16 @@ import assert from 'assert';

export default drawSky;

const TRANSITION_OPACITY_ZOOM_START = 7;
const TRANSITION_OPACITY_ZOOM_END = 8;

function drawSky(painter: Painter, sourceCache: SourceCache, layer: SkyLayer) {
const opacity = layer.paint.get('sky-opacity');
const tr = painter.transform;
const isMercator = tr.projection.name === 'mercator';
// For non-mercator projection, use a forced opacity transition. This transition is set to be
// 1.0 after the sheer adjustment upper bound which ensures to be in the mercator projection.
const transitionOpacity = isMercator ? 1.0 : smoothstep(TRANSITION_OPACITY_ZOOM_START, TRANSITION_OPACITY_ZOOM_END, tr.zoom);
const opacity = layer.paint.get('sky-opacity') * transitionOpacity;
if (opacity === 0) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/style-spec/reference/v8.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
},
"projection": {
"type": "projection",
"doc": "The projection the map should be rendered in. Suported projections are Albers, Equal Earth, Equirectangular (WGS84), Lambert conformal conic, Mercator, Natural Earth, and Winkel Tripel. Terrain, fog and CustomLayerInterface are not supported for projections other than mercator.",
"doc": "The projection the map should be rendered in. Suported projections are Albers, Equal Earth, Equirectangular (WGS84), Lambert conformal conic, Mercator, Natural Earth, and Winkel Tripel. Terrain, fog, sky and CustomLayerInterface are not supported for projections other than mercator.",
"example": {
"name": "albers",
"center": [-154, 50],
Expand Down
2 changes: 1 addition & 1 deletion src/ui/camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ class Camera extends Evented {
const raycast = this._raycastElevationBox(point0, point1);

if (!raycast) {
if (this.transform.isCornerOffEdge(point0, point1)) {
if (this.transform.anyCornerOffEdge(point0, point1)) {
return this;
}

Expand Down
12 changes: 6 additions & 6 deletions test/unit/geo/transform.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ test('transform', (t) => {

t.test('isHorizonVisible', (t) => {

t.test('isCornerOffEdge', (t) => {
t.test('anyCornerOffEdge', (t) => {
const transform = new Transform();
transform.maxPitch = 85;
transform.resize(800, 800);
Expand All @@ -1109,21 +1109,21 @@ test('transform', (t) => {
t.true(transform.isHorizonVisible());

p0 = new Point(0, 0); p1 = new Point(10, 10);
t.true(transform.isCornerOffEdge(p0, p1));
t.true(transform.anyCornerOffEdge(p0, p1));

p0 = new Point(0, 250); p1 = new Point(10, 350);
t.true(transform.isCornerOffEdge(p0, p1));
t.true(transform.anyCornerOffEdge(p0, p1));

p0 = new Point(0, transform.horizonLineFromTop() - 10);
p1 = new Point(10, transform.horizonLineFromTop() + 10);
t.true(transform.isCornerOffEdge(p0, p1));
t.true(transform.anyCornerOffEdge(p0, p1));

p0 = new Point(0, 700); p1 = new Point(10, 710);
t.false(transform.isCornerOffEdge(p0, p1));
t.false(transform.anyCornerOffEdge(p0, p1));

p0 = new Point(0, transform.horizonLineFromTop());
p1 = new Point(10, transform.horizonLineFromTop() + 10);
t.false(transform.isCornerOffEdge(p0, p1));
t.false(transform.anyCornerOffEdge(p0, p1));

t.end();
});
Expand Down

0 comments on commit 92284d3

Please sign in to comment.