@babylonjs/core 8.50.5 → 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 (77) hide show
  1. package/Animations/animation.d.ts +6 -2
  2. package/Animations/animation.js +28 -4
  3. package/Animations/animation.js.map +1 -1
  4. package/Animations/animationGroup.d.ts +2 -1
  5. package/Animations/animationGroup.js +3 -2
  6. package/Animations/animationGroup.js.map +1 -1
  7. package/Animations/animatorAvatar.d.ts +161 -0
  8. package/Animations/animatorAvatar.js +573 -0
  9. package/Animations/animatorAvatar.js.map +1 -0
  10. package/Animations/index.d.ts +1 -0
  11. package/Animations/index.js +1 -0
  12. package/Animations/index.js.map +1 -1
  13. package/AudioV2/webAudio/webAudioSoundSource.d.ts +2 -2
  14. package/AudioV2/webAudio/webAudioSoundSource.js +12 -2
  15. package/AudioV2/webAudio/webAudioSoundSource.js.map +1 -1
  16. package/Bones/index.d.ts +1 -0
  17. package/Bones/index.js +1 -0
  18. package/Bones/index.js.map +1 -1
  19. package/Bones/skeleton.d.ts +13 -0
  20. package/Bones/skeleton.functions.d.ts +26 -0
  21. package/Bones/skeleton.functions.js +91 -0
  22. package/Bones/skeleton.functions.js.map +1 -0
  23. package/Bones/skeleton.js +26 -0
  24. package/Bones/skeleton.js.map +1 -1
  25. package/Cameras/geospatialCamera.js +21 -20
  26. package/Cameras/geospatialCamera.js.map +1 -1
  27. package/Cameras/geospatialCameraMovement.d.ts +8 -1
  28. package/Cameras/geospatialCameraMovement.js +29 -8
  29. package/Cameras/geospatialCameraMovement.js.map +1 -1
  30. package/Collisions/gpuPicker.d.ts +11 -0
  31. package/Collisions/gpuPicker.js +148 -19
  32. package/Collisions/gpuPicker.js.map +1 -1
  33. package/Debug/skeletonViewer.d.ts +4 -8
  34. package/Debug/skeletonViewer.js +13 -22
  35. package/Debug/skeletonViewer.js.map +1 -1
  36. package/Engines/abstractEngine.js +2 -2
  37. package/Engines/abstractEngine.js.map +1 -1
  38. package/Instrumentation/engineInstrumentation.js +2 -1
  39. package/Instrumentation/engineInstrumentation.js.map +1 -1
  40. package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.d.ts +109 -0
  41. package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.js +210 -0
  42. package/Materials/GaussianSplatting/gaussianSplattingGpuPickingMaterialPlugin.js.map +1 -0
  43. package/Materials/GaussianSplatting/gaussianSplattingMaterial.d.ts +1 -0
  44. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +56 -15
  45. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
  46. package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.d.ts +86 -0
  47. package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.js +161 -0
  48. package/Materials/GaussianSplatting/gaussianSplattingSolidColorMaterialPlugin.js.map +1 -0
  49. package/Materials/index.d.ts +2 -0
  50. package/Materials/index.js +2 -0
  51. package/Materials/index.js.map +1 -1
  52. package/Maths/math.constants.d.ts +2 -1
  53. package/Maths/math.constants.js +3 -2
  54. package/Maths/math.constants.js.map +1 -1
  55. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +17 -1
  56. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
  57. package/Misc/dataStorage.d.ts +13 -0
  58. package/Misc/dataStorage.js +25 -0
  59. package/Misc/dataStorage.js.map +1 -1
  60. package/Morph/morphTarget.d.ts +9 -5
  61. package/Morph/morphTarget.js +15 -7
  62. package/Morph/morphTarget.js.map +1 -1
  63. package/Morph/morphTargetManager.d.ts +3 -1
  64. package/Morph/morphTargetManager.js +5 -2
  65. package/Morph/morphTargetManager.js.map +1 -1
  66. package/Physics/v2/Plugins/havokPlugin.d.ts +14 -1
  67. package/Physics/v2/Plugins/havokPlugin.js +154 -10
  68. package/Physics/v2/Plugins/havokPlugin.js.map +1 -1
  69. package/Shaders/gaussianSplatting.fragment.js +8 -2
  70. package/Shaders/gaussianSplatting.fragment.js.map +1 -1
  71. package/Shaders/gaussianSplatting.vertex.js +8 -2
  72. package/Shaders/gaussianSplatting.vertex.js.map +1 -1
  73. package/ShadersWGSL/gaussianSplatting.fragment.js +7 -1
  74. package/ShadersWGSL/gaussianSplatting.fragment.js.map +1 -1
  75. package/ShadersWGSL/gaussianSplatting.vertex.js +8 -2
  76. package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
  77. package/package.json +1 -1
@@ -53,7 +53,8 @@ export class EngineInstrumentation {
53
53
  this._shaderCompilationTime.beginMonitoring();
54
54
  });
55
55
  this._onAfterShaderCompilationObserver = this.engine.onAfterShaderCompilationObservable.add(() => {
56
- this._shaderCompilationTime.endMonitoring();
56
+ this._shaderCompilationTime.endMonitoring(false);
57
+ this._shaderCompilationTime.endFrame();
57
58
  });
58
59
  }
59
60
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"engineInstrumentation.js","sourceRoot":"","sources":["../../../../dev/core/src/Instrumentation/engineInstrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Observer } from \"../Misc/observable\";\r\nimport { PerfCounter } from \"../Misc/perfCounter\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { IDisposable } from \"../scene\";\r\nimport type { AbstractEngine } from \"../Engines/abstractEngine\";\r\n/**\r\n * This class can be used to get instrumentation data from a Babylon engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n */\r\nexport class EngineInstrumentation implements IDisposable {\r\n private _captureGPUFrameTime = false;\r\n\r\n private _captureShaderCompilationTime = false;\r\n private _shaderCompilationTime = new PerfCounter();\r\n\r\n // Observers\r\n private _onBeginFrameObserver: Nullable<Observer<AbstractEngine>> = null;\r\n private _onEndFrameObserver: Nullable<Observer<AbstractEngine>> = null;\r\n private _onBeforeShaderCompilationObserver: Nullable<Observer<AbstractEngine>> = null;\r\n private _onAfterShaderCompilationObserver: Nullable<Observer<AbstractEngine>> = null;\r\n\r\n private _disposed = false;\r\n\r\n // Properties\r\n /**\r\n * Gets the perf counter used for GPU frame time\r\n */\r\n public get gpuFrameTimeCounter(): PerfCounter {\r\n return this.engine.getGPUFrameTimeCounter();\r\n }\r\n\r\n /**\r\n * Gets the GPU frame time capture status\r\n */\r\n public get captureGPUFrameTime(): boolean {\r\n return this._captureGPUFrameTime;\r\n }\r\n\r\n /**\r\n * Enable or disable the GPU frame time capture\r\n */\r\n public set captureGPUFrameTime(value: boolean) {\r\n if (value === this._captureGPUFrameTime) {\r\n return;\r\n }\r\n\r\n this._captureGPUFrameTime = value;\r\n this.engine.captureGPUFrameTime(value);\r\n }\r\n\r\n /**\r\n * Gets the perf counter used for shader compilation time\r\n */\r\n public get shaderCompilationTimeCounter(): PerfCounter {\r\n return this._shaderCompilationTime;\r\n }\r\n\r\n /**\r\n * Gets the shader compilation time capture status\r\n */\r\n public get captureShaderCompilationTime(): boolean {\r\n return this._captureShaderCompilationTime;\r\n }\r\n\r\n /**\r\n * Enable or disable the shader compilation time capture\r\n */\r\n public set captureShaderCompilationTime(value: boolean) {\r\n if (value === this._captureShaderCompilationTime) {\r\n return;\r\n }\r\n\r\n this._captureShaderCompilationTime = value;\r\n\r\n if (value) {\r\n this._onBeforeShaderCompilationObserver = this.engine.onBeforeShaderCompilationObservable.add(() => {\r\n this._shaderCompilationTime.fetchNewFrame();\r\n this._shaderCompilationTime.beginMonitoring();\r\n });\r\n\r\n this._onAfterShaderCompilationObserver = this.engine.onAfterShaderCompilationObservable.add(() => {\r\n this._shaderCompilationTime.endMonitoring();\r\n });\r\n } else {\r\n this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);\r\n this._onBeforeShaderCompilationObserver = null;\r\n this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);\r\n this._onAfterShaderCompilationObserver = null;\r\n }\r\n }\r\n\r\n /**\r\n * Instantiates a new engine instrumentation.\r\n * This class can be used to get instrumentation data from a Babylon engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n * @param engine Defines the engine to instrument\r\n */\r\n public constructor(\r\n /**\r\n * Define the instrumented engine.\r\n */\r\n public engine: AbstractEngine\r\n ) {}\r\n\r\n /**\r\n * Dispose and release associated resources.\r\n */\r\n public dispose() {\r\n if (this._disposed) {\r\n return;\r\n }\r\n\r\n this.engine.onBeginFrameObservable.remove(this._onBeginFrameObserver);\r\n this._onBeginFrameObserver = null;\r\n\r\n this.engine.onEndFrameObservable.remove(this._onEndFrameObserver);\r\n this._onEndFrameObserver = null;\r\n\r\n this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);\r\n this._onBeforeShaderCompilationObserver = null;\r\n\r\n this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);\r\n this._onAfterShaderCompilationObserver = null;\r\n\r\n (<any>this.engine) = null;\r\n this._disposed = true;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"engineInstrumentation.js","sourceRoot":"","sources":["../../../../dev/core/src/Instrumentation/engineInstrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Observer } from \"../Misc/observable\";\r\nimport { PerfCounter } from \"../Misc/perfCounter\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { IDisposable } from \"../scene\";\r\nimport type { AbstractEngine } from \"../Engines/abstractEngine\";\r\n/**\r\n * This class can be used to get instrumentation data from a Babylon engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n */\r\nexport class EngineInstrumentation implements IDisposable {\r\n private _captureGPUFrameTime = false;\r\n\r\n private _captureShaderCompilationTime = false;\r\n private _shaderCompilationTime = new PerfCounter();\r\n\r\n // Observers\r\n private _onBeginFrameObserver: Nullable<Observer<AbstractEngine>> = null;\r\n private _onEndFrameObserver: Nullable<Observer<AbstractEngine>> = null;\r\n private _onBeforeShaderCompilationObserver: Nullable<Observer<AbstractEngine>> = null;\r\n private _onAfterShaderCompilationObserver: Nullable<Observer<AbstractEngine>> = null;\r\n\r\n private _disposed = false;\r\n\r\n // Properties\r\n /**\r\n * Gets the perf counter used for GPU frame time\r\n */\r\n public get gpuFrameTimeCounter(): PerfCounter {\r\n return this.engine.getGPUFrameTimeCounter();\r\n }\r\n\r\n /**\r\n * Gets the GPU frame time capture status\r\n */\r\n public get captureGPUFrameTime(): boolean {\r\n return this._captureGPUFrameTime;\r\n }\r\n\r\n /**\r\n * Enable or disable the GPU frame time capture\r\n */\r\n public set captureGPUFrameTime(value: boolean) {\r\n if (value === this._captureGPUFrameTime) {\r\n return;\r\n }\r\n\r\n this._captureGPUFrameTime = value;\r\n this.engine.captureGPUFrameTime(value);\r\n }\r\n\r\n /**\r\n * Gets the perf counter used for shader compilation time\r\n */\r\n public get shaderCompilationTimeCounter(): PerfCounter {\r\n return this._shaderCompilationTime;\r\n }\r\n\r\n /**\r\n * Gets the shader compilation time capture status\r\n */\r\n public get captureShaderCompilationTime(): boolean {\r\n return this._captureShaderCompilationTime;\r\n }\r\n\r\n /**\r\n * Enable or disable the shader compilation time capture\r\n */\r\n public set captureShaderCompilationTime(value: boolean) {\r\n if (value === this._captureShaderCompilationTime) {\r\n return;\r\n }\r\n\r\n this._captureShaderCompilationTime = value;\r\n\r\n if (value) {\r\n this._onBeforeShaderCompilationObserver = this.engine.onBeforeShaderCompilationObservable.add(() => {\r\n this._shaderCompilationTime.fetchNewFrame();\r\n this._shaderCompilationTime.beginMonitoring();\r\n });\r\n\r\n this._onAfterShaderCompilationObserver = this.engine.onAfterShaderCompilationObservable.add(() => {\r\n this._shaderCompilationTime.endMonitoring(false);\r\n this._shaderCompilationTime.endFrame();\r\n });\r\n } else {\r\n this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);\r\n this._onBeforeShaderCompilationObserver = null;\r\n this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);\r\n this._onAfterShaderCompilationObserver = null;\r\n }\r\n }\r\n\r\n /**\r\n * Instantiates a new engine instrumentation.\r\n * This class can be used to get instrumentation data from a Babylon engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n * @param engine Defines the engine to instrument\r\n */\r\n public constructor(\r\n /**\r\n * Define the instrumented engine.\r\n */\r\n public engine: AbstractEngine\r\n ) {}\r\n\r\n /**\r\n * Dispose and release associated resources.\r\n */\r\n public dispose() {\r\n if (this._disposed) {\r\n return;\r\n }\r\n\r\n this.engine.onBeginFrameObservable.remove(this._onBeginFrameObserver);\r\n this._onBeginFrameObserver = null;\r\n\r\n this.engine.onEndFrameObservable.remove(this._onEndFrameObserver);\r\n this._onEndFrameObserver = null;\r\n\r\n this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);\r\n this._onBeforeShaderCompilationObserver = null;\r\n\r\n this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);\r\n this._onAfterShaderCompilationObserver = null;\r\n\r\n (<any>this.engine) = null;\r\n this._disposed = true;\r\n }\r\n}\r\n"]}
@@ -0,0 +1,109 @@
1
+ import type { Nullable } from "../../types.js";
2
+ import type { Scene } from "../../scene.js";
3
+ import type { AbstractEngine } from "../../Engines/abstractEngine.js";
4
+ import type { SubMesh } from "../../Meshes/subMesh.js";
5
+ import type { UniformBuffer } from "../uniformBuffer.js";
6
+ import type { MaterialDefines } from "../materialDefines.js";
7
+ import { MaterialPluginBase } from "../materialPluginBase.js";
8
+ import { ShaderLanguage } from "../shaderLanguage.js";
9
+ import type { GaussianSplattingMaterial } from "./gaussianSplattingMaterial.js";
10
+ /**
11
+ * Plugin for GaussianSplattingMaterial that replaces per-splat color output with
12
+ * a pre-computed picking color for GPU-based hit testing.
13
+ *
14
+ * The picking color is computed on the CPU by encoding a 24-bit picking ID as RGB
15
+ * (matching the readback decoding in GPUPicker).
16
+ * @experimental
17
+ */
18
+ export declare class GaussianSplattingGpuPickingMaterialPlugin extends MaterialPluginBase {
19
+ private _pickingColor;
20
+ private _isCompound;
21
+ private _partPickingColors;
22
+ private _maxPartCount;
23
+ /**
24
+ * Creates a new GaussianSplattingGpuPickingMaterialPlugin.
25
+ * @param material The GaussianSplattingMaterial to attach the plugin to.
26
+ * @param maxPartCount The maximum number of parts supported for compound meshes.
27
+ */
28
+ constructor(material: GaussianSplattingMaterial, maxPartCount?: number);
29
+ /**
30
+ * Encodes a 24-bit picking ID into normalized RGB components.
31
+ * @param id The picking ID to encode
32
+ * @returns A tuple [r, g, b] with values in [0, 1]
33
+ */
34
+ static EncodeIdToColor(id: number): [number, number, number];
35
+ /**
36
+ * Sets the picking color for a non-compound mesh from a picking ID.
37
+ * The ID is encoded into an RGB color on the CPU.
38
+ * @param id The 24-bit picking ID.
39
+ */
40
+ set meshId(id: number);
41
+ /**
42
+ * Sets whether this material is for a compound mesh with per-part picking.
43
+ */
44
+ set isCompound(value: boolean);
45
+ /**
46
+ * Gets whether this material is for a compound mesh with per-part picking.
47
+ */
48
+ get isCompound(): boolean;
49
+ /**
50
+ * Sets the per-part picking colors from an array of picking IDs.
51
+ * Each ID is encoded into an RGB color on the CPU.
52
+ * @param ids Array mapping part index to picking ID.
53
+ */
54
+ set partMeshIds(ids: number[]);
55
+ /**
56
+ * @returns the class name
57
+ */
58
+ getClassName(): string;
59
+ /**
60
+ * Indicates this plugin supports both GLSL and WGSL.
61
+ * @param shaderLanguage the shader language to check
62
+ * @returns true for GLSL and WGSL
63
+ */
64
+ isCompatible(shaderLanguage: ShaderLanguage): boolean;
65
+ /**
66
+ * Always ready — no textures or async resources to wait on.
67
+ * @param _defines the defines
68
+ * @param _scene the scene
69
+ * @param _engine the engine
70
+ * @param _subMesh the submesh
71
+ * @returns true
72
+ */
73
+ isReadyForSubMesh(_defines: MaterialDefines, _scene: Scene, _engine: AbstractEngine, _subMesh: SubMesh): boolean;
74
+ /**
75
+ * Returns custom shader code to inject GPU picking color output.
76
+ *
77
+ * @param shaderType "vertex" or "fragment"
78
+ * @param shaderLanguage the shader language to use (default: GLSL)
79
+ * @returns null or a map of injection point names to code strings
80
+ */
81
+ getCustomCode(shaderType: string, shaderLanguage?: ShaderLanguage): Nullable<{
82
+ [pointName: string]: string;
83
+ }>;
84
+ private _getCustomCodeGLSL;
85
+ private _getCustomCodeWGSL;
86
+ /**
87
+ * Registers the picking uniforms with the engine.
88
+ * @returns uniform descriptions
89
+ */
90
+ getUniforms(): {
91
+ ubo?: Array<{
92
+ name: string;
93
+ size?: number;
94
+ type?: string;
95
+ arraySize?: number;
96
+ }>;
97
+ vertex?: string;
98
+ fragment?: string;
99
+ externalUniforms?: string[];
100
+ };
101
+ /**
102
+ * Binds the picking color uniform(s) each frame.
103
+ * @param _uniformBuffer the uniform buffer (unused — we bind directly on the effect)
104
+ * @param _scene the current scene
105
+ * @param _engine the current engine
106
+ * @param subMesh the submesh being rendered
107
+ */
108
+ bindForSubMesh(_uniformBuffer: UniformBuffer, _scene: Scene, _engine: AbstractEngine, subMesh: SubMesh): void;
109
+ }
@@ -0,0 +1,210 @@
1
+ import { MaterialPluginBase } from "../materialPluginBase.js";
2
+ import { RegisterClass } from "../../Misc/typeStore.js";
3
+ import { GaussianSplattingMaxPartCount } from "./gaussianSplattingMaterial.js";
4
+ /**
5
+ * Plugin for GaussianSplattingMaterial that replaces per-splat color output with
6
+ * a pre-computed picking color for GPU-based hit testing.
7
+ *
8
+ * The picking color is computed on the CPU by encoding a 24-bit picking ID as RGB
9
+ * (matching the readback decoding in GPUPicker).
10
+ * @experimental
11
+ */
12
+ export class GaussianSplattingGpuPickingMaterialPlugin extends MaterialPluginBase {
13
+ /**
14
+ * Creates a new GaussianSplattingGpuPickingMaterialPlugin.
15
+ * @param material The GaussianSplattingMaterial to attach the plugin to.
16
+ * @param maxPartCount The maximum number of parts supported for compound meshes.
17
+ */
18
+ constructor(material, maxPartCount = GaussianSplattingMaxPartCount) {
19
+ super(material, "GaussianSplatGpuPicking", 200);
20
+ this._pickingColor = [0, 0, 0];
21
+ this._isCompound = false;
22
+ this._partPickingColors = [];
23
+ this._maxPartCount = maxPartCount;
24
+ this._enable(true);
25
+ }
26
+ /**
27
+ * Encodes a 24-bit picking ID into normalized RGB components.
28
+ * @param id The picking ID to encode
29
+ * @returns A tuple [r, g, b] with values in [0, 1]
30
+ */
31
+ static EncodeIdToColor(id) {
32
+ return [((id >> 16) & 0xff) / 255, ((id >> 8) & 0xff) / 255, (id & 0xff) / 255];
33
+ }
34
+ /**
35
+ * Sets the picking color for a non-compound mesh from a picking ID.
36
+ * The ID is encoded into an RGB color on the CPU.
37
+ * @param id The 24-bit picking ID.
38
+ */
39
+ set meshId(id) {
40
+ this._pickingColor = GaussianSplattingGpuPickingMaterialPlugin.EncodeIdToColor(id);
41
+ }
42
+ /**
43
+ * Sets whether this material is for a compound mesh with per-part picking.
44
+ */
45
+ set isCompound(value) {
46
+ this._isCompound = value;
47
+ this.markAllDefinesAsDirty();
48
+ }
49
+ /**
50
+ * Gets whether this material is for a compound mesh with per-part picking.
51
+ */
52
+ get isCompound() {
53
+ return this._isCompound;
54
+ }
55
+ /**
56
+ * Sets the per-part picking colors from an array of picking IDs.
57
+ * Each ID is encoded into an RGB color on the CPU.
58
+ * @param ids Array mapping part index to picking ID.
59
+ */
60
+ set partMeshIds(ids) {
61
+ const colors = [];
62
+ for (let i = 0; i < this._maxPartCount; i++) {
63
+ const c = i < ids.length ? GaussianSplattingGpuPickingMaterialPlugin.EncodeIdToColor(ids[i]) : [0, 0, 0];
64
+ colors.push(c[0], c[1], c[2]);
65
+ }
66
+ this._partPickingColors = colors;
67
+ }
68
+ /**
69
+ * @returns the class name
70
+ */
71
+ getClassName() {
72
+ return "GaussianSplattingGpuPickingMaterialPlugin";
73
+ }
74
+ /**
75
+ * Indicates this plugin supports both GLSL and WGSL.
76
+ * @param shaderLanguage the shader language to check
77
+ * @returns true for GLSL and WGSL
78
+ */
79
+ isCompatible(shaderLanguage) {
80
+ switch (shaderLanguage) {
81
+ case 0 /* ShaderLanguage.GLSL */:
82
+ case 1 /* ShaderLanguage.WGSL */:
83
+ return true;
84
+ default:
85
+ return false;
86
+ }
87
+ }
88
+ /**
89
+ * Always ready — no textures or async resources to wait on.
90
+ * @param _defines the defines
91
+ * @param _scene the scene
92
+ * @param _engine the engine
93
+ * @param _subMesh the submesh
94
+ * @returns true
95
+ */
96
+ isReadyForSubMesh(_defines, _scene, _engine, _subMesh) {
97
+ return true;
98
+ }
99
+ /**
100
+ * Returns custom shader code to inject GPU picking color output.
101
+ *
102
+ * @param shaderType "vertex" or "fragment"
103
+ * @param shaderLanguage the shader language to use (default: GLSL)
104
+ * @returns null or a map of injection point names to code strings
105
+ */
106
+ getCustomCode(shaderType, shaderLanguage = 0 /* ShaderLanguage.GLSL */) {
107
+ if (shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
108
+ return this._getCustomCodeWGSL(shaderType);
109
+ }
110
+ return this._getCustomCodeGLSL(shaderType);
111
+ }
112
+ _getCustomCodeGLSL(shaderType) {
113
+ if (shaderType === "vertex") {
114
+ return {
115
+ CUSTOM_VERTEX_DEFINITIONS: `varying float vPartIndex;`,
116
+ CUSTOM_VERTEX_UPDATE: `
117
+ #if IS_COMPOUND
118
+ vPartIndex = float(splat.partIndex);
119
+ #else
120
+ vPartIndex = 0.0;
121
+ #endif
122
+ `,
123
+ };
124
+ }
125
+ else if (shaderType === "fragment") {
126
+ return {
127
+ CUSTOM_FRAGMENT_DEFINITIONS: `
128
+ varying float vPartIndex;
129
+ #if IS_COMPOUND
130
+ uniform vec3 partPickingColors[${this._maxPartCount}];
131
+ #else
132
+ uniform vec3 pickingColor;
133
+ #endif
134
+ `,
135
+ CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `
136
+ #if IS_COMPOUND
137
+ finalColor = vec4(partPickingColors[int(vPartIndex + 0.5)], 1.0);
138
+ #else
139
+ finalColor = vec4(pickingColor, 1.0);
140
+ #endif
141
+ `,
142
+ };
143
+ }
144
+ return null;
145
+ }
146
+ _getCustomCodeWGSL(shaderType) {
147
+ if (shaderType === "vertex") {
148
+ return {
149
+ CUSTOM_VERTEX_DEFINITIONS: `varying vPartIndex: f32;`,
150
+ CUSTOM_VERTEX_UPDATE: `
151
+ #if IS_COMPOUND
152
+ vertexOutputs.vPartIndex = f32(splat.partIndex);
153
+ #else
154
+ vertexOutputs.vPartIndex = 0.0;
155
+ #endif
156
+ `,
157
+ };
158
+ }
159
+ else if (shaderType === "fragment") {
160
+ return {
161
+ CUSTOM_FRAGMENT_DEFINITIONS: `
162
+ varying vPartIndex: f32;
163
+ #if IS_COMPOUND
164
+ uniform partPickingColors: array<vec3f, ${this._maxPartCount}>;
165
+ #else
166
+ uniform pickingColor: vec3f;
167
+ #endif
168
+ `,
169
+ CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR: `
170
+ #if IS_COMPOUND
171
+ finalColor = vec4f(uniforms.partPickingColors[i32(fragmentInputs.vPartIndex + 0.5)], 1.0);
172
+ #else
173
+ finalColor = vec4f(uniforms.pickingColor, 1.0);
174
+ #endif
175
+ `,
176
+ };
177
+ }
178
+ return null;
179
+ }
180
+ /**
181
+ * Registers the picking uniforms with the engine.
182
+ * @returns uniform descriptions
183
+ */
184
+ getUniforms() {
185
+ return {
186
+ externalUniforms: ["pickingColor", "partPickingColors"],
187
+ };
188
+ }
189
+ /**
190
+ * Binds the picking color uniform(s) each frame.
191
+ * @param _uniformBuffer the uniform buffer (unused — we bind directly on the effect)
192
+ * @param _scene the current scene
193
+ * @param _engine the current engine
194
+ * @param subMesh the submesh being rendered
195
+ */
196
+ bindForSubMesh(_uniformBuffer, _scene, _engine, subMesh) {
197
+ const effect = subMesh.effect;
198
+ if (!effect) {
199
+ return;
200
+ }
201
+ if (this._isCompound) {
202
+ effect.setArray3("partPickingColors", this._partPickingColors);
203
+ }
204
+ else {
205
+ effect.setFloat3("pickingColor", this._pickingColor[0], this._pickingColor[1], this._pickingColor[2]);
206
+ }
207
+ }
208
+ }
209
+ RegisterClass("BABYLON.GaussianSplattingGpuPickingMaterialPlugin", GaussianSplattingGpuPickingMaterialPlugin);
210
+ //# sourceMappingURL=gaussianSplattingGpuPickingMaterialPlugin.js.map
@@ -0,0 +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 { GaussianSplattingMaxPartCount } from \"./gaussianSplattingMaterial\";\r\nimport 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 _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 = GaussianSplattingMaxPartCount) {\r\n super(material, \"GaussianSplatGpuPicking\", 200);\r\n\r\n this._maxPartCount = maxPartCount;\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 * @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 finalColor = vec4(partPickingColors[int(vPartIndex + 0.5)], 1.0);\r\n#else\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 finalColor = vec4f(uniforms.partPickingColors[i32(fragmentInputs.vPartIndex + 0.5)], 1.0);\r\n#else\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 } 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"]}
@@ -17,6 +17,7 @@ import "../../Shaders/gaussianSplattingDepth.vertex.js";
17
17
  import "../../ShadersWGSL/gaussianSplattingDepth.fragment.js";
18
18
  import "../../ShadersWGSL/gaussianSplattingDepth.vertex.js";
19
19
  import { ShaderLanguage } from "../shaderLanguage.js";
20
+ export declare const GaussianSplattingMaxPartCount = 256;
20
21
  /**
21
22
  * GaussianSplattingMaterial material used to render Gaussian Splatting
22
23
  * @experimental
@@ -7,6 +7,7 @@ import { AddClipPlaneUniforms, BindClipPlane } from "../clipPlaneMaterialHelper.
7
7
  import { Camera } from "../../Cameras/camera.js";
8
8
  import { ShadowDepthWrapper } from "../../Materials/shadowDepthWrapper.js";
9
9
  import { ShaderMaterial } from "../../Materials/shaderMaterial.js";
10
+ import { Material } from "../material.js";
10
11
  import "../../Shaders/gaussianSplatting.fragment.js";
11
12
  import "../../Shaders/gaussianSplatting.vertex.js";
12
13
  import "../../ShadersWGSL/gaussianSplatting.fragment.js";
@@ -16,15 +17,18 @@ import "../../Shaders/gaussianSplattingDepth.vertex.js";
16
17
  import "../../ShadersWGSL/gaussianSplattingDepth.fragment.js";
17
18
  import "../../ShadersWGSL/gaussianSplattingDepth.vertex.js";
18
19
  import { BindFogParameters, BindLogDepth, PrepareAttributesForInstances, PrepareDefinesForAttributes, PrepareDefinesForFrameBoundValues, PrepareDefinesForMisc, PrepareUniformsAndSamplersList, } from "../materialHelper.functions.js";
20
+ // Can be up to 256, then we'll need to change the partIndices texture format to uint16
21
+ export const GaussianSplattingMaxPartCount = 256;
19
22
  /**
20
23
  * @internal
21
24
  */
22
25
  class GaussianSplattingMaterialDefines extends MaterialDefines {
23
26
  /**
24
27
  * Constructor of the defines.
28
+ * @param externalProperties External properties (e.g. from material plugins) to add to the defines.
25
29
  */
26
- constructor() {
27
- super();
30
+ constructor(externalProperties) {
31
+ super(externalProperties);
28
32
  this.FOG = false;
29
33
  this.THIN_INSTANCES = true;
30
34
  this.LOGARITHMICDEPTH = false;
@@ -37,7 +41,7 @@ class GaussianSplattingMaterialDefines extends MaterialDefines {
37
41
  this.SH_DEGREE = 0;
38
42
  this.COMPENSATION = false;
39
43
  this.IS_COMPOUND = false;
40
- this.MAX_PART_COUNT = 16; // Can be up to 256, then we'll need to change the partIndices texture format to uint16
44
+ this.MAX_PART_COUNT = GaussianSplattingMaxPartCount;
41
45
  this.rebuild();
42
46
  }
43
47
  }
@@ -116,12 +120,21 @@ export class GaussianSplattingMaterial extends PushMaterial {
116
120
  }
117
121
  }
118
122
  if (!subMesh.materialDefines) {
119
- defines = subMesh.materialDefines = new GaussianSplattingMaterialDefines();
123
+ this._callbackPluginEventGeneric(4 /* MaterialPluginEvent.GetDefineNames */, this._eventInfo);
124
+ defines = subMesh.materialDefines = new GaussianSplattingMaterialDefines(this._eventInfo.defineNames);
120
125
  }
121
126
  const scene = this.getScene();
122
127
  if (this._isReadyForSubMesh(subMesh)) {
123
128
  return true;
124
129
  }
130
+ // Check plugin readiness
131
+ this._eventInfo.isReadyForSubMesh = true;
132
+ this._eventInfo.defines = defines;
133
+ this._eventInfo.subMesh = subMesh;
134
+ this._callbackPluginEventIsReadyForSubMesh(this._eventInfo);
135
+ if (!this._eventInfo.isReadyForSubMesh) {
136
+ return false;
137
+ }
125
138
  if (!this._sourceMesh) {
126
139
  return false;
127
140
  }
@@ -147,23 +160,42 @@ export class GaussianSplattingMaterial extends PushMaterial {
147
160
  scene.resetCachedMaterial();
148
161
  //Attributes
149
162
  PrepareAttributesForInstances(GaussianSplattingMaterial._Attribs, defines);
163
+ const attribs = GaussianSplattingMaterial._Attribs.slice();
164
+ const uniforms = GaussianSplattingMaterial._Uniforms.slice();
165
+ const samplers = GaussianSplattingMaterial._Samplers.slice();
166
+ const uniformBuffers = GaussianSplattingMaterial._UniformBuffers.slice();
150
167
  PrepareUniformsAndSamplersList({
151
- uniformsNames: GaussianSplattingMaterial._Uniforms,
152
- uniformBuffersNames: GaussianSplattingMaterial._UniformBuffers,
153
- samplers: GaussianSplattingMaterial._Samplers,
168
+ uniformsNames: uniforms,
169
+ uniformBuffersNames: uniformBuffers,
170
+ samplers: samplers,
154
171
  defines: defines,
155
172
  });
156
- AddClipPlaneUniforms(GaussianSplattingMaterial._Uniforms);
173
+ AddClipPlaneUniforms(uniforms);
174
+ // Let plugin manager prepare its uniform/sampler/ubo lists
175
+ if (!this._uniformBufferLayoutBuilt) {
176
+ this.buildUniformLayout();
177
+ }
178
+ // Prepare plugin effect
179
+ this._eventInfo.fallbackRank = 0;
180
+ this._eventInfo.defines = defines;
181
+ this._eventInfo.attributes = attribs;
182
+ this._eventInfo.uniforms = uniforms;
183
+ this._eventInfo.samplers = samplers;
184
+ this._eventInfo.uniformBuffersNames = uniformBuffers;
185
+ this._eventInfo.customCode = undefined;
186
+ this._eventInfo.mesh = mesh;
187
+ this._callbackPluginEventGeneric(128 /* MaterialPluginEvent.PrepareEffect */, this._eventInfo);
157
188
  const join = defines.toString();
158
189
  const effect = scene.getEngine().createEffect("gaussianSplatting", {
159
- attributes: GaussianSplattingMaterial._Attribs,
160
- uniformsNames: GaussianSplattingMaterial._Uniforms,
161
- uniformBuffersNames: GaussianSplattingMaterial._UniformBuffers,
162
- samplers: GaussianSplattingMaterial._Samplers,
190
+ attributes: attribs,
191
+ uniformsNames: uniforms,
192
+ uniformBuffersNames: uniformBuffers,
193
+ samplers: samplers,
163
194
  defines: join,
164
195
  onCompiled: this.onCompiled,
165
196
  onError: this.onError,
166
197
  indexParameters: {},
198
+ processCodeAfterIncludes: this._eventInfo.customCode,
167
199
  shaderLanguage: this._shaderLanguage,
168
200
  extraInitializationsAsync: async () => {
169
201
  if (this._shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
@@ -300,6 +332,9 @@ export class GaussianSplattingMaterial extends PushMaterial {
300
332
  if (this.useLogarithmicDepth) {
301
333
  BindLogDepth(defines, effect, scene);
302
334
  }
335
+ // Bind plugins
336
+ this._eventInfo.subMesh = subMesh;
337
+ this._callbackPluginEventBindForSubMesh(this._eventInfo);
303
338
  this._afterBind(mesh, this._activeEffect, subMesh);
304
339
  }
305
340
  static _BindEffectUniforms(gsMesh, gsMaterial, shaderMaterial, scene) {
@@ -383,7 +418,7 @@ export class GaussianSplattingMaterial extends PushMaterial {
383
418
  }
384
419
  if (compoundMesh) {
385
420
  defines.push("#define IS_COMPOUND");
386
- defines.push("#define MAX_PART_COUNT 16");
421
+ defines.push(`#define MAX_PART_COUNT ${GaussianSplattingMaxPartCount}`);
387
422
  }
388
423
  const shaderMaterial = new ShaderMaterial("gaussianSplattingDepthRender", scene, {
389
424
  vertex: "gaussianSplattingDepth",
@@ -431,7 +466,11 @@ export class GaussianSplattingMaterial extends PushMaterial {
431
466
  * @returns The cloned material.
432
467
  */
433
468
  clone(name) {
434
- return SerializationHelper.Clone(() => new GaussianSplattingMaterial(name, this.getScene()), this);
469
+ const clone = SerializationHelper.Clone(() => new GaussianSplattingMaterial(name, this.getScene()), this);
470
+ clone.id = name;
471
+ clone.name = name;
472
+ this._clonePlugins(clone, "");
473
+ return clone;
435
474
  }
436
475
  /**
437
476
  * Serializes the current material to its JSON representation.
@@ -457,7 +496,9 @@ export class GaussianSplattingMaterial extends PushMaterial {
457
496
  * @returns the instantiated GaussianSplattingMaterial.
458
497
  */
459
498
  static Parse(source, scene, rootUrl) {
460
- return SerializationHelper.Parse(() => new GaussianSplattingMaterial(source.name, scene), source, scene, rootUrl);
499
+ const material = SerializationHelper.Parse(() => new GaussianSplattingMaterial(source.name, scene), source, scene, rootUrl);
500
+ Material._ParsePlugins(source, material, scene, rootUrl);
501
+ return material;
461
502
  }
462
503
  }
463
504
  /**