p5 2.2.2 → 2.2.3-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 (98) hide show
  1. package/dist/accessibility/color_namer.js +5 -5
  2. package/dist/accessibility/index.js +5 -5
  3. package/dist/app.js +5 -5
  4. package/dist/color/color_conversion.js +5 -5
  5. package/dist/color/index.js +1 -1
  6. package/dist/color/setting.js +1 -1
  7. package/dist/{constants-BxjhKpTv.js → constants-BUwWryrh.js} +1 -1
  8. package/dist/core/constants.js +1 -1
  9. package/dist/core/environment.js +7 -3
  10. package/dist/core/filterShaders.js +1 -1
  11. package/dist/core/friendly_errors/fes_core.js +1 -1
  12. package/dist/core/friendly_errors/file_errors.js +1 -1
  13. package/dist/core/friendly_errors/index.js +1 -1
  14. package/dist/core/friendly_errors/param_validator.js +2063 -2014
  15. package/dist/core/friendly_errors/sketch_verifier.js +1 -1
  16. package/dist/core/helpers.js +1 -1
  17. package/dist/core/init.js +5 -5
  18. package/dist/core/internationalization.js +1 -1
  19. package/dist/core/legacy.js +5 -5
  20. package/dist/core/main.js +5 -5
  21. package/dist/core/p5.Graphics.js +3 -3
  22. package/dist/core/p5.Renderer.js +2 -2
  23. package/dist/core/p5.Renderer2D.js +5 -5
  24. package/dist/core/p5.Renderer3D.js +3 -3
  25. package/dist/core/rendering.js +3 -3
  26. package/dist/dom/dom.js +1 -1
  27. package/dist/dom/index.js +1 -1
  28. package/dist/dom/p5.Element.js +1 -1
  29. package/dist/dom/p5.MediaElement.js +11 -4
  30. package/dist/events/pointer.js +4 -0
  31. package/dist/image/const.js +1 -1
  32. package/dist/image/filterRenderer2D.js +4 -4
  33. package/dist/image/image.js +3 -3
  34. package/dist/image/index.js +3 -3
  35. package/dist/image/loading_displaying.js +3 -3
  36. package/dist/image/p5.Image.js +2 -2
  37. package/dist/io/files.js +3 -3
  38. package/dist/io/index.js +3 -3
  39. package/dist/{ir_builders-w12-GSxu.js → ir_builders-Cd6rU9Vm.js} +48 -14
  40. package/dist/{main-DDs4QOnh.js → main-DFpoFdvM.js} +126 -36
  41. package/dist/math/Matrices/Matrix.js +1 -1
  42. package/dist/math/Matrices/MatrixNumjs.js +1 -1
  43. package/dist/math/index.js +1 -1
  44. package/dist/math/p5.Matrix.js +1 -1
  45. package/dist/math/p5.Vector.js +1 -1
  46. package/dist/math/trigonometry.js +1 -1
  47. package/dist/{p5.Renderer-BSGddFv7.js → p5.Renderer-D-EuAodU.js} +9 -2
  48. package/dist/{rendering-C9g7uSQ5.js → rendering-DE9-Hl7Y.js} +103 -78
  49. package/dist/shape/2d_primitives.js +1 -1
  50. package/dist/shape/attributes.js +1 -1
  51. package/dist/shape/custom_shapes.js +1 -1
  52. package/dist/shape/index.js +1 -1
  53. package/dist/strands/ir_builders.js +1 -1
  54. package/dist/strands/ir_dag.js +32 -2
  55. package/dist/strands/ir_types.js +18 -11
  56. package/dist/strands/p5.strands.js +24 -35
  57. package/dist/strands/strands_api.js +86 -41
  58. package/dist/strands/strands_codegen.js +0 -12
  59. package/dist/strands/strands_conditionals.js +1 -1
  60. package/dist/strands/strands_for.js +1 -1
  61. package/dist/strands/strands_node.js +1 -1
  62. package/dist/strands/strands_phi_utils.js +27 -9
  63. package/dist/strands/strands_transpiler.js +1237 -831
  64. package/dist/type/index.js +2 -2
  65. package/dist/type/p5.Font.js +7 -5
  66. package/dist/type/textCore.js +2 -2
  67. package/dist/webgl/3d_primitives.js +3 -3
  68. package/dist/webgl/GeometryBuilder.js +1 -1
  69. package/dist/webgl/ShapeBuilder.js +1 -1
  70. package/dist/webgl/enums.js +1 -1
  71. package/dist/webgl/index.js +4 -4
  72. package/dist/webgl/interaction.js +1 -1
  73. package/dist/webgl/light.js +3 -3
  74. package/dist/webgl/loading.js +41 -35
  75. package/dist/webgl/material.js +3 -3
  76. package/dist/webgl/p5.Camera.js +3 -3
  77. package/dist/webgl/p5.Framebuffer.js +3 -3
  78. package/dist/webgl/p5.Geometry.js +1 -1
  79. package/dist/webgl/p5.Quat.js +1 -1
  80. package/dist/webgl/p5.RendererGL.js +4 -4
  81. package/dist/webgl/p5.Shader.js +14 -6
  82. package/dist/webgl/p5.Texture.js +3 -3
  83. package/dist/webgl/strands_glslBackend.js +1 -1
  84. package/dist/webgl/text.js +3 -3
  85. package/dist/webgl/utils.js +3 -3
  86. package/dist/webgpu/index.js +2 -2
  87. package/dist/webgpu/p5.RendererWebGPU.js +2 -2
  88. package/dist/webgpu/strands_wgslBackend.js +13 -4
  89. package/lib/p5.esm.js +3670 -2951
  90. package/lib/p5.esm.min.js +1 -1
  91. package/lib/p5.js +3670 -2951
  92. package/lib/p5.min.js +1 -1
  93. package/lib/p5.webgpu.esm.js +43 -21
  94. package/lib/p5.webgpu.js +43 -21
  95. package/lib/p5.webgpu.min.js +1 -1
  96. package/package.json +1 -1
  97. package/types/global.d.ts +1283 -1301
  98. package/types/p5.d.ts +655 -657
@@ -11,7 +11,7 @@ const _PI = Math.PI;
11
11
  * @property {String} VERSION
12
12
  * @final
13
13
  */
14
- const VERSION = '2.2.2';
14
+ const VERSION = '2.2.3-rc.1';
15
15
 
16
16
  // GRAPHICS RENDERER
17
17
  /**
@@ -1459,6 +1459,7 @@ const BaseType = {
1459
1459
  BOOL: "bool",
1460
1460
  MAT: "mat",
1461
1461
  DEFER: "defer",
1462
+ ASSIGN_ON_USE: "assign_on_use",
1462
1463
  SAMPLER2D: "sampler2D",
1463
1464
  SAMPLER: "sampler",
1464
1465
  };
@@ -1468,6 +1469,7 @@ const BasePriority = {
1468
1469
  [BaseType.BOOL]: 1,
1469
1470
  [BaseType.MAT]: 0,
1470
1471
  [BaseType.DEFER]: -1,
1472
+ [BaseType.ASSIGN_ON_USE]: -2,
1471
1473
  [BaseType.SAMPLER2D]: -10,
1472
1474
  [BaseType.SAMPLER]: -11,
1473
1475
  };
@@ -1488,6 +1490,7 @@ const DataType = {
1488
1490
  mat3: { fnName: "mat3x3", baseType: BaseType.MAT, dimension:3, priority: 0, },
1489
1491
  mat4: { fnName: "mat4x4", baseType: BaseType.MAT, dimension:4, priority: 0, },
1490
1492
  defer: { fnName: null, baseType: BaseType.DEFER, dimension: null, priority: -1 },
1493
+ assign_on_use: { fnName: null, baseType: BaseType.ASSIGN_ON_USE, dimension: null, priority: -2 },
1491
1494
  sampler2D: { fnName: "sampler2D", baseType: BaseType.SAMPLER2D, dimension: 1, priority: -10 },
1492
1495
  sampler: { fnName: "sampler", baseType: BaseType.SAMPLER, dimension: 1, priority: -11 },
1493
1496
  };
@@ -1535,7 +1538,7 @@ const OpCode = {
1535
1538
  CONSTRUCTOR: 201,
1536
1539
  }};
1537
1540
  const OperatorTable = [
1538
- { arity: "unary", name: "not", symbol: "!", opCode: OpCode.Unary.LOGICAL_NOT },
1541
+ { arity: "unary", boolean: true, name: "not", symbol: "!", opCode: OpCode.Unary.LOGICAL_NOT },
1539
1542
  { arity: "unary", name: "neg", symbol: "-", opCode: OpCode.Unary.NEGATE },
1540
1543
  { arity: "unary", name: "plus", symbol: "+", opCode: OpCode.Unary.PLUS },
1541
1544
  { arity: "binary", name: "add", symbol: "+", opCode: OpCode.Binary.ADD },
@@ -1543,18 +1546,18 @@ const OperatorTable = [
1543
1546
  { arity: "binary", name: "mult", symbol: "*", opCode: OpCode.Binary.MULTIPLY },
1544
1547
  { arity: "binary", name: "div", symbol: "/", opCode: OpCode.Binary.DIVIDE },
1545
1548
  { arity: "binary", name: "mod", symbol: "%", opCode: OpCode.Binary.MODULO },
1546
- { arity: "binary", name: "equalTo", symbol: "==", opCode: OpCode.Binary.EQUAL },
1547
- { arity: "binary", name: "notEqual", symbol: "!=", opCode: OpCode.Binary.NOT_EQUAL },
1548
- { arity: "binary", name: "greaterThan", symbol: ">", opCode: OpCode.Binary.GREATER_THAN },
1549
- { arity: "binary", name: "greaterEqual", symbol: ">=", opCode: OpCode.Binary.GREATER_EQUAL },
1550
- { arity: "binary", name: "lessThan", symbol: "<", opCode: OpCode.Binary.LESS_THAN },
1551
- { arity: "binary", name: "lessEqual", symbol: "<=", opCode: OpCode.Binary.LESS_EQUAL },
1552
- { arity: "binary", name: "and", symbol: "&&", opCode: OpCode.Binary.LOGICAL_AND },
1553
- { arity: "binary", name: "or", symbol: "||", opCode: OpCode.Binary.LOGICAL_OR },
1549
+ { arity: "binary", boolean: true, name: "equalTo", symbol: "==", opCode: OpCode.Binary.EQUAL },
1550
+ { arity: "binary", boolean: true, name: "notEqual", symbol: "!=", opCode: OpCode.Binary.NOT_EQUAL },
1551
+ { arity: "binary", boolean: true, name: "greaterThan", symbol: ">", opCode: OpCode.Binary.GREATER_THAN },
1552
+ { arity: "binary", boolean: true, name: "greaterEqual", symbol: ">=", opCode: OpCode.Binary.GREATER_EQUAL },
1553
+ { arity: "binary", boolean: true, name: "lessThan", symbol: "<", opCode: OpCode.Binary.LESS_THAN },
1554
+ { arity: "binary", boolean: true, name: "lessEqual", symbol: "<=", opCode: OpCode.Binary.LESS_EQUAL },
1555
+ { arity: "binary", boolean: true, name: "and", symbol: "&&", opCode: OpCode.Binary.LOGICAL_AND },
1556
+ { arity: "binary", boolean: true, name: "or", symbol: "||", opCode: OpCode.Binary.LOGICAL_OR },
1554
1557
  ];
1555
1558
  // export const SymbolToOpCode = {};
1556
1559
  const OpCodeToSymbol = {};
1557
- for (const { symbol, opCode, name, arity } of OperatorTable) {
1560
+ for (const { symbol, opCode, name, arity, boolean } of OperatorTable) {
1558
1561
  // SymbolToOpCode[symbol] = opCode;
1559
1562
  OpCodeToSymbol[opCode] = symbol;
1560
1563
  }
@@ -3036,9 +3039,6 @@ class StrandsNode {
3036
3039
  const assignmentID = getOrCreateNode(dag, assignmentNode);
3037
3040
  recordInBasicBlock(cfg, cfg.currentBlock, assignmentID);
3038
3041
 
3039
- // Track for global assignments processing
3040
- this.strandsContext.globalAssignments.push(assignmentID);
3041
-
3042
3042
  // Simply update this node to be a variable node with the identifier
3043
3043
  // This ensures it always generates the variable name in expressions
3044
3044
  const variableNodeData = createNodeData({
@@ -3102,9 +3102,6 @@ class StrandsNode {
3102
3102
  const assignmentID = getOrCreateNode(dag, assignmentNode);
3103
3103
  recordInBasicBlock(cfg, cfg.currentBlock, assignmentID);
3104
3104
 
3105
- // Track for global assignments processing in the current hook context
3106
- this.strandsContext.globalAssignments.push(assignmentID);
3107
-
3108
3105
  // Simply update this node to be a variable node with the identifier
3109
3106
  // This ensures it always generates the variable name in expressions
3110
3107
  const variableNodeData = createNodeData({
@@ -3319,6 +3316,17 @@ function mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn) {
3319
3316
  calculatedDimensions += dimension;
3320
3317
  continue;
3321
3318
  }
3319
+ else if (typeof dep === 'boolean') {
3320
+ // Handle boolean literals - convert to bool type
3321
+ const { id, dimension } = scalarLiteralNode(strandsContext, { dimension: 1, baseType: BaseType.BOOL }, dep);
3322
+ mappedDependencies.push(id);
3323
+ calculatedDimensions += dimension;
3324
+ // Update baseType to BOOL if it was inferred
3325
+ if (baseType !== BaseType.BOOL) {
3326
+ baseType = BaseType.BOOL;
3327
+ }
3328
+ continue;
3329
+ }
3322
3330
  else {
3323
3331
  userError('type error', `You've tried to construct a scalar or vector type with a non-numeric value: ${dep}`);
3324
3332
  }
@@ -3369,7 +3377,12 @@ function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
3369
3377
  const { mappedDependencies, inferredTypeInfo } = mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn);
3370
3378
 
3371
3379
  const finalType = {
3372
- baseType: typeInfo.baseType,
3380
+ // We might have inferred a non numeric type. Currently this is
3381
+ // just used for booleans. Maybe this needs to be something more robust
3382
+ // if we ever want to support inference of e.g. int vectors?
3383
+ baseType: inferredTypeInfo.baseType === BaseType.BOOL
3384
+ ? BaseType.BOOL
3385
+ : typeInfo.baseType,
3373
3386
  dimension: inferredTypeInfo.dimension
3374
3387
  };
3375
3388
 
@@ -3690,10 +3703,10 @@ const cfgHandlers = {
3690
3703
  // Initialize with default value - WGSL requires initialization
3691
3704
  let defaultValue;
3692
3705
  if (T.dimension === 1) {
3693
- defaultValue = T.baseType === 'float' ? '0.0' : '0';
3706
+ defaultValue = this.defaultScalarValue(T.baseType);
3694
3707
  } else {
3695
3708
  // For vector types, use constructor with repeated scalar values
3696
- const scalarDefault = T.baseType === 'float' ? '0.0' : '0';
3709
+ const scalarDefault = this.defaultScalarValue(T.baseType);
3697
3710
  const components = Array(T.dimension).fill(scalarDefault).join(', ');
3698
3711
  defaultValue = `${typeName}(${components})`;
3699
3712
  }
@@ -3702,6 +3715,15 @@ const cfgHandlers = {
3702
3715
  }
3703
3716
  this[BlockType.DEFAULT](blockID, strandsContext, generationContext);
3704
3717
  },
3718
+ defaultScalarValue(baseType) {
3719
+ if (baseType === BaseType.FLOAT) {
3720
+ return '0.0';
3721
+ } else if (baseType === BaseType.BOOL) {
3722
+ return 'false';
3723
+ } else {
3724
+ return '0';
3725
+ }
3726
+ },
3705
3727
  [BlockType.IF_COND](blockID, strandsContext, generationContext) {
3706
3728
  const { dag, cfg } = strandsContext;
3707
3729
  const conditionID = cfg.blockConditions[blockID];
@@ -4081,7 +4103,7 @@ const wgslBackend = {
4081
4103
  if (validInputs.length > 0) {
4082
4104
  return this.generateExpression(generationContext, dag, validInputs[0]);
4083
4105
  } else {
4084
- throw new Error(`No valid inputs for node`)
4106
+ throw new Error('No valid inputs for node');
4085
4107
  }
4086
4108
  }
4087
4109
  case NodeType.ASSIGNMENT:
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.2';
17
+ const VERSION = '2.2.3-rc.1';
18
18
 
19
19
  // GRAPHICS RENDERER
20
20
  /**
@@ -1462,6 +1462,7 @@
1462
1462
  BOOL: "bool",
1463
1463
  MAT: "mat",
1464
1464
  DEFER: "defer",
1465
+ ASSIGN_ON_USE: "assign_on_use",
1465
1466
  SAMPLER2D: "sampler2D",
1466
1467
  SAMPLER: "sampler",
1467
1468
  };
@@ -1471,6 +1472,7 @@
1471
1472
  [BaseType.BOOL]: 1,
1472
1473
  [BaseType.MAT]: 0,
1473
1474
  [BaseType.DEFER]: -1,
1475
+ [BaseType.ASSIGN_ON_USE]: -2,
1474
1476
  [BaseType.SAMPLER2D]: -10,
1475
1477
  [BaseType.SAMPLER]: -11,
1476
1478
  };
@@ -1491,6 +1493,7 @@
1491
1493
  mat3: { fnName: "mat3x3", baseType: BaseType.MAT, dimension:3, priority: 0, },
1492
1494
  mat4: { fnName: "mat4x4", baseType: BaseType.MAT, dimension:4, priority: 0, },
1493
1495
  defer: { fnName: null, baseType: BaseType.DEFER, dimension: null, priority: -1 },
1496
+ assign_on_use: { fnName: null, baseType: BaseType.ASSIGN_ON_USE, dimension: null, priority: -2 },
1494
1497
  sampler2D: { fnName: "sampler2D", baseType: BaseType.SAMPLER2D, dimension: 1, priority: -10 },
1495
1498
  sampler: { fnName: "sampler", baseType: BaseType.SAMPLER, dimension: 1, priority: -11 },
1496
1499
  };
@@ -1538,7 +1541,7 @@
1538
1541
  CONSTRUCTOR: 201,
1539
1542
  }};
1540
1543
  const OperatorTable = [
1541
- { arity: "unary", name: "not", symbol: "!", opCode: OpCode.Unary.LOGICAL_NOT },
1544
+ { arity: "unary", boolean: true, name: "not", symbol: "!", opCode: OpCode.Unary.LOGICAL_NOT },
1542
1545
  { arity: "unary", name: "neg", symbol: "-", opCode: OpCode.Unary.NEGATE },
1543
1546
  { arity: "unary", name: "plus", symbol: "+", opCode: OpCode.Unary.PLUS },
1544
1547
  { arity: "binary", name: "add", symbol: "+", opCode: OpCode.Binary.ADD },
@@ -1546,18 +1549,18 @@
1546
1549
  { arity: "binary", name: "mult", symbol: "*", opCode: OpCode.Binary.MULTIPLY },
1547
1550
  { arity: "binary", name: "div", symbol: "/", opCode: OpCode.Binary.DIVIDE },
1548
1551
  { arity: "binary", name: "mod", symbol: "%", opCode: OpCode.Binary.MODULO },
1549
- { arity: "binary", name: "equalTo", symbol: "==", opCode: OpCode.Binary.EQUAL },
1550
- { arity: "binary", name: "notEqual", symbol: "!=", opCode: OpCode.Binary.NOT_EQUAL },
1551
- { arity: "binary", name: "greaterThan", symbol: ">", opCode: OpCode.Binary.GREATER_THAN },
1552
- { arity: "binary", name: "greaterEqual", symbol: ">=", opCode: OpCode.Binary.GREATER_EQUAL },
1553
- { arity: "binary", name: "lessThan", symbol: "<", opCode: OpCode.Binary.LESS_THAN },
1554
- { arity: "binary", name: "lessEqual", symbol: "<=", opCode: OpCode.Binary.LESS_EQUAL },
1555
- { arity: "binary", name: "and", symbol: "&&", opCode: OpCode.Binary.LOGICAL_AND },
1556
- { arity: "binary", name: "or", symbol: "||", opCode: OpCode.Binary.LOGICAL_OR },
1552
+ { arity: "binary", boolean: true, name: "equalTo", symbol: "==", opCode: OpCode.Binary.EQUAL },
1553
+ { arity: "binary", boolean: true, name: "notEqual", symbol: "!=", opCode: OpCode.Binary.NOT_EQUAL },
1554
+ { arity: "binary", boolean: true, name: "greaterThan", symbol: ">", opCode: OpCode.Binary.GREATER_THAN },
1555
+ { arity: "binary", boolean: true, name: "greaterEqual", symbol: ">=", opCode: OpCode.Binary.GREATER_EQUAL },
1556
+ { arity: "binary", boolean: true, name: "lessThan", symbol: "<", opCode: OpCode.Binary.LESS_THAN },
1557
+ { arity: "binary", boolean: true, name: "lessEqual", symbol: "<=", opCode: OpCode.Binary.LESS_EQUAL },
1558
+ { arity: "binary", boolean: true, name: "and", symbol: "&&", opCode: OpCode.Binary.LOGICAL_AND },
1559
+ { arity: "binary", boolean: true, name: "or", symbol: "||", opCode: OpCode.Binary.LOGICAL_OR },
1557
1560
  ];
1558
1561
  // export const SymbolToOpCode = {};
1559
1562
  const OpCodeToSymbol = {};
1560
- for (const { symbol, opCode, name, arity } of OperatorTable) {
1563
+ for (const { symbol, opCode, name, arity, boolean } of OperatorTable) {
1561
1564
  // SymbolToOpCode[symbol] = opCode;
1562
1565
  OpCodeToSymbol[opCode] = symbol;
1563
1566
  }
@@ -3039,9 +3042,6 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
3039
3042
  const assignmentID = getOrCreateNode(dag, assignmentNode);
3040
3043
  recordInBasicBlock(cfg, cfg.currentBlock, assignmentID);
3041
3044
 
3042
- // Track for global assignments processing
3043
- this.strandsContext.globalAssignments.push(assignmentID);
3044
-
3045
3045
  // Simply update this node to be a variable node with the identifier
3046
3046
  // This ensures it always generates the variable name in expressions
3047
3047
  const variableNodeData = createNodeData({
@@ -3105,9 +3105,6 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
3105
3105
  const assignmentID = getOrCreateNode(dag, assignmentNode);
3106
3106
  recordInBasicBlock(cfg, cfg.currentBlock, assignmentID);
3107
3107
 
3108
- // Track for global assignments processing in the current hook context
3109
- this.strandsContext.globalAssignments.push(assignmentID);
3110
-
3111
3108
  // Simply update this node to be a variable node with the identifier
3112
3109
  // This ensures it always generates the variable name in expressions
3113
3110
  const variableNodeData = createNodeData({
@@ -3322,6 +3319,17 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
3322
3319
  calculatedDimensions += dimension;
3323
3320
  continue;
3324
3321
  }
3322
+ else if (typeof dep === 'boolean') {
3323
+ // Handle boolean literals - convert to bool type
3324
+ const { id, dimension } = scalarLiteralNode(strandsContext, { dimension: 1, baseType: BaseType.BOOL }, dep);
3325
+ mappedDependencies.push(id);
3326
+ calculatedDimensions += dimension;
3327
+ // Update baseType to BOOL if it was inferred
3328
+ if (baseType !== BaseType.BOOL) {
3329
+ baseType = BaseType.BOOL;
3330
+ }
3331
+ continue;
3332
+ }
3325
3333
  else {
3326
3334
  userError('type error', `You've tried to construct a scalar or vector type with a non-numeric value: ${dep}`);
3327
3335
  }
@@ -3372,7 +3380,12 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
3372
3380
  const { mappedDependencies, inferredTypeInfo } = mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn);
3373
3381
 
3374
3382
  const finalType = {
3375
- baseType: typeInfo.baseType,
3383
+ // We might have inferred a non numeric type. Currently this is
3384
+ // just used for booleans. Maybe this needs to be something more robust
3385
+ // if we ever want to support inference of e.g. int vectors?
3386
+ baseType: inferredTypeInfo.baseType === BaseType.BOOL
3387
+ ? BaseType.BOOL
3388
+ : typeInfo.baseType,
3376
3389
  dimension: inferredTypeInfo.dimension
3377
3390
  };
3378
3391
 
@@ -3693,10 +3706,10 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
3693
3706
  // Initialize with default value - WGSL requires initialization
3694
3707
  let defaultValue;
3695
3708
  if (T.dimension === 1) {
3696
- defaultValue = T.baseType === 'float' ? '0.0' : '0';
3709
+ defaultValue = this.defaultScalarValue(T.baseType);
3697
3710
  } else {
3698
3711
  // For vector types, use constructor with repeated scalar values
3699
- const scalarDefault = T.baseType === 'float' ? '0.0' : '0';
3712
+ const scalarDefault = this.defaultScalarValue(T.baseType);
3700
3713
  const components = Array(T.dimension).fill(scalarDefault).join(', ');
3701
3714
  defaultValue = `${typeName}(${components})`;
3702
3715
  }
@@ -3705,6 +3718,15 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
3705
3718
  }
3706
3719
  this[BlockType.DEFAULT](blockID, strandsContext, generationContext);
3707
3720
  },
3721
+ defaultScalarValue(baseType) {
3722
+ if (baseType === BaseType.FLOAT) {
3723
+ return '0.0';
3724
+ } else if (baseType === BaseType.BOOL) {
3725
+ return 'false';
3726
+ } else {
3727
+ return '0';
3728
+ }
3729
+ },
3708
3730
  [BlockType.IF_COND](blockID, strandsContext, generationContext) {
3709
3731
  const { dag, cfg } = strandsContext;
3710
3732
  const conditionID = cfg.blockConditions[blockID];
@@ -4084,7 +4106,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
4084
4106
  if (validInputs.length > 0) {
4085
4107
  return this.generateExpression(generationContext, dag, validInputs[0]);
4086
4108
  } else {
4087
- throw new Error(`No valid inputs for node`)
4109
+ throw new Error('No valid inputs for node');
4088
4110
  }
4089
4111
  }
4090
4112
  case NodeType.ASSIGNMENT: