p5 2.2.1 → 2.2.2-rc.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.
- package/dist/accessibility/color_namer.js +6 -6
- package/dist/accessibility/index.js +6 -6
- package/dist/app.js +6 -6
- package/dist/color/color_conversion.js +6 -6
- package/dist/color/creating_reading.js +1 -1
- package/dist/color/index.js +2 -2
- package/dist/color/p5.Color.js +1 -1
- package/dist/color/setting.js +2 -2
- package/dist/{constants-DQyACdzq.js → constants-DAnmXDew.js} +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/environment.js +1 -1
- package/dist/core/filterShaders.js +1 -1
- package/dist/core/friendly_errors/fes_core.js +1 -1
- package/dist/core/friendly_errors/file_errors.js +1 -1
- package/dist/core/friendly_errors/index.js +1 -1
- package/dist/core/friendly_errors/param_validator.js +1 -1
- package/dist/core/friendly_errors/sketch_verifier.js +2 -2
- package/dist/core/helpers.js +1 -1
- package/dist/core/init.js +6 -6
- package/dist/core/internationalization.js +1 -1
- package/dist/core/legacy.js +6 -6
- package/dist/core/main.js +6 -6
- package/dist/core/p5.Graphics.js +4 -4
- package/dist/core/p5.Renderer.js +3 -3
- package/dist/core/p5.Renderer2D.js +6 -6
- package/dist/core/p5.Renderer3D.js +4 -4
- package/dist/core/rendering.js +4 -4
- package/dist/{creating_reading-ZXzcZEsb.js → creating_reading-C7hu6sg1.js} +2 -2
- package/dist/dom/dom.js +2 -2
- package/dist/dom/index.js +2 -2
- package/dist/dom/p5.Element.js +2 -2
- package/dist/dom/p5.MediaElement.js +2 -2
- package/dist/image/const.js +1 -1
- package/dist/image/filterRenderer2D.js +5 -5
- package/dist/image/image.js +4 -4
- package/dist/image/index.js +4 -4
- package/dist/image/loading_displaying.js +4 -4
- package/dist/image/p5.Image.js +3 -3
- package/dist/io/files.js +4 -4
- package/dist/io/index.js +4 -4
- package/dist/{ir_builders-DXNgaB9N.js → ir_builders-w12-GSxu.js} +37 -5
- package/dist/{main-DvN69W3f.js → main-E-swj5tF.js} +4 -4
- package/dist/math/Matrices/Matrix.js +1 -1
- package/dist/math/Matrices/MatrixNumjs.js +1 -1
- package/dist/math/index.js +1 -1
- package/dist/math/p5.Matrix.js +1 -1
- package/dist/math/p5.Vector.js +1 -1
- package/dist/math/trigonometry.js +1 -1
- package/dist/{p5.Renderer-D-5LdCRz.js → p5.Renderer-DOk9UW65.js} +2 -2
- package/dist/{rendering-h9unX5K0.js → rendering-B8V5Zt4k.js} +58 -14
- package/dist/shape/2d_primitives.js +1 -1
- package/dist/shape/attributes.js +1 -1
- package/dist/shape/custom_shapes.js +2 -2
- package/dist/shape/index.js +2 -2
- package/dist/strands/ir_builders.js +1 -1
- package/dist/strands/p5.strands.js +1 -1
- package/dist/strands/strands_api.js +91 -31
- package/dist/strands/strands_conditionals.js +1 -1
- package/dist/strands/strands_for.js +2 -2
- package/dist/strands/strands_node.js +1 -1
- package/dist/type/index.js +3 -3
- package/dist/type/p5.Font.js +3 -3
- package/dist/type/textCore.js +3 -3
- package/dist/webgl/3d_primitives.js +4 -4
- package/dist/webgl/GeometryBuilder.js +1 -1
- package/dist/webgl/ShapeBuilder.js +1 -1
- package/dist/webgl/enums.js +1 -1
- package/dist/webgl/index.js +5 -5
- package/dist/webgl/interaction.js +1 -1
- package/dist/webgl/light.js +4 -4
- package/dist/webgl/loading.js +12 -14
- package/dist/webgl/material.js +4 -4
- package/dist/webgl/p5.Camera.js +4 -4
- package/dist/webgl/p5.Framebuffer.js +4 -4
- package/dist/webgl/p5.Geometry.js +1 -1
- package/dist/webgl/p5.Quat.js +1 -1
- package/dist/webgl/p5.RendererGL.js +5 -5
- package/dist/webgl/p5.Texture.js +4 -4
- package/dist/webgl/strands_glslBackend.js +1 -1
- package/dist/webgl/text.js +5 -5
- package/dist/webgl/utils.js +4 -4
- package/dist/webgpu/index.js +2 -2
- package/dist/webgpu/p5.RendererWebGPU.js +13 -4
- package/dist/webgpu/strands_wgslBackend.js +5 -4
- package/lib/p5.esm.js +196 -62
- package/lib/p5.esm.min.js +1 -1
- package/lib/p5.js +196 -62
- package/lib/p5.min.js +1 -1
- package/lib/p5.webgpu.esm.js +51 -9
- package/lib/p5.webgpu.js +51 -9
- package/lib/p5.webgpu.min.js +1 -1
- package/package.json +1 -1
- package/types/global.d.ts +1453 -1383
- package/types/p5.d.ts +729 -694
package/lib/p5.webgpu.esm.js
CHANGED
|
@@ -11,7 +11,7 @@ const _PI = Math.PI;
|
|
|
11
11
|
* @property {String} VERSION
|
|
12
12
|
* @final
|
|
13
13
|
*/
|
|
14
|
-
const VERSION = '2.2.1';
|
|
14
|
+
const VERSION = '2.2.2-rc.1';
|
|
15
15
|
|
|
16
16
|
// GRAPHICS RENDERER
|
|
17
17
|
/**
|
|
@@ -3007,7 +3007,7 @@ class StrandsNode {
|
|
|
3007
3007
|
const baseType = orig?.baseType ?? BaseType.FLOAT;
|
|
3008
3008
|
|
|
3009
3009
|
let newValueID;
|
|
3010
|
-
if (value
|
|
3010
|
+
if (value?.isStrandsNode) {
|
|
3011
3011
|
newValueID = value.id;
|
|
3012
3012
|
} else {
|
|
3013
3013
|
const newVal = primitiveConstructorNode(
|
|
@@ -3062,7 +3062,7 @@ class StrandsNode {
|
|
|
3062
3062
|
const baseType = orig?.baseType ?? BaseType.FLOAT;
|
|
3063
3063
|
|
|
3064
3064
|
let newValueID;
|
|
3065
|
-
if (value
|
|
3065
|
+
if (value?.isStrandsNode) {
|
|
3066
3066
|
newValueID = value.id;
|
|
3067
3067
|
} else {
|
|
3068
3068
|
const newVal = primitiveConstructorNode(
|
|
@@ -3352,6 +3352,20 @@ function constructTypeFromIDs(strandsContext, typeInfo, strandsNodesArray) {
|
|
|
3352
3352
|
|
|
3353
3353
|
function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
|
|
3354
3354
|
const cfg = strandsContext.cfg;
|
|
3355
|
+
dependsOn = (Array.isArray(dependsOn) ? dependsOn : [dependsOn])
|
|
3356
|
+
.flat(Infinity)
|
|
3357
|
+
.map(a => {
|
|
3358
|
+
if (
|
|
3359
|
+
a.isStrandsNode &&
|
|
3360
|
+
a.typeInfo().baseType === BaseType.INT &&
|
|
3361
|
+
// TODO: handle ivec inputs instead of just int scalars
|
|
3362
|
+
a.typeInfo().dimension === 1
|
|
3363
|
+
) {
|
|
3364
|
+
return castToFloat(strandsContext, a);
|
|
3365
|
+
} else {
|
|
3366
|
+
return a;
|
|
3367
|
+
}
|
|
3368
|
+
});
|
|
3355
3369
|
const { mappedDependencies, inferredTypeInfo } = mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn);
|
|
3356
3370
|
|
|
3357
3371
|
const finalType = {
|
|
@@ -3367,6 +3381,24 @@ function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
|
|
|
3367
3381
|
return { id, dimension: finalType.dimension, components: mappedDependencies };
|
|
3368
3382
|
}
|
|
3369
3383
|
|
|
3384
|
+
function castToFloat(strandsContext, dep) {
|
|
3385
|
+
const { id, dimension } = functionCallNode(
|
|
3386
|
+
strandsContext,
|
|
3387
|
+
strandsContext.backend.getTypeName('float', dep.typeInfo().dimension),
|
|
3388
|
+
[dep],
|
|
3389
|
+
{
|
|
3390
|
+
overloads: [{
|
|
3391
|
+
params: [dep.typeInfo()],
|
|
3392
|
+
returnType: {
|
|
3393
|
+
...dep.typeInfo(),
|
|
3394
|
+
baseType: BaseType.FLOAT,
|
|
3395
|
+
},
|
|
3396
|
+
}],
|
|
3397
|
+
}
|
|
3398
|
+
);
|
|
3399
|
+
return createStrandsNode(id, dimension, strandsContext);
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3370
3402
|
function functionCallNode(
|
|
3371
3403
|
strandsContext,
|
|
3372
3404
|
functionName,
|
|
@@ -3537,7 +3569,7 @@ function swizzleTrap(id, dimension, strandsContext, onRebind) {
|
|
|
3537
3569
|
// This may not be the most efficient way, as we swizzle each component individually,
|
|
3538
3570
|
// so that .xyz becomes .x, .y, .z
|
|
3539
3571
|
let scalars = [];
|
|
3540
|
-
if (value
|
|
3572
|
+
if (value?.isStrandsNode) {
|
|
3541
3573
|
if (value.dimension === 1) {
|
|
3542
3574
|
scalars = Array(chars.length).fill(value);
|
|
3543
3575
|
} else if (value.dimension === chars.length) {
|
|
@@ -3808,10 +3840,11 @@ const wgslBackend = {
|
|
|
3808
3840
|
return primitiveTypeName;
|
|
3809
3841
|
},
|
|
3810
3842
|
generateHookUniformKey(name, typeInfo) {
|
|
3811
|
-
// For sampler2D types, we don't add them to the uniform struct
|
|
3812
|
-
//
|
|
3843
|
+
// For sampler2D types, we don't add them to the uniform struct,
|
|
3844
|
+
// but we still need them in the shader's hooks object so that
|
|
3845
|
+
// they can be set by users.
|
|
3813
3846
|
if (typeInfo.baseType === 'sampler2D') {
|
|
3814
|
-
return
|
|
3847
|
+
return `${name}: sampler2D`; // Signal that this should not be added to uniform struct
|
|
3815
3848
|
}
|
|
3816
3849
|
return `${name}: ${this.getTypeName(typeInfo.baseType, typeInfo.dimension)}`;
|
|
3817
3850
|
},
|
|
@@ -4593,6 +4626,10 @@ function rendererWebGPU(p5, fn) {
|
|
|
4593
4626
|
this.finalCamera = new Camera(this);
|
|
4594
4627
|
this.finalCamera._computeCameraDefaultSettings();
|
|
4595
4628
|
this.finalCamera._setDefaultCamera();
|
|
4629
|
+
|
|
4630
|
+
this.depthFormat = 'depth24plus-stencil8';
|
|
4631
|
+
this.depthTexture = null;
|
|
4632
|
+
this.depthTextureView = null;
|
|
4596
4633
|
}
|
|
4597
4634
|
|
|
4598
4635
|
async setupContext() {
|
|
@@ -4633,7 +4670,6 @@ function rendererWebGPU(p5, fn) {
|
|
|
4633
4670
|
});
|
|
4634
4671
|
|
|
4635
4672
|
// TODO disablable stencil
|
|
4636
|
-
this.depthFormat = 'depth24plus-stencil8';
|
|
4637
4673
|
this.mainFramebuffer = this.createFramebuffer({ _useCanvasFormat: true });
|
|
4638
4674
|
this._updateSize();
|
|
4639
4675
|
this._update();
|
|
@@ -4690,6 +4726,7 @@ function rendererWebGPU(p5, fn) {
|
|
|
4690
4726
|
}
|
|
4691
4727
|
|
|
4692
4728
|
_updateSize() {
|
|
4729
|
+
if (!this.device || !this.depthFormat) return;
|
|
4693
4730
|
if (this.depthTexture && this.depthTexture.destroy) {
|
|
4694
4731
|
this.flushDraw();
|
|
4695
4732
|
const textureToDestroy = this.depthTexture;
|
|
@@ -4784,6 +4821,7 @@ function rendererWebGPU(p5, fn) {
|
|
|
4784
4821
|
}
|
|
4785
4822
|
|
|
4786
4823
|
clear(...args) {
|
|
4824
|
+
if (!this.device || !this.drawingContext) return;
|
|
4787
4825
|
const _r = args[0] || 0;
|
|
4788
4826
|
const _g = args[1] || 0;
|
|
4789
4827
|
const _b = args[2] || 0;
|
|
@@ -4850,6 +4888,7 @@ function rendererWebGPU(p5, fn) {
|
|
|
4850
4888
|
* occlude anything subsequently drawn.
|
|
4851
4889
|
*/
|
|
4852
4890
|
clearDepth(depth = 1) {
|
|
4891
|
+
if (!this.device || !this.depthTextureView) return;
|
|
4853
4892
|
this._finishActiveRenderPass();
|
|
4854
4893
|
const commandEncoder = this.device.createCommandEncoder();
|
|
4855
4894
|
|
|
@@ -6398,7 +6437,7 @@ function rendererWebGPU(p5, fn) {
|
|
|
6398
6437
|
|
|
6399
6438
|
getNextBindingIndex({ vert, frag }, group = 0) {
|
|
6400
6439
|
// Get the highest binding index in the specified group and return the next available
|
|
6401
|
-
const samplerRegex = /@group\((\d+)\)\s*@binding\((\d+)\)\s*var
|
|
6440
|
+
const samplerRegex = /@group\((\d+)\)\s*@binding\((\d+)\)\s*var(?:<uniform>)?\s+(\w+)\s*:\s*(texture_2d<f32>|sampler|uniform|\w+)/g;
|
|
6402
6441
|
let maxBindingIndex = -1;
|
|
6403
6442
|
|
|
6404
6443
|
for (const [src, visibility] of [
|
|
@@ -6748,6 +6787,9 @@ function rendererWebGPU(p5, fn) {
|
|
|
6748
6787
|
// Inject hook uniforms as a separate struct at a new binding
|
|
6749
6788
|
let hookUniformFields = '';
|
|
6750
6789
|
for (const key in shader.hooks.uniforms) {
|
|
6790
|
+
// Skip textures, they don't get added to structs
|
|
6791
|
+
if (key.endsWith(': sampler2D')) continue;
|
|
6792
|
+
|
|
6751
6793
|
// WGSL format: "name: type"
|
|
6752
6794
|
hookUniformFields += ` ${key},\n`;
|
|
6753
6795
|
}
|
package/lib/p5.webgpu.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* @property {String} VERSION
|
|
15
15
|
* @final
|
|
16
16
|
*/
|
|
17
|
-
const VERSION = '2.2.1';
|
|
17
|
+
const VERSION = '2.2.2-rc.1';
|
|
18
18
|
|
|
19
19
|
// GRAPHICS RENDERER
|
|
20
20
|
/**
|
|
@@ -3010,7 +3010,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
3010
3010
|
const baseType = orig?.baseType ?? BaseType.FLOAT;
|
|
3011
3011
|
|
|
3012
3012
|
let newValueID;
|
|
3013
|
-
if (value
|
|
3013
|
+
if (value?.isStrandsNode) {
|
|
3014
3014
|
newValueID = value.id;
|
|
3015
3015
|
} else {
|
|
3016
3016
|
const newVal = primitiveConstructorNode(
|
|
@@ -3065,7 +3065,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
3065
3065
|
const baseType = orig?.baseType ?? BaseType.FLOAT;
|
|
3066
3066
|
|
|
3067
3067
|
let newValueID;
|
|
3068
|
-
if (value
|
|
3068
|
+
if (value?.isStrandsNode) {
|
|
3069
3069
|
newValueID = value.id;
|
|
3070
3070
|
} else {
|
|
3071
3071
|
const newVal = primitiveConstructorNode(
|
|
@@ -3355,6 +3355,20 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
3355
3355
|
|
|
3356
3356
|
function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
|
|
3357
3357
|
const cfg = strandsContext.cfg;
|
|
3358
|
+
dependsOn = (Array.isArray(dependsOn) ? dependsOn : [dependsOn])
|
|
3359
|
+
.flat(Infinity)
|
|
3360
|
+
.map(a => {
|
|
3361
|
+
if (
|
|
3362
|
+
a.isStrandsNode &&
|
|
3363
|
+
a.typeInfo().baseType === BaseType.INT &&
|
|
3364
|
+
// TODO: handle ivec inputs instead of just int scalars
|
|
3365
|
+
a.typeInfo().dimension === 1
|
|
3366
|
+
) {
|
|
3367
|
+
return castToFloat(strandsContext, a);
|
|
3368
|
+
} else {
|
|
3369
|
+
return a;
|
|
3370
|
+
}
|
|
3371
|
+
});
|
|
3358
3372
|
const { mappedDependencies, inferredTypeInfo } = mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn);
|
|
3359
3373
|
|
|
3360
3374
|
const finalType = {
|
|
@@ -3370,6 +3384,24 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
3370
3384
|
return { id, dimension: finalType.dimension, components: mappedDependencies };
|
|
3371
3385
|
}
|
|
3372
3386
|
|
|
3387
|
+
function castToFloat(strandsContext, dep) {
|
|
3388
|
+
const { id, dimension } = functionCallNode(
|
|
3389
|
+
strandsContext,
|
|
3390
|
+
strandsContext.backend.getTypeName('float', dep.typeInfo().dimension),
|
|
3391
|
+
[dep],
|
|
3392
|
+
{
|
|
3393
|
+
overloads: [{
|
|
3394
|
+
params: [dep.typeInfo()],
|
|
3395
|
+
returnType: {
|
|
3396
|
+
...dep.typeInfo(),
|
|
3397
|
+
baseType: BaseType.FLOAT,
|
|
3398
|
+
},
|
|
3399
|
+
}],
|
|
3400
|
+
}
|
|
3401
|
+
);
|
|
3402
|
+
return createStrandsNode(id, dimension, strandsContext);
|
|
3403
|
+
}
|
|
3404
|
+
|
|
3373
3405
|
function functionCallNode(
|
|
3374
3406
|
strandsContext,
|
|
3375
3407
|
functionName,
|
|
@@ -3540,7 +3572,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
3540
3572
|
// This may not be the most efficient way, as we swizzle each component individually,
|
|
3541
3573
|
// so that .xyz becomes .x, .y, .z
|
|
3542
3574
|
let scalars = [];
|
|
3543
|
-
if (value
|
|
3575
|
+
if (value?.isStrandsNode) {
|
|
3544
3576
|
if (value.dimension === 1) {
|
|
3545
3577
|
scalars = Array(chars.length).fill(value);
|
|
3546
3578
|
} else if (value.dimension === chars.length) {
|
|
@@ -3811,10 +3843,11 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
3811
3843
|
return primitiveTypeName;
|
|
3812
3844
|
},
|
|
3813
3845
|
generateHookUniformKey(name, typeInfo) {
|
|
3814
|
-
// For sampler2D types, we don't add them to the uniform struct
|
|
3815
|
-
//
|
|
3846
|
+
// For sampler2D types, we don't add them to the uniform struct,
|
|
3847
|
+
// but we still need them in the shader's hooks object so that
|
|
3848
|
+
// they can be set by users.
|
|
3816
3849
|
if (typeInfo.baseType === 'sampler2D') {
|
|
3817
|
-
return
|
|
3850
|
+
return `${name}: sampler2D`; // Signal that this should not be added to uniform struct
|
|
3818
3851
|
}
|
|
3819
3852
|
return `${name}: ${this.getTypeName(typeInfo.baseType, typeInfo.dimension)}`;
|
|
3820
3853
|
},
|
|
@@ -4596,6 +4629,10 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
4596
4629
|
this.finalCamera = new Camera(this);
|
|
4597
4630
|
this.finalCamera._computeCameraDefaultSettings();
|
|
4598
4631
|
this.finalCamera._setDefaultCamera();
|
|
4632
|
+
|
|
4633
|
+
this.depthFormat = 'depth24plus-stencil8';
|
|
4634
|
+
this.depthTexture = null;
|
|
4635
|
+
this.depthTextureView = null;
|
|
4599
4636
|
}
|
|
4600
4637
|
|
|
4601
4638
|
async setupContext() {
|
|
@@ -4636,7 +4673,6 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
4636
4673
|
});
|
|
4637
4674
|
|
|
4638
4675
|
// TODO disablable stencil
|
|
4639
|
-
this.depthFormat = 'depth24plus-stencil8';
|
|
4640
4676
|
this.mainFramebuffer = this.createFramebuffer({ _useCanvasFormat: true });
|
|
4641
4677
|
this._updateSize();
|
|
4642
4678
|
this._update();
|
|
@@ -4693,6 +4729,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
4693
4729
|
}
|
|
4694
4730
|
|
|
4695
4731
|
_updateSize() {
|
|
4732
|
+
if (!this.device || !this.depthFormat) return;
|
|
4696
4733
|
if (this.depthTexture && this.depthTexture.destroy) {
|
|
4697
4734
|
this.flushDraw();
|
|
4698
4735
|
const textureToDestroy = this.depthTexture;
|
|
@@ -4787,6 +4824,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
4787
4824
|
}
|
|
4788
4825
|
|
|
4789
4826
|
clear(...args) {
|
|
4827
|
+
if (!this.device || !this.drawingContext) return;
|
|
4790
4828
|
const _r = args[0] || 0;
|
|
4791
4829
|
const _g = args[1] || 0;
|
|
4792
4830
|
const _b = args[2] || 0;
|
|
@@ -4853,6 +4891,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
4853
4891
|
* occlude anything subsequently drawn.
|
|
4854
4892
|
*/
|
|
4855
4893
|
clearDepth(depth = 1) {
|
|
4894
|
+
if (!this.device || !this.depthTextureView) return;
|
|
4856
4895
|
this._finishActiveRenderPass();
|
|
4857
4896
|
const commandEncoder = this.device.createCommandEncoder();
|
|
4858
4897
|
|
|
@@ -6401,7 +6440,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
6401
6440
|
|
|
6402
6441
|
getNextBindingIndex({ vert, frag }, group = 0) {
|
|
6403
6442
|
// Get the highest binding index in the specified group and return the next available
|
|
6404
|
-
const samplerRegex = /@group\((\d+)\)\s*@binding\((\d+)\)\s*var
|
|
6443
|
+
const samplerRegex = /@group\((\d+)\)\s*@binding\((\d+)\)\s*var(?:<uniform>)?\s+(\w+)\s*:\s*(texture_2d<f32>|sampler|uniform|\w+)/g;
|
|
6405
6444
|
let maxBindingIndex = -1;
|
|
6406
6445
|
|
|
6407
6446
|
for (const [src, visibility] of [
|
|
@@ -6751,6 +6790,9 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
|
|
|
6751
6790
|
// Inject hook uniforms as a separate struct at a new binding
|
|
6752
6791
|
let hookUniformFields = '';
|
|
6753
6792
|
for (const key in shader.hooks.uniforms) {
|
|
6793
|
+
// Skip textures, they don't get added to structs
|
|
6794
|
+
if (key.endsWith(': sampler2D')) continue;
|
|
6795
|
+
|
|
6754
6796
|
// WGSL format: "name: type"
|
|
6755
6797
|
hookUniformFields += ` ${key},\n`;
|
|
6756
6798
|
}
|