@@ -126,7 +126,7 @@ export class RenderAdditiveLightQueue {
126126 private declare _lightBuffer : Buffer ;
127127 private declare _firstLightBufferView : Buffer ;
128128 private declare _lightBufferData : Float32Array ;
129- private _instancedQueues : RenderInstancedQueue [ ] = [ ] ;
129+ private _instancedQueues : ( RenderInstancedQueue | undefined ) [ ] = [ ] ;
130130 private _lightMeterScale = 10000.0 ;
131131
132132 constructor ( pipeline : PipelineRuntime ) {
@@ -151,7 +151,9 @@ export class RenderAdditiveLightQueue {
151151
152152 public clear ( ) : void {
153153 this . _instancedQueues . forEach ( ( instancedQueue ) => {
154- instancedQueue . clear ( ) ;
154+ if ( instancedQueue ) {
155+ instancedQueue . clear ( ) ;
156+ }
155157 } ) ;
156158 this . _instancedQueues . length = 0 ;
157159
@@ -196,7 +198,7 @@ export class RenderAdditiveLightQueue {
196198
197199 this . _lightCulling ( model , validPunctualLights ) ;
198200
199- if ( ! _lightIndices . length && validPunctualLights . length > 0 ) { continue ; }
201+ if ( ! _lightIndices . length ) { continue ; }
200202
201203 for ( let j = 0 ; j < subModels . length ; j ++ ) {
202204 const lightPassIdx = _lightPassIndices [ j ] ;
@@ -219,15 +221,14 @@ export class RenderAdditiveLightQueue {
219221 public gatherLightPasses ( camera : Camera , cmdBuff : CommandBuffer , passLayout = 'default' ) : void {
220222 this . clear ( ) ;
221223
222- const validPunctualLights = this . _pipeline . pipelineSceneData . validPunctualLights ;
223- if ( ! validPunctualLights . length ) {
224- this . _bindForwardAddLight ( validPunctualLights , passLayout ) ;
225- return ;
226- }
227-
228224 this . _updateUBOs ( camera , cmdBuff ) ;
229225 this . _updateLightDescriptorSet ( camera , cmdBuff ) ;
226+
227+ const validPunctualLights = this . _pipeline . pipelineSceneData . validPunctualLights ;
228+ if ( ! validPunctualLights . length ) { return ; }
229+
230230 this . _bindForwardAddLight ( validPunctualLights , passLayout ) ;
231+
231232 // only for instanced and batched, no light culling applied
232233 for ( let l = 0 ; l < validPunctualLights . length ; l ++ ) {
233234 const light = validPunctualLights [ l ] ;
@@ -236,17 +237,21 @@ export class RenderAdditiveLightQueue {
236237 }
237238
238239 this . _instancedQueues . forEach ( ( instancedQueue ) => {
239- instancedQueue . uploadBuffers ( cmdBuff ) ;
240+ if ( instancedQueue ) {
241+ instancedQueue . uploadBuffers ( cmdBuff ) ;
242+ }
240243 } ) ;
241244 }
242245
243246 public recordCommandBuffer ( device : Device , renderPass : RenderPass , cmdBuff : CommandBuffer ) : void {
244247 const globalDSManager : GlobalDSManager = this . _pipeline . globalDSManager ;
245248 for ( let j = 0 ; j < this . _instancedQueues . length ; ++ j ) {
249+ const queue = this . _instancedQueues [ j ] ;
250+ if ( ! queue ) { continue ; }
246251 const light = this . _instancedLightPassPool . lights [ j ] ;
247252 _dynamicOffsets [ 0 ] = this . _instancedLightPassPool . dynamicOffsets [ j ] ;
248253 const descriptorSet = globalDSManager . getOrCreateDescriptorSet ( light ) ;
249- this . _instancedQueues [ j ] . recordCommandBuffer ( device , renderPass , cmdBuff , descriptorSet , _dynamicOffsets ) ;
254+ queue . recordCommandBuffer ( device , renderPass , cmdBuff , descriptorSet , _dynamicOffsets ) ;
250255 }
251256
252257 for ( let i = 0 ; i < this . _lightPasses . length ; i ++ ) {
@@ -315,14 +320,18 @@ export class RenderAdditiveLightQueue {
315320 const lightIdx = _lightIndices [ l ] ;
316321 const light = validPunctualLights [ lightIdx ] ;
317322 const visibility = light . visibility ;
318- if ( ( ( visibility & model . node . layer ) === model . node . layer ) ) {
323+ if ( ( ( visibility & model . node . layer ) === model . node . layer )
324+ || ( visibility & model . visFlags ) ) {
319325 switch ( batchingScheme ) {
320326 case BatchingSchemes . INSTANCING : {
321- const buffer = pass . getInstancedBuffer ( l ) ;
327+ const buffer = pass . getInstancedBuffer ( lightIdx ) ;
322328 buffer . merge ( subModel , lightPassIdx ) ;
323- buffer . dynamicOffsets [ 0 ] = this . _lightBufferStride ;
324- if ( ! this . _instancedQueues [ l ] ) { this . _instancedQueues [ l ] = new RenderInstancedQueue ( ) ; }
325- this . _instancedQueues [ l ] . queue . add ( buffer ) ;
329+ buffer . dynamicOffsets [ 0 ] = this . _lightBufferStride * lightIdx ;
330+ if ( this . _instancedQueues . length <= lightIdx || ! this . _instancedQueues [ lightIdx ] ) {
331+ this . _instancedQueues . length = lightIdx + 1 ;
332+ this . _instancedQueues [ lightIdx ] = new RenderInstancedQueue ( ) ;
333+ }
334+ this . _instancedQueues [ lightIdx ] ! . queue . add ( buffer ) ;
326335 } break ;
327336 default :
328337 lp ! . lights . push ( light ) ;
@@ -370,9 +379,6 @@ export class RenderAdditiveLightQueue {
370379 this . _shadowUBO [ UBOShadowEnum . SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 1 ] = packing ;
371380 this . _shadowUBO [ UBOShadowEnum . SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 2 ] = 0.0 ;
372381 this . _shadowUBO [ UBOShadowEnum . SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 3 ] = 0.0 ;
373-
374- // Reserve sphere light shadow interface
375- Color . toArray ( this . _shadowUBO , shadowInfo . shadowColor , UBOShadowEnum . SHADOW_COLOR_OFFSET ) ;
376382 break ;
377383 }
378384 case LightType . SPOT : {
@@ -437,8 +443,6 @@ export class RenderAdditiveLightQueue {
437443 this . _shadowUBO [ UBOShadowEnum . SHADOW_PROJ_INFO_OFFSET + 2 ] = 1.0 / matShadowProj . m00 ;
438444 this . _shadowUBO [ UBOShadowEnum . SHADOW_PROJ_INFO_OFFSET + 3 ] = 1.0 / matShadowProj . m05 ;
439445
440- Color . toArray ( this . _shadowUBO , shadowInfo . shadowColor , UBOShadowEnum . SHADOW_COLOR_OFFSET ) ;
441-
442446 // Spot light sampler binding
443447 if ( shadowFrameBufferMap . has ( light ) ) {
444448 const texture = shadowFrameBufferMap . get ( light ) ?. colorTextures [ 0 ] ;
@@ -463,15 +467,15 @@ export class RenderAdditiveLightQueue {
463467 this . _shadowUBO [ UBOShadowEnum . SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 1 ] = packing ;
464468 this . _shadowUBO [ UBOShadowEnum . SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 2 ] = 0.0 ;
465469 this . _shadowUBO [ UBOShadowEnum . SHADOW_LIGHT_PACKING_NBIAS_NULL_INFO_OFFSET + 3 ] = 0.0 ;
466-
467- // Reserve point light shadow interface
468- Color . toArray ( this . _shadowUBO , shadowInfo . shadowColor , UBOShadowEnum . SHADOW_COLOR_OFFSET ) ;
469470 break ;
470471 }
471472 default :
472473 }
473- globalDSManager . update ( ) ;
474- cmdBuff . updateBuffer ( descriptorSet . getBuffer ( UBOShadow . BINDING ) ! , this . _shadowUBO ) ;
474+ Color . toArray ( this . _shadowUBO , shadowInfo . shadowColor , UBOShadowEnum . SHADOW_COLOR_OFFSET ) ;
475+
476+ descriptorSet . update ( ) ;
477+
478+ cmdBuff . updateBuffer ( descriptorSet . getBuffer ( UBOShadow . BINDING ) ! , this . _shadowUBO . buffer , this . _shadowUBO . byteLength ) ;
475479 }
476480 }
477481
@@ -627,6 +631,6 @@ export class RenderAdditiveLightQueue {
627631 }
628632 }
629633
630- cmdBuff . updateBuffer ( this . _lightBuffer , this . _lightBufferData ) ;
634+ cmdBuff . updateBuffer ( this . _lightBuffer , this . _lightBufferData . buffer as ArrayBuffer , this . _lightBufferData . byteLength ) ;
631635 }
632636}
0 commit comments