@@ -8,16 +8,17 @@ import Color from '../../src/style-spec/util/color';
88import { FreeCamera } from '../../src/ui/free_camera' ;
99import { mercatorZfromAltitude , tileToMeter } from '../../src/geo/mercator_coordinate' ;
1010import { cartesianPositionToSpherical , sphericalPositionToCartesian , clamp , linearVec3TosRGB } from '../../src/util/util' ;
11- import { DevTools } from '../../src/ui/devtools' ;
1211import { defaultShadowUniformValues } from '../render/shadow_uniforms' ;
1312import TextureSlots from './texture_slots' ;
1413import assert from 'assert' ;
1514import { mat4 , vec3 } from 'gl-matrix' ;
1615import { groundShadowUniformValues } from './program/ground_shadow_program' ;
1716import EXTENT from '../../src/style-spec/data/extent' ;
1817import { getCutoffParams } from '../../src/render/cutoff' ;
18+ import { Debug } from '../../src/util/debug' ;
1919
2020import type { vec4 } from 'gl-matrix' ;
21+ import type { DevToolsFolder } from '../../src/ui/control/devtools' ;
2122import type Lights from '../style/lights' ;
2223import type { OverscaledTileID , UnwrappedTileID } from '../../src/source/tile_id' ;
2324import type Transform from '../../src/geo/transform' ;
@@ -70,12 +71,6 @@ export type TileShadowVolume = {
7071
7172type ShadowNormalOffsetMode = 'vector-tile' | 'model-tile' ;
7273
73- const shadowParameters = {
74- cascadeCount : 2 ,
75- normalOffset : 3 ,
76- shadowMapResolution : 2048
77- } ;
78-
7974function lerpClamp ( x : number , x1 : number , x2 : number , y1 : number , y2 : number ) {
8075 const t = clamp ( ( x - x1 ) / ( x2 - x1 ) , 0 , 1 ) ;
8176 return ( 1 - t ) * y1 + t * y2 ;
@@ -173,6 +168,13 @@ export class ShadowRenderer {
173168 useNormalOffset : boolean ;
174169
175170 _forceDisable : boolean ;
171+ _devtoolsFolder : DevToolsFolder | null ;
172+
173+ _shadowParameters : {
174+ cascadeCount : number ,
175+ normalOffset : number ,
176+ shadowMapResolution : number
177+ } ;
176178
177179 constructor ( painter : Painter ) {
178180 this . painter = painter ;
@@ -185,17 +187,25 @@ export class ShadowRenderer {
185187 this . _depthMode = new DepthMode ( painter . context . gl . LEQUAL , DepthMode . ReadWrite , [ 0 , 1 ] ) ;
186188 this . _uniformValues = defaultShadowUniformValues ( ) ;
187189 this . _forceDisable = false ;
190+ this . _devtoolsFolder = null ;
188191
189192 this . useNormalOffset = false ;
190193
191- DevTools . addParameter ( this , '_forceDisable' , 'Shadows' , { label : 'forceDisable' } , ( ) => { this . painter . style . map . triggerRepaint ( ) ; } ) ;
192- DevTools . addParameter ( shadowParameters , 'cascadeCount' , 'Shadows' , { min : 1 , max : 2 , step : 1 } ) ;
193- DevTools . addParameter ( shadowParameters , 'normalOffset' , 'Shadows' , { min : 0 , max : 10 , step : 0.05 } ) ;
194- DevTools . addParameter ( shadowParameters , 'shadowMapResolution' , 'Shadows' , { min : 32 , max : 2048 , step : 32 } ) ;
195- DevTools . addBinding ( this , '_numCascadesToRender' , 'Shadows' , { readonly : true , label : 'numCascadesToRender' } ) ;
194+ this . _shadowParameters = {
195+ cascadeCount : 2 ,
196+ normalOffset : 3 ,
197+ shadowMapResolution : 2048
198+ } ;
196199 }
197200
198201 destroy ( ) {
202+ Debug . run ( ( ) => {
203+ if ( this . painter . _devtools ) {
204+ this . painter . _devtools . removeFolder ( 'Shadows' ) ;
205+ }
206+ this . _devtoolsFolder = null ;
207+ } ) ;
208+
199209 for ( const cascade of this . _cascades ) {
200210 cascade . texture . destroy ( ) ;
201211 cascade . framebuffer . destroy ( ) ;
@@ -207,6 +217,18 @@ export class ShadowRenderer {
207217 updateShadowParameters ( transform : Transform , directionalLight ?: Lights < Directional > | null ) {
208218 const painter = this . painter ;
209219
220+ Debug . run ( ( ) => {
221+ if ( painter . _devtools && ! this . _devtoolsFolder ) {
222+ const folder = painter . _devtools . addFolder ( 'Shadows' ) ;
223+ folder . addBinding ( this , '_forceDisable' , { label : 'forceDisable' } , ( ) => painter . style . map . triggerRepaint ( ) ) ;
224+ folder . addBinding ( this . _shadowParameters , 'cascadeCount' , { min : 1 , max : 2 , step : 1 } ) ;
225+ folder . addBinding ( this . _shadowParameters , 'normalOffset' , { min : 0 , max : 10 , step : 0.05 } ) ;
226+ folder . addBinding ( this . _shadowParameters , 'shadowMapResolution' , { min : 32 , max : 2048 , step : 32 } ) ;
227+ folder . addReadonly ( this , '_numCascadesToRender' , { label : 'numCascadesToRender' } ) ;
228+ this . _devtoolsFolder = folder ;
229+ }
230+ } ) ;
231+
210232 this . _enabled = false ;
211233 this . _drawShadowAfterLayer = - 1 ;
212234 this . _receivers . clear ( ) ;
@@ -252,12 +274,12 @@ export class ShadowRenderer {
252274 }
253275
254276 const context = painter . context ;
255- const width = shadowParameters . shadowMapResolution ;
256- const height = shadowParameters . shadowMapResolution ;
277+ const width = this . _shadowParameters . shadowMapResolution ;
278+ const height = this . _shadowParameters . shadowMapResolution ;
257279
258- if ( this . _cascades . length === 0 || shadowParameters . shadowMapResolution !== this . _cascades [ 0 ] . texture . size [ 0 ] ) {
280+ if ( this . _cascades . length === 0 || this . _shadowParameters . shadowMapResolution !== this . _cascades [ 0 ] . texture . size [ 0 ] ) {
259281 this . _cascades = [ ] ;
260- for ( let i = 0 ; i < shadowParameters . cascadeCount ; ++ i ) {
282+ for ( let i = 0 ; i < this . _shadowParameters . cascadeCount ; ++ i ) {
261283 const gl = context . gl ;
262284 const fbo = context . createFramebuffer ( width , height , 0 , 'texture' ) ;
263285 const depthTexture = new Texture ( context , { width, height, data : null } , gl . DEPTH_COMPONENT16 ) ;
@@ -299,7 +321,7 @@ export class ShadowRenderer {
299321 let near = transform . height / 50.0 ;
300322 let far = 1.0 ;
301323
302- if ( shadowParameters . cascadeCount === 1 ) {
324+ if ( this . _shadowParameters . cascadeCount === 1 ) {
303325 far = shadowCutoutDist ;
304326 } else {
305327 if ( cascadeIndex === 0 ) {
@@ -310,7 +332,7 @@ export class ShadowRenderer {
310332 }
311333 }
312334
313- const [ matrix , radius ] = createLightMatrix ( transform , this . shadowDirection , near , far , shadowParameters . shadowMapResolution , verticalRange ) ;
335+ const [ matrix , radius ] = createLightMatrix ( transform , this . shadowDirection , near , far , this . _shadowParameters . shadowMapResolution , verticalRange ) ;
314336 cascade . scale = transform . scale ;
315337 cascade . matrix = matrix ;
316338 cascade . boundingSphereRadius = radius ;
@@ -323,8 +345,8 @@ export class ShadowRenderer {
323345 this . _uniformValues [ 'u_fade_range' ] = [ this . _cascades [ fadeRangeIdx ] . far * 0.75 , this . _cascades [ fadeRangeIdx ] . far ] ;
324346 this . _uniformValues [ 'u_shadow_intensity' ] = shadowIntensity ;
325347 this . _uniformValues [ 'u_shadow_direction' ] = [ this . shadowDirection [ 0 ] , this . shadowDirection [ 1 ] , this . shadowDirection [ 2 ] ] ;
326- this . _uniformValues [ 'u_shadow_texel_size' ] = 1 / shadowParameters . shadowMapResolution ;
327- this . _uniformValues [ 'u_shadow_map_resolution' ] = shadowParameters . shadowMapResolution ;
348+ this . _uniformValues [ 'u_shadow_texel_size' ] = 1 / this . _shadowParameters . shadowMapResolution ;
349+ this . _uniformValues [ 'u_shadow_map_resolution' ] = this . _shadowParameters . shadowMapResolution ;
328350 this . _uniformValues [ 'u_shadowmap_0' ] = TextureSlots . ShadowMap0 ;
329351 this . _uniformValues [ 'u_shadowmap_1' ] = TextureSlots . ShadowMap0 + 1 ;
330352
@@ -373,7 +395,7 @@ export class ShadowRenderer {
373395 // shadows.
374396 this . _numCascadesToRender = this . _receivers . computeRequiredCascades ( painter . transform . getFrustum ( 0 ) , painter . transform . worldSize , this . _cascades ) ;
375397
376- context . viewport . set ( [ 0 , 0 , shadowParameters . shadowMapResolution , shadowParameters . shadowMapResolution ] ) ;
398+ context . viewport . set ( [ 0 , 0 , this . _shadowParameters . shadowMapResolution , this . _shadowParameters . shadowMapResolution ] ) ;
377399
378400 for ( let cascade = 0 ; cascade < this . _numCascadesToRender ; ++ cascade ) {
379401 painter . currentShadowCascade = cascade ;
@@ -492,7 +514,7 @@ export class ShadowRenderer {
492514
493515 if ( this . useNormalOffset ) {
494516 const meterInTiles = tileToMeter ( unwrappedTileID . canonical ) ;
495- const texelScale = 2.0 / transform . tileSize * EXTENT / shadowParameters . shadowMapResolution ;
517+ const texelScale = 2.0 / transform . tileSize * EXTENT / this . _shadowParameters . shadowMapResolution ;
496518 const shadowTexelInTileCoords0 = texelScale * this . _cascades [ 0 ] . boundingSphereRadius ;
497519 const shadowTexelInTileCoords1 = texelScale * this . _cascades [ this . _cascades . length - 1 ] . boundingSphereRadius ;
498520 // Instanced model tiles could have smoothened (shared among neighbor faces) normals. Normal is not surface normal
@@ -523,7 +545,7 @@ export class ShadowRenderer {
523545 const uniforms = this . _uniformValues ;
524546
525547 const lightMatrix = new Float64Array ( 16 ) ;
526- for ( let i = 0 ; i < shadowParameters . cascadeCount ; i ++ ) {
548+ for ( let i = 0 ; i < this . _shadowParameters . cascadeCount ; i ++ ) {
527549 mat4 . multiply ( lightMatrix , this . _cascades [ i ] . matrix , worldMatrix ) ;
528550 uniforms [ i === 0 ? 'u_light_matrix_0' : 'u_light_matrix_1' ] = Float32Array . from ( lightMatrix ) ;
529551 context . activeTexture . set ( gl . TEXTURE0 + TextureSlots . ShadowMap0 + i ) ;
@@ -533,7 +555,7 @@ export class ShadowRenderer {
533555 this . useNormalOffset = normalOffset ;
534556
535557 if ( normalOffset ) {
536- const scale = shadowParameters . normalOffset ;
558+ const scale = this . _shadowParameters . normalOffset ;
537559 uniforms [ "u_shadow_normal_offset" ] = [ 1.0 , scale , scale ] ; // meterToTile isn't used
538560 uniforms [ "u_shadow_bias" ] = [ 0.00006 , 0.0012 , 0.012 ] ; // Reduce constant offset
539561 } else {
0 commit comments