From 555e2cad2ad56fe7c9bd748c80c1db729ae808d8 Mon Sep 17 00:00:00 2001 From: Larrieu Vivian Date: Sat, 29 Jun 2024 10:33:40 +0200 Subject: [PATCH 1/3] Merge Sky and Atmosphere code. --- src/data/atmosphere_attributes.ts | 5 -- src/render/draw_atmosphere.ts | 80 --------------------------- src/render/draw_sky.ts | 87 +++++++++++++++++++++++++----- src/render/painter.ts | 3 +- src/shaders/atmosphere.vertex.glsl | 8 +-- 5 files changed, 79 insertions(+), 104 deletions(-) delete mode 100644 src/data/atmosphere_attributes.ts delete mode 100644 src/render/draw_atmosphere.ts diff --git a/src/data/atmosphere_attributes.ts b/src/data/atmosphere_attributes.ts deleted file mode 100644 index 322e637470..0000000000 --- a/src/data/atmosphere_attributes.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {createLayout} from '../util/struct_array'; - -export const atmosphereAttributes = createLayout([ - {name: 'a_pos', type: 'Float32', components: 4} -]); diff --git a/src/render/draw_atmosphere.ts b/src/render/draw_atmosphere.ts deleted file mode 100644 index 3b8086e3d2..0000000000 --- a/src/render/draw_atmosphere.ts +++ /dev/null @@ -1,80 +0,0 @@ -import {StencilMode} from '../gl/stencil_mode'; -import {DepthMode} from '../gl/depth_mode'; -import {CullFaceMode} from '../gl/cull_face_mode'; -import {atmosphereUniformValues} from './program/atmosphere_program'; - -import type {Painter} from './painter'; -import {ColorMode} from '../gl/color_mode'; -import {Sky} from '../style/sky'; -import {Light} from '../style/light'; -import {AtmosphereBoundsArray, TriangleIndexArray} from '../data/array_types.g'; -import {atmosphereAttributes} from '../data/atmosphere_attributes'; -import {Mesh} from './mesh'; -import {SegmentVector} from '../data/segment'; -import {Transform} from '../geo/transform'; -import {mat4, vec3} from 'gl-matrix'; - -function getSunPos(light: Light, transform: Transform): vec3 { - const _lp = light.properties.get('position'); - const lightPos = [-_lp.x, -_lp.y, -_lp.z] as vec3; - - const lightMat = mat4.identity(new Float64Array(16) as any); - - if (light.properties.get('anchor') === 'map') { - mat4.rotateX(lightMat, lightMat, -transform.pitch * Math.PI / 180); - mat4.rotateZ(lightMat, lightMat, -transform.angle); - mat4.rotateX(lightMat, lightMat, transform.center.lat * Math.PI / 180.0); - mat4.rotateY(lightMat, lightMat, -transform.center.lng * Math.PI / 180.0); - } - - vec3.transformMat4(lightPos, lightPos, lightMat); - - return lightPos; -} - -export function drawAtmosphere(painter: Painter, sky: Sky, light: Light) { - const context = painter.context; - const gl = context.gl; - const program = painter.useProgram('atmosphere'); - const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadOnly, [0, 1]); - - const projection = painter.style.projection; - const projectionData = projection.getProjectionData(null, null); - - const sunPos = getSunPos(light, painter.transform); - - const atmosphereBlend = sky.properties.get('atmosphere-blend'); - if (atmosphereBlend === 0) { - // Don't draw anythink if atmosphere is fully transparent - return; - } - - const globePosition = projection.worldCenterPosition; - const globeRadius = projection.worldSize; - const invProjMatrix = projection.invProjMatrix; - - const uniformValues = atmosphereUniformValues(sunPos, atmosphereBlend, globePosition, globeRadius, invProjMatrix); - - // Create the atmosphere mesh the first time we need it - if (!sky.atmosphereMesh) { - const vertexArray = new AtmosphereBoundsArray(); - vertexArray.emplaceBack(-1, -1, 0.0, 1.0); - vertexArray.emplaceBack(+1, -1, 0.0, 1.0); - vertexArray.emplaceBack(+1, +1, 0.0, 1.0); - vertexArray.emplaceBack(-1, +1, 0.0, 1.0); - - const indexArray = new TriangleIndexArray(); - indexArray.emplaceBack(0, 1, 2); - indexArray.emplaceBack(0, 2, 3); - - sky.atmosphereMesh = new Mesh( - context.createVertexBuffer(vertexArray, atmosphereAttributes.members), - context.createIndexBuffer(indexArray), - SegmentVector.simpleSegment(0, 0, vertexArray.length, indexArray.length) - ); - } - - const mesh = sky.atmosphereMesh; - - program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, ColorMode.alphaBlended, CullFaceMode.disabled, uniformValues, null, projectionData, 'atmosphere', mesh.vertexBuffer, mesh.indexBuffer, mesh.segments); -} diff --git a/src/render/draw_sky.ts b/src/render/draw_sky.ts index 5e4ec3a5cc..fe57f17bb5 100644 --- a/src/render/draw_sky.ts +++ b/src/render/draw_sky.ts @@ -5,21 +5,18 @@ import {PosArray, TriangleIndexArray} from '../data/array_types.g'; import posAttributes from '../data/pos_attributes'; import {SegmentVector} from '../data/segment'; import {skyUniformValues} from './program/sky_program'; +import {atmosphereUniformValues} from './program/atmosphere_program'; import {Sky} from '../style/sky'; +import {Light} from '../style/light'; import {Mesh} from './mesh'; +import {mat4, vec3} from 'gl-matrix'; +import {Transform} from '../geo/transform'; +import {ColorMode} from '../gl/color_mode'; import type {Painter} from './painter'; +import {Context} from '../gl/context'; -export function drawSky(painter: Painter, sky: Sky) { - const context = painter.context; - const gl = context.gl; - - const skyUniforms = skyUniformValues(sky, painter.style.map.transform, painter.pixelRatio); - - const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); - const stencilMode = StencilMode.disabled; - const colorMode = painter.colorModeForRenderPass(); - const program = painter.useProgram('sky'); - +function getMesh(context: Context, sky: Sky): Mesh { + // Create the Sky mesh the first time we need it if (!sky.mesh) { const vertexArray = new PosArray(); vertexArray.emplaceBack(-1, -1); @@ -38,7 +35,71 @@ export function drawSky(painter: Painter, sky: Sky) { ); } + return sky.mesh; +} + +export function drawSky(painter: Painter, sky: Sky) { + const context = painter.context; + const gl = context.gl; + + const skyUniforms = skyUniformValues(sky, painter.style.map.transform, painter.pixelRatio); + + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1]); + const stencilMode = StencilMode.disabled; + const colorMode = painter.colorModeForRenderPass(); + const program = painter.useProgram('sky'); + + const mesh = getMesh(context, sky); + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, - CullFaceMode.disabled, skyUniforms, null, undefined, 'sky', sky.mesh.vertexBuffer, - sky.mesh.indexBuffer, sky.mesh.segments); + CullFaceMode.disabled, skyUniforms, null, undefined, 'sky', mesh.vertexBuffer, + mesh.indexBuffer, mesh.segments); +} + +function getSunPos(light: Light, transform: Transform): vec3 { + const _lp = light.properties.get('position'); + const lightPos = [-_lp.x, -_lp.y, -_lp.z] as vec3; + + const lightMat = mat4.identity(new Float64Array(16) as any); + + if (light.properties.get('anchor') === 'map') { + mat4.rotateX(lightMat, lightMat, -transform.pitch * Math.PI / 180); + mat4.rotateZ(lightMat, lightMat, -transform.angle); + mat4.rotateX(lightMat, lightMat, transform.center.lat * Math.PI / 180.0); + mat4.rotateY(lightMat, lightMat, -transform.center.lng * Math.PI / 180.0); + } + + vec3.transformMat4(lightPos, lightPos, lightMat); + + return lightPos; +} + +export function drawAtmosphere(painter: Painter, sky: Sky, light: Light) { + const context = painter.context; + const gl = context.gl; + const program = painter.useProgram('atmosphere'); + const depthMode = new DepthMode(gl.LEQUAL, DepthMode.ReadOnly, [0, 1]); + + const projection = painter.style.projection; + const projectionData = projection.getProjectionData(null, null); + + const sunPos = getSunPos(light, painter.transform); + + const atmosphereBlend = sky.properties.get('atmosphere-blend'); + if (atmosphereBlend === 0) { + // Don't draw anythink if atmosphere is fully transparent + return; + } + + const globePosition = projection.worldCenterPosition; + const globeRadius = projection.worldSize; + const invProjMatrix = projection.invProjMatrix; + + const uniformValues = atmosphereUniformValues(sunPos, atmosphereBlend, globePosition, globeRadius, invProjMatrix); + + const mesh = getMesh(context, sky); + + program.draw(context, gl.TRIANGLES, depthMode, StencilMode.disabled, ColorMode.alphaBlended, + CullFaceMode.disabled, uniformValues, null, projectionData, 'atmosphere', mesh.vertexBuffer, + mesh.indexBuffer, mesh.segments); } diff --git a/src/render/painter.ts b/src/render/painter.ts index 1691871b39..220b7c3d4b 100644 --- a/src/render/painter.ts +++ b/src/render/painter.ts @@ -27,12 +27,11 @@ import {drawFillExtrusion} from './draw_fill_extrusion'; import {drawHillshade} from './draw_hillshade'; import {drawRaster} from './draw_raster'; import {drawBackground} from './draw_background'; -import {drawAtmosphere} from './draw_atmosphere'; import {drawDebug, drawDebugPadding, selectDebugSource} from './draw_debug'; import {drawCustom} from './draw_custom'; import {drawDepth, drawCoords} from './draw_terrain'; import {OverscaledTileID} from '../source/tile_id'; -import {drawSky} from './draw_sky'; +import {drawSky, drawAtmosphere} from './draw_sky'; import {Mesh} from './mesh'; import {translatePosMatrix as mercatorTranslatePosMatrix, MercatorShaderDefine, MercatorShaderVariantKey} from '../geo/projection/mercator'; diff --git a/src/shaders/atmosphere.vertex.glsl b/src/shaders/atmosphere.vertex.glsl index e766372aaa..73432948db 100644 --- a/src/shaders/atmosphere.vertex.glsl +++ b/src/shaders/atmosphere.vertex.glsl @@ -1,4 +1,4 @@ -in vec4 a_pos; +in vec2 a_pos; uniform mat4 u_inv_proj_matrix; @@ -6,6 +6,6 @@ out vec3 view_direction; void main() { // Compute each camera ray - view_direction = (u_inv_proj_matrix * a_pos).xyz; - gl_Position = a_pos; -} \ No newline at end of file + view_direction = (u_inv_proj_matrix * vec4(a_pos, 0.0, 1.0)).xyz; + gl_Position = vec4(a_pos, 0.0, 1.0); +} From b1545c6e247042df09a3423579a5c1b66d26755d Mon Sep 17 00:00:00 2001 From: Larrieu Vivian Date: Sat, 29 Jun 2024 10:40:02 +0200 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19b564da30..ccb15530d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## main ### ✨ Features and improvements - +- Merge atmosphere an sky implementation ([#3888](https://github.com/maplibre/maplibre-gl-js/issues/3888)) - _...Add new stuff here..._ ### 🐞 Bug fixes From 65250eabc5df52ef644723997d1cdf12853e6f3b Mon Sep 17 00:00:00 2001 From: Larrieu Vivian Date: Sat, 29 Jun 2024 10:45:36 +0200 Subject: [PATCH 3/3] Fix generate-struct-arrays --- build/generate-struct-arrays.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build/generate-struct-arrays.ts b/build/generate-struct-arrays.ts index e8ef8710d6..257e06bdeb 100644 --- a/build/generate-struct-arrays.ts +++ b/build/generate-struct-arrays.ts @@ -22,7 +22,6 @@ import fillExtrusionAttributes from '../src/data/bucket/fill_extrusion_attribute import {lineLayoutAttributes} from '../src/data/bucket/line_attributes'; import {lineLayoutAttributesExt} from '../src/data/bucket/line_attributes_ext'; import {patternAttributes} from '../src/data/bucket/pattern_attributes'; -import {atmosphereAttributes} from '../src/data/atmosphere_attributes'; // symbol layer specific arrays import { symbolLayoutAttributes, @@ -192,9 +191,6 @@ createStructArrayType('line_strip_index', createLayout([ {type: 'Uint16', name: 'vertices', components: 1} ])); -// atmosphere bounds array -createStructArrayType('atmosphere_bounds', atmosphereAttributes); - // paint vertex arrays // used by SourceBinder for float properties