Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Globe atmosphere + Style specification #11590

Merged
merged 41 commits into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
34531ca
Globe atmosphere style specification
karimnaaji Feb 23, 2022
dc93f05
Fix alpha blending for background
karimnaaji Mar 22, 2022
c73e44a
Update atmosphere shader to be based off horizon angle instead of dis…
karimnaaji Mar 23, 2022
85bf837
Compute view space horizon angle in mercator
karimnaaji Mar 23, 2022
dfc77a5
Add separate fog tile matrix to prevent ecef encoding and artifacts d…
karimnaaji Mar 24, 2022
2f0cd42
Fix horizon-blend
karimnaaji Mar 27, 2022
e28ef0a
Fixup shader definition of fog on default atmosphere shader
karimnaaji Mar 29, 2022
d49faf4
Cleanup clear and fog uniform initialization
karimnaaji Mar 29, 2022
770dd33
Renaming spec `sky-color` -> `high-color`
karimnaaji Mar 30, 2022
c77182d
Add frustum corner class and reduce some code duplication
karimnaaji Mar 30, 2022
43b2f79
Cleanup premultiply alpha inlined code
karimnaaji Mar 30, 2022
b58e526
Fix flow and lint syntax
karimnaaji Mar 30, 2022
8fb0df1
Simplify `viewMatrix` calculation for atmosphere render
karimnaaji Mar 30, 2022
b9e9ec6
Fix `horizonClipR` calculation
karimnaaji Mar 30, 2022
8d6a290
Correct orientation of uvs with 3d parallax
karimnaaji Mar 31, 2022
19d57f3
Remove commented out code
karimnaaji Apr 2, 2022
8c8881d
Add `atmosphere_attributes` and `atmosphere_buffer` to decouple creat…
karimnaaji Apr 4, 2022
b1524a0
Draw atmosphere first, to give it higher priority over `sky` layers
karimnaaji Apr 4, 2022
1fbeed5
Add `mapValue` unit tests
karimnaaji Apr 5, 2022
27a06b1
Add default style specification values
karimnaaji Apr 6, 2022
2d6b1a7
Add `-transition` unit tests
karimnaaji Apr 6, 2022
ceead21
Add spec default values unit tests
karimnaaji Apr 6, 2022
3d189db
Fix flow and unit tests
karimnaaji Apr 6, 2022
3cb3443
Update render tests and some baselines
karimnaaji Apr 6, 2022
9785fb5
Update render tests
karimnaaji Apr 6, 2022
20e53bc
Update render tests baselines
karimnaaji Apr 7, 2022
317c9d2
Update render tests baseline
karimnaaji Apr 7, 2022
63be834
Increase rate of change for horizon angle interpolation for smoother …
karimnaaji Apr 7, 2022
7fd7514
Update flaky render tests
karimnaaji Apr 7, 2022
476fa5b
Ensure that symbols aren't occluded by fog range while using thin atm…
karimnaaji Apr 7, 2022
6a7b114
Update heatmaps to disable atmosphere contribution to prevent flickering
karimnaaji Apr 7, 2022
1b07512
Address some review comments
karimnaaji Apr 11, 2022
e0deb84
Fix shader discontinuity resulting in visual artifacts by making sure…
karimnaaji Apr 11, 2022
c280145
Address review feedback, fix override of properties to default when f…
karimnaaji Apr 12, 2022
682392e
Address review comment, add atmosphere to other pages
karimnaaji Apr 12, 2022
a8523af
Increase render test allowed threshold for
karimnaaji Apr 12, 2022
e6a0e66
Add style specification entry
karimnaaji Apr 13, 2022
6aaface
Fix early exit when inside the globe
karimnaaji Apr 13, 2022
b7376f8
Address review comment, simplify to pow(x,-1) to 1/x
karimnaaji Apr 13, 2022
73566dc
Refresh values when updating atmosphere preset
karimnaaji Apr 13, 2022
59e3d81
Address review comment
karimnaaji Apr 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions build/generate-struct-arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,10 @@ createStructArrayType('symbol_instance', symbolInstance, true);
createStructArrayType('glyph_offset', glyphOffset, true);
createStructArrayType('symbol_line_vertex', lineVertex, true);

import globeAttributes, {atmosphereLayout} from '../src/terrain/globe_attributes.js';
import globeAttributes from '../src/terrain/globe_attributes.js';
import {atmosphereLayout} from '../src/render/atmosphere_attributes.js';
createStructArrayType('globe_vertex', globeAttributes);
createStructArrayType('globe_atmosphere_vertex', atmosphereLayout);
createStructArrayType('atmosphere_vertex', atmosphereLayout);

// feature index array
createStructArrayType('feature_index', createLayout([
Expand Down
1 change: 1 addition & 0 deletions debug/3d-playground.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@
]
}
});
map.setFog({});
var elevationDebug = document.getElementById('elevationDebug');
map.on('mousemove', (e) => {
const elevation = map.queryTerrainElevation(map.unproject(e.point));
Expand Down
229 changes: 229 additions & 0 deletions debug/atmosphere.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
<!DOCTYPE html>
<html>
<head>
<title>Mapbox GL JS debug page</title>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel='stylesheet' href='../dist/mapbox-gl.css' />
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
.mapboxgl-canvas {
background-image: url("https://img.favpng.com/9/21/21/royalty-free-photography-illustration-png-favpng-d38x16Mw2kxSFqtUSXG8gT5CQ_t.jpg");
}
</style>
</head>

<body>
<div id='map'></div>

<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js'></script>
<script src='../dist/mapbox-gl-dev.js'></script>
<script src='access_token_generated.js'></script>
<script>

var GUIParams = function() {
this.enable = true;
this.style = 'streets-v11';
this.start = 0.8;
this.end = 8.0;
this.color = [255, 255, 255];
this.highColor = [0, 0, 0];
this.spaceColor = [0, 0, 0];
this.spaceAlpha = 1.0;
this.colorAlpha = 1.0;
this.skyAlpha = 1.0;
this.horizonBlend = 0.5;
this.starIntensity = 0.15;
this.presets = 'preset1';
};

var guiParams = new GUIParams();

var map = window.map = new mapboxgl.Map({
container: 'map',
zoom: 10,
center: [78.7193, 36.2927],
pitch: 75,
bearing: -10,
style: 'mapbox://styles/mapbox/streets-v11',
hash: true,
projection: 'globe'
});

function updatePreset(value) {
// 'mapbox/streets-v11',
// 'mapbox/satellite-streets-v11',
// 'mapbox/light-v10',
// 'mapbox/dark-v10',
// 'mapbox/outdoors-v11',
// 'mapbox/satellite-v9',
if (value === 'preset1') {
guiParams.enable = true;
guiParams.style = 'satellite-streets-v11';
guiParams.color = [220, 159, 159];
guiParams.highColor = [36, 92, 223];
guiParams.spaceColor = [0, 0, 0];
guiParams.spaceAlpha = 1.0;
guiParams.colorAlpha = 1.0;
guiParams.skyAlpha = 0.7;
guiParams.horizonBlend = 0.5;
guiParams.starIntensity = 0.15;
karimnaaji marked this conversation as resolved.
Show resolved Hide resolved
} else if (value === 'preset2') {
guiParams.enable = true;
guiParams.style = 'satellite-v9';
guiParams.color = [225, 225, 225];
guiParams.highColor = [44, 73, 175];
guiParams.spaceColor = [11, 11, 25];
guiParams.spaceAlpha = 1.0;
guiParams.colorAlpha = 1.0;
guiParams.skyAlpha = 1;
guiParams.horizonBlend = 0.025;
guiParams.starIntensity = 0.150;
} else if (value === 'preset3') {
guiParams.enable = true;
guiParams.style = 'light-v10';
guiParams.color = [200, 160, 160];
guiParams.highColor = [200, 200, 200];
guiParams.spaceColor = [57, 72, 85];
guiParams.spaceAlpha = 1.0;
guiParams.colorAlpha = 0.5;
guiParams.skyAlpha = 1;
guiParams.horizonBlend = 0.05;
guiParams.starIntensity = 0.2;
} else if (value === 'preset4') {
guiParams.enable = true;
guiParams.style = 'streets-v11';
guiParams.color = [255, 255, 255];
guiParams.highColor = [19, 122, 255];
guiParams.spaceColor = [0, 0, 0];
guiParams.spaceAlpha = 1.0;
guiParams.colorAlpha = 1;
guiParams.skyAlpha = 1;
guiParams.horizonBlend = 0.3;
guiParams.starIntensity = 1.0;
} else if (value === 'preset5') {
guiParams.enable = true;
guiParams.style = 'dark-v10';
guiParams.color = [13, 13, 13];
guiParams.highColor = [255, 255, 255];
guiParams.spaceColor = [50, 50, 50];
guiParams.spaceAlpha = 1.0;
guiParams.colorAlpha = 1;
guiParams.skyAlpha = 0.5;
guiParams.horizonBlend = 0.025;
guiParams.starIntensity = 0.1;
} else if (value === 'preset6') {
guiParams.enable = true;
guiParams.style = 'outdoors-v11';
guiParams.color = [85, 119, 140];
guiParams.highColor = [36, 92, 223];
guiParams.spaceColor = [2, 20, 50];
guiParams.spaceAlpha = 1.0;
guiParams.colorAlpha = 0.8;
guiParams.skyAlpha = 1.0;
guiParams.horizonBlend = 1;
guiParams.starIntensity = 0.75;
}
map.setStyle('mapbox://styles/mapbox/' + guiParams.style);
}

updatePreset('preset1');

window.onload = function() {
var gui = new dat.GUI(); // eslint-disable-line

var presets = gui.add(guiParams, 'presets', [
'preset1',
'preset2',
'preset3',
'preset4',
'preset5',
'preset6'
]);

presets.onFinishChange((value) => {
updatePreset(value);
});

var fog = gui.addFolder('Atmosphere');
var enable = fog.add(guiParams, 'enable');
enable.onFinishChange((value) => {
map.setFog(value ? {
"range": [guiParams.start, guiParams.end],
"color": 'rgba(' + guiParams.color[0] + ', ' + guiParams.color[1] + ', ' + guiParams.color[2] + ', ' + guiParams.colorAlpha + ')',
"horizon-blend": guiParams.horizonBlend,
"high-color": 'rgba(' + guiParams.highColor[0] + ', ' + guiParams.highColor[1] + ', ' + guiParams.highColor[2] + ', ' + guiParams.skyAlpha + ')',
"space-color": 'rgba(' + guiParams.spaceColor[0] + ', ' + guiParams.spaceColor[1] + ', ' + guiParams.spaceColor[2] + ', ' + guiParams.spaceAlpha + ')',
"star-intensity": guiParams.starIntensity
} : null);
});

var horizonBlend = fog.add(guiParams, 'horizonBlend', 0.0, 1.0);
horizonBlend.onChange((value) => {
map.setFog({
"horizon-blend": value,
});
});
var starIntensity = fog.add(guiParams, 'starIntensity', 0.0, 1.0);
starIntensity.onChange((value) => {
map.setFog({
"star-intensity": value,
});
});

var colorAlpha = fog.add(guiParams, 'colorAlpha', 0.0, 1.0);
colorAlpha.onChange((value) => {
map.setFog({
"color": 'rgba(' + guiParams.color[0] + ', ' + guiParams.color[1] + ', ' + guiParams.color[2] + ', ' + value + ')'
});
});

var color = fog.addColor(guiParams, 'color');
color.onChange((value) => {
map.setFog({
"color": 'rgba(' + value[0] + ', ' + value[1] + ', ' + value[2] + ', ' + guiParams.colorAlpha + ')'
});
});

var skyAlpha = fog.add(guiParams, 'skyAlpha', 0.0, 1.0);
skyAlpha.onChange((value) => {
map.setFog({
"high-color": 'rgba(' + guiParams.highColor[0] + ', ' + guiParams.highColor[1] + ', ' + guiParams.highColor[2] + ', ' + value + ')'
});
});
var highColor = fog.addColor(guiParams, 'highColor');
highColor.onChange((value) => {
map.setFog({
"high-color": 'rgba(' + value[0] + ', ' + value[1] + ', ' + value[2] + ', ' + guiParams.skyAlpha + ')'
});
});

var spaceAlpha = fog.add(guiParams, 'spaceAlpha', 0.0, 1.0);
spaceAlpha.onChange((value) => {
map.setFog({
"space-color": 'rgba(' + guiParams.spaceColor[0] + ', ' + guiParams.spaceColor[1] + ', ' + guiParams.spaceColor[2] + ', ' + value + ')'
});
});
var spaceColor = fog.addColor(guiParams, 'spaceColor');
spaceColor.onChange((value) => {
map.setFog({
"space-color": 'rgba(' + value[0] + ', ' + value[1] + ', ' + value[2] + ', ' + guiParams.spaceAlpha + ')'
});
});
};

map.on('style.load', function() {
map.setFog({
"range": [guiParams.start, guiParams.end],
"color": 'rgba(' + guiParams.color[0] + ', ' + guiParams.color[1] + ', ' + guiParams.color[2] + ', ' + guiParams.colorAlpha + ')',
"horizon-blend": guiParams.horizonBlend,
"high-color": 'rgba(' + guiParams.highColor[0] + ', ' + guiParams.highColor[1] + ', ' + guiParams.highColor[2] + ', ' + guiParams.skyAlpha + ')',
"space-color": 'rgba(' + guiParams.spaceColor[0] + ', ' + guiParams.spaceColor[1] + ', ' + guiParams.spaceColor[2] + ', ' + guiParams.spaceAlpha + ')',
"star-intensity": guiParams.starIntensity
});
});

</script>
</body>
</html>
2 changes: 2 additions & 0 deletions debug/circles.html
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@
}
});

map.setFog({});

document.getElementById('terrain-checkbox').onclick();
});

Expand Down
2 changes: 1 addition & 1 deletion debug/fog.html
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,4 @@

</script>
</body>
</html>
</html>
2 changes: 2 additions & 0 deletions debug/globe-fill-extrusion.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
"maxzoom": 14
});

map.setFog({});

document.getElementById('terrain-checkbox').onclick();
});

Expand Down
2 changes: 2 additions & 0 deletions debug/markers.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@
"tileSize": 512,
"maxzoom": 14
});

map.setFog({});
});

document.getElementById('terrain-checkbox').onclick = function() {
Expand Down
2 changes: 2 additions & 0 deletions debug/terrain-debug.html
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@
}
};

map.setFog({});

map.addLayer(highlightLayer);

document.getElementById('road-label-checkbox').onclick();
Expand Down
2 changes: 1 addition & 1 deletion src/data/array_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,7 @@ export {
StructArrayLayout3f12 as CollisionVertexExtArray,
StructArrayLayout3ui6 as QuadTriangleArray,
StructArrayLayout7f28 as GlobeVertexArray,
StructArrayLayout5f20 as GlobeAtmosphereVertexArray,
StructArrayLayout5f20 as AtmosphereVertexArray,
StructArrayLayout3ui6 as TriangleIndexArray,
StructArrayLayout2ui4 as LineIndexArray,
StructArrayLayout1ui2 as LineStripIndexArray,
Expand Down
6 changes: 5 additions & 1 deletion src/geo/projection/globe.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class Globe extends Mercator {
super(options);
this.requiresDraping = true;
this.supportsWorldCopies = false;
this.supportsFog = false;
this.supportsFog = true;
this.zAxisUnit = "pixels";
this.unsupportedLayers = ['debug', 'custom'];
}
Expand Down Expand Up @@ -86,6 +86,10 @@ export default class Globe extends Mercator {
return mat4.multiply(new Float64Array(16), tr.globeMatrix, decode);
}

createFogTileMatrix(tr: Transform): Float64Array {
return mat4.clone(tr.globeMatrix);
}

createInversionMatrix(tr: Transform, id: CanonicalTileID): Float32Array {
const {center, worldSize} = tr;
const ecefUnitsToPixels = globeECEFUnitsToPixelScale(worldSize);
Expand Down
28 changes: 2 additions & 26 deletions src/geo/projection/globe_util.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import {number as interpolate} from '../../style-spec/util/interpolate.js';
import {degToRad, smoothstep, clamp} from '../../util/util.js';
import {vec3, mat4} from 'gl-matrix';
import SegmentVector from '../../data/segment.js';
import {members as globeLayoutAttributes, atmosphereLayout} from '../../terrain/globe_attributes.js';
import {members as globeLayoutAttributes} from '../../terrain/globe_attributes.js';
import posAttributes from '../../data/pos_attributes.js';
import {TriangleIndexArray, GlobeVertexArray, GlobeAtmosphereVertexArray, LineIndexArray, PosArray} from '../../data/array_types.js';
import {TriangleIndexArray, GlobeVertexArray, LineIndexArray, PosArray} from '../../data/array_types.js';
import {Aabb} from '../../util/primitives.js';
import LngLatBounds from '../lng_lat_bounds.js';

Expand Down Expand Up @@ -467,17 +467,12 @@ export class GlobeSharedBuffers {
_gridIndexBuffer: IndexBuffer;
_gridSegments: Array<SegmentVector>;

atmosphereVertexBuffer: VertexBuffer;
atmosphereIndexBuffer: IndexBuffer;
atmosphereSegments: SegmentVector;

_wireframeIndexBuffer: IndexBuffer;
_wireframeSegments: Array<SegmentVector>;

constructor(context: Context) {
this._createGrid(context);
this._createPoles(context);
this._createAtmosphere(context);
}

destroy() {
Expand All @@ -488,9 +483,6 @@ export class GlobeSharedBuffers {
this._poleSouthVertexBuffer.destroy();
for (const segments of this._poleSegments) segments.destroy();
for (const segments of this._gridSegments) segments.destroy();
this.atmosphereVertexBuffer.destroy();
this.atmosphereIndexBuffer.destroy();
this.atmosphereSegments.destroy();

if (this._wireframeIndexBuffer) {
this._wireframeIndexBuffer.destroy();
Expand Down Expand Up @@ -569,22 +561,6 @@ export class GlobeSharedBuffers {
this._poleSouthVertexBuffer = context.createVertexBuffer(southVertices, globeLayoutAttributes, false);
}

_createAtmosphere(context: Context) {
const atmosphereVertices = new GlobeAtmosphereVertexArray();
atmosphereVertices.emplaceBack(-1, 1, 1, 0, 0);
atmosphereVertices.emplaceBack(1, 1, 1, 1, 0);
atmosphereVertices.emplaceBack(1, -1, 1, 1, 1);
atmosphereVertices.emplaceBack(-1, -1, 1, 0, 1);

const atmosphereTriangles = new TriangleIndexArray();
atmosphereTriangles.emplaceBack(0, 1, 2);
atmosphereTriangles.emplaceBack(2, 3, 0);

this.atmosphereVertexBuffer = context.createVertexBuffer(atmosphereVertices, atmosphereLayout.members);
this.atmosphereIndexBuffer = context.createIndexBuffer(atmosphereTriangles);
this.atmosphereSegments = SegmentVector.simpleSegment(0, 0, 4, 2);
}

getGridBuffers(latitudinalLod: number): [VertexBuffer, IndexBuffer, SegmentVector] {
return [this._gridBuffer, this._gridIndexBuffer, this._gridSegments[latitudinalLod]];
}
Expand Down
4 changes: 4 additions & 0 deletions src/geo/projection/projection.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ export default class Projection {
return posMatrix;
}

createFogTileMatrix(tr: Transform, worldSize: number, id: UnwrappedTileID): Float64Array {
return this.createTileMatrix(tr, worldSize, id);
}

upVector(id: CanonicalTileID, x: number, y: number): Vec3 { // eslint-disable-line
return [0, 0, 1];
}
Expand Down
Loading