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.
Files changed (94) hide show
  1. package/dist/accessibility/color_namer.js +6 -6
  2. package/dist/accessibility/index.js +6 -6
  3. package/dist/app.js +6 -6
  4. package/dist/color/color_conversion.js +6 -6
  5. package/dist/color/creating_reading.js +1 -1
  6. package/dist/color/index.js +2 -2
  7. package/dist/color/p5.Color.js +1 -1
  8. package/dist/color/setting.js +2 -2
  9. package/dist/{constants-DQyACdzq.js → constants-DAnmXDew.js} +1 -1
  10. package/dist/core/constants.js +1 -1
  11. package/dist/core/environment.js +1 -1
  12. package/dist/core/filterShaders.js +1 -1
  13. package/dist/core/friendly_errors/fes_core.js +1 -1
  14. package/dist/core/friendly_errors/file_errors.js +1 -1
  15. package/dist/core/friendly_errors/index.js +1 -1
  16. package/dist/core/friendly_errors/param_validator.js +1 -1
  17. package/dist/core/friendly_errors/sketch_verifier.js +2 -2
  18. package/dist/core/helpers.js +1 -1
  19. package/dist/core/init.js +6 -6
  20. package/dist/core/internationalization.js +1 -1
  21. package/dist/core/legacy.js +6 -6
  22. package/dist/core/main.js +6 -6
  23. package/dist/core/p5.Graphics.js +4 -4
  24. package/dist/core/p5.Renderer.js +3 -3
  25. package/dist/core/p5.Renderer2D.js +6 -6
  26. package/dist/core/p5.Renderer3D.js +4 -4
  27. package/dist/core/rendering.js +4 -4
  28. package/dist/{creating_reading-ZXzcZEsb.js → creating_reading-C7hu6sg1.js} +2 -2
  29. package/dist/dom/dom.js +2 -2
  30. package/dist/dom/index.js +2 -2
  31. package/dist/dom/p5.Element.js +2 -2
  32. package/dist/dom/p5.MediaElement.js +2 -2
  33. package/dist/image/const.js +1 -1
  34. package/dist/image/filterRenderer2D.js +5 -5
  35. package/dist/image/image.js +4 -4
  36. package/dist/image/index.js +4 -4
  37. package/dist/image/loading_displaying.js +4 -4
  38. package/dist/image/p5.Image.js +3 -3
  39. package/dist/io/files.js +4 -4
  40. package/dist/io/index.js +4 -4
  41. package/dist/{ir_builders-DXNgaB9N.js → ir_builders-w12-GSxu.js} +37 -5
  42. package/dist/{main-DvN69W3f.js → main-E-swj5tF.js} +4 -4
  43. package/dist/math/Matrices/Matrix.js +1 -1
  44. package/dist/math/Matrices/MatrixNumjs.js +1 -1
  45. package/dist/math/index.js +1 -1
  46. package/dist/math/p5.Matrix.js +1 -1
  47. package/dist/math/p5.Vector.js +1 -1
  48. package/dist/math/trigonometry.js +1 -1
  49. package/dist/{p5.Renderer-D-5LdCRz.js → p5.Renderer-DOk9UW65.js} +2 -2
  50. package/dist/{rendering-h9unX5K0.js → rendering-B8V5Zt4k.js} +58 -14
  51. package/dist/shape/2d_primitives.js +1 -1
  52. package/dist/shape/attributes.js +1 -1
  53. package/dist/shape/custom_shapes.js +2 -2
  54. package/dist/shape/index.js +2 -2
  55. package/dist/strands/ir_builders.js +1 -1
  56. package/dist/strands/p5.strands.js +1 -1
  57. package/dist/strands/strands_api.js +91 -31
  58. package/dist/strands/strands_conditionals.js +1 -1
  59. package/dist/strands/strands_for.js +2 -2
  60. package/dist/strands/strands_node.js +1 -1
  61. package/dist/type/index.js +3 -3
  62. package/dist/type/p5.Font.js +3 -3
  63. package/dist/type/textCore.js +3 -3
  64. package/dist/webgl/3d_primitives.js +4 -4
  65. package/dist/webgl/GeometryBuilder.js +1 -1
  66. package/dist/webgl/ShapeBuilder.js +1 -1
  67. package/dist/webgl/enums.js +1 -1
  68. package/dist/webgl/index.js +5 -5
  69. package/dist/webgl/interaction.js +1 -1
  70. package/dist/webgl/light.js +4 -4
  71. package/dist/webgl/loading.js +12 -14
  72. package/dist/webgl/material.js +4 -4
  73. package/dist/webgl/p5.Camera.js +4 -4
  74. package/dist/webgl/p5.Framebuffer.js +4 -4
  75. package/dist/webgl/p5.Geometry.js +1 -1
  76. package/dist/webgl/p5.Quat.js +1 -1
  77. package/dist/webgl/p5.RendererGL.js +5 -5
  78. package/dist/webgl/p5.Texture.js +4 -4
  79. package/dist/webgl/strands_glslBackend.js +1 -1
  80. package/dist/webgl/text.js +5 -5
  81. package/dist/webgl/utils.js +4 -4
  82. package/dist/webgpu/index.js +2 -2
  83. package/dist/webgpu/p5.RendererWebGPU.js +13 -4
  84. package/dist/webgpu/strands_wgslBackend.js +5 -4
  85. package/lib/p5.esm.js +196 -62
  86. package/lib/p5.esm.min.js +1 -1
  87. package/lib/p5.js +196 -62
  88. package/lib/p5.min.js +1 -1
  89. package/lib/p5.webgpu.esm.js +51 -9
  90. package/lib/p5.webgpu.js +51 -9
  91. package/lib/p5.webgpu.min.js +1 -1
  92. package/package.json +1 -1
  93. package/types/global.d.ts +1453 -1383
  94. package/types/p5.d.ts +729 -694
@@ -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 instanceof StrandsNode) {
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 instanceof StrandsNode) {
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 instanceof StrandsNode) {
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
- // Instead, they become separate texture and sampler bindings
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 null; // Signal that this should not be added to uniform struct
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\s+(\w+)\s*:\s*(texture_2d<f32>|sampler|uniform)/g;
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 instanceof StrandsNode) {
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 instanceof StrandsNode) {
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 instanceof StrandsNode) {
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
- // Instead, they become separate texture and sampler bindings
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 null; // Signal that this should not be added to uniform struct
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\s+(\w+)\s*:\s*(texture_2d<f32>|sampler|uniform)/g;
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
  }