@@ -23,6 +23,7 @@ import {mercatorXfromLng, mercatorYfromLat} from '../geo/mercator_coordinate';
2323import { COLOR_MIX_FACTOR } from '../style/style_layer/raster_style_layer' ;
2424import RasterArrayTile from '../source/raster_array_tile' ;
2525import RasterArrayTileSource from '../source/raster_array_tile_source' ;
26+ import ColorMode from '../gl/color_mode' ;
2627
2728import type Transform from '../geo/transform' ;
2829import type { OverscaledTileID } from '../source/tile_id' ;
@@ -62,10 +63,16 @@ function adjustColorMix(colorMix: [number, number, number, number]): [number, nu
6263
6364function drawRaster ( painter : Painter , sourceCache : SourceCache , layer : RasterStyleLayer , tileIDs : Array < OverscaledTileID > , variableOffsets ?: Partial < Record < CrossTileID , VariableOffset > > , isInitialLoad ?: boolean ) {
6465 if ( painter . renderPass !== 'translucent' ) return ;
65- if ( layer . paint . get ( 'raster-opacity' ) === 0 ) return ;
66+
67+ const rasterOpacity = layer . paint . get ( 'raster-opacity' ) ;
68+ if ( rasterOpacity === 0 ) return ;
69+
6670 const isGlobeProjection = painter . transform . projection . name === 'globe' ;
6771 const renderingWithElevation = layer . paint . get ( 'raster-elevation' ) !== 0.0 ;
6872 const renderingElevatedOnGlobe = renderingWithElevation && isGlobeProjection ;
73+ const isElevationReferenceTerrainGroundLevel = painter . terrain && painter . terrain . exaggeration ( ) > 0 && renderingWithElevation && layer . paint . get ( 'raster-elevation-reference' ) === 'ground' ;
74+ const renderingElevatedOnTerrain = ! isGlobeProjection && isElevationReferenceTerrainGroundLevel ;
75+
6976 if ( painter . renderElevatedRasterBackface && ! renderingElevatedOnGlobe ) {
7077 return ;
7178 }
@@ -117,7 +124,10 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty
117124 rasterConfig . defines . push ( "PROJECTION_GLOBE_VIEW" ) ;
118125 }
119126 if ( renderingWithElevation ) {
120- rasterConfig . defines . push ( "RENDER_CUTOFF" ) ;
127+ rasterConfig . defines . push ( "RENDER_CUTOFF" , "ELEVATED" ) ;
128+ }
129+ if ( isElevationReferenceTerrainGroundLevel ) {
130+ rasterConfig . defines . push ( "ELEVATION_REFERENCE_GROUND" ) ;
121131 }
122132
123133 const drawTiles = ( tiles : Array < OverscaledTileID > , cullFaceMode : CullFaceMode , elevatedStencilMode ?: StencilMode ) => {
@@ -131,7 +141,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty
131141 if ( ! textureDescriptor || ! textureDescriptor . texture ) continue ;
132142 const { texture, mix : rasterColorMix , offset : rasterColorOffset , tileSize, buffer} = textureDescriptor ;
133143
134- let depthMode ;
144+ let depthMode : DepthMode ;
135145 let projMatrix ;
136146 if ( renderingToTexture ) {
137147 depthMode = DepthMode . disabled ;
@@ -143,7 +153,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty
143153 // Set the lower zoom level to sublayer 0, and higher zoom levels to higher sublayers
144154 // Use gl.LESS to prevent double drawing in areas where tiles overlap.
145155 depthMode = painter . depthModeForSublayer ( coord . overscaledZ - minTileZ ,
146- layer . paint . get ( 'raster-opacity' ) === 1 ? DepthMode . ReadWrite : DepthMode . ReadOnly , gl . LESS ) ;
156+ rasterOpacity === 1 ? DepthMode . ReadWrite : DepthMode . ReadOnly , gl . LESS ) ;
147157 projMatrix = painter . transform . calculateProjMatrix ( unwrappedTileID , align ) ;
148158 }
149159
@@ -229,6 +239,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty
229239 }
230240
231241 const uniformValues = rasterUniformValues (
242+ painter ,
232243 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
233244 projMatrix ,
234245 normalizeMatrix ,
@@ -263,7 +274,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty
263274 const elevatedGlobeIndexBuffer = source . elevatedGlobeIndexBuffer ;
264275 if ( renderingToTexture || ! isGlobeProjection ) {
265276 if ( source . boundsBuffer && source . boundsSegments ) program . draw (
266- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
277+
267278 painter , gl . TRIANGLES , depthMode , StencilMode . disabled , colorMode , CullFaceMode . disabled ,
268279 uniformValues , layer . id , source . boundsBuffer ,
269280 painter . quadTriangleIndexBuffer , source . boundsSegments ) ;
@@ -273,7 +284,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty
273284 source . getSegmentsForLongitude ( tr . center . lng ) ;
274285 if ( segments ) {
275286 program . draw (
276- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
287+
277288 painter , gl . TRIANGLES , depthMode , StencilMode . disabled , colorMode , cullFaceMode ,
278289 uniformValues , layer . id , elevatedGlobeVertexBuffer ,
279290 elevatedGlobeIndexBuffer , segments ) ;
@@ -283,17 +294,36 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty
283294 depthMode = new DepthMode ( gl . LEQUAL , DepthMode . ReadOnly , painter . depthRangeFor3D ) ;
284295 const sharedBuffers = painter . globeSharedBuffers ;
285296 if ( sharedBuffers ) {
297+ if ( isElevationReferenceTerrainGroundLevel ) {
298+ painter . terrain . setupElevationDraw ( tile , program ) ;
299+ painter . uploadCommonUniforms ( context , program , tile . tileID . toUnwrapped ( ) ) ;
300+ }
286301 const [ buffer , indexBuffer , segments ] = sharedBuffers . getGridBuffers ( latitudinalLod , false ) ;
287302 assert ( buffer ) ;
288303 assert ( indexBuffer ) ;
289304 assert ( segments ) ;
290- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
305+
291306 program . draw ( painter , gl . TRIANGLES , depthMode , elevatedStencilMode || stencilMode , painter . colorModeForRenderPass ( ) , cullFaceMode , uniformValues , layer . id , buffer , indexBuffer , segments ) ;
292307 }
308+ } else if ( renderingElevatedOnTerrain ) {
309+ depthMode = new DepthMode ( gl . LEQUAL , DepthMode . ReadWrite , painter . depthRangeFor3D ) ;
310+ painter . terrain . setupElevationDraw ( tile , program ) ;
311+ painter . uploadCommonUniforms ( context , program , tile . tileID . toUnwrapped ( ) ) ;
312+
313+ // 2-pass rendering in case layer is not fully opaque and we are looking at higher pitch angles
314+ const pitchThresholdForTwoPassRendering = 20.0 ;
315+ if ( tr . pitch > pitchThresholdForTwoPassRendering ) {
316+ program . draw ( painter , gl . TRIANGLES , depthMode , StencilMode . disabled , ColorMode . disabled , CullFaceMode . frontCCW ,
317+ uniformValues , layer . id , painter . terrain . gridBuffer ,
318+ painter . terrain . gridIndexBuffer , painter . terrain . gridSegments ) ;
319+ }
320+
321+ program . draw ( painter , gl . TRIANGLES , depthMode , stencilMode , colorMode , CullFaceMode . backCCW ,
322+ uniformValues , layer . id , painter . terrain . gridBuffer ,
323+ painter . terrain . gridIndexBuffer , painter . terrain . gridSegments ) ;
293324 } else {
294325 const { tileBoundsBuffer, tileBoundsIndexBuffer, tileBoundsSegments} = painter . getTileBoundsBuffers ( tile ) ;
295326
296- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
297327 program . draw ( painter , gl . TRIANGLES , depthMode , stencilMode , colorMode , CullFaceMode . disabled ,
298328 uniformValues , layer . id , tileBoundsBuffer ,
299329 tileBoundsIndexBuffer , tileBoundsSegments ) ;
@@ -395,7 +425,7 @@ function drawPole(isNorth: boolean, coord: OverscaledTileID | null | undefined,
395425 }
396426 const rasterColorMix = adjustColorMix ( rasterConfig . mix ) ;
397427
398- const uniformValues = rasterPoleUniformValues ( projMatrix , normalizeMatrix , globeMatrix as Float32Array , globeToMercatorTransition ( painter . transform . zoom ) , fade , layer , [ 0 , 0 ] , elevation , RASTER_COLOR_TEXTURE_UNIT , rasterColorMix , rasterConfig . offset , rasterConfig . range , emissiveStrength ) ;
428+ const uniformValues = rasterPoleUniformValues ( painter , projMatrix , normalizeMatrix , globeMatrix as Float32Array , globeToMercatorTransition ( painter . transform . zoom ) , fade , layer , [ 0 , 0 ] , elevation , RASTER_COLOR_TEXTURE_UNIT , rasterColorMix , rasterConfig . offset , rasterConfig . range , emissiveStrength ) ;
399429 const program = painter . getOrCreateProgram ( 'raster' , { defines} ) ;
400430
401431 painter . uploadCommonUniforms ( context , program , null ) ;
0 commit comments