@babylonjs/core 9.8.0 → 9.9.0

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 (103) hide show
  1. package/Audio/audioSceneComponent.pure.js +17 -9
  2. package/Bones/bone.pure.js +39 -29
  3. package/Cameras/arcRotateCamera.pure.d.ts +0 -8
  4. package/Cameras/arcRotateCamera.pure.js +0 -12
  5. package/Cameras/arcRotateCamera.pure.js.map +1 -1
  6. package/Cameras/inputMapper.d.ts +29 -8
  7. package/Cameras/inputMapper.js +63 -10
  8. package/Cameras/inputMapper.js.map +1 -1
  9. package/Cameras/targetCamera.pure.js +40 -27
  10. package/Culling/Helper/transformFeedbackBoundingHelper.pure.js +17 -23
  11. package/Engines/abstractEngine.pure.js +4 -4
  12. package/Engines/abstractEngine.pure.js.map +1 -1
  13. package/Engines/thinEngine.pure.js +234 -280
  14. package/Materials/Background/backgroundMaterial.pure.js +5 -4
  15. package/Materials/Background/backgroundMaterial.pure.js.map +1 -1
  16. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.d.ts +5 -0
  17. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.js +8 -0
  18. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.js.map +1 -0
  19. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.d.ts +278 -0
  20. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js +718 -0
  21. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js.map +1 -0
  22. package/Materials/GaussianSplatting/pure.d.ts +1 -0
  23. package/Materials/GaussianSplatting/pure.js +1 -0
  24. package/Materials/GaussianSplatting/pure.js.map +1 -1
  25. package/Materials/Node/Blocks/Dual/imageSourceBlock.pure.js +10 -14
  26. package/Materials/Node/Blocks/Dual/index.d.ts +0 -14
  27. package/Materials/Node/Blocks/Dual/index.js +0 -18
  28. package/Materials/Node/Blocks/Dual/index.js.map +1 -1
  29. package/Materials/Node/Blocks/Dual/textureBlock.pure.js +660 -662
  30. package/Materials/Node/Blocks/Fragment/index.d.ts +0 -10
  31. package/Materials/Node/Blocks/Fragment/index.js +0 -13
  32. package/Materials/Node/Blocks/Fragment/index.js.map +1 -1
  33. package/Materials/Node/Blocks/GaussianSplatting/index.d.ts +12 -0
  34. package/Materials/Node/Blocks/GaussianSplatting/index.js +14 -1
  35. package/Materials/Node/Blocks/GaussianSplatting/index.js.map +1 -1
  36. package/Materials/Node/Blocks/Vertex/index.d.ts +0 -8
  37. package/Materials/Node/Blocks/Vertex/index.js +0 -10
  38. package/Materials/Node/Blocks/Vertex/index.js.map +1 -1
  39. package/Materials/PBR/openpbrMaterial.pure.js +6 -5
  40. package/Materials/PBR/openpbrMaterial.pure.js.map +1 -1
  41. package/Materials/PBR/pbrBaseMaterial.pure.js +6 -5
  42. package/Materials/PBR/pbrBaseMaterial.pure.js.map +1 -1
  43. package/Materials/Textures/index.d.ts +1 -0
  44. package/Materials/Textures/index.js +1 -0
  45. package/Materials/Textures/index.js.map +1 -1
  46. package/Materials/Textures/internalTexture.js +7 -0
  47. package/Materials/Textures/internalTexture.js.map +1 -1
  48. package/Materials/Textures/texture.pure.js +157 -255
  49. package/Materials/index.d.ts +30 -0
  50. package/Materials/index.js +31 -0
  51. package/Materials/index.js.map +1 -1
  52. package/Materials/material.pure.js +128 -69
  53. package/Materials/pure.d.ts +1 -0
  54. package/Materials/pure.js +1 -0
  55. package/Materials/pure.js.map +1 -1
  56. package/Materials/standardMaterial.pure.js +6 -5
  57. package/Materials/standardMaterial.pure.js.map +1 -1
  58. package/Maths/math.color.pure.js +55 -47
  59. package/Maths/math.vector.pure.js +118 -242
  60. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.d.ts +7 -0
  61. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.js +8 -0
  62. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.js.map +1 -0
  63. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.d.ts +147 -0
  64. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.js +257 -0
  65. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.js.map +1 -0
  66. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +11 -0
  67. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +31 -0
  68. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
  69. package/Meshes/GaussianSplatting/pure.d.ts +1 -0
  70. package/Meshes/GaussianSplatting/pure.js +1 -0
  71. package/Meshes/GaussianSplatting/pure.js.map +1 -1
  72. package/Meshes/GreasedLine/greasedLineMesh.pure.js +9 -14
  73. package/Meshes/GreasedLine/greasedLineRibbonMesh.pure.js +26 -27
  74. package/Meshes/index.d.ts +1 -0
  75. package/Meshes/index.js +1 -0
  76. package/Meshes/index.js.map +1 -1
  77. package/Meshes/meshSimplification.common.d.ts +53 -0
  78. package/Meshes/meshSimplification.common.js +34 -0
  79. package/Meshes/meshSimplification.common.js.map +1 -0
  80. package/Meshes/meshSimplification.d.ts +3 -53
  81. package/Meshes/meshSimplification.js +1 -33
  82. package/Meshes/meshSimplification.js.map +1 -1
  83. package/Meshes/meshSimplificationSceneComponent.pure.js.map +1 -1
  84. package/Meshes/meshSimplificationSceneComponent.types.d.ts +2 -1
  85. package/Meshes/meshSimplificationSceneComponent.types.js.map +1 -1
  86. package/Meshes/pure.d.ts +1 -0
  87. package/Meshes/pure.js +1 -0
  88. package/Meshes/pure.js.map +1 -1
  89. package/Meshes/transformNode.pure.js +82 -44
  90. package/Misc/tools.pure.js +124 -186
  91. package/Misc/tools.pure.js.map +1 -1
  92. package/Physics/v1/physicsImpostor.pure.js +43 -37
  93. package/Shaders/ShadersInclude/gaussianSplatting.js +33 -10
  94. package/Shaders/ShadersInclude/gaussianSplatting.js.map +1 -1
  95. package/Shaders/gaussianSplatting.vertex.js +20 -1
  96. package/Shaders/gaussianSplatting.vertex.js.map +1 -1
  97. package/Shaders/picking.fragment.js +4 -1
  98. package/Shaders/picking.fragment.js.map +1 -1
  99. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js +33 -10
  100. package/ShadersWGSL/ShadersInclude/gaussianSplatting.js.map +1 -1
  101. package/ShadersWGSL/gaussianSplatting.vertex.js +21 -2
  102. package/ShadersWGSL/gaussianSplatting.vertex.js.map +1 -1
  103. package/package.json +3 -1
@@ -1,668 +1,666 @@
1
- /** This file must only contain pure code and pure imports */
2
- import { NodeMaterialBlock } from "../../nodeMaterialBlock.js";
3
- import { NodeMaterialBlockConnectionPointTypes } from "../../Enums/nodeMaterialBlockConnectionPointTypes.js";
4
- import { NodeMaterialBlockTargets } from "../../Enums/nodeMaterialBlockTargets.js";
5
- import { NodeMaterial } from "../../nodeMaterial.pure.js";
6
- import { InputBlock } from "../Input/inputBlock.pure.js";
7
- import { Texture } from "../../../Textures/texture.pure.js";
8
- import { ThinTexture } from "../../../Textures/thinTexture.js";
9
- import { NodeMaterialModes } from "../../Enums/nodeMaterialModes.js";
10
-
11
- import { ImageSourceBlock } from "./imageSourceBlock.pure.js";
12
- import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject.js";
13
- import { EngineStore } from "../../../../Engines/engineStore.js";
14
- import { RegisterClass } from "../../../../Misc/typeStore.js";
15
- /**
16
- * Block used to read a texture from a sampler
17
- */
18
- export class TextureBlock extends NodeMaterialBlock {
19
- /**
20
- * Gets or sets a boolean indicating if the block is used in fragment shader only
21
- * If false the system will allow optimizations to use it in vertex shader when possible for the uv computation
22
- */
23
- get fragmentOnly() {
24
- return this._fragmentOnly;
25
- }
26
- set fragmentOnly(value) {
27
- this._fragmentOnly = value;
28
- }
29
- /**
30
- * Gets or sets the texture associated with the node
31
- */
32
- get texture() {
33
- if (this.source.isConnected) {
34
- return (this.source.connectedPoint?.ownerBlock).texture;
35
- }
36
- return this._texture;
37
- }
38
- set texture(texture) {
39
- if (this._texture === texture) {
40
- return;
41
- }
42
- const scene = texture?.getScene() ?? EngineStore.LastCreatedScene;
43
- if (!texture && scene) {
44
- scene.markAllMaterialsAsDirty(1, (mat) => {
45
- return mat.hasTexture(this._texture);
46
- });
47
- }
48
- this._texture = texture;
49
- if (texture && scene) {
50
- scene.markAllMaterialsAsDirty(1, (mat) => {
51
- return mat.hasTexture(texture);
52
- });
53
- }
54
- }
55
- static _IsPrePassTextureBlock(block) {
56
- return block?.getClassName() === "PrePassTextureBlock";
57
- }
58
- static _GetDefaultTexture(engine) {
59
- let defaultTexture = TextureBlock._DefaultTextureByEngine.get(engine);
60
- if (!defaultTexture || defaultTexture.getInternalTexture() !== engine.emptyTexture) {
61
- defaultTexture = new ThinTexture(engine.emptyTexture);
62
- TextureBlock._DefaultTextureByEngine.set(engine, defaultTexture);
63
- }
64
- return defaultTexture;
65
- }
66
- get _isSourcePrePass() {
67
- return TextureBlock._IsPrePassTextureBlock(this._imageSource);
68
- }
69
- /**
70
- * Gets the sampler name associated with this texture
71
- */
72
- get samplerName() {
73
- if (this._imageSource) {
74
- if (!TextureBlock._IsPrePassTextureBlock(this._imageSource)) {
75
- return this._imageSource.samplerName;
76
- }
77
- if (this.source.connectedPoint) {
78
- return this._imageSource.getSamplerName(this.source.connectedPoint);
79
- }
80
- }
81
- return this._samplerName;
82
- }
83
- /**
84
- * Gets a boolean indicating that this block is linked to an ImageSourceBlock
85
- */
86
- get hasImageSource() {
87
- return this.source.isConnected;
88
- }
89
- /**
90
- * Gets or sets a boolean indicating if content needs to be converted to gamma space
91
- */
92
- set convertToGammaSpace(value) {
93
- if (value === this._convertToGammaSpace) {
94
- return;
95
- }
96
- this._convertToGammaSpace = value;
97
- if (this.texture) {
98
- const scene = this.texture.getScene() ?? EngineStore.LastCreatedScene;
99
- scene?.markAllMaterialsAsDirty(1, (mat) => {
100
- return mat.hasTexture(this.texture);
101
- });
102
- }
103
- }
104
- get convertToGammaSpace() {
105
- return this._convertToGammaSpace;
106
- }
107
- /**
108
- * Gets or sets a boolean indicating if content needs to be converted to linear space
109
- */
110
- set convertToLinearSpace(value) {
111
- if (value === this._convertToLinearSpace) {
112
- return;
113
- }
114
- this._convertToLinearSpace = value;
115
- if (this.texture) {
116
- const scene = this.texture.getScene() ?? EngineStore.LastCreatedScene;
117
- scene?.markAllMaterialsAsDirty(1, (mat) => {
118
- return mat.hasTexture(this.texture);
119
- });
120
- }
121
- }
122
- get convertToLinearSpace() {
123
- return this._convertToLinearSpace;
124
- }
125
- /**
126
- * Create a new TextureBlock
127
- * @param name defines the block name
128
- * @param fragmentOnly
129
- */
130
- constructor(name, fragmentOnly = false) {
131
- super(name, fragmentOnly ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.VertexAndFragment);
132
- this._convertToGammaSpace = false;
133
- this._convertToLinearSpace = false;
134
- /**
135
- * Gets or sets a boolean indicating if multiplication of texture with level should be disabled
136
- */
137
- this.disableLevelMultiplication = false;
138
- this._fragmentOnly = fragmentOnly;
139
- this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.VertexAndFragment);
140
- this.registerInput(
141
- "source",
142
- NodeMaterialBlockConnectionPointTypes.Object,
143
- true,
144
- NodeMaterialBlockTargets.VertexAndFragment,
145
- new NodeMaterialConnectionPointCustomObject("source", this, 0 /* NodeMaterialConnectionPointDirection.Input */, ImageSourceBlock, "ImageSourceBlock")
146
- );
147
- this.registerInput("layer", NodeMaterialBlockConnectionPointTypes.Float, true);
148
- this.registerInput("lod", NodeMaterialBlockConnectionPointTypes.Float, true);
149
- this.registerOutput("rgba", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Neutral);
150
- this.registerOutput("rgb", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Neutral);
151
- this.registerOutput("r", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
152
- this.registerOutput("g", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
153
- this.registerOutput("b", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
154
- this.registerOutput("a", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
155
- this.registerOutput("level", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
156
- this._inputs[0].addExcludedConnectionPointFromAllowedTypes(
157
- NodeMaterialBlockConnectionPointTypes.Vector2 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4
158
- );
159
- this._inputs[0]._prioritizeVertex = !fragmentOnly;
160
- }
161
- /**
162
- * Gets the current class name
163
- * @returns the class name
164
- */
165
- getClassName() {
166
- return "TextureBlock";
167
- }
168
- /**
169
- * Gets the uv input component
170
- */
171
- get uv() {
172
- return this._inputs[0];
173
- }
174
- /**
175
- * Gets the source input component
176
- */
177
- get source() {
178
- return this._inputs[1];
179
- }
180
- /**
181
- * Gets the layer input component
182
- */
183
- get layer() {
184
- return this._inputs[2];
185
- }
186
- /**
187
- * Gets the LOD input component
188
- */
189
- get lod() {
190
- return this._inputs[3];
191
- }
192
- /**
193
- * Gets the rgba output component
194
- */
195
- get rgba() {
196
- return this._outputs[0];
197
- }
198
- /**
199
- * Gets the rgb output component
200
- */
201
- get rgb() {
202
- return this._outputs[1];
203
- }
204
- /**
205
- * Gets the r output component
206
- */
207
- get r() {
208
- return this._outputs[2];
209
- }
210
- /**
211
- * Gets the g output component
212
- */
213
- get g() {
214
- return this._outputs[3];
215
- }
216
- /**
217
- * Gets the b output component
218
- */
219
- get b() {
220
- return this._outputs[4];
221
- }
222
- /**
223
- * Gets the a output component
224
- */
225
- get a() {
226
- return this._outputs[5];
227
- }
228
- /**
229
- * Gets the level output component
230
- */
231
- get level() {
232
- return this._outputs[6];
233
- }
234
- _isTiedToFragment(input) {
235
- if (input.target === NodeMaterialBlockTargets.Fragment) {
236
- return true;
237
- }
238
- if (input.target === NodeMaterialBlockTargets.Vertex) {
239
- return false;
240
- }
241
- if (input.target === NodeMaterialBlockTargets.Neutral || input.target === NodeMaterialBlockTargets.VertexAndFragment) {
242
- const parentBlock = input.ownerBlock;
243
- if (parentBlock.target === NodeMaterialBlockTargets.Fragment) {
244
- return true;
245
- }
246
- for (const input of parentBlock.inputs) {
247
- if (!input.isConnected) {
248
- continue;
249
- }
250
- if (this._isTiedToFragment(input.connectedPoint)) {
251
- return true;
252
- }
253
- }
254
- }
255
- return false;
256
- }
257
- _getEffectiveTarget() {
258
- if (this._fragmentOnly) {
259
- return NodeMaterialBlockTargets.Fragment;
260
- }
261
- // TextureBlock has a special optimizations for uvs that come from the vertex shaders as they can be packed into a single varyings.
262
- // But we need to detect uvs coming from fragment then
263
- if (!this.uv.isConnected) {
264
- return NodeMaterialBlockTargets.VertexAndFragment;
265
- }
266
- if (this.uv.sourceBlock.isInput) {
267
- return NodeMaterialBlockTargets.VertexAndFragment;
268
- }
269
- if (this._isTiedToFragment(this.uv.connectedPoint)) {
270
- return NodeMaterialBlockTargets.Fragment;
271
- }
272
- return NodeMaterialBlockTargets.VertexAndFragment;
273
- }
274
- /** {@inheritDoc} */
275
- get target() {
276
- return this._getEffectiveTarget();
277
- }
278
- /** {@inheritDoc} */
279
- set target(value) {}
280
- /**
281
- * Initialize the block and prepare the context for build
282
- * @param state defines the state that will be used for the build
283
- */
284
- initialize(state) {
285
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
286
- this._initShaderSourceAsync(state.shaderLanguage);
287
- }
288
- async _initShaderSourceAsync(shaderLanguage) {
289
- this._codeIsReady = false;
290
- if (shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
291
- await import("../../../../ShadersWGSL/ShadersInclude/helperFunctions.js");
292
- } else {
293
- await import("../../../../Shaders/ShadersInclude/helperFunctions.js");
294
- }
295
- this._codeIsReady = true;
296
- this.onCodeIsReadyObservable.notifyObservers(this);
297
- }
298
- /**
299
- * Auto configure the block based on the material
300
- * @param material - the node material
301
- * @param additionalFilteringInfo - optional filtering info
302
- */
303
- autoConfigure(material, additionalFilteringInfo = () => true) {
304
- if (!this.uv.isConnected) {
305
- if (material.mode === NodeMaterialModes.PostProcess) {
306
- const uvInput = material.getBlockByPredicate((b) => b.name === "uv" && additionalFilteringInfo(b));
307
- if (uvInput) {
308
- uvInput.connectTo(this);
309
- }
310
- } else if (material.mode !== NodeMaterialModes.ProceduralTexture) {
311
- const attributeName = material.mode === NodeMaterialModes.Particle ? "particle_uv" : "uv";
312
- let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === attributeName && additionalFilteringInfo(b));
313
- if (!uvInput) {
314
- uvInput = new InputBlock("uv");
315
- uvInput.setAsAttribute(attributeName);
316
- }
317
- uvInput.output.connectTo(this.uv);
318
- }
319
- }
320
- }
321
- /**
322
- * Initialize the list of defines
323
- * @param defines - the material defines
324
- */
325
- initializeDefines(defines) {
326
- if (!defines._areTexturesDirty) {
327
- return;
328
- }
329
- if (this._mainUVDefineName !== undefined) {
330
- defines.setValue(this._mainUVDefineName, false, true);
331
- }
332
- }
333
- /**
334
- * Prepare the list of defines
335
- * @param defines - the material defines
336
- */
337
- prepareDefines(defines) {
338
- if (!defines._areTexturesDirty) {
339
- return;
340
- }
341
- if (!this.texture || !this.texture.getTextureMatrix) {
342
- if (this._isMixed) {
343
- defines.setValue(this._defineName, false, true);
344
- defines.setValue(this._mainUVDefineName, true, true);
345
- }
346
- return;
347
- }
348
- const toGamma = this.convertToGammaSpace && this.texture && !this.texture.gammaSpace;
349
- const toLinear = this.convertToLinearSpace && this.texture && this.texture.gammaSpace;
350
- // Not a bug... Name defines the texture space not the required conversion
351
- defines.setValue(this._linearDefineName, toGamma, true);
352
- defines.setValue(this._gammaDefineName, toLinear, true);
353
- if (this._isMixed) {
354
- if (!this.texture.getTextureMatrix().isIdentityAs3x2()) {
355
- defines.setValue(this._defineName, true);
356
- if (defines[this._mainUVDefineName] == undefined) {
357
- defines.setValue(this._mainUVDefineName, false, true);
358
- }
359
- } else {
360
- defines.setValue(this._defineName, false, true);
361
- defines.setValue(this._mainUVDefineName, true, true);
362
- }
363
- }
364
- }
365
- /**
366
- * Checks if the block is ready
367
- * @returns true if ready
368
- */
369
- isReady() {
370
- if (this._isSourcePrePass) {
371
- return true;
372
- }
373
- if (this.texture && !this.texture.isReadyOrNotBlocking()) {
374
- return false;
375
- }
376
- return true;
377
- }
378
- /**
379
- * Bind data to effect
380
- * @param effect - the effect to bind to
381
- */
382
- bind(effect) {
383
- if (this._isSourcePrePass) {
384
- effect.setFloat(this._textureInfoName, 1);
385
- }
386
- const texture = this.texture;
387
- if (!texture) {
388
- const engine = effect.getEngine();
389
- if (engine.isWebGPU && !this._imageSource) {
390
- effect.setTexture(this._samplerName, TextureBlock._GetDefaultTexture(engine));
391
- }
392
- return;
393
- }
394
- if (this._isMixed) {
395
- effect.setFloat(this._textureInfoName, texture.level);
396
- effect.setMatrix(this._textureTransformName, texture.getTextureMatrix());
397
- }
398
- if (!this._imageSource) {
399
- effect.setTexture(this._samplerName, texture);
400
- }
401
- }
402
- get _isMixed() {
403
- return this.target !== NodeMaterialBlockTargets.Fragment;
404
- }
405
- _injectVertexCode(state) {
406
- const uvInput = this.uv;
407
- // Inject code in vertex
408
- this._defineName = state._getFreeDefineName("UVTRANSFORM");
409
- this._mainUVDefineName = "VMAIN" + uvInput.declarationVariableName.toUpperCase();
410
- this._mainUVName = "vMain" + uvInput.declarationVariableName;
411
- this._transformedUVName = state._getFreeVariableName("transformedUV");
412
- this._textureTransformName = state._getFreeVariableName("textureTransform");
413
- this._textureInfoName = state._getFreeVariableName("textureInfoName");
414
- this.level.associatedVariableName = this._textureInfoName;
415
- state._emitVaryingFromString(this._transformedUVName, NodeMaterialBlockConnectionPointTypes.Vector2, this._defineName);
416
- state._emitVaryingFromString(this._mainUVName, NodeMaterialBlockConnectionPointTypes.Vector2, this._mainUVDefineName);
417
- state._emitUniformFromString(this._textureTransformName, NodeMaterialBlockConnectionPointTypes.Matrix, this._defineName);
418
- const vec4 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector4);
419
- const vec2 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector2);
420
- state.compilationString += `#ifdef ${this._defineName}\n`;
421
- state.compilationString += `${state._getVaryingName(this._transformedUVName)} = ${vec2}(${this._textureTransformName} * ${vec4}(${uvInput.associatedVariableName}.xy, 1.0, 0.0));\n`;
422
- state.compilationString += `#elif defined(${this._mainUVDefineName})\n`;
423
- let automaticPrefix = "";
424
- if (state.shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
425
- if (uvInput.isConnectedToInputBlock && uvInput.associatedVariableName.indexOf("vertexInputs.") === -1) {
426
- automaticPrefix = "vertexInputs."; // Force the prefix
427
- }
428
- }
429
- state.compilationString += `${state._getVaryingName(this._mainUVName)} = ${automaticPrefix}${uvInput.associatedVariableName}.xy;\n`;
430
- state.compilationString += `#endif\n`;
431
- if (!this._outputs.some((o) => o.isConnectedInVertexShader)) {
432
- return;
433
- }
434
- this._writeTextureRead(state, true);
435
- for (const output of this._outputs) {
436
- if (output.hasEndpoints && output.name !== "level") {
437
- this._writeOutput(state, output, output.name, true);
438
- }
439
- }
440
- }
441
- _getUVW(uvName) {
442
- let coords = uvName;
443
- const is2DArrayTexture = this._texture?._texture?.is2DArray ?? false;
444
- const is3D = this._texture?._texture?.is3D ?? false;
445
- if (is2DArrayTexture) {
446
- const layerValue = this.layer.isConnected ? this.layer.associatedVariableName : "0";
447
- coords = `vec3(${uvName}, ${layerValue})`;
448
- } else if (is3D) {
449
- const layerValue = this.layer.isConnected ? this.layer.associatedVariableName : "0";
450
- coords = `vec3(${uvName}, ${layerValue})`;
451
- }
452
- return coords;
453
- }
454
- _samplerFunc(state) {
455
- if (state.shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
456
- return state.target === NodeMaterialBlockTargets.Vertex ? "textureSampleLevel" : "textureSample";
457
- }
458
- return this.lod.isConnected ? "texture2DLodEXT" : "texture2D";
459
- }
460
- get _samplerLodSuffix() {
461
- return this.lod.isConnected ? `, ${this.lod.associatedVariableName}` : "";
462
- }
463
- _generateTextureSample(uv, state) {
464
- if (state.shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
465
- const isVertex = state.target === NodeMaterialBlockTargets.Vertex;
466
- return `${this._samplerFunc(state)}(${this.samplerName},${this.samplerName + `Sampler`}, ${this._getUVW(uv)}${this._samplerLodSuffix}${isVertex ? ", 0" : ""})`;
467
- }
468
- return `${this._samplerFunc(state)}(${this.samplerName}, ${this._getUVW(uv)}${this._samplerLodSuffix})`;
469
- }
470
- _generateTextureLookup(state) {
471
- state.compilationString += `#ifdef ${this._defineName}\n`;
472
- state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(state._getVaryingName(this._transformedUVName), state)};\n`;
473
- state.compilationString += `#elif defined(${this._mainUVDefineName})\n`;
474
- state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(this._mainUVName ? state._getVaryingName(this._mainUVName) : this.uv.associatedVariableName, state)}${this._samplerLodSuffix};\n`;
475
- state.compilationString += `#endif\n`;
476
- }
477
- _writeTextureRead(state, vertexMode = false) {
478
- const uvInput = this.uv;
479
- if (vertexMode) {
480
- if (state.target === NodeMaterialBlockTargets.Fragment) {
481
- return;
482
- }
483
- this._generateTextureLookup(state);
484
- return;
485
- }
486
- if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {
487
- state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(uvInput.associatedVariableName, state)}${this._samplerLodSuffix};\n`;
488
- return;
489
- }
490
- this._generateTextureLookup(state);
491
- }
492
- _generateConversionCode(state, output, swizzle) {
493
- if (swizzle !== "a") {
494
- // no conversion if the output is "a" (alpha)
495
- if (!this.texture || !this.texture.gammaSpace) {
1
+ /** This file must only contain pure code and pure imports */
2
+ import { NodeMaterialBlock } from "../../nodeMaterialBlock.js";
3
+ import { NodeMaterialBlockConnectionPointTypes } from "../../Enums/nodeMaterialBlockConnectionPointTypes.js";
4
+ import { NodeMaterialBlockTargets } from "../../Enums/nodeMaterialBlockTargets.js";
5
+ import { NodeMaterial } from "../../nodeMaterial.pure.js";
6
+ import { InputBlock } from "../Input/inputBlock.pure.js";
7
+ import { Texture } from "../../../Textures/texture.pure.js";
8
+ import { ThinTexture } from "../../../Textures/thinTexture.js";
9
+ import { NodeMaterialModes } from "../../Enums/nodeMaterialModes.js";
10
+
11
+ import { ImageSourceBlock } from "./imageSourceBlock.pure.js";
12
+ import { NodeMaterialConnectionPointCustomObject } from "../../nodeMaterialConnectionPointCustomObject.js";
13
+ import { EngineStore } from "../../../../Engines/engineStore.js";
14
+ import { RegisterClass } from "../../../../Misc/typeStore.js";
15
+ /**
16
+ * Block used to read a texture from a sampler
17
+ */
18
+ export class TextureBlock extends NodeMaterialBlock {
19
+ /**
20
+ * Gets or sets a boolean indicating if the block is used in fragment shader only
21
+ * If false the system will allow optimizations to use it in vertex shader when possible for the uv computation
22
+ */
23
+ get fragmentOnly() {
24
+ return this._fragmentOnly;
25
+ }
26
+ set fragmentOnly(value) {
27
+ this._fragmentOnly = value;
28
+ }
29
+ /**
30
+ * Gets or sets the texture associated with the node
31
+ */
32
+ get texture() {
33
+ if (this.source.isConnected) {
34
+ return (this.source.connectedPoint?.ownerBlock).texture;
35
+ }
36
+ return this._texture;
37
+ }
38
+ set texture(texture) {
39
+ if (this._texture === texture) {
40
+ return;
41
+ }
42
+ const scene = texture?.getScene() ?? EngineStore.LastCreatedScene;
43
+ if (!texture && scene) {
44
+ scene.markAllMaterialsAsDirty(1, (mat) => {
45
+ return mat.hasTexture(this._texture);
46
+ });
47
+ }
48
+ this._texture = texture;
49
+ if (texture && scene) {
50
+ scene.markAllMaterialsAsDirty(1, (mat) => {
51
+ return mat.hasTexture(texture);
52
+ });
53
+ }
54
+ }
55
+ static _IsPrePassTextureBlock(block) {
56
+ return block?.getClassName() === "PrePassTextureBlock";
57
+ }
58
+ static _GetDefaultTexture(engine) {
59
+ let defaultTexture = TextureBlock._DefaultTextureByEngine.get(engine);
60
+ if (!defaultTexture || defaultTexture.getInternalTexture() !== engine.emptyTexture) {
61
+ defaultTexture = new ThinTexture(engine.emptyTexture);
62
+ TextureBlock._DefaultTextureByEngine.set(engine, defaultTexture);
63
+ }
64
+ return defaultTexture;
65
+ }
66
+ get _isSourcePrePass() {
67
+ return TextureBlock._IsPrePassTextureBlock(this._imageSource);
68
+ }
69
+ /**
70
+ * Gets the sampler name associated with this texture
71
+ */
72
+ get samplerName() {
73
+ if (this._imageSource) {
74
+ if (!TextureBlock._IsPrePassTextureBlock(this._imageSource)) {
75
+ return this._imageSource.samplerName;
76
+ }
77
+ if (this.source.connectedPoint) {
78
+ return this._imageSource.getSamplerName(this.source.connectedPoint);
79
+ }
80
+ }
81
+ return this._samplerName;
82
+ }
83
+ /**
84
+ * Gets a boolean indicating that this block is linked to an ImageSourceBlock
85
+ */
86
+ get hasImageSource() {
87
+ return this.source.isConnected;
88
+ }
89
+ /**
90
+ * Gets or sets a boolean indicating if content needs to be converted to gamma space
91
+ */
92
+ set convertToGammaSpace(value) {
93
+ if (value === this._convertToGammaSpace) {
94
+ return;
95
+ }
96
+ this._convertToGammaSpace = value;
97
+ if (this.texture) {
98
+ const scene = this.texture.getScene() ?? EngineStore.LastCreatedScene;
99
+ scene?.markAllMaterialsAsDirty(1, (mat) => {
100
+ return mat.hasTexture(this.texture);
101
+ });
102
+ }
103
+ }
104
+ get convertToGammaSpace() {
105
+ return this._convertToGammaSpace;
106
+ }
107
+ /**
108
+ * Gets or sets a boolean indicating if content needs to be converted to linear space
109
+ */
110
+ set convertToLinearSpace(value) {
111
+ if (value === this._convertToLinearSpace) {
112
+ return;
113
+ }
114
+ this._convertToLinearSpace = value;
115
+ if (this.texture) {
116
+ const scene = this.texture.getScene() ?? EngineStore.LastCreatedScene;
117
+ scene?.markAllMaterialsAsDirty(1, (mat) => {
118
+ return mat.hasTexture(this.texture);
119
+ });
120
+ }
121
+ }
122
+ get convertToLinearSpace() {
123
+ return this._convertToLinearSpace;
124
+ }
125
+ /**
126
+ * Create a new TextureBlock
127
+ * @param name defines the block name
128
+ * @param fragmentOnly
129
+ */
130
+ constructor(name, fragmentOnly = false) {
131
+ super(name, fragmentOnly ? NodeMaterialBlockTargets.Fragment : NodeMaterialBlockTargets.VertexAndFragment);
132
+ this._convertToGammaSpace = false;
133
+ this._convertToLinearSpace = false;
134
+ /**
135
+ * Gets or sets a boolean indicating if multiplication of texture with level should be disabled
136
+ */
137
+ this.disableLevelMultiplication = false;
138
+ this._fragmentOnly = fragmentOnly;
139
+ this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.AutoDetect, false, NodeMaterialBlockTargets.VertexAndFragment);
140
+ this.registerInput("source", NodeMaterialBlockConnectionPointTypes.Object, true, NodeMaterialBlockTargets.VertexAndFragment, new NodeMaterialConnectionPointCustomObject("source", this, 0 /* NodeMaterialConnectionPointDirection.Input */, ImageSourceBlock, "ImageSourceBlock"));
141
+ this.registerInput("layer", NodeMaterialBlockConnectionPointTypes.Float, true);
142
+ this.registerInput("lod", NodeMaterialBlockConnectionPointTypes.Float, true);
143
+ this.registerOutput("rgba", NodeMaterialBlockConnectionPointTypes.Color4, NodeMaterialBlockTargets.Neutral);
144
+ this.registerOutput("rgb", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Neutral);
145
+ this.registerOutput("r", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
146
+ this.registerOutput("g", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
147
+ this.registerOutput("b", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
148
+ this.registerOutput("a", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
149
+ this.registerOutput("level", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Neutral);
150
+ this._inputs[0].addExcludedConnectionPointFromAllowedTypes(NodeMaterialBlockConnectionPointTypes.Vector2 | NodeMaterialBlockConnectionPointTypes.Vector3 | NodeMaterialBlockConnectionPointTypes.Vector4);
151
+ this._inputs[0]._prioritizeVertex = !fragmentOnly;
152
+ }
153
+ /**
154
+ * Gets the current class name
155
+ * @returns the class name
156
+ */
157
+ getClassName() {
158
+ return "TextureBlock";
159
+ }
160
+ /**
161
+ * Gets the uv input component
162
+ */
163
+ get uv() {
164
+ return this._inputs[0];
165
+ }
166
+ /**
167
+ * Gets the source input component
168
+ */
169
+ get source() {
170
+ return this._inputs[1];
171
+ }
172
+ /**
173
+ * Gets the layer input component
174
+ */
175
+ get layer() {
176
+ return this._inputs[2];
177
+ }
178
+ /**
179
+ * Gets the LOD input component
180
+ */
181
+ get lod() {
182
+ return this._inputs[3];
183
+ }
184
+ /**
185
+ * Gets the rgba output component
186
+ */
187
+ get rgba() {
188
+ return this._outputs[0];
189
+ }
190
+ /**
191
+ * Gets the rgb output component
192
+ */
193
+ get rgb() {
194
+ return this._outputs[1];
195
+ }
196
+ /**
197
+ * Gets the r output component
198
+ */
199
+ get r() {
200
+ return this._outputs[2];
201
+ }
202
+ /**
203
+ * Gets the g output component
204
+ */
205
+ get g() {
206
+ return this._outputs[3];
207
+ }
208
+ /**
209
+ * Gets the b output component
210
+ */
211
+ get b() {
212
+ return this._outputs[4];
213
+ }
214
+ /**
215
+ * Gets the a output component
216
+ */
217
+ get a() {
218
+ return this._outputs[5];
219
+ }
220
+ /**
221
+ * Gets the level output component
222
+ */
223
+ get level() {
224
+ return this._outputs[6];
225
+ }
226
+ _isTiedToFragment(input) {
227
+ if (input.target === NodeMaterialBlockTargets.Fragment) {
228
+ return true;
229
+ }
230
+ if (input.target === NodeMaterialBlockTargets.Vertex) {
231
+ return false;
232
+ }
233
+ if (input.target === NodeMaterialBlockTargets.Neutral || input.target === NodeMaterialBlockTargets.VertexAndFragment) {
234
+ const parentBlock = input.ownerBlock;
235
+ if (parentBlock.target === NodeMaterialBlockTargets.Fragment) {
236
+ return true;
237
+ }
238
+ for (const input of parentBlock.inputs) {
239
+ if (!input.isConnected) {
240
+ continue;
241
+ }
242
+ if (this._isTiedToFragment(input.connectedPoint)) {
243
+ return true;
244
+ }
245
+ }
246
+ }
247
+ return false;
248
+ }
249
+ _getEffectiveTarget() {
250
+ if (this._fragmentOnly) {
251
+ return NodeMaterialBlockTargets.Fragment;
252
+ }
253
+ // TextureBlock has a special optimizations for uvs that come from the vertex shaders as they can be packed into a single varyings.
254
+ // But we need to detect uvs coming from fragment then
255
+ if (!this.uv.isConnected) {
256
+ return NodeMaterialBlockTargets.VertexAndFragment;
257
+ }
258
+ if (this.uv.sourceBlock.isInput) {
259
+ return NodeMaterialBlockTargets.VertexAndFragment;
260
+ }
261
+ if (this._isTiedToFragment(this.uv.connectedPoint)) {
262
+ return NodeMaterialBlockTargets.Fragment;
263
+ }
264
+ return NodeMaterialBlockTargets.VertexAndFragment;
265
+ }
266
+ /** {@inheritDoc} */
267
+ get target() {
268
+ return this._getEffectiveTarget();
269
+ }
270
+ /** {@inheritDoc} */
271
+ set target(value) { }
272
+ /**
273
+ * Initialize the block and prepare the context for build
274
+ * @param state defines the state that will be used for the build
275
+ */
276
+ initialize(state) {
277
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
278
+ this._initShaderSourceAsync(state.shaderLanguage);
279
+ }
280
+ async _initShaderSourceAsync(shaderLanguage) {
281
+ this._codeIsReady = false;
282
+ if (shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
283
+ await import("../../../../ShadersWGSL/ShadersInclude/helperFunctions.js");
284
+ }
285
+ else {
286
+ await import("../../../../Shaders/ShadersInclude/helperFunctions.js");
287
+ }
288
+ this._codeIsReady = true;
289
+ this.onCodeIsReadyObservable.notifyObservers(this);
290
+ }
291
+ /**
292
+ * Auto configure the block based on the material
293
+ * @param material - the node material
294
+ * @param additionalFilteringInfo - optional filtering info
295
+ */
296
+ autoConfigure(material, additionalFilteringInfo = () => true) {
297
+ if (!this.uv.isConnected) {
298
+ if (material.mode === NodeMaterialModes.PostProcess) {
299
+ const uvInput = material.getBlockByPredicate((b) => b.name === "uv" && additionalFilteringInfo(b));
300
+ if (uvInput) {
301
+ uvInput.connectTo(this);
302
+ }
303
+ }
304
+ else if (material.mode !== NodeMaterialModes.ProceduralTexture) {
305
+ const attributeName = material.mode === NodeMaterialModes.Particle ? "particle_uv" : "uv";
306
+ let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === attributeName && additionalFilteringInfo(b));
307
+ if (!uvInput) {
308
+ uvInput = new InputBlock("uv");
309
+ uvInput.setAsAttribute(attributeName);
310
+ }
311
+ uvInput.output.connectTo(this.uv);
312
+ }
313
+ }
314
+ }
315
+ /**
316
+ * Initialize the list of defines
317
+ * @param defines - the material defines
318
+ */
319
+ initializeDefines(defines) {
320
+ if (!defines._areTexturesDirty) {
321
+ return;
322
+ }
323
+ if (this._mainUVDefineName !== undefined) {
324
+ defines.setValue(this._mainUVDefineName, false, true);
325
+ }
326
+ }
327
+ /**
328
+ * Prepare the list of defines
329
+ * @param defines - the material defines
330
+ */
331
+ prepareDefines(defines) {
332
+ if (!defines._areTexturesDirty) {
333
+ return;
334
+ }
335
+ if (!this.texture || !this.texture.getTextureMatrix) {
336
+ if (this._isMixed) {
337
+ defines.setValue(this._defineName, false, true);
338
+ defines.setValue(this._mainUVDefineName, true, true);
339
+ }
340
+ return;
341
+ }
342
+ const toGamma = this.convertToGammaSpace && this.texture && !this.texture.gammaSpace;
343
+ const toLinear = this.convertToLinearSpace && this.texture && this.texture.gammaSpace;
344
+ // Not a bug... Name defines the texture space not the required conversion
345
+ defines.setValue(this._linearDefineName, toGamma, true);
346
+ defines.setValue(this._gammaDefineName, toLinear, true);
347
+ if (this._isMixed) {
348
+ if (!this.texture.getTextureMatrix().isIdentityAs3x2()) {
349
+ defines.setValue(this._defineName, true);
350
+ if (defines[this._mainUVDefineName] == undefined) {
351
+ defines.setValue(this._mainUVDefineName, false, true);
352
+ }
353
+ }
354
+ else {
355
+ defines.setValue(this._defineName, false, true);
356
+ defines.setValue(this._mainUVDefineName, true, true);
357
+ }
358
+ }
359
+ }
360
+ /**
361
+ * Checks if the block is ready
362
+ * @returns true if ready
363
+ */
364
+ isReady() {
365
+ if (this._isSourcePrePass) {
366
+ return true;
367
+ }
368
+ if (this.texture && !this.texture.isReadyOrNotBlocking()) {
369
+ return false;
370
+ }
371
+ return true;
372
+ }
373
+ /**
374
+ * Bind data to effect
375
+ * @param effect - the effect to bind to
376
+ */
377
+ bind(effect) {
378
+ if (this._isSourcePrePass) {
379
+ effect.setFloat(this._textureInfoName, 1);
380
+ }
381
+ const texture = this.texture;
382
+ if (!texture) {
383
+ const engine = effect.getEngine();
384
+ if (engine.isWebGPU && !this._imageSource) {
385
+ effect.setTexture(this._samplerName, TextureBlock._GetDefaultTexture(engine));
386
+ }
387
+ return;
388
+ }
389
+ if (this._isMixed) {
390
+ effect.setFloat(this._textureInfoName, texture.level);
391
+ effect.setMatrix(this._textureTransformName, texture.getTextureMatrix());
392
+ }
393
+ if (!this._imageSource) {
394
+ effect.setTexture(this._samplerName, texture);
395
+ }
396
+ }
397
+ get _isMixed() {
398
+ return this.target !== NodeMaterialBlockTargets.Fragment;
399
+ }
400
+ _injectVertexCode(state) {
401
+ const uvInput = this.uv;
402
+ // Inject code in vertex
403
+ this._defineName = state._getFreeDefineName("UVTRANSFORM");
404
+ this._mainUVDefineName = "VMAIN" + uvInput.declarationVariableName.toUpperCase();
405
+ this._mainUVName = "vMain" + uvInput.declarationVariableName;
406
+ this._transformedUVName = state._getFreeVariableName("transformedUV");
407
+ this._textureTransformName = state._getFreeVariableName("textureTransform");
408
+ this._textureInfoName = state._getFreeVariableName("textureInfoName");
409
+ this.level.associatedVariableName = this._textureInfoName;
410
+ state._emitVaryingFromString(this._transformedUVName, NodeMaterialBlockConnectionPointTypes.Vector2, this._defineName);
411
+ state._emitVaryingFromString(this._mainUVName, NodeMaterialBlockConnectionPointTypes.Vector2, this._mainUVDefineName);
412
+ state._emitUniformFromString(this._textureTransformName, NodeMaterialBlockConnectionPointTypes.Matrix, this._defineName);
413
+ const vec4 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector4);
414
+ const vec2 = state._getShaderType(NodeMaterialBlockConnectionPointTypes.Vector2);
415
+ state.compilationString += `#ifdef ${this._defineName}\n`;
416
+ state.compilationString += `${state._getVaryingName(this._transformedUVName)} = ${vec2}(${this._textureTransformName} * ${vec4}(${uvInput.associatedVariableName}.xy, 1.0, 0.0));\n`;
417
+ state.compilationString += `#elif defined(${this._mainUVDefineName})\n`;
418
+ let automaticPrefix = "";
419
+ if (state.shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
420
+ if (uvInput.isConnectedToInputBlock && uvInput.associatedVariableName.indexOf("vertexInputs.") === -1) {
421
+ automaticPrefix = "vertexInputs."; // Force the prefix
422
+ }
423
+ }
424
+ state.compilationString += `${state._getVaryingName(this._mainUVName)} = ${automaticPrefix}${uvInput.associatedVariableName}.xy;\n`;
425
+ state.compilationString += `#endif\n`;
426
+ if (!this._outputs.some((o) => o.isConnectedInVertexShader)) {
427
+ return;
428
+ }
429
+ this._writeTextureRead(state, true);
430
+ for (const output of this._outputs) {
431
+ if (output.hasEndpoints && output.name !== "level") {
432
+ this._writeOutput(state, output, output.name, true);
433
+ }
434
+ }
435
+ }
436
+ _getUVW(uvName) {
437
+ let coords = uvName;
438
+ const is2DArrayTexture = this._texture?._texture?.is2DArray ?? false;
439
+ const is3D = this._texture?._texture?.is3D ?? false;
440
+ if (is2DArrayTexture) {
441
+ const layerValue = this.layer.isConnected ? this.layer.associatedVariableName : "0";
442
+ coords = `vec3(${uvName}, ${layerValue})`;
443
+ }
444
+ else if (is3D) {
445
+ const layerValue = this.layer.isConnected ? this.layer.associatedVariableName : "0";
446
+ coords = `vec3(${uvName}, ${layerValue})`;
447
+ }
448
+ return coords;
449
+ }
450
+ _samplerFunc(state) {
451
+ if (state.shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
452
+ return state.target === NodeMaterialBlockTargets.Vertex ? "textureSampleLevel" : "textureSample";
453
+ }
454
+ return this.lod.isConnected ? "texture2DLodEXT" : "texture2D";
455
+ }
456
+ get _samplerLodSuffix() {
457
+ return this.lod.isConnected ? `, ${this.lod.associatedVariableName}` : "";
458
+ }
459
+ _generateTextureSample(uv, state) {
460
+ if (state.shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
461
+ const isVertex = state.target === NodeMaterialBlockTargets.Vertex;
462
+ return `${this._samplerFunc(state)}(${this.samplerName},${this.samplerName + `Sampler`}, ${this._getUVW(uv)}${this._samplerLodSuffix}${isVertex ? ", 0" : ""})`;
463
+ }
464
+ return `${this._samplerFunc(state)}(${this.samplerName}, ${this._getUVW(uv)}${this._samplerLodSuffix})`;
465
+ }
466
+ _generateTextureLookup(state) {
467
+ state.compilationString += `#ifdef ${this._defineName}\n`;
468
+ state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(state._getVaryingName(this._transformedUVName), state)};\n`;
469
+ state.compilationString += `#elif defined(${this._mainUVDefineName})\n`;
470
+ state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(this._mainUVName ? state._getVaryingName(this._mainUVName) : this.uv.associatedVariableName, state)}${this._samplerLodSuffix};\n`;
471
+ state.compilationString += `#endif\n`;
472
+ }
473
+ _writeTextureRead(state, vertexMode = false) {
474
+ const uvInput = this.uv;
475
+ if (vertexMode) {
476
+ if (state.target === NodeMaterialBlockTargets.Fragment) {
477
+ return;
478
+ }
479
+ this._generateTextureLookup(state);
480
+ return;
481
+ }
482
+ if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {
483
+ state.compilationString += `${state._declareLocalVar(this._tempTextureRead, NodeMaterialBlockConnectionPointTypes.Vector4)} = ${this._generateTextureSample(uvInput.associatedVariableName, state)}${this._samplerLodSuffix};\n`;
484
+ return;
485
+ }
486
+ this._generateTextureLookup(state);
487
+ }
488
+ _generateConversionCode(state, output, swizzle) {
489
+ if (swizzle !== "a") {
490
+ // no conversion if the output is "a" (alpha)
491
+ if (!this.texture || !this.texture.gammaSpace) {
496
492
  state.compilationString += `#ifdef ${this._linearDefineName}
497
493
  ${output.associatedVariableName} = toGammaSpace(${output.associatedVariableName});
498
494
  #endif
499
- `;
500
- }
495
+ `;
496
+ }
501
497
  state.compilationString += `#ifdef ${this._gammaDefineName}
502
498
  ${output.associatedVariableName} = ${state._toLinearSpace(output)};
503
499
  #endif
504
- `;
505
- }
506
- }
507
- _writeOutput(state, output, swizzle, vertexMode = false) {
508
- if (vertexMode) {
509
- if (state.target === NodeMaterialBlockTargets.Fragment) {
510
- return;
511
- }
512
- state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\n`;
513
- this._generateConversionCode(state, output, swizzle);
514
- return;
515
- }
516
- if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {
517
- state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\n`;
518
- this._generateConversionCode(state, output, swizzle);
519
- return;
520
- }
521
- let complement = "";
522
- if (!this.disableLevelMultiplication) {
523
- complement = ` * ${(state.shaderLanguage === 1 /* ShaderLanguage.WGSL */ ? "uniforms." : "") + this._textureInfoName}`;
524
- }
525
- state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle}${complement};\n`;
526
- this._generateConversionCode(state, output, swizzle);
527
- }
528
- _buildBlock(state) {
529
- super._buildBlock(state);
530
- if (this.source.isConnected) {
531
- this._imageSource = this.source.connectedPoint.ownerBlock;
532
- } else {
533
- this._imageSource = null;
534
- }
535
- if (state.target === NodeMaterialBlockTargets.Vertex || this._fragmentOnly || state.target === NodeMaterialBlockTargets.Fragment) {
536
- this._tempTextureRead = state._getFreeVariableName("tempTextureRead");
537
- this._linearDefineName = state._getFreeDefineName("ISLINEAR");
538
- this._gammaDefineName = state._getFreeDefineName("ISGAMMA");
539
- }
540
- if ((!this._isMixed && state.target === NodeMaterialBlockTargets.Fragment) || (this._isMixed && state.target === NodeMaterialBlockTargets.Vertex)) {
541
- if (!this._imageSource) {
542
- const varName = state._getFreeVariableName(this.name);
543
- this._samplerName = varName + "Texture";
544
- if (this._texture?._texture?.is2DArray) {
545
- state._emit2DArraySampler(this._samplerName);
546
- } else {
547
- state._emit2DSampler(this._samplerName);
548
- }
549
- }
550
- // Declarations
551
- state.sharedData.blockingBlocks.push(this);
552
- state.sharedData.textureBlocks.push(this);
553
- state.sharedData.blocksWithDefines.push(this);
554
- state.sharedData.bindableBlocks.push(this);
555
- }
556
- if (state.target !== NodeMaterialBlockTargets.Fragment) {
557
- // Vertex
558
- this._injectVertexCode(state);
559
- return;
560
- }
561
- // Fragment
562
- if (!this._outputs.some((o) => o.isConnectedInFragmentShader)) {
563
- return;
564
- }
565
- if (this._isMixed && !this._imageSource) {
566
- // Reexport the sampler
567
- if (this._texture?._texture?.is2DArray) {
568
- state._emit2DArraySampler(this._samplerName);
569
- } else {
570
- state._emit2DSampler(this._samplerName);
571
- }
572
- }
573
- const comments = `//${this.name}`;
574
- state._emitFunctionFromInclude("helperFunctions", comments);
575
- if (this._isMixed) {
576
- state._emitUniformFromString(this._textureInfoName, NodeMaterialBlockConnectionPointTypes.Float);
577
- }
578
- this._writeTextureRead(state);
579
- for (const output of this._outputs) {
580
- if (output.hasEndpoints && output.name !== "level") {
581
- this._writeOutput(state, output, output.name);
582
- }
583
- }
584
- return this;
585
- }
586
- _dumpPropertiesCode() {
587
- let codeString = super._dumpPropertiesCode();
588
- codeString += `${this._codeVariableName}.convertToGammaSpace = ${this.convertToGammaSpace};\n`;
589
- codeString += `${this._codeVariableName}.convertToLinearSpace = ${this.convertToLinearSpace};\n`;
590
- codeString += `${this._codeVariableName}.disableLevelMultiplication = ${this.disableLevelMultiplication};\n`;
591
- if (!this.texture) {
592
- return codeString;
593
- }
594
- codeString += `${this._codeVariableName}.texture = new BABYLON.Texture("${this.texture.name}", null, ${this.texture.noMipmap}, ${this.texture.invertY}, ${this.texture.samplingMode});\n`;
595
- codeString += `${this._codeVariableName}.texture.wrapU = ${this.texture.wrapU};\n`;
596
- codeString += `${this._codeVariableName}.texture.wrapV = ${this.texture.wrapV};\n`;
597
- codeString += `${this._codeVariableName}.texture.uAng = ${this.texture.uAng};\n`;
598
- codeString += `${this._codeVariableName}.texture.vAng = ${this.texture.vAng};\n`;
599
- codeString += `${this._codeVariableName}.texture.wAng = ${this.texture.wAng};\n`;
600
- codeString += `${this._codeVariableName}.texture.uOffset = ${this.texture.uOffset};\n`;
601
- codeString += `${this._codeVariableName}.texture.vOffset = ${this.texture.vOffset};\n`;
602
- codeString += `${this._codeVariableName}.texture.uScale = ${this.texture.uScale};\n`;
603
- codeString += `${this._codeVariableName}.texture.vScale = ${this.texture.vScale};\n`;
604
- codeString += `${this._codeVariableName}.texture.coordinatesMode = ${this.texture.coordinatesMode};\n`;
605
- return codeString;
606
- }
607
- /**
608
- * Serializes the block
609
- * @returns the serialized object
610
- */
611
- serialize() {
612
- const serializationObject = super.serialize();
613
- serializationObject.convertToGammaSpace = this.convertToGammaSpace;
614
- serializationObject.convertToLinearSpace = this.convertToLinearSpace;
615
- serializationObject.fragmentOnly = this._fragmentOnly;
616
- serializationObject.disableLevelMultiplication = this.disableLevelMultiplication;
617
- if (
618
- !this.hasImageSource &&
619
- this.texture &&
620
- (NodeMaterial.AllowSerializationOfRenderTargetTextures || !this.texture.isRenderTarget) &&
621
- this.texture.getClassName() !== "VideoTexture"
622
- ) {
623
- serializationObject.texture = this.texture.serialize();
624
- }
625
- return serializationObject;
626
- }
627
- /**
628
- * Deserializes the block
629
- * @param serializationObject - the serialization object
630
- * @param scene - the scene
631
- * @param rootUrl - the root url
632
- * @param urlRewriter - optional url rewriter
633
- */
634
- _deserialize(serializationObject, scene, rootUrl, urlRewriter) {
635
- super._deserialize(serializationObject, scene, rootUrl);
636
- this.convertToGammaSpace = serializationObject.convertToGammaSpace;
637
- this.convertToLinearSpace = !!serializationObject.convertToLinearSpace;
638
- this._fragmentOnly = !!serializationObject.fragmentOnly;
639
- this.disableLevelMultiplication = !!serializationObject.disableLevelMultiplication;
640
- if (serializationObject.texture && !NodeMaterial.IgnoreTexturesAtLoadTime) {
641
- if (serializationObject.texture.url !== undefined) {
642
- if (serializationObject.texture.url.indexOf("data:") === 0) {
643
- rootUrl = "";
644
- } else if (urlRewriter) {
645
- serializationObject.texture.url = urlRewriter(serializationObject.texture.url);
646
- serializationObject.texture.name = serializationObject.texture.url;
647
- }
648
- }
649
- if (serializationObject.texture.base64String || serializationObject.texture.url !== undefined) {
650
- this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl);
651
- }
652
- }
653
- }
654
- }
655
- TextureBlock._DefaultTextureByEngine = /*#__PURE__*/ new WeakMap();
656
- let _Registered = false;
657
- /**
658
- * Register side effects for textureBlock.
659
- * Safe to call multiple times; only the first call has an effect.
660
- */
661
- export function RegisterTextureBlock() {
662
- if (_Registered) {
663
- return;
664
- }
665
- _Registered = true;
666
- RegisterClass("BABYLON.TextureBlock", TextureBlock);
667
- }
668
- //# sourceMappingURL=textureBlock.pure.js.map
500
+ `;
501
+ }
502
+ }
503
+ _writeOutput(state, output, swizzle, vertexMode = false) {
504
+ if (vertexMode) {
505
+ if (state.target === NodeMaterialBlockTargets.Fragment) {
506
+ return;
507
+ }
508
+ state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\n`;
509
+ this._generateConversionCode(state, output, swizzle);
510
+ return;
511
+ }
512
+ if (this.uv.ownerBlock.target === NodeMaterialBlockTargets.Fragment) {
513
+ state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle};\n`;
514
+ this._generateConversionCode(state, output, swizzle);
515
+ return;
516
+ }
517
+ let complement = "";
518
+ if (!this.disableLevelMultiplication) {
519
+ complement = ` * ${(state.shaderLanguage === 1 /* ShaderLanguage.WGSL */ ? "uniforms." : "") + this._textureInfoName}`;
520
+ }
521
+ state.compilationString += `${state._declareOutput(output)} = ${this._tempTextureRead}.${swizzle}${complement};\n`;
522
+ this._generateConversionCode(state, output, swizzle);
523
+ }
524
+ _buildBlock(state) {
525
+ super._buildBlock(state);
526
+ if (this.source.isConnected) {
527
+ this._imageSource = this.source.connectedPoint.ownerBlock;
528
+ }
529
+ else {
530
+ this._imageSource = null;
531
+ }
532
+ if (state.target === NodeMaterialBlockTargets.Vertex || this._fragmentOnly || state.target === NodeMaterialBlockTargets.Fragment) {
533
+ this._tempTextureRead = state._getFreeVariableName("tempTextureRead");
534
+ this._linearDefineName = state._getFreeDefineName("ISLINEAR");
535
+ this._gammaDefineName = state._getFreeDefineName("ISGAMMA");
536
+ }
537
+ if ((!this._isMixed && state.target === NodeMaterialBlockTargets.Fragment) || (this._isMixed && state.target === NodeMaterialBlockTargets.Vertex)) {
538
+ if (!this._imageSource) {
539
+ const varName = state._getFreeVariableName(this.name);
540
+ this._samplerName = varName + "Texture";
541
+ if (this._texture?._texture?.is2DArray) {
542
+ state._emit2DArraySampler(this._samplerName);
543
+ }
544
+ else {
545
+ state._emit2DSampler(this._samplerName);
546
+ }
547
+ }
548
+ // Declarations
549
+ state.sharedData.blockingBlocks.push(this);
550
+ state.sharedData.textureBlocks.push(this);
551
+ state.sharedData.blocksWithDefines.push(this);
552
+ state.sharedData.bindableBlocks.push(this);
553
+ }
554
+ if (state.target !== NodeMaterialBlockTargets.Fragment) {
555
+ // Vertex
556
+ this._injectVertexCode(state);
557
+ return;
558
+ }
559
+ // Fragment
560
+ if (!this._outputs.some((o) => o.isConnectedInFragmentShader)) {
561
+ return;
562
+ }
563
+ if (this._isMixed && !this._imageSource) {
564
+ // Reexport the sampler
565
+ if (this._texture?._texture?.is2DArray) {
566
+ state._emit2DArraySampler(this._samplerName);
567
+ }
568
+ else {
569
+ state._emit2DSampler(this._samplerName);
570
+ }
571
+ }
572
+ const comments = `//${this.name}`;
573
+ state._emitFunctionFromInclude("helperFunctions", comments);
574
+ if (this._isMixed) {
575
+ state._emitUniformFromString(this._textureInfoName, NodeMaterialBlockConnectionPointTypes.Float);
576
+ }
577
+ this._writeTextureRead(state);
578
+ for (const output of this._outputs) {
579
+ if (output.hasEndpoints && output.name !== "level") {
580
+ this._writeOutput(state, output, output.name);
581
+ }
582
+ }
583
+ return this;
584
+ }
585
+ _dumpPropertiesCode() {
586
+ let codeString = super._dumpPropertiesCode();
587
+ codeString += `${this._codeVariableName}.convertToGammaSpace = ${this.convertToGammaSpace};\n`;
588
+ codeString += `${this._codeVariableName}.convertToLinearSpace = ${this.convertToLinearSpace};\n`;
589
+ codeString += `${this._codeVariableName}.disableLevelMultiplication = ${this.disableLevelMultiplication};\n`;
590
+ if (!this.texture) {
591
+ return codeString;
592
+ }
593
+ codeString += `${this._codeVariableName}.texture = new BABYLON.Texture("${this.texture.name}", null, ${this.texture.noMipmap}, ${this.texture.invertY}, ${this.texture.samplingMode});\n`;
594
+ codeString += `${this._codeVariableName}.texture.wrapU = ${this.texture.wrapU};\n`;
595
+ codeString += `${this._codeVariableName}.texture.wrapV = ${this.texture.wrapV};\n`;
596
+ codeString += `${this._codeVariableName}.texture.uAng = ${this.texture.uAng};\n`;
597
+ codeString += `${this._codeVariableName}.texture.vAng = ${this.texture.vAng};\n`;
598
+ codeString += `${this._codeVariableName}.texture.wAng = ${this.texture.wAng};\n`;
599
+ codeString += `${this._codeVariableName}.texture.uOffset = ${this.texture.uOffset};\n`;
600
+ codeString += `${this._codeVariableName}.texture.vOffset = ${this.texture.vOffset};\n`;
601
+ codeString += `${this._codeVariableName}.texture.uScale = ${this.texture.uScale};\n`;
602
+ codeString += `${this._codeVariableName}.texture.vScale = ${this.texture.vScale};\n`;
603
+ codeString += `${this._codeVariableName}.texture.coordinatesMode = ${this.texture.coordinatesMode};\n`;
604
+ return codeString;
605
+ }
606
+ /**
607
+ * Serializes the block
608
+ * @returns the serialized object
609
+ */
610
+ serialize() {
611
+ const serializationObject = super.serialize();
612
+ serializationObject.convertToGammaSpace = this.convertToGammaSpace;
613
+ serializationObject.convertToLinearSpace = this.convertToLinearSpace;
614
+ serializationObject.fragmentOnly = this._fragmentOnly;
615
+ serializationObject.disableLevelMultiplication = this.disableLevelMultiplication;
616
+ if (!this.hasImageSource &&
617
+ this.texture &&
618
+ (NodeMaterial.AllowSerializationOfRenderTargetTextures || !this.texture.isRenderTarget) &&
619
+ this.texture.getClassName() !== "VideoTexture") {
620
+ serializationObject.texture = this.texture.serialize();
621
+ }
622
+ return serializationObject;
623
+ }
624
+ /**
625
+ * Deserializes the block
626
+ * @param serializationObject - the serialization object
627
+ * @param scene - the scene
628
+ * @param rootUrl - the root url
629
+ * @param urlRewriter - optional url rewriter
630
+ */
631
+ _deserialize(serializationObject, scene, rootUrl, urlRewriter) {
632
+ super._deserialize(serializationObject, scene, rootUrl);
633
+ this.convertToGammaSpace = serializationObject.convertToGammaSpace;
634
+ this.convertToLinearSpace = !!serializationObject.convertToLinearSpace;
635
+ this._fragmentOnly = !!serializationObject.fragmentOnly;
636
+ this.disableLevelMultiplication = !!serializationObject.disableLevelMultiplication;
637
+ if (serializationObject.texture && !NodeMaterial.IgnoreTexturesAtLoadTime) {
638
+ if (serializationObject.texture.url !== undefined) {
639
+ if (serializationObject.texture.url.indexOf("data:") === 0) {
640
+ rootUrl = "";
641
+ }
642
+ else if (urlRewriter) {
643
+ serializationObject.texture.url = urlRewriter(serializationObject.texture.url);
644
+ serializationObject.texture.name = serializationObject.texture.url;
645
+ }
646
+ }
647
+ if (serializationObject.texture.base64String || serializationObject.texture.url !== undefined) {
648
+ this.texture = Texture.Parse(serializationObject.texture, scene, rootUrl);
649
+ }
650
+ }
651
+ }
652
+ }
653
+ TextureBlock._DefaultTextureByEngine = /*#__PURE__*/ new WeakMap();
654
+ let _Registered = false;
655
+ /**
656
+ * Register side effects for textureBlock.
657
+ * Safe to call multiple times; only the first call has an effect.
658
+ */
659
+ export function RegisterTextureBlock() {
660
+ if (_Registered) {
661
+ return;
662
+ }
663
+ _Registered = true;
664
+ RegisterClass("BABYLON.TextureBlock", TextureBlock);
665
+ }
666
+ //# sourceMappingURL=textureBlock.pure.js.map