@onerjs/core 8.50.8 → 8.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/Cameras/Inputs/freeCameraTouchInput.js +5 -3
  2. package/Cameras/Inputs/freeCameraTouchInput.js.map +1 -1
  3. package/Cameras/Inputs/freeCameraVirtualJoystickInput.js +11 -7
  4. package/Cameras/Inputs/freeCameraVirtualJoystickInput.js.map +1 -1
  5. package/Cameras/arcRotateCamera.js +2 -1
  6. package/Cameras/arcRotateCamera.js.map +1 -1
  7. package/Cameras/camera.js +1 -0
  8. package/Cameras/camera.js.map +1 -1
  9. package/Cameras/followCamera.js +1 -1
  10. package/Cameras/followCamera.js.map +1 -1
  11. package/Collisions/gpuPicker.d.ts +12 -0
  12. package/Collisions/gpuPicker.js +51 -0
  13. package/Collisions/gpuPicker.js.map +1 -1
  14. package/Culling/ray.core.js +46 -2
  15. package/Culling/ray.core.js.map +1 -1
  16. package/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.js +10 -3
  17. package/FlowGraph/Blocks/Event/flowGraphMeshPickEventBlock.js.map +1 -1
  18. package/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.d.ts +1 -0
  19. package/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.js +36 -3
  20. package/FlowGraph/Blocks/Execution/flowGraphConsoleLogBlock.js.map +1 -1
  21. package/FlowGraph/flowGraphEventBlock.d.ts +13 -0
  22. package/FlowGraph/flowGraphEventBlock.js +21 -2
  23. package/FlowGraph/flowGraphEventBlock.js.map +1 -1
  24. package/Layers/layer.js +5 -1
  25. package/Layers/layer.js.map +1 -1
  26. package/LensFlares/lensFlareSystem.js +1 -0
  27. package/LensFlares/lensFlareSystem.js.map +1 -1
  28. package/Lights/Clustered/clusteredLightContainer.js +11 -1
  29. package/Lights/Clustered/clusteredLightContainer.js.map +1 -1
  30. package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.d.ts +1 -0
  31. package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.js +6 -3
  32. package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.js.map +1 -1
  33. package/Materials/GaussianSplatting/gaussianSplattingMaterial.d.ts +2 -0
  34. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +10 -3
  35. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
  36. package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.d.ts +2 -1
  37. package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.js +10 -4
  38. package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.js.map +1 -1
  39. package/Materials/PBR/openpbrMaterial.js +3 -3
  40. package/Materials/PBR/openpbrMaterial.js.map +1 -1
  41. package/Materials/Textures/envCubeTexture.js +33 -15
  42. package/Materials/Textures/envCubeTexture.js.map +1 -1
  43. package/Materials/standardMaterial.js +4 -2
  44. package/Materials/standardMaterial.js.map +1 -1
  45. package/Meshes/abstractMesh.js +1 -0
  46. package/Meshes/abstractMesh.js.map +1 -1
  47. package/Misc/brdfTextureTools.d.ts +12 -0
  48. package/Misc/brdfTextureTools.js +22 -0
  49. package/Misc/brdfTextureTools.js.map +1 -1
  50. package/Misc/depthReducer.js +1 -1
  51. package/Misc/depthReducer.js.map +1 -1
  52. package/Particles/Node/Blocks/Update/updateFlowMapBlock.js +17 -10
  53. package/Particles/Node/Blocks/Update/updateFlowMapBlock.js.map +1 -1
  54. package/Particles/Node/Blocks/Update/updateNoiseBlock.js +14 -0
  55. package/Particles/Node/Blocks/Update/updateNoiseBlock.js.map +1 -1
  56. package/Particles/Node/Blocks/particleSourceTextureBlock.js +114 -12
  57. package/Particles/Node/Blocks/particleSourceTextureBlock.js.map +1 -1
  58. package/Particles/Node/nodeParticleBuildState.d.ts +11 -0
  59. package/Particles/Node/nodeParticleBuildState.js +15 -0
  60. package/Particles/Node/nodeParticleBuildState.js.map +1 -1
  61. package/Particles/Node/nodeParticleSystemSet.js +23 -22
  62. package/Particles/Node/nodeParticleSystemSet.js.map +1 -1
  63. package/Particles/gpuParticleSystem.js +1 -0
  64. package/Particles/gpuParticleSystem.js.map +1 -1
  65. package/Particles/thinParticleSystem.js +1 -0
  66. package/Particles/thinParticleSystem.js.map +1 -1
  67. package/PostProcesses/postProcessManager.d.ts +2 -0
  68. package/PostProcesses/postProcessManager.js +14 -8
  69. package/PostProcesses/postProcessManager.js.map +1 -1
  70. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js +12 -9
  71. package/Rendering/IBLShadows/iblShadowsVoxelRenderer.js.map +1 -1
  72. package/Rendering/depthRendererSceneComponent.js +7 -7
  73. package/Rendering/depthRendererSceneComponent.js.map +1 -1
  74. package/Rendering/iblCdfGeneratorSceneComponent.d.ts +6 -0
  75. package/Rendering/iblCdfGeneratorSceneComponent.js +16 -0
  76. package/Rendering/iblCdfGeneratorSceneComponent.js.map +1 -1
  77. package/Rendering/prePassRenderer.d.ts +4 -1
  78. package/Rendering/prePassRenderer.js +31 -9
  79. package/Rendering/prePassRenderer.js.map +1 -1
  80. package/Shaders/ShadersInclude/openpbrBackgroundTransmission.js +1 -1
  81. package/Shaders/ShadersInclude/openpbrBackgroundTransmission.js.map +1 -1
  82. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js +3 -3
  83. package/Shaders/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  84. package/Shaders/ShadersInclude/openpbrIblFunctions.js +8 -5
  85. package/Shaders/ShadersInclude/openpbrIblFunctions.js.map +1 -1
  86. package/Shaders/ShadersInclude/pbrBRDFFunctions.js +10 -6
  87. package/Shaders/ShadersInclude/pbrBRDFFunctions.js.map +1 -1
  88. package/Shaders/openpbr.fragment.js +4 -4
  89. package/Shaders/openpbr.fragment.js.map +1 -1
  90. package/ShadersWGSL/ShadersInclude/openpbrBackgroundTransmission.js +1 -1
  91. package/ShadersWGSL/ShadersInclude/openpbrBackgroundTransmission.js.map +1 -1
  92. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js +3 -3
  93. package/ShadersWGSL/ShadersInclude/openpbrEnvironmentLighting.js.map +1 -1
  94. package/ShadersWGSL/ShadersInclude/openpbrIblFunctions.js +5 -3
  95. package/ShadersWGSL/ShadersInclude/openpbrIblFunctions.js.map +1 -1
  96. package/ShadersWGSL/ShadersInclude/pbrBRDFFunctions.js +5 -6
  97. package/ShadersWGSL/ShadersInclude/pbrBRDFFunctions.js.map +1 -1
  98. package/ShadersWGSL/openpbr.fragment.js +6 -6
  99. package/ShadersWGSL/openpbr.fragment.js.map +1 -1
  100. package/Sprites/spriteManager.js +1 -0
  101. package/Sprites/spriteManager.js.map +1 -1
  102. package/package.json +1 -1
  103. package/scene.d.ts +16 -0
  104. package/scene.js +13 -0
  105. package/scene.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"clusteredLightContainer.js","sourceRoot":"","sources":["../../../../../dev/core/src/Lights/Clustered/clusteredLightContainer.ts"],"names":[],"mappings":"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","sourcesContent":["import { StorageBuffer } from \"core/Buffers/storageBuffer\";\nimport { type Camera } from \"core/Cameras/camera\";\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\nimport { Constants } from \"core/Engines/constants\";\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine\";\nimport { type Effect } from \"core/Materials/effect\";\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial\";\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\nimport { UniformBuffer } from \"core/Materials/uniformBuffer\";\nimport { TmpColors } from \"core/Maths/math.color\";\nimport { TmpVectors, Vector3 } from \"core/Maths/math.vector\";\nimport { CreatePlane } from \"core/Meshes/Builders/planeBuilder\";\nimport { type Mesh } from \"core/Meshes/mesh\";\nimport { serialize } from \"core/Misc/decorators\";\nimport { _WarnImport } from \"core/Misc/devTools\";\nimport { Logger } from \"core/Misc/logger\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\nimport { Node } from \"core/node\";\nimport { type Scene } from \"core/scene\";\nimport { type Nullable } from \"core/types\";\n\nimport { Light } from \"../light\";\nimport { LightConstants } from \"../lightConstants\";\nimport { type PointLight } from \"../pointLight\";\nimport { type SpotLight } from \"../spotLight\";\nimport { type RenderTargetWrapper } from \"../../Engines/renderTargetWrapper\";\n\nimport \"core/Meshes/thinInstanceMesh\";\n\nNode.AddNodeConstructor(\"Light_Type_5\", (name, scene) => {\n return () => new ClusteredLightContainer(name, [], scene);\n});\n\nconst DefaultDepthSlices = 16;\nconst MobileClusteredLightBatchSize = 8;\n\n/**\n * A special light that renders all its associated spot or point lights using a clustered or forward+ system.\n */\nexport class ClusteredLightContainer extends Light {\n private static _GetEngineBatchSize(engine: AbstractEngine): number {\n const caps = engine._caps;\n if (!caps.texelFetch) {\n return 0;\n } else if (engine.isWebGPU) {\n // On WebGPU we use atomic writes to storage textures\n return 32;\n } else if (engine.version > 1) {\n // On WebGL 2 we use additive float blending as the light mask\n if (!caps.colorBufferFloat || !caps.blendFloat) {\n return 0;\n }\n // Due to the use of floats we want to limit lights to the precision of floats\n // The reduced precision for mobiles is because some devices (like Samsung Galaxy) report support for R32F but actually create the texture with less precision.\n return engine.hostInformation.isMobile ? MobileClusteredLightBatchSize : caps.shaderFloatPrecision;\n } else {\n // WebGL 1 is not supported due to lack of dynamic for loops\n return 0;\n }\n }\n\n /**\n * Checks if the clustered lighting system supports the given light with its current parameters.\n * This will also check if the light's associated engine supports clustered lighting.\n *\n * @param light The light to test\n * @returns true if the light and its engine is supported\n */\n public static IsLightSupported(light: Light): boolean {\n if (ClusteredLightContainer._GetEngineBatchSize(light.getEngine()) === 0) {\n return false;\n }\n\n if (light.shadowEnabled && light._scene.shadowsEnabled && light.getShadowGenerators()) {\n // Shadows are not supported\n return false;\n }\n\n if (light.falloffType !== Light.FALLOFF_DEFAULT) {\n // Only the default falloff is supported\n return false;\n }\n\n if (light.getTypeID() === LightConstants.LIGHTTYPEID_POINTLIGHT) {\n return true;\n }\n\n if (light.getTypeID() === LightConstants.LIGHTTYPEID_SPOTLIGHT) {\n // Extra texture bindings per light are not supported\n return !(<SpotLight>light).projectionTexture && !(<SpotLight>light).iesProfileTexture;\n }\n\n // Currently only point and spot lights are supported\n return false;\n }\n\n /** @internal */\n public static _SceneComponentInitialization: (scene: Scene) => void = () => {\n throw _WarnImport(\"ClusteredLightingSceneComponent\");\n };\n\n private readonly _batchSize: number;\n\n /**\n * True if clustered lighting is supported.\n */\n public get isSupported(): boolean {\n return this._batchSize > 0;\n }\n\n private readonly _lights: Light[] = [];\n /**\n * Gets the current list of lights added to this clustering system.\n */\n public get lights(): readonly Light[] {\n return this._lights;\n }\n\n private _camera: Nullable<Camera> = null;\n\n // The lights sorted by depth\n private readonly _sortedLights: (PointLight | SpotLight)[] = [];\n\n private _lightDataBuffer: Float32Array;\n private _lightDataTexture: RawTexture;\n private _lightDataRenderId = -1;\n\n private _tileMaskBatches = -1;\n private _tileMaskTexture: RenderTargetTexture;\n private _tileMaskBuffer: Nullable<StorageBuffer>;\n\n private _horizontalTiles = 64;\n /**\n * The number of tiles in the horizontal direction to cluster lights into.\n * A lower value will reduce memory and make the clustering step faster, while a higher value increases memory and makes the rendering step faster.\n */\n @serialize()\n public get horizontalTiles(): number {\n return this._horizontalTiles;\n }\n\n public set horizontalTiles(horizontal: number) {\n if (this._horizontalTiles === horizontal) {\n return;\n }\n this._horizontalTiles = horizontal;\n // Force the batch data to be recreated\n this._tileMaskBatches = -1;\n }\n\n private _verticalTiles = 64;\n /**\n * The number of tiles in the vertical direction to cluster lights into.\n * A lower value will reduce memory and make the clustering step faster, while a higher value increases memory and makes the rendering step faster.\n */\n @serialize()\n public get verticalTiles(): number {\n return this._verticalTiles;\n }\n\n public set verticalTiles(vertical: number) {\n if (this._verticalTiles === vertical) {\n return;\n }\n this._verticalTiles = vertical;\n // Force the batch data to be recreated\n this._tileMaskBatches = -1;\n }\n\n private _sliceScale = 0;\n private _sliceBias = 0;\n // List of vec2's that keep track of the min and max index per slice\n private _sliceRanges: Float32Array<ArrayBuffer>;\n // Tracks the last lightIndex string passed to transferToEffect, or null if the cluster\n // has not yet been bound. Used to refresh the camera-dependent UBO entries (vSliceData /\n // vSliceRanges) every frame in cases where material binding is bypassed (e.g. WebGPU FAST\n // snapshot rendering replays cached bundles and never re-runs Light._bindLight).\n private _lastBoundLightIndex: Nullable<string> = null;\n\n private _depthSlices = DefaultDepthSlices;\n /**\n * The number of slices to split the depth range by and cluster lights into.\n */\n @serialize()\n public get depthSlices(): number {\n return this._depthSlices;\n }\n\n public set depthSlices(slices: number) {\n if (this._depthSlices === slices) {\n return;\n }\n this._depthSlices = slices;\n this._sliceRanges = new Float32Array(slices * 2);\n\n // UBO size depends on the number of depth slices\n this._uniformBuffer.dispose();\n this._uniformBuffer = new UniformBuffer(this.getEngine(), undefined, undefined, this.name);\n this._buildUniformLayout();\n // The UBO has been recreated so previous bindings are no longer valid; transferToEffect will repopulate it.\n this._lastBoundLightIndex = null;\n\n // CLUSTLIGHT_SLICES is a shader define that sizes the vSliceRanges array in the UBO.\n // Materials must recompile when depthSlices changes so the shader layout matches the rebuilt UBO.\n // Otherwise, if depthSlices is reduced, the rebuilt UBO can be smaller than what the previously compiled shader expects, causing rendering to fail.\n this._markMeshesAsLightDirty();\n }\n\n private readonly _proxyMaterial: ShaderMaterial;\n private readonly _proxyMesh: Mesh;\n\n private _maxRange = 16383;\n private _minInverseSquaredRange = 1 / (this._maxRange * this._maxRange);\n /**\n * This limits the range of all the added lights, so even lights with extreme ranges will still have bounds for clustering.\n */\n @serialize()\n public get maxRange(): number {\n return this._maxRange;\n }\n\n public set maxRange(range: number) {\n if (this._maxRange === range) {\n return;\n }\n this._maxRange = range;\n this._minInverseSquaredRange = 1 / (range * range);\n }\n\n /**\n * Creates a new clustered light system with an initial set of lights.\n *\n * @param name The name of the clustered light container\n * @param lights The initial set of lights to add\n * @param scene The scene the clustered light container belongs to\n */\n constructor(name: string, lights: Light[] = [], scene?: Scene) {\n super(name, scene);\n const engine = this.getEngine();\n this._batchSize = ClusteredLightContainer._GetEngineBatchSize(engine);\n\n const proxyShader = { vertex: \"lightProxy\", fragment: \"lightProxy\" };\n const defines = [`CLUSTLIGHT_BATCH ${this._batchSize}`];\n if (this._scene.useRightHandedSystem) {\n defines.push(\"#define RIGHT_HANDED\");\n }\n this._proxyMaterial = new ShaderMaterial(\"ProxyMaterial\", this._scene, proxyShader, {\n attributes: [\"position\"],\n uniforms: [\"view\", \"projection\", \"tileMaskResolution\"],\n samplers: [\"lightDataTexture\"],\n uniformBuffers: [\"Scene\"],\n storageBuffers: [\"tileMaskBuffer\"],\n defines,\n shaderLanguage: engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n extraInitializationsAsync: async () => {\n if (engine.isWebGPU) {\n await Promise.all([import(\"../../ShadersWGSL/lightProxy.vertex\"), import(\"../../ShadersWGSL/lightProxy.fragment\")]);\n } else {\n await Promise.all([import(\"../../Shaders/lightProxy.vertex\"), import(\"../../Shaders/lightProxy.fragment\")]);\n }\n },\n });\n\n // Additive blending is for merging masks on WebGL\n this._proxyMaterial.transparencyMode = ShaderMaterial.MATERIAL_ALPHABLEND;\n this._proxyMaterial.alphaMode = Constants.ALPHA_ADD;\n this._proxyMaterial.sideOrientation = Constants.MATERIAL_CounterClockWiseSideOrientation;\n\n this._proxyMesh = CreatePlane(\"ProxyMesh\", { size: 2 }, this._scene);\n // Make sure it doesn't render for the default scene\n this._scene.removeMesh(this._proxyMesh);\n this._proxyMesh.material = this._proxyMaterial;\n\n this._updateBatches();\n\n this._sliceRanges = new Float32Array(this._depthSlices * 2);\n\n if (this._batchSize > 0) {\n ClusteredLightContainer._SceneComponentInitialization(this._scene);\n for (const light of lights) {\n this.addLight(light);\n }\n }\n }\n\n public override getClassName(): string {\n return \"ClusteredLightContainer\";\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public override getTypeID(): number {\n return LightConstants.LIGHTTYPEID_CLUSTERED_CONTAINER;\n }\n\n /** @internal */\n public _updateBatches(camera: Nullable<Camera> = null): RenderTargetTexture {\n this._camera = camera;\n this._proxyMesh.isVisible = this._sortedLights.length > 0;\n\n // Ensure space for atleast 1 batch\n const batches = Math.max(Math.ceil(this._sortedLights.length / this._batchSize), 1);\n if (this._tileMaskBatches >= batches) {\n this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n return this._tileMaskTexture;\n }\n const engine = this.getEngine();\n // Round up to a batch size so we don't have to reallocate as often\n const maxLights = batches * this._batchSize;\n\n this._lightDataBuffer = new Float32Array(20 * maxLights);\n this._lightDataTexture?.dispose();\n this._lightDataTexture = new RawTexture(\n this._lightDataBuffer,\n 5,\n maxLights,\n Constants.TEXTUREFORMAT_RGBA,\n this._scene,\n false,\n false,\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n Constants.TEXTURETYPE_FLOAT\n );\n this._lightDataTexture.name = \"LightDataTexture_clustered_\" + this.name;\n this._proxyMaterial.setTexture(\"lightDataTexture\", this._lightDataTexture);\n\n this._tileMaskTexture?.dispose();\n const textureSize = { width: this._horizontalTiles, height: this._verticalTiles };\n if (!engine.isWebGPU) {\n // In WebGL we shift the light proxy by the batch number\n textureSize.height *= batches;\n }\n this._tileMaskTexture = new RenderTargetTexture(\"TileMaskTexture\", textureSize, this._scene, {\n // We don't write anything on WebGPU so make it as small as possible\n type: engine.isWebGPU ? Constants.TEXTURETYPE_UNSIGNED_BYTE : Constants.TEXTURETYPE_FLOAT,\n format: Constants.TEXTUREFORMAT_RED,\n generateDepthBuffer: false,\n });\n\n this._tileMaskTexture.renderParticles = false;\n this._tileMaskTexture.renderSprites = false;\n this._tileMaskTexture.noPrePassRenderer = true;\n this._tileMaskTexture.renderList = [this._proxyMesh];\n\n let currentRenderTarget: Nullable<RenderTargetWrapper> = null;\n\n this._tileMaskTexture.onBeforeBindObservable.add(() => {\n currentRenderTarget = engine._currentRenderTarget;\n this._updateLightData();\n // On WebGPU, clear the storage buffer here (before bindFramebuffer) because\n // clearBuffer is a command encoder operation that cannot run while a render pass is open.\n // In snapshot rendering mode, bindFramebuffer eagerly creates the render pass, so\n // clearing must happen before that point.\n if (engine.isWebGPU) {\n this._tileMaskBuffer?.clear();\n }\n });\n\n this._tileMaskTexture.onAfterUnbindObservable.add(() => {\n if (engine._currentRenderTarget !== currentRenderTarget) {\n if (!currentRenderTarget) {\n engine.restoreDefaultFramebuffer();\n } else {\n engine.bindFramebuffer(currentRenderTarget);\n }\n }\n });\n\n this._tileMaskTexture.onClearObservable.add(() => {\n if (!engine.isWebGPU) {\n // Only clear the texture on WebGL\n engine.clear({ r: 0, g: 0, b: 0, a: 1 }, true, false);\n }\n });\n\n if (engine.isWebGPU) {\n // WebGPU also needs a storage buffer to write to\n this._tileMaskBuffer?.dispose();\n const bufferSize = this._horizontalTiles * this._verticalTiles * batches * 4;\n this._tileMaskBuffer = new StorageBuffer(<WebGPUEngine>engine, bufferSize);\n this._proxyMaterial.setStorageBuffer(\"tileMaskBuffer\", this._tileMaskBuffer);\n }\n\n this._proxyMaterial.setVector3(\"tileMaskResolution\", new Vector3(this._horizontalTiles, this.verticalTiles, batches));\n\n // We don't actually use the matrix data but we need enough capacity for the lights\n this._proxyMesh.thinInstanceSetBuffer(\"matrix\", new Float32Array(maxLights * 16));\n this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n this._tileMaskBatches = batches;\n return this._tileMaskTexture;\n }\n\n private _getSliceIndex(camera: Camera, depth: number): number {\n if (depth < camera.minZ) {\n // Prevent calling log on small or negative values\n return -1;\n }\n return Math.floor(Math.log(depth) * this._sliceScale + this._sliceBias);\n }\n\n private _updateLightData(): void {\n const camera = this._camera || this._scene.activeCamera;\n const renderId = this._scene.getRenderId();\n if (!camera || this._lightDataRenderId === renderId) {\n return;\n }\n this._lightDataRenderId = renderId;\n\n // Resort lights based on distance from camera\n const view = camera.getViewMatrix();\n for (const light of this._sortedLights) {\n const position = light.computeTransformedInformation() ? light.transformedPosition : light.position;\n const viewPosition = Vector3.TransformCoordinatesToRef(position, view, TmpVectors.Vector3[0]);\n light._currentViewDepth = this._scene.useRightHandedSystem ? -viewPosition.z : viewPosition.z;\n }\n this._sortedLights.sort((a, b) => a._currentViewDepth - b._currentViewDepth);\n\n // DOOM 2016 subdivision scheme, copied from: https://www.aortiz.me/2018/12/21/CG.html\n const logFarNear = Math.log(camera.maxZ / camera.minZ);\n this._sliceScale = this._depthSlices / logFarNear;\n this._sliceBias = -(this._depthSlices * Math.log(camera.minZ)) / logFarNear;\n\n this._sliceRanges.fill(0);\n // Last slice which had had its min index updated\n let minSlice = -1;\n\n const buf = this._lightDataBuffer;\n const offset = this._scene.floatingOriginOffset;\n\n for (let i = 0; i < this._sortedLights.length; i += 1) {\n const light = this._sortedLights[i];\n const off = i * 20;\n const computed = light.computeTransformedInformation();\n const scaledIntensity = light.getScaledIntensity();\n\n const position = computed ? light.transformedPosition : light.position;\n const diffuse = light.diffuse.scaleToRef(scaledIntensity, TmpColors.Color3[0]);\n const specular = light.specular.scaleToRef(scaledIntensity, TmpColors.Color3[1]);\n const range = Math.min(light.range, this.maxRange);\n const inverseSquaredRange = Math.max(light._inverseSquaredRange, this._minInverseSquaredRange);\n\n // vLightData\n buf[off + 0] = position.x - offset.x;\n buf[off + 1] = position.y - offset.y;\n buf[off + 2] = position.z - offset.z;\n buf[off + 3] = 0;\n // vLightDiffuse\n buf[off + 4] = diffuse.r;\n buf[off + 5] = diffuse.g;\n buf[off + 6] = diffuse.b;\n buf[off + 7] = range;\n // vLightSpecular\n buf[off + 8] = specular.r;\n buf[off + 9] = specular.g;\n buf[off + 10] = specular.b;\n buf[off + 11] = light.radius;\n // vLightDirection\n buf[off + 12] = 0;\n buf[off + 13] = 0;\n buf[off + 14] = 0;\n buf[off + 15] = -1;\n // vLightFalloff\n buf[off + 16] = range;\n buf[off + 17] = inverseSquaredRange;\n buf[off + 18] = 0;\n buf[off + 19] = 0;\n\n if (light.getTypeID() === LightConstants.LIGHTTYPEID_SPOTLIGHT) {\n const spotLight = <SpotLight>light;\n const direction = Vector3.NormalizeToRef(computed ? spotLight.transformedDirection : spotLight.direction, TmpVectors.Vector3[0]);\n\n // vLightData.a\n buf[off + 3] = spotLight.exponent;\n // vLightDirection\n buf[off + 12] = direction.x;\n buf[off + 13] = direction.y;\n buf[off + 14] = direction.z;\n buf[off + 15] = spotLight._cosHalfAngle;\n // vLightFalloff.zw\n buf[off + 18] = spotLight._lightAngleScale;\n buf[off + 19] = spotLight._lightAngleOffset;\n }\n\n // Update the depth slices that include this light\n const firstSlice = this._getSliceIndex(camera, light._currentViewDepth - range);\n const lastSlice = this._getSliceIndex(camera, light._currentViewDepth + range);\n for (let j = firstSlice; j <= lastSlice; j += 1) {\n if (j < 0 || j >= this._depthSlices) {\n continue;\n } else if (j > minSlice) {\n // Update min index\n this._sliceRanges[j * 2] = i;\n minSlice = j;\n }\n // Update max index\n this._sliceRanges[j * 2 + 1] = i;\n }\n }\n\n const engine = this.getEngine();\n if (engine.isWebGPU) {\n // Whenever the light data changes we have to flush pending WebGPU command buffers so that\n // previous render passes use the old data and later render passes use the new data.\n engine.flushFramebuffer();\n }\n this._lightDataTexture.update(this._lightDataBuffer);\n\n // Refresh camera-dependent UBO fields when running under FAST snapshot rendering, where\n // ObjectRenderer.render bypasses the rendering manager and Light._bindLight is not\n // re-invoked each frame. Without this, transferToEffect would never run again after the\n // recording frame and the slice data would stay frozen, producing visibly stale lighting\n // as the camera moves. STANDARD snapshot mode and non-snapshot rendering still go through\n // material binding each frame, so transferToEffect already keeps the UBO up to date.\n if (this._lastBoundLightIndex !== null && engine.snapshotRendering && engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST) {\n this._uniformBuffer.updateFloat2(\"vSliceData\", this._sliceScale, this._sliceBias, this._lastBoundLightIndex);\n this._uniformBuffer.updateFloatArray(\"vSliceRanges\", this._sliceRanges, this._lastBoundLightIndex);\n this._uniformBuffer.update();\n }\n }\n\n public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures?: boolean): void {\n for (const light of this._lights) {\n light.dispose(doNotRecurse, disposeMaterialAndTextures);\n }\n this._lightDataTexture.dispose();\n this._tileMaskTexture.dispose();\n this._tileMaskBuffer?.dispose();\n this._proxyMesh.dispose(doNotRecurse, disposeMaterialAndTextures);\n super.dispose(doNotRecurse, disposeMaterialAndTextures);\n }\n\n /**\n * Adds a light to the clustering system.\n * @param light The light to add\n */\n public addLight(light: Light): void {\n if (!ClusteredLightContainer.IsLightSupported(light)) {\n Logger.Warn(\"Attempting to add a light to cluster that does not support clustering\");\n return;\n }\n this._scene.removeLight(light);\n this._lights.push(light);\n this._sortedLights.push(<PointLight | SpotLight>light);\n\n this._proxyMesh.isVisible = true;\n this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n }\n\n /**\n * Removes a light from the clustering system.\n * @param light The light to remove\n * @returns the index where the light was in the light list\n */\n public removeLight(light: Light): number {\n // Convert to `Light` array without cast so `indexOf` has correct typing\n const sortedLights: Light[] = this._sortedLights;\n const sortedIndex = sortedLights.indexOf(light);\n if (sortedIndex !== -1) {\n sortedLights.splice(sortedIndex, 1);\n\n this._proxyMesh.thinInstanceCount = sortedLights.length;\n if (sortedLights.length === 0) {\n this._proxyMesh.isVisible = false;\n }\n }\n\n const index = this._lights.indexOf(light);\n if (index !== -1) {\n this._lights.splice(index, 1);\n // We treat the unsorted array as the \"real\" one so only add back to the scene if it was found in that\n this._scene.addLight(light);\n }\n return index;\n }\n\n protected override _buildUniformLayout(): void {\n this._uniformBuffer.addUniform(\"vLightData\", 4);\n this._uniformBuffer.addUniform(\"vLightDiffuse\", 4);\n this._uniformBuffer.addUniform(\"vLightSpecular\", 4);\n this._uniformBuffer.addUniform(\"vSliceData\", 2);\n // _depthSlices might not be initialized yet\n this._uniformBuffer.addUniform(\"vSliceRanges\", 2, this._depthSlices ?? DefaultDepthSlices);\n this._uniformBuffer.addUniform(\"shadowsInfo\", 3);\n this._uniformBuffer.addUniform(\"depthValues\", 2);\n this._uniformBuffer.create();\n }\n\n public override transferToEffect(effect: Effect, lightIndex: string): Light {\n const engine = this.getEngine();\n const hscale = this._horizontalTiles / engine.getRenderWidth();\n const vscale = this._verticalTiles / engine.getRenderHeight();\n this._uniformBuffer.updateFloat4(\"vLightData\", hscale, vscale, this._verticalTiles, this._tileMaskBatches, lightIndex);\n this._uniformBuffer.updateFloat2(\"vSliceData\", this._sliceScale, this._sliceBias, lightIndex);\n this._uniformBuffer.updateFloatArray(\"vSliceRanges\", this._sliceRanges, lightIndex);\n this._lastBoundLightIndex = lightIndex;\n return this;\n }\n\n public override transferTexturesToEffect(effect: Effect, lightIndex: string): Light {\n const engine = this.getEngine();\n effect.setTexture(\"lightDataTexture\" + lightIndex, this._lightDataTexture);\n if (engine.isWebGPU) {\n (<WebGPUEngine>engine).setStorageBuffer(\"tileMaskBuffer\" + lightIndex, this._tileMaskBuffer);\n } else {\n effect.setTexture(\"tileMaskTexture\" + lightIndex, this._tileMaskTexture);\n }\n return this;\n }\n\n public override transferToNodeMaterialEffect(_effect: Effect): Light {\n return this;\n }\n\n public override prepareLightSpecificDefines(defines: any, lightIndex: number): void {\n defines[\"CLUSTLIGHT\" + lightIndex] = true;\n defines[\"CLUSTLIGHT_BATCH\"] = this._batchSize;\n defines[\"CLUSTLIGHT_SLICES\"] = this._depthSlices;\n }\n\n public override _isReady(): boolean {\n this._updateBatches();\n return this._proxyMesh.isReady(true, true);\n }\n\n /**\n * Serializes the ClusteredLightContainer to a JSON object, including all child lights.\n * @returns the serialized object\n */\n public override serialize(): any {\n const serializationObject = super.serialize();\n\n // Serialize child lights inline so they round-trip with the container.\n // Child lights are removed from scene.lights by addLight(), so the scene\n // serializer would not reach them on its own.\n serializationObject.clusteredLights = [];\n for (const light of this._lights) {\n if (!light.doNotSerialize) {\n serializationObject.clusteredLights.push(light.serialize());\n }\n }\n\n return serializationObject;\n }\n\n protected override _onParsed(parsedLight: any, scene: Scene): void {\n if (parsedLight.clusteredLights) {\n // Parse child lights first, but defer addLight() until after the loader\n // fixup passes (parent resolution, excluded/included mesh resolution)\n // have run on scene.lights. addLight() removes lights from scene.lights,\n // which would cause those fixups to miss the child lights.\n const parsedChildLights: Light[] = [];\n for (const parsedChildLight of parsedLight.clusteredLights) {\n const childLight = Light.Parse(parsedChildLight, scene);\n if (childLight) {\n parsedChildLights.push(childLight);\n }\n }\n\n if (parsedChildLights.length > 0) {\n scene.onDataLoadedObservable.addOnce(() => {\n for (const childLight of parsedChildLights) {\n this.addLight(childLight);\n }\n });\n }\n }\n }\n}\n\n// Register Class Name\nRegisterClass(\"BABYLON.ClusteredLightContainer\", ClusteredLightContainer);\n"]}
1
+ {"version":3,"file":"clusteredLightContainer.js","sourceRoot":"","sources":["../../../../../dev/core/src/Lights/Clustered/clusteredLightContainer.ts"],"names":[],"mappings":"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","sourcesContent":["import { StorageBuffer } from \"core/Buffers/storageBuffer\";\nimport { type Camera } from \"core/Cameras/camera\";\nimport { type AbstractEngine } from \"core/Engines/abstractEngine\";\nimport { Constants } from \"core/Engines/constants\";\nimport { type WebGPUEngine } from \"core/Engines/webgpuEngine\";\nimport { type Effect } from \"core/Materials/effect\";\nimport { ShaderLanguage } from \"core/Materials/shaderLanguage\";\nimport { ShaderMaterial } from \"core/Materials/shaderMaterial\";\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\nimport { RenderTargetTexture } from \"core/Materials/Textures/renderTargetTexture\";\nimport { UniformBuffer } from \"core/Materials/uniformBuffer\";\nimport { TmpColors } from \"core/Maths/math.color\";\nimport { TmpVectors, Vector3 } from \"core/Maths/math.vector\";\nimport { CreatePlane } from \"core/Meshes/Builders/planeBuilder\";\nimport { type Mesh } from \"core/Meshes/mesh\";\nimport { serialize } from \"core/Misc/decorators\";\nimport { _WarnImport } from \"core/Misc/devTools\";\nimport { Logger } from \"core/Misc/logger\";\nimport { RegisterClass } from \"core/Misc/typeStore\";\nimport { Node } from \"core/node\";\nimport { type Scene } from \"core/scene\";\nimport { type Nullable } from \"core/types\";\n\nimport { Light } from \"../light\";\nimport { LightConstants } from \"../lightConstants\";\nimport { type PointLight } from \"../pointLight\";\nimport { type SpotLight } from \"../spotLight\";\nimport { type RenderTargetWrapper } from \"../../Engines/renderTargetWrapper\";\n\nimport \"core/Meshes/thinInstanceMesh\";\n\nNode.AddNodeConstructor(\"Light_Type_5\", (name, scene) => {\n return () => new ClusteredLightContainer(name, [], scene);\n});\n\nconst DefaultDepthSlices = 16;\nconst MobileClusteredLightBatchSize = 8;\n\n/**\n * A special light that renders all its associated spot or point lights using a clustered or forward+ system.\n */\nexport class ClusteredLightContainer extends Light {\n private static _GetEngineBatchSize(engine: AbstractEngine): number {\n const caps = engine._caps;\n if (!caps.texelFetch) {\n return 0;\n } else if (engine.isWebGPU) {\n // On WebGPU we use atomic writes to storage textures\n return 32;\n } else if (engine.version > 1) {\n // On WebGL 2 we use additive float blending as the light mask\n if (!caps.colorBufferFloat || !caps.blendFloat) {\n return 0;\n }\n // Due to the use of floats we want to limit lights to the precision of floats\n // The reduced precision for mobiles is because some devices (like Samsung Galaxy) report support for R32F but actually create the texture with less precision.\n return engine.hostInformation.isMobile ? MobileClusteredLightBatchSize : caps.shaderFloatPrecision;\n } else {\n // WebGL 1 is not supported due to lack of dynamic for loops\n return 0;\n }\n }\n\n /**\n * Checks if the clustered lighting system supports the given light with its current parameters.\n * This will also check if the light's associated engine supports clustered lighting.\n *\n * @param light The light to test\n * @returns true if the light and its engine is supported\n */\n public static IsLightSupported(light: Light): boolean {\n if (ClusteredLightContainer._GetEngineBatchSize(light.getEngine()) === 0) {\n return false;\n }\n\n if (light.shadowEnabled && light._scene.shadowsEnabled && light.getShadowGenerators()) {\n // Shadows are not supported\n return false;\n }\n\n if (light.falloffType !== Light.FALLOFF_DEFAULT) {\n // Only the default falloff is supported\n return false;\n }\n\n if (light.getTypeID() === LightConstants.LIGHTTYPEID_POINTLIGHT) {\n return true;\n }\n\n if (light.getTypeID() === LightConstants.LIGHTTYPEID_SPOTLIGHT) {\n // Extra texture bindings per light are not supported\n return !(<SpotLight>light).projectionTexture && !(<SpotLight>light).iesProfileTexture;\n }\n\n // Currently only point and spot lights are supported\n return false;\n }\n\n /** @internal */\n public static _SceneComponentInitialization: (scene: Scene) => void = () => {\n throw _WarnImport(\"ClusteredLightingSceneComponent\");\n };\n\n private readonly _batchSize: number;\n\n /**\n * True if clustered lighting is supported.\n */\n public get isSupported(): boolean {\n return this._batchSize > 0;\n }\n\n private readonly _lights: Light[] = [];\n /**\n * Gets the current list of lights added to this clustering system.\n */\n public get lights(): readonly Light[] {\n return this._lights;\n }\n\n private _camera: Nullable<Camera> = null;\n\n // The lights sorted by depth\n private readonly _sortedLights: (PointLight | SpotLight)[] = [];\n\n private _lightDataBuffer: Float32Array;\n private _lightDataTexture: RawTexture;\n private _lightDataRenderId = -1;\n\n private _tileMaskBatches = -1;\n private _tileMaskTexture: RenderTargetTexture;\n private _tileMaskBuffer: Nullable<StorageBuffer>;\n\n private _horizontalTiles = 64;\n /**\n * The number of tiles in the horizontal direction to cluster lights into.\n * A lower value will reduce memory and make the clustering step faster, while a higher value increases memory and makes the rendering step faster.\n */\n @serialize()\n public get horizontalTiles(): number {\n return this._horizontalTiles;\n }\n\n public set horizontalTiles(horizontal: number) {\n if (this._horizontalTiles === horizontal) {\n return;\n }\n this._horizontalTiles = horizontal;\n // Force the batch data to be recreated\n this._tileMaskBatches = -1;\n }\n\n private _verticalTiles = 64;\n /**\n * The number of tiles in the vertical direction to cluster lights into.\n * A lower value will reduce memory and make the clustering step faster, while a higher value increases memory and makes the rendering step faster.\n */\n @serialize()\n public get verticalTiles(): number {\n return this._verticalTiles;\n }\n\n public set verticalTiles(vertical: number) {\n if (this._verticalTiles === vertical) {\n return;\n }\n this._verticalTiles = vertical;\n // Force the batch data to be recreated\n this._tileMaskBatches = -1;\n }\n\n private _sliceScale = 0;\n private _sliceBias = 0;\n // List of vec2's that keep track of the min and max index per slice\n private _sliceRanges: Float32Array<ArrayBuffer>;\n // Tracks the last lightIndex string passed to transferToEffect, or null if the cluster\n // has not yet been bound. Used to refresh the camera-dependent UBO entries (vSliceData /\n // vSliceRanges) every frame in cases where material binding is bypassed (e.g. WebGPU FAST\n // snapshot rendering replays cached bundles and never re-runs Light._bindLight).\n private _lastBoundLightIndex: Nullable<string> = null;\n\n private _depthSlices = DefaultDepthSlices;\n /**\n * The number of slices to split the depth range by and cluster lights into.\n */\n @serialize()\n public get depthSlices(): number {\n return this._depthSlices;\n }\n\n public set depthSlices(slices: number) {\n if (this._depthSlices === slices) {\n return;\n }\n this._depthSlices = slices;\n this._sliceRanges = new Float32Array(slices * 2);\n\n // UBO size depends on the number of depth slices\n this._uniformBuffer.dispose();\n this._uniformBuffer = new UniformBuffer(this.getEngine(), undefined, undefined, this.name);\n this._buildUniformLayout();\n // The UBO has been recreated so previous bindings are no longer valid; transferToEffect will repopulate it.\n this._lastBoundLightIndex = null;\n\n // CLUSTLIGHT_SLICES is a shader define that sizes the vSliceRanges array in the UBO.\n // Materials must recompile when depthSlices changes so the shader layout matches the rebuilt UBO.\n // Otherwise, if depthSlices is reduced, the rebuilt UBO can be smaller than what the previously compiled shader expects, causing rendering to fail.\n this._markMeshesAsLightDirty();\n }\n\n private readonly _proxyMaterial: ShaderMaterial;\n private readonly _proxyMesh: Mesh;\n\n private _maxRange = 16383;\n private _minInverseSquaredRange = 1 / (this._maxRange * this._maxRange);\n /**\n * This limits the range of all the added lights, so even lights with extreme ranges will still have bounds for clustering.\n */\n @serialize()\n public get maxRange(): number {\n return this._maxRange;\n }\n\n public set maxRange(range: number) {\n if (this._maxRange === range) {\n return;\n }\n this._maxRange = range;\n this._minInverseSquaredRange = 1 / (range * range);\n }\n\n /**\n * Creates a new clustered light system with an initial set of lights.\n *\n * @param name The name of the clustered light container\n * @param lights The initial set of lights to add\n * @param scene The scene the clustered light container belongs to\n */\n constructor(name: string, lights: Light[] = [], scene?: Scene) {\n super(name, scene);\n const engine = this.getEngine();\n this._batchSize = ClusteredLightContainer._GetEngineBatchSize(engine);\n\n const proxyShader = { vertex: \"lightProxy\", fragment: \"lightProxy\" };\n const defines = [`CLUSTLIGHT_BATCH ${this._batchSize}`];\n if (this._scene.useRightHandedSystem) {\n defines.push(\"#define RIGHT_HANDED\");\n }\n this._proxyMaterial = new ShaderMaterial(\"ProxyMaterial\", this._scene, proxyShader, {\n attributes: [\"position\"],\n uniforms: [\"view\", \"projection\", \"tileMaskResolution\"],\n samplers: [\"lightDataTexture\"],\n uniformBuffers: [\"Scene\"],\n storageBuffers: [\"tileMaskBuffer\"],\n defines,\n shaderLanguage: engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\n extraInitializationsAsync: async () => {\n if (engine.isWebGPU) {\n await Promise.all([import(\"../../ShadersWGSL/lightProxy.vertex\"), import(\"../../ShadersWGSL/lightProxy.fragment\")]);\n } else {\n await Promise.all([import(\"../../Shaders/lightProxy.vertex\"), import(\"../../Shaders/lightProxy.fragment\")]);\n }\n },\n });\n\n // Additive blending is for merging masks on WebGL\n this._proxyMaterial.transparencyMode = ShaderMaterial.MATERIAL_ALPHABLEND;\n this._proxyMaterial.alphaMode = Constants.ALPHA_ADD;\n this._proxyMaterial.sideOrientation = Constants.MATERIAL_CounterClockWiseSideOrientation;\n\n this._proxyMesh = CreatePlane(\"ProxyMesh\", { size: 2 }, this._scene);\n // Make sure it doesn't render for the default scene\n this._scene.removeMesh(this._proxyMesh);\n this._proxyMesh.material = this._proxyMaterial;\n\n this._updateBatches();\n\n this._sliceRanges = new Float32Array(this._depthSlices * 2);\n\n if (this._batchSize > 0) {\n ClusteredLightContainer._SceneComponentInitialization(this._scene);\n for (const light of lights) {\n this.addLight(light);\n }\n }\n }\n\n public override getClassName(): string {\n return \"ClusteredLightContainer\";\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public override getTypeID(): number {\n return LightConstants.LIGHTTYPEID_CLUSTERED_CONTAINER;\n }\n\n /** @internal */\n public _updateBatches(camera: Nullable<Camera> = null): RenderTargetTexture {\n this._camera = camera;\n this._proxyMesh.isVisible = this._sortedLights.length > 0;\n\n // Ensure space for atleast 1 batch\n const batches = Math.max(Math.ceil(this._sortedLights.length / this._batchSize), 1);\n if (this._tileMaskBatches >= batches) {\n this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n return this._tileMaskTexture;\n }\n const engine = this.getEngine();\n // Round up to a batch size so we don't have to reallocate as often\n const maxLights = batches * this._batchSize;\n\n this._lightDataBuffer = new Float32Array(20 * maxLights);\n this._lightDataTexture?.dispose();\n this._lightDataTexture = new RawTexture(\n this._lightDataBuffer,\n 5,\n maxLights,\n Constants.TEXTUREFORMAT_RGBA,\n this._scene,\n false,\n false,\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\n Constants.TEXTURETYPE_FLOAT\n );\n this._lightDataTexture.name = \"LightDataTexture_clustered_\" + this.name;\n this._proxyMaterial.setTexture(\"lightDataTexture\", this._lightDataTexture);\n\n this._tileMaskTexture?.dispose();\n const textureSize = { width: this._horizontalTiles, height: this._verticalTiles };\n if (!engine.isWebGPU) {\n // In WebGL we shift the light proxy by the batch number\n textureSize.height *= batches;\n }\n this._tileMaskTexture = new RenderTargetTexture(\"TileMaskTexture\", textureSize, this._scene, {\n // We don't write anything on WebGPU so make it as small as possible\n type: engine.isWebGPU ? Constants.TEXTURETYPE_UNSIGNED_BYTE : Constants.TEXTURETYPE_FLOAT,\n format: Constants.TEXTUREFORMAT_RED,\n generateDepthBuffer: false,\n });\n\n this._tileMaskTexture.renderParticles = false;\n this._tileMaskTexture.renderSprites = false;\n this._tileMaskTexture.noPrePassRenderer = true;\n this._tileMaskTexture.renderList = [this._proxyMesh];\n\n let currentRenderTarget: Nullable<RenderTargetWrapper> = null;\n\n this._tileMaskTexture.onBeforeBindObservable.add(() => {\n currentRenderTarget = engine._currentRenderTarget;\n this._updateLightData();\n // On WebGPU, clear the storage buffer here (before bindFramebuffer) because\n // clearBuffer is a command encoder operation that cannot run while a render pass is open.\n // In snapshot rendering mode, bindFramebuffer eagerly creates the render pass, so\n // clearing must happen before that point.\n if (engine.isWebGPU) {\n this._tileMaskBuffer?.clear();\n }\n });\n\n this._tileMaskTexture.onAfterUnbindObservable.add(() => {\n if (engine._currentRenderTarget !== currentRenderTarget) {\n if (!currentRenderTarget) {\n engine.restoreDefaultFramebuffer();\n } else {\n engine.bindFramebuffer(currentRenderTarget);\n }\n }\n });\n\n this._tileMaskTexture.onClearObservable.add(() => {\n if (!engine.isWebGPU) {\n // Only clear the texture on WebGL\n engine.clear({ r: 0, g: 0, b: 0, a: 1 }, true, false);\n }\n });\n\n if (engine.isWebGPU) {\n // WebGPU also needs a storage buffer to write to\n this._tileMaskBuffer?.dispose();\n const bufferSize = this._horizontalTiles * this._verticalTiles * batches * 4;\n this._tileMaskBuffer = new StorageBuffer(<WebGPUEngine>engine, bufferSize);\n this._proxyMaterial.setStorageBuffer(\"tileMaskBuffer\", this._tileMaskBuffer);\n }\n\n this._proxyMaterial.setVector3(\"tileMaskResolution\", new Vector3(this._horizontalTiles, this.verticalTiles, batches));\n\n // We don't actually use the matrix data but we need enough capacity for the lights\n this._proxyMesh.thinInstanceSetBuffer(\"matrix\", new Float32Array(maxLights * 16));\n this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n this._tileMaskBatches = batches;\n return this._tileMaskTexture;\n }\n\n private _getSliceIndex(camera: Camera, depth: number): number {\n if (depth < camera.minZ) {\n // Prevent calling log on small or negative values\n return -1;\n }\n return Math.floor(Math.log(depth) * this._sliceScale + this._sliceBias);\n }\n\n private _updateLightData(): void {\n const camera = this._camera || this._scene.activeCamera;\n const renderId = this._scene.getRenderId();\n if (!camera || this._lightDataRenderId === renderId) {\n return;\n }\n this._lightDataRenderId = renderId;\n\n // Resort lights based on distance from camera\n const view = camera.getViewMatrix();\n for (const light of this._sortedLights) {\n const position = light.computeTransformedInformation() ? light.transformedPosition : light.position;\n const viewPosition = Vector3.TransformCoordinatesToRef(position, view, TmpVectors.Vector3[0]);\n light._currentViewDepth = this._scene.useRightHandedSystem ? -viewPosition.z : viewPosition.z;\n }\n this._sortedLights.sort((a, b) => a._currentViewDepth - b._currentViewDepth);\n\n // DOOM 2016 subdivision scheme, copied from: https://www.aortiz.me/2018/12/21/CG.html\n const logFarNear = Math.log(camera.maxZ / camera.minZ);\n this._sliceScale = this._depthSlices / logFarNear;\n this._sliceBias = -(this._depthSlices * Math.log(camera.minZ)) / logFarNear;\n\n this._sliceRanges.fill(0);\n // Last slice which had had its min index updated\n let minSlice = -1;\n\n const buf = this._lightDataBuffer;\n const offset = this._scene.floatingOriginOffset;\n\n for (let i = 0; i < this._sortedLights.length; i += 1) {\n const light = this._sortedLights[i];\n const off = i * 20;\n const computed = light.computeTransformedInformation();\n const scaledIntensity = light.getScaledIntensity();\n\n const position = computed ? light.transformedPosition : light.position;\n const diffuse = light.diffuse.scaleToRef(scaledIntensity, TmpColors.Color3[0]);\n const specular = light.specular.scaleToRef(scaledIntensity, TmpColors.Color3[1]);\n const range = Math.min(light.range, this.maxRange);\n const inverseSquaredRange = Math.max(light._inverseSquaredRange, this._minInverseSquaredRange);\n\n // vLightData\n buf[off + 0] = position.x - offset.x;\n buf[off + 1] = position.y - offset.y;\n buf[off + 2] = position.z - offset.z;\n buf[off + 3] = 0;\n // vLightDiffuse\n buf[off + 4] = diffuse.r;\n buf[off + 5] = diffuse.g;\n buf[off + 6] = diffuse.b;\n buf[off + 7] = range;\n // vLightSpecular\n buf[off + 8] = specular.r;\n buf[off + 9] = specular.g;\n buf[off + 10] = specular.b;\n buf[off + 11] = light.radius;\n // vLightDirection\n buf[off + 12] = 0;\n buf[off + 13] = 0;\n buf[off + 14] = 0;\n buf[off + 15] = -1;\n // vLightFalloff\n buf[off + 16] = range;\n buf[off + 17] = inverseSquaredRange;\n buf[off + 18] = 0;\n buf[off + 19] = 0;\n\n if (light.getTypeID() === LightConstants.LIGHTTYPEID_SPOTLIGHT) {\n const spotLight = <SpotLight>light;\n const direction = Vector3.NormalizeToRef(computed ? spotLight.transformedDirection : spotLight.direction, TmpVectors.Vector3[0]);\n\n // vLightData.a\n buf[off + 3] = spotLight.exponent;\n // vLightDirection\n buf[off + 12] = direction.x;\n buf[off + 13] = direction.y;\n buf[off + 14] = direction.z;\n buf[off + 15] = spotLight._cosHalfAngle;\n // vLightFalloff.zw\n buf[off + 18] = spotLight._lightAngleScale;\n buf[off + 19] = spotLight._lightAngleOffset;\n }\n\n // Update the depth slices that include this light\n const firstSlice = this._getSliceIndex(camera, light._currentViewDepth - range);\n const lastSlice = this._getSliceIndex(camera, light._currentViewDepth + range);\n for (let j = firstSlice; j <= lastSlice; j += 1) {\n if (j < 0 || j >= this._depthSlices) {\n continue;\n } else if (j > minSlice) {\n // Update min index\n this._sliceRanges[j * 2] = i;\n minSlice = j;\n }\n // Update max index\n this._sliceRanges[j * 2 + 1] = i;\n }\n }\n\n const engine = this.getEngine();\n if (engine.isWebGPU) {\n // Whenever the light data changes we have to flush pending WebGPU command buffers so that\n // previous render passes use the old data and later render passes use the new data.\n engine.flushFramebuffer();\n }\n this._lightDataTexture.update(this._lightDataBuffer);\n\n // Refresh camera-dependent UBO fields when running under FAST snapshot rendering, where\n // ObjectRenderer.render bypasses the rendering manager and Light._bindLight is not\n // re-invoked each frame. Without this, transferToEffect would never run again after the\n // recording frame and the slice data would stay frozen, producing visibly stale lighting\n // as the camera moves. STANDARD snapshot mode and non-snapshot rendering still go through\n // material binding each frame, so transferToEffect already keeps the UBO up to date.\n if (this._lastBoundLightIndex !== null && engine.snapshotRendering && engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST) {\n this._uniformBuffer.updateFloat2(\"vSliceData\", this._sliceScale, this._sliceBias, this._lastBoundLightIndex);\n this._uniformBuffer.updateFloatArray(\"vSliceRanges\", this._sliceRanges, this._lastBoundLightIndex);\n this._uniformBuffer.update();\n }\n }\n\n public override dispose(doNotRecurse?: boolean, disposeMaterialAndTextures?: boolean): void {\n for (const light of this._lights) {\n light.dispose(doNotRecurse, disposeMaterialAndTextures);\n }\n this._lightDataTexture.dispose();\n this._tileMaskTexture.dispose();\n this._tileMaskBuffer?.dispose();\n this._proxyMesh.dispose(doNotRecurse, disposeMaterialAndTextures);\n super.dispose(doNotRecurse, disposeMaterialAndTextures);\n }\n\n /**\n * Adds a light to the clustering system.\n * @param light The light to add\n */\n public addLight(light: Light): void {\n if (!ClusteredLightContainer.IsLightSupported(light)) {\n Logger.Warn(\"Attempting to add a light to cluster that does not support clustering\");\n return;\n }\n // scene.removeLight returns -1 if the light wasn't in scene.lights. In that case the\n // mesh.lightSources cleanup it normally performs didn't happen — but the light may still be\n // there: lights constructed with `dontAddToScene = true` are pushed into mesh.lightSources\n // by the Light constructor (the `includedOnlyMeshes` setter calls `_resyncMeshes`).\n // Without explicit cleanup, the orphan would be picked up by PrepareDefinesForLights and\n // rendered as a regular point/spot light, bypassing the cluster (notably ignoring `maxRange`).\n if (this._scene.removeLight(light) === -1) {\n for (const mesh of this._scene.meshes) {\n mesh._removeLightSource(light, false);\n }\n }\n this._lights.push(light);\n this._sortedLights.push(<PointLight | SpotLight>light);\n\n this._proxyMesh.isVisible = true;\n this._proxyMesh.thinInstanceCount = this._sortedLights.length;\n }\n\n /**\n * Removes a light from the clustering system.\n * @param light The light to remove\n * @returns the index where the light was in the light list\n */\n public removeLight(light: Light): number {\n // Convert to `Light` array without cast so `indexOf` has correct typing\n const sortedLights: Light[] = this._sortedLights;\n const sortedIndex = sortedLights.indexOf(light);\n if (sortedIndex !== -1) {\n sortedLights.splice(sortedIndex, 1);\n\n this._proxyMesh.thinInstanceCount = sortedLights.length;\n if (sortedLights.length === 0) {\n this._proxyMesh.isVisible = false;\n }\n }\n\n const index = this._lights.indexOf(light);\n if (index !== -1) {\n this._lights.splice(index, 1);\n // We treat the unsorted array as the \"real\" one so only add back to the scene if it was found in that\n this._scene.addLight(light);\n }\n return index;\n }\n\n protected override _buildUniformLayout(): void {\n this._uniformBuffer.addUniform(\"vLightData\", 4);\n this._uniformBuffer.addUniform(\"vLightDiffuse\", 4);\n this._uniformBuffer.addUniform(\"vLightSpecular\", 4);\n this._uniformBuffer.addUniform(\"vSliceData\", 2);\n // _depthSlices might not be initialized yet\n this._uniformBuffer.addUniform(\"vSliceRanges\", 2, this._depthSlices ?? DefaultDepthSlices);\n this._uniformBuffer.addUniform(\"shadowsInfo\", 3);\n this._uniformBuffer.addUniform(\"depthValues\", 2);\n this._uniformBuffer.create();\n }\n\n public override transferToEffect(effect: Effect, lightIndex: string): Light {\n const engine = this.getEngine();\n const hscale = this._horizontalTiles / engine.getRenderWidth();\n const vscale = this._verticalTiles / engine.getRenderHeight();\n this._uniformBuffer.updateFloat4(\"vLightData\", hscale, vscale, this._verticalTiles, this._tileMaskBatches, lightIndex);\n this._uniformBuffer.updateFloat2(\"vSliceData\", this._sliceScale, this._sliceBias, lightIndex);\n this._uniformBuffer.updateFloatArray(\"vSliceRanges\", this._sliceRanges, lightIndex);\n this._lastBoundLightIndex = lightIndex;\n return this;\n }\n\n public override transferTexturesToEffect(effect: Effect, lightIndex: string): Light {\n const engine = this.getEngine();\n effect.setTexture(\"lightDataTexture\" + lightIndex, this._lightDataTexture);\n if (engine.isWebGPU) {\n (<WebGPUEngine>engine).setStorageBuffer(\"tileMaskBuffer\" + lightIndex, this._tileMaskBuffer);\n } else {\n effect.setTexture(\"tileMaskTexture\" + lightIndex, this._tileMaskTexture);\n }\n return this;\n }\n\n public override transferToNodeMaterialEffect(_effect: Effect): Light {\n return this;\n }\n\n public override prepareLightSpecificDefines(defines: any, lightIndex: number): void {\n defines[\"CLUSTLIGHT\" + lightIndex] = true;\n defines[\"CLUSTLIGHT_BATCH\"] = this._batchSize;\n defines[\"CLUSTLIGHT_SLICES\"] = this._depthSlices;\n }\n\n public override _isReady(): boolean {\n this._updateBatches();\n return this._proxyMesh.isReady(true, true);\n }\n\n /**\n * Serializes the ClusteredLightContainer to a JSON object, including all child lights.\n * @returns the serialized object\n */\n public override serialize(): any {\n const serializationObject = super.serialize();\n\n // Serialize child lights inline so they round-trip with the container.\n // Child lights are removed from scene.lights by addLight(), so the scene\n // serializer would not reach them on its own.\n serializationObject.clusteredLights = [];\n for (const light of this._lights) {\n if (!light.doNotSerialize) {\n serializationObject.clusteredLights.push(light.serialize());\n }\n }\n\n return serializationObject;\n }\n\n protected override _onParsed(parsedLight: any, scene: Scene): void {\n if (parsedLight.clusteredLights) {\n // Parse child lights first, but defer addLight() until after the loader\n // fixup passes (parent resolution, excluded/included mesh resolution)\n // have run on scene.lights. addLight() removes lights from scene.lights,\n // which would cause those fixups to miss the child lights.\n const parsedChildLights: Light[] = [];\n for (const parsedChildLight of parsedLight.clusteredLights) {\n const childLight = Light.Parse(parsedChildLight, scene);\n if (childLight) {\n parsedChildLights.push(childLight);\n }\n }\n\n if (parsedChildLights.length > 0) {\n scene.onDataLoadedObservable.addOnce(() => {\n for (const childLight of parsedChildLights) {\n this.addLight(childLight);\n }\n });\n }\n }\n }\n}\n\n// Register Class Name\nRegisterClass(\"BABYLON.ClusteredLightContainer\", ClusteredLightContainer);\n"]}
@@ -20,6 +20,7 @@ export declare class GaussianSplattingGpuPickingMaterialPlugin extends MaterialP
20
20
  private _isCompound;
21
21
  private _partPickingColors;
22
22
  private _partVisibility;
23
+ private _defaultPartVisibility;
23
24
  private _maxPartCount;
24
25
  /**
25
26
  * Creates a new GaussianSplattingGpuPickingMaterialPlugin.
@@ -21,7 +21,9 @@ export class GaussianSplattingGpuPickingMaterialPlugin extends MaterialPluginBas
21
21
  this._isCompound = false;
22
22
  this._partPickingColors = [];
23
23
  this._partVisibility = [];
24
+ this._defaultPartVisibility = [];
24
25
  this._maxPartCount = maxPartCount ?? GetGaussianSplattingMaxPartCount(material.getScene().getEngine());
26
+ this._defaultPartVisibility = new Array(this._maxPartCount).fill(1.0);
25
27
  this._enable(true);
26
28
  }
27
29
  /**
@@ -72,13 +74,14 @@ export class GaussianSplattingGpuPickingMaterialPlugin extends MaterialPluginBas
72
74
  * @param activeParts Array of part indices that should be pickable.
73
75
  */
74
76
  setPartActive(activeParts) {
75
- const visibility = new Array(this._maxPartCount).fill(0.0);
77
+ const visibility = this._partVisibility;
78
+ visibility.length = this._maxPartCount;
79
+ visibility.fill(0.0);
76
80
  for (const index of activeParts) {
77
81
  if (index >= 0 && index < this._maxPartCount) {
78
82
  visibility[index] = 1.0;
79
83
  }
80
84
  }
81
- this._partVisibility = visibility;
82
85
  }
83
86
  /**
84
87
  * @returns the class name
@@ -220,7 +223,7 @@ uniform pickingColor: vec3f;
220
223
  if (this._isCompound) {
221
224
  effect.setArray3("partPickingColors", this._partPickingColors);
222
225
  // default all visible when setPartActive hasn't been called
223
- const visibility = this._partVisibility.length > 0 ? this._partVisibility : new Array(this._maxPartCount).fill(1.0);
226
+ const visibility = this._partVisibility.length > 0 ? this._partVisibility : this._defaultPartVisibility;
224
227
  effect.setArray("partVisibility", visibility);
225
228
  }
226
229
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"gaussianSplattingGpuPickingMaterialPlugin.js","sourceRoot":"","sources":["../../../../../dev/core/src/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\nimport { type UniformBuffer } from \"../uniformBuffer\";\r\nimport { type MaterialDefines } from \"../materialDefines\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\nimport { GetGaussianSplattingMaxPartCount, type GaussianSplattingMaterial } from \"./gaussianSplattingMaterial\";\r\n\r\n/**\r\n * Plugin for GaussianSplattingMaterial that replaces per-splat color output with\r\n * a pre-computed picking color for GPU-based hit testing.\r\n *\r\n * The picking color is computed on the CPU by encoding a 24-bit picking ID as RGB\r\n * (matching the readback decoding in GPUPicker).\r\n * @experimental\r\n */\r\nexport class GaussianSplattingGpuPickingMaterialPlugin extends MaterialPluginBase {\r\n private _pickingColor: [number, number, number] = [0, 0, 0];\r\n private _isCompound: boolean = false;\r\n private _partPickingColors: number[] = [];\r\n private _partVisibility: number[] = [];\r\n private _maxPartCount: number;\r\n\r\n /**\r\n * Creates a new GaussianSplattingGpuPickingMaterialPlugin.\r\n * @param material The GaussianSplattingMaterial to attach the plugin to.\r\n * @param maxPartCount The maximum number of parts supported for compound meshes.\r\n */\r\n constructor(material: GaussianSplattingMaterial, maxPartCount?: number) {\r\n super(material, \"GaussianSplatGpuPicking\", 200);\r\n\r\n this._maxPartCount = maxPartCount ?? GetGaussianSplattingMaxPartCount(material.getScene().getEngine());\r\n this._enable(true);\r\n }\r\n\r\n /**\r\n * Encodes a 24-bit picking ID into normalized RGB components.\r\n * @param id The picking ID to encode\r\n * @returns A tuple [r, g, b] with values in [0, 1]\r\n */\r\n public static EncodeIdToColor(id: number): [number, number, number] {\r\n return [((id >> 16) & 0xff) / 255, ((id >> 8) & 0xff) / 255, (id & 0xff) / 255];\r\n }\r\n\r\n /**\r\n * Sets the picking color for a non-compound mesh from a picking ID.\r\n * The ID is encoded into an RGB color on the CPU.\r\n * @param id The 24-bit picking ID.\r\n */\r\n public set meshId(id: number) {\r\n this._pickingColor = GaussianSplattingGpuPickingMaterialPlugin.EncodeIdToColor(id);\r\n }\r\n\r\n /**\r\n * Sets whether this material is for a compound mesh with per-part picking.\r\n */\r\n public set isCompound(value: boolean) {\r\n this._isCompound = value;\r\n this.markAllDefinesAsDirty();\r\n }\r\n\r\n /**\r\n * Gets whether this material is for a compound mesh with per-part picking.\r\n */\r\n public get isCompound(): boolean {\r\n return this._isCompound;\r\n }\r\n\r\n /**\r\n * Sets the per-part picking colors from an array of picking IDs.\r\n * Each ID is encoded into an RGB color on the CPU.\r\n * @param ids Array mapping part index to picking ID.\r\n */\r\n public set partMeshIds(ids: number[]) {\r\n const colors: number[] = [];\r\n for (let i = 0; i < this._maxPartCount; i++) {\r\n const c = i < ids.length ? GaussianSplattingGpuPickingMaterialPlugin.EncodeIdToColor(ids[i]) : ([0, 0, 0] as [number, number, number]);\r\n colors.push(c[0], c[1], c[2]);\r\n }\r\n this._partPickingColors = colors;\r\n }\r\n\r\n /**\r\n * Sets which parts are active (pickable) for the compound picking pass.\r\n * Parts not in the set are discarded in the shader by overriding partVisibility to 0.\r\n * @param activeParts Array of part indices that should be pickable.\r\n */\r\n public setPartActive(activeParts: number[]): void {\r\n const visibility = new Array(this._maxPartCount).fill(0.0);\r\n for (const index of activeParts) {\r\n if (index >= 0 && index < this._maxPartCount) {\r\n visibility[index] = 1.0;\r\n }\r\n }\r\n this._partVisibility = visibility;\r\n }\r\n\r\n /**\r\n * @returns the class name\r\n */\r\n public override getClassName(): string {\r\n return \"GaussianSplattingGpuPickingMaterialPlugin\";\r\n }\r\n\r\n /**\r\n * Indicates this plugin supports both GLSL and WGSL.\r\n * @param shaderLanguage the shader language to check\r\n * @returns true for GLSL and WGSL\r\n */\r\n public override isCompatible(shaderLanguage: ShaderLanguage): boolean {\r\n switch (shaderLanguage) {\r\n case ShaderLanguage.GLSL:\r\n case ShaderLanguage.WGSL:\r\n return true;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Always ready — no textures or async resources to wait on.\r\n * @param _defines the defines\r\n * @param _scene the scene\r\n * @param _engine the engine\r\n * @param _subMesh the submesh\r\n * @returns true\r\n */\r\n public override isReadyForSubMesh(_defines: MaterialDefines, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns custom shader code to inject GPU picking color output.\r\n *\r\n * @param shaderType \"vertex\" or \"fragment\"\r\n * @param shaderLanguage the shader language to use (default: GLSL)\r\n * @returns null or a map of injection point names to code strings\r\n */\r\n public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n if (shaderLanguage === ShaderLanguage.WGSL) {\r\n return this._getCustomCodeWGSL(shaderType);\r\n }\r\n return this._getCustomCodeGLSL(shaderType);\r\n }\r\n\r\n private _getCustomCodeGLSL(shaderType: string): Nullable<{ [pointName: string]: string }> {\r\n if (shaderType === \"vertex\") {\r\n return {\r\n CUSTOM_VERTEX_DEFINITIONS: `varying float vPartIndex;`,\r\n CUSTOM_VERTEX_UPDATE: `\r\n#if IS_COMPOUND\r\n vPartIndex = float(splat.partIndex);\r\n#else\r\n vPartIndex = 0.0;\r\n#endif\r\n `,\r\n };\r\n } else if (shaderType === \"fragment\") {\r\n return {\r\n CUSTOM_FRAGMENT_DEFINITIONS: `\r\nvarying float vPartIndex;\r\n#if IS_COMPOUND\r\nuniform vec3 partPickingColors[${this._maxPartCount}];\r\n#else\r\nuniform vec3 pickingColor;\r\n#endif\r\n `,\r\n CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n#if IS_COMPOUND\r\n if (vColor.a < 0.001) discard;\r\n finalColor = vec4(partPickingColors[int(vPartIndex + 0.5)], 1.0);\r\n#else\r\n if (vColor.a < 0.001) discard;\r\n finalColor = vec4(pickingColor, 1.0);\r\n#endif\r\n `,\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n private _getCustomCodeWGSL(shaderType: string): Nullable<{ [pointName: string]: string }> {\r\n if (shaderType === \"vertex\") {\r\n return {\r\n CUSTOM_VERTEX_DEFINITIONS: `varying vPartIndex: f32;`,\r\n CUSTOM_VERTEX_UPDATE: `\r\n#if IS_COMPOUND\r\n vertexOutputs.vPartIndex = f32(splat.partIndex);\r\n#else\r\n vertexOutputs.vPartIndex = 0.0;\r\n#endif\r\n `,\r\n };\r\n } else if (shaderType === \"fragment\") {\r\n return {\r\n CUSTOM_FRAGMENT_DEFINITIONS: `\r\nvarying vPartIndex: f32;\r\n#if IS_COMPOUND\r\nuniform partPickingColors: array<vec3f, ${this._maxPartCount}>;\r\n#else\r\nuniform pickingColor: vec3f;\r\n#endif\r\n `,\r\n CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n#if IS_COMPOUND\r\n if (fragmentInputs.vColor.a < 0.001) { discard; }\r\n finalColor = vec4f(uniforms.partPickingColors[i32(fragmentInputs.vPartIndex + 0.5)], 1.0);\r\n#else\r\n if (fragmentInputs.vColor.a < 0.001) { discard; }\r\n finalColor = vec4f(uniforms.pickingColor, 1.0);\r\n#endif\r\n `,\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Registers the picking uniforms with the engine.\r\n * @returns uniform descriptions\r\n */\r\n public override getUniforms(): {\r\n ubo?: Array<{ name: string; size?: number; type?: string; arraySize?: number }>;\r\n vertex?: string;\r\n fragment?: string;\r\n externalUniforms?: string[];\r\n } {\r\n return {\r\n externalUniforms: [\"pickingColor\", \"partPickingColors\"],\r\n };\r\n }\r\n\r\n /**\r\n * Binds the picking color uniform(s) each frame.\r\n * @param _uniformBuffer the uniform buffer (unused — we bind directly on the effect)\r\n * @param _scene the current scene\r\n * @param _engine the current engine\r\n * @param subMesh the submesh being rendered\r\n */\r\n public override bindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, subMesh: SubMesh): void {\r\n const effect = subMesh.effect;\r\n if (!effect) {\r\n return;\r\n }\r\n\r\n if (this._isCompound) {\r\n effect.setArray3(\"partPickingColors\", this._partPickingColors);\r\n // default all visible when setPartActive hasn't been called\r\n const visibility = this._partVisibility.length > 0 ? this._partVisibility : new Array(this._maxPartCount).fill(1.0);\r\n effect.setArray(\"partVisibility\", visibility);\r\n } else {\r\n effect.setFloat3(\"pickingColor\", this._pickingColor[0], this._pickingColor[1], this._pickingColor[2]);\r\n }\r\n }\r\n}\r\n\r\nRegisterClass(\"BABYLON.GaussianSplattingGpuPickingMaterialPlugin\", GaussianSplattingGpuPickingMaterialPlugin);\r\n"]}
1
+ {"version":3,"file":"gaussianSplattingGpuPickingMaterialPlugin.js","sourceRoot":"","sources":["../../../../../dev/core/src/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"../../types\";\r\nimport { type Scene } from \"../../scene\";\r\nimport { type AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { type SubMesh } from \"../../Meshes/subMesh\";\r\nimport { type UniformBuffer } from \"../uniformBuffer\";\r\nimport { type MaterialDefines } from \"../materialDefines\";\r\nimport { MaterialPluginBase } from \"../materialPluginBase\";\r\nimport { ShaderLanguage } from \"../shaderLanguage\";\r\nimport { RegisterClass } from \"../../Misc/typeStore\";\r\nimport { GetGaussianSplattingMaxPartCount, type GaussianSplattingMaterial } from \"./gaussianSplattingMaterial\";\r\n\r\n/**\r\n * Plugin for GaussianSplattingMaterial that replaces per-splat color output with\r\n * a pre-computed picking color for GPU-based hit testing.\r\n *\r\n * The picking color is computed on the CPU by encoding a 24-bit picking ID as RGB\r\n * (matching the readback decoding in GPUPicker).\r\n * @experimental\r\n */\r\nexport class GaussianSplattingGpuPickingMaterialPlugin extends MaterialPluginBase {\r\n private _pickingColor: [number, number, number] = [0, 0, 0];\r\n private _isCompound: boolean = false;\r\n private _partPickingColors: number[] = [];\r\n private _partVisibility: number[] = [];\r\n private _defaultPartVisibility: number[] = [];\r\n private _maxPartCount: number;\r\n\r\n /**\r\n * Creates a new GaussianSplattingGpuPickingMaterialPlugin.\r\n * @param material The GaussianSplattingMaterial to attach the plugin to.\r\n * @param maxPartCount The maximum number of parts supported for compound meshes.\r\n */\r\n constructor(material: GaussianSplattingMaterial, maxPartCount?: number) {\r\n super(material, \"GaussianSplatGpuPicking\", 200);\r\n\r\n this._maxPartCount = maxPartCount ?? GetGaussianSplattingMaxPartCount(material.getScene().getEngine());\r\n this._defaultPartVisibility = new Array(this._maxPartCount).fill(1.0);\r\n this._enable(true);\r\n }\r\n\r\n /**\r\n * Encodes a 24-bit picking ID into normalized RGB components.\r\n * @param id The picking ID to encode\r\n * @returns A tuple [r, g, b] with values in [0, 1]\r\n */\r\n public static EncodeIdToColor(id: number): [number, number, number] {\r\n return [((id >> 16) & 0xff) / 255, ((id >> 8) & 0xff) / 255, (id & 0xff) / 255];\r\n }\r\n\r\n /**\r\n * Sets the picking color for a non-compound mesh from a picking ID.\r\n * The ID is encoded into an RGB color on the CPU.\r\n * @param id The 24-bit picking ID.\r\n */\r\n public set meshId(id: number) {\r\n this._pickingColor = GaussianSplattingGpuPickingMaterialPlugin.EncodeIdToColor(id);\r\n }\r\n\r\n /**\r\n * Sets whether this material is for a compound mesh with per-part picking.\r\n */\r\n public set isCompound(value: boolean) {\r\n this._isCompound = value;\r\n this.markAllDefinesAsDirty();\r\n }\r\n\r\n /**\r\n * Gets whether this material is for a compound mesh with per-part picking.\r\n */\r\n public get isCompound(): boolean {\r\n return this._isCompound;\r\n }\r\n\r\n /**\r\n * Sets the per-part picking colors from an array of picking IDs.\r\n * Each ID is encoded into an RGB color on the CPU.\r\n * @param ids Array mapping part index to picking ID.\r\n */\r\n public set partMeshIds(ids: number[]) {\r\n const colors: number[] = [];\r\n for (let i = 0; i < this._maxPartCount; i++) {\r\n const c = i < ids.length ? GaussianSplattingGpuPickingMaterialPlugin.EncodeIdToColor(ids[i]) : ([0, 0, 0] as [number, number, number]);\r\n colors.push(c[0], c[1], c[2]);\r\n }\r\n this._partPickingColors = colors;\r\n }\r\n\r\n /**\r\n * Sets which parts are active (pickable) for the compound picking pass.\r\n * Parts not in the set are discarded in the shader by overriding partVisibility to 0.\r\n * @param activeParts Array of part indices that should be pickable.\r\n */\r\n public setPartActive(activeParts: number[]): void {\r\n const visibility = this._partVisibility;\r\n visibility.length = this._maxPartCount;\r\n visibility.fill(0.0);\r\n for (const index of activeParts) {\r\n if (index >= 0 && index < this._maxPartCount) {\r\n visibility[index] = 1.0;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @returns the class name\r\n */\r\n public override getClassName(): string {\r\n return \"GaussianSplattingGpuPickingMaterialPlugin\";\r\n }\r\n\r\n /**\r\n * Indicates this plugin supports both GLSL and WGSL.\r\n * @param shaderLanguage the shader language to check\r\n * @returns true for GLSL and WGSL\r\n */\r\n public override isCompatible(shaderLanguage: ShaderLanguage): boolean {\r\n switch (shaderLanguage) {\r\n case ShaderLanguage.GLSL:\r\n case ShaderLanguage.WGSL:\r\n return true;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Always ready — no textures or async resources to wait on.\r\n * @param _defines the defines\r\n * @param _scene the scene\r\n * @param _engine the engine\r\n * @param _subMesh the submesh\r\n * @returns true\r\n */\r\n public override isReadyForSubMesh(_defines: MaterialDefines, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns custom shader code to inject GPU picking color output.\r\n *\r\n * @param shaderType \"vertex\" or \"fragment\"\r\n * @param shaderLanguage the shader language to use (default: GLSL)\r\n * @returns null or a map of injection point names to code strings\r\n */\r\n public override getCustomCode(shaderType: string, shaderLanguage = ShaderLanguage.GLSL): Nullable<{ [pointName: string]: string }> {\r\n if (shaderLanguage === ShaderLanguage.WGSL) {\r\n return this._getCustomCodeWGSL(shaderType);\r\n }\r\n return this._getCustomCodeGLSL(shaderType);\r\n }\r\n\r\n private _getCustomCodeGLSL(shaderType: string): Nullable<{ [pointName: string]: string }> {\r\n if (shaderType === \"vertex\") {\r\n return {\r\n CUSTOM_VERTEX_DEFINITIONS: `varying float vPartIndex;`,\r\n CUSTOM_VERTEX_UPDATE: `\r\n#if IS_COMPOUND\r\n vPartIndex = float(splat.partIndex);\r\n#else\r\n vPartIndex = 0.0;\r\n#endif\r\n `,\r\n };\r\n } else if (shaderType === \"fragment\") {\r\n return {\r\n CUSTOM_FRAGMENT_DEFINITIONS: `\r\nvarying float vPartIndex;\r\n#if IS_COMPOUND\r\nuniform vec3 partPickingColors[${this._maxPartCount}];\r\n#else\r\nuniform vec3 pickingColor;\r\n#endif\r\n `,\r\n CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n#if IS_COMPOUND\r\n if (vColor.a < 0.001) discard;\r\n finalColor = vec4(partPickingColors[int(vPartIndex + 0.5)], 1.0);\r\n#else\r\n if (vColor.a < 0.001) discard;\r\n finalColor = vec4(pickingColor, 1.0);\r\n#endif\r\n `,\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n private _getCustomCodeWGSL(shaderType: string): Nullable<{ [pointName: string]: string }> {\r\n if (shaderType === \"vertex\") {\r\n return {\r\n CUSTOM_VERTEX_DEFINITIONS: `varying vPartIndex: f32;`,\r\n CUSTOM_VERTEX_UPDATE: `\r\n#if IS_COMPOUND\r\n vertexOutputs.vPartIndex = f32(splat.partIndex);\r\n#else\r\n vertexOutputs.vPartIndex = 0.0;\r\n#endif\r\n `,\r\n };\r\n } else if (shaderType === \"fragment\") {\r\n return {\r\n CUSTOM_FRAGMENT_DEFINITIONS: `\r\nvarying vPartIndex: f32;\r\n#if IS_COMPOUND\r\nuniform partPickingColors: array<vec3f, ${this._maxPartCount}>;\r\n#else\r\nuniform pickingColor: vec3f;\r\n#endif\r\n `,\r\n CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `\r\n#if IS_COMPOUND\r\n if (fragmentInputs.vColor.a < 0.001) { discard; }\r\n finalColor = vec4f(uniforms.partPickingColors[i32(fragmentInputs.vPartIndex + 0.5)], 1.0);\r\n#else\r\n if (fragmentInputs.vColor.a < 0.001) { discard; }\r\n finalColor = vec4f(uniforms.pickingColor, 1.0);\r\n#endif\r\n `,\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Registers the picking uniforms with the engine.\r\n * @returns uniform descriptions\r\n */\r\n public override getUniforms(): {\r\n ubo?: Array<{ name: string; size?: number; type?: string; arraySize?: number }>;\r\n vertex?: string;\r\n fragment?: string;\r\n externalUniforms?: string[];\r\n } {\r\n return {\r\n externalUniforms: [\"pickingColor\", \"partPickingColors\"],\r\n };\r\n }\r\n\r\n /**\r\n * Binds the picking color uniform(s) each frame.\r\n * @param _uniformBuffer the uniform buffer (unused — we bind directly on the effect)\r\n * @param _scene the current scene\r\n * @param _engine the current engine\r\n * @param subMesh the submesh being rendered\r\n */\r\n public override bindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, subMesh: SubMesh): void {\r\n const effect = subMesh.effect;\r\n if (!effect) {\r\n return;\r\n }\r\n\r\n if (this._isCompound) {\r\n effect.setArray3(\"partPickingColors\", this._partPickingColors);\r\n // default all visible when setPartActive hasn't been called\r\n const visibility = this._partVisibility.length > 0 ? this._partVisibility : this._defaultPartVisibility;\r\n effect.setArray(\"partVisibility\", visibility);\r\n } else {\r\n effect.setFloat3(\"pickingColor\", this._pickingColor[0], this._pickingColor[1], this._pickingColor[2]);\r\n }\r\n }\r\n}\r\n\r\nRegisterClass(\"BABYLON.GaussianSplattingGpuPickingMaterialPlugin\", GaussianSplattingGpuPickingMaterialPlugin);\r\n"]}
@@ -118,6 +118,8 @@ export declare class GaussianSplattingMaterial extends PushMaterial {
118
118
  bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
119
119
  protected static _BindEffectUniforms(gsMesh: GaussianSplattingMesh, gsMaterial: GaussianSplattingMaterial, shaderMaterial: ShaderMaterial, scene: Scene): void;
120
120
  private _voxelMissingTextureWarned;
121
+ private _voxelPartWorldData;
122
+ private readonly _voxelPartVisibilityData;
121
123
  protected _bindVoxelEffectUniforms(gsMesh: GaussianSplattingMesh, gsMaterial: GaussianSplattingMaterial, shaderMaterial: ShaderMaterial): boolean;
122
124
  /**
123
125
  * Create a voxel rendering material for a Gaussian Splatting mesh, for use with IBL shadow voxelization.
@@ -102,6 +102,8 @@ export class GaussianSplattingMaterial extends PushMaterial {
102
102
  this._isDirty = false;
103
103
  this._sourceMesh = null;
104
104
  this._voxelMissingTextureWarned = new Set();
105
+ this._voxelPartWorldData = new Float32Array(0);
106
+ this._voxelPartVisibilityData = [];
105
107
  this.backFaceCulling = false;
106
108
  this.shadowDepthWrapper = GaussianSplattingMaterial._MakeGaussianSplattingShadowDepthWrapper(scene, this.shaderLanguage);
107
109
  }
@@ -451,14 +453,19 @@ export class GaussianSplattingMaterial extends PushMaterial {
451
453
  effect.setTexture("colorsTexture", gsMesh.colorsTexture);
452
454
  if (gsMesh.partIndicesTexture) {
453
455
  effect.setTexture("partIndicesTexture", gsMesh.partIndicesTexture);
454
- const partWorldData = new Float32Array(gsMesh.partCount * 16);
456
+ const partWorldDataLength = gsMesh.partCount * 16;
457
+ if (this._voxelPartWorldData.length !== partWorldDataLength) {
458
+ this._voxelPartWorldData = new Float32Array(partWorldDataLength);
459
+ }
460
+ const partWorldData = this._voxelPartWorldData;
455
461
  for (let i = 0; i < gsMesh.partCount; i++) {
456
462
  gsMesh.getWorldMatrixForPart(i).toArray(partWorldData, i * 16);
457
463
  }
458
464
  effect.setMatrices("partWorld", partWorldData);
459
- const partVisibilityData = [];
465
+ const partVisibilityData = this._voxelPartVisibilityData;
466
+ partVisibilityData.length = gsMesh.partCount;
460
467
  for (let i = 0; i < gsMesh.partCount; i++) {
461
- partVisibilityData.push(gsMesh.partVisibility[i] ?? 1.0);
468
+ partVisibilityData[i] = gsMesh.partVisibility[i] ?? 1.0;
462
469
  }
463
470
  effect.setArray("partVisibility", partVisibilityData);
464
471
  }