@@ -17,7 +17,6 @@ export type TerrainModuleProps = {
1717 isPicking : boolean ;
1818 heightMap : Texture | null ;
1919 heightMapBounds ?: Bounds | null ;
20- dummyHeightMap : Texture ;
2120 terrainCover ?: TerrainCover | null ;
2221 drawToTerrainHeightMap ?: boolean ;
2322 useTerrainHeightMap ?: boolean ;
@@ -119,23 +118,27 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US
119118 } ,
120119 // eslint-disable-next-line complexity
121120 getUniforms : ( opts : Partial < TerrainModuleProps > = { } ) => {
122- if ( 'dummyHeightMap' in opts ) {
121+ const dummyHeightMap = terrainModule . dummyHeightMap ;
122+ if ( ! dummyHeightMap ) {
123+ // TerrainEffect has not been set up yet
124+ return { } ;
125+ }
126+
127+ if ( 'terrainSkipRender' in opts || 'drawToTerrainHeightMap' in opts ) {
123128 const {
124129 drawToTerrainHeightMap,
125130 heightMap,
126131 heightMapBounds,
127- dummyHeightMap,
128132 terrainCover,
129133 useTerrainHeightMap,
130134 terrainSkipRender
131135 } = opts ;
132-
133136 const projectUniforms = project . getUniforms ( opts . project ) as ProjectUniforms ;
134137 const { commonOrigin} = projectUniforms ;
135138
136139 let mode : number = terrainSkipRender ? TERRAIN_MODE . SKIP : TERRAIN_MODE . NONE ;
137140 // height map if case USE_HEIGHT_MAP, terrain cover if USE_COVER, otherwise empty
138- let sampler : Texture | undefined = dummyHeightMap as Texture ;
141+ let sampler : Texture = dummyHeightMap ;
139142 // height map bounds if case USE_HEIGHT_MAP, terrain cover bounds if USE_COVER, otherwise null
140143 let bounds : number [ ] | null = null ;
141144 if ( drawToTerrainHeightMap ) {
@@ -150,15 +153,15 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US
150153 const fbo = opts . isPicking
151154 ? terrainCover . getPickingFramebuffer ( )
152155 : terrainCover . getRenderFramebuffer ( ) ;
153- sampler = fbo ?. colorAttachments [ 0 ] . texture ;
156+ const coverTexture = fbo ?. colorAttachments [ 0 ] . texture ;
154157 if ( opts . isPicking ) {
155158 mode = TERRAIN_MODE . SKIP ;
156159 }
157- if ( sampler ) {
160+ if ( coverTexture ) {
161+ sampler = coverTexture ;
158162 mode = mode === TERRAIN_MODE . SKIP ? TERRAIN_MODE . USE_COVER_ONLY : TERRAIN_MODE . USE_COVER ;
159163 bounds = terrainCover . bounds ;
160164 } else {
161- sampler = dummyHeightMap ! ;
162165 if ( opts . isPicking && ! terrainSkipRender ) {
163166 // terrain+draw layer without cover FBO: render own picking colors
164167 mode = TERRAIN_MODE . NONE ;
@@ -181,22 +184,20 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US
181184 : [ 0 , 0 , 0 , 0 ]
182185 } ;
183186 }
184- // When terrain props are not provided (e.g. mask pass), provide the dummy
185- // texture to satisfy the terrain_map binding and prevent draw abort.
186- // dummyHeightMap is stored on the module by TerrainEffect.setup.
187- if ( terrainModule . dummyHeightMap ) {
188- return {
189- mode : TERRAIN_MODE . NONE ,
190- terrain_map : terrainModule . dummyHeightMap ,
191- bounds : [ 0 , 0 , 0 , 0 ]
192- } ;
193- }
194- return { } ;
187+ // No terrain-specific props provided (e.g. mask pass or other non-terrain render pass).
188+ // Provide the dummy texture to satisfy the terrain_map binding.
189+ return {
190+ mode : TERRAIN_MODE . NONE ,
191+ terrain_map : dummyHeightMap ,
192+ bounds : [ 0 , 0 , 0 , 0 ]
193+ } ;
195194 } ,
196195 uniformTypes : {
197196 mode : 'f32' ,
198197 bounds : 'vec4<f32>'
199198 } ,
200- /** Dummy texture stored by TerrainEffect.setup, used as fallback terrain_map binding */
199+ /** Dummy texture created by TerrainEffect.setup, used as default terrain_map binding */
201200 dummyHeightMap : null as Texture | null
202- } as ShaderModule < TerrainModuleProps , TerrainModuleUniforms , TerrainModuleBindings > & { dummyHeightMap : Texture | null } ;
201+ } as ShaderModule < TerrainModuleProps , TerrainModuleUniforms , TerrainModuleBindings > & {
202+ dummyHeightMap : Texture | null ;
203+ } ;
0 commit comments