p5 2.2.1-rc.0 → 2.2.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 (117) hide show
  1. package/dist/accessibility/color_namer.js +5 -6
  2. package/dist/accessibility/describe.js +4 -26
  3. package/dist/accessibility/index.js +5 -6
  4. package/dist/accessibility/outputs.js +6 -38
  5. package/dist/app.js +5 -6
  6. package/dist/color/color_conversion.js +5 -6
  7. package/dist/color/creating_reading.js +1 -1
  8. package/dist/color/index.js +2 -2
  9. package/dist/color/p5.Color.js +1 -1
  10. package/dist/color/setting.js +59 -357
  11. package/dist/{constants-DEJVKr9Z.js → constants-DQyACdzq.js} +11 -61
  12. package/dist/core/constants.js +1 -1
  13. package/dist/core/environment.js +26 -158
  14. package/dist/core/filterShaders.js +1 -1
  15. package/dist/core/friendly_errors/fes_core.js +1 -1
  16. package/dist/core/friendly_errors/file_errors.js +1 -1
  17. package/dist/core/friendly_errors/index.js +1 -1
  18. package/dist/core/friendly_errors/param_validator.js +1 -1
  19. package/dist/core/friendly_errors/sketch_verifier.js +1 -1
  20. package/dist/core/helpers.js +1 -1
  21. package/dist/core/init.js +5 -6
  22. package/dist/core/internationalization.js +1 -1
  23. package/dist/core/legacy.js +5 -6
  24. package/dist/core/main.js +5 -6
  25. package/dist/core/p5.Graphics.js +4 -5
  26. package/dist/core/p5.Renderer.js +3 -4
  27. package/dist/core/p5.Renderer2D.js +5 -6
  28. package/dist/core/p5.Renderer3D.js +4 -5
  29. package/dist/core/rendering.js +4 -5
  30. package/dist/core/structure.js +13 -52
  31. package/dist/core/transform.js +32 -176
  32. package/dist/{creating_reading-CgHCHxqN.js → creating_reading-ZXzcZEsb.js} +3 -196
  33. package/dist/data/local_storage.js +4 -30
  34. package/dist/dom/dom.js +24 -159
  35. package/dist/dom/index.js +2 -2
  36. package/dist/dom/p5.Element.js +31 -208
  37. package/dist/dom/p5.File.js +1 -32
  38. package/dist/dom/p5.MediaElement.js +10 -113
  39. package/dist/events/acceleration.js +11 -64
  40. package/dist/events/keyboard.js +13 -81
  41. package/dist/events/pointer.js +18 -160
  42. package/dist/image/const.js +1 -1
  43. package/dist/image/filterRenderer2D.js +4 -5
  44. package/dist/image/image.js +4 -5
  45. package/dist/image/index.js +4 -5
  46. package/dist/image/loading_displaying.js +4 -5
  47. package/dist/image/p5.Image.js +3 -4
  48. package/dist/image/pixels.js +17 -100
  49. package/dist/io/files.js +4 -5
  50. package/dist/io/index.js +4 -5
  51. package/dist/io/p5.Table.js +66 -158
  52. package/dist/io/p5.TableRow.js +48 -71
  53. package/dist/io/p5.XML.js +6 -99
  54. package/dist/io/utilities.js +8 -3
  55. package/dist/{main-_RXV5Lx8.js → main-DvN69W3f.js} +13 -42
  56. package/dist/math/Matrices/Matrix.js +87 -126
  57. package/dist/math/Matrices/MatrixNumjs.js +1 -5
  58. package/dist/math/calculation.js +10 -112
  59. package/dist/math/index.js +1 -1
  60. package/dist/math/math.js +2 -12
  61. package/dist/math/noise.js +5 -32
  62. package/dist/math/p5.Matrix.js +3 -3
  63. package/dist/math/p5.Vector.js +104 -345
  64. package/dist/math/random.js +5 -32
  65. package/dist/math/trigonometry.js +15 -105
  66. package/dist/{p5.Renderer-QoFcvj3f.js → p5.Renderer-D-5LdCRz.js} +25 -178
  67. package/dist/{rendering-CsICjEXA.js → rendering-h9unX5K0.js} +254 -1156
  68. package/dist/shape/2d_primitives.js +33 -194
  69. package/dist/shape/attributes.js +12 -73
  70. package/dist/shape/curves.js +30 -95
  71. package/dist/shape/custom_shapes.js +63 -144
  72. package/dist/shape/index.js +2 -2
  73. package/dist/shape/vertex.js +21 -106
  74. package/dist/strands/p5.strands.js +248 -46
  75. package/dist/type/index.js +3 -4
  76. package/dist/type/p5.Font.js +4 -49
  77. package/dist/type/textCore.js +5 -158
  78. package/dist/utilities/conversion.js +17 -104
  79. package/dist/utilities/time_date.js +3 -40
  80. package/dist/utilities/utility_functions.js +6 -48
  81. package/dist/webgl/3d_primitives.js +4 -5
  82. package/dist/webgl/GeometryBuilder.js +1 -2
  83. package/dist/webgl/ShapeBuilder.js +22 -2
  84. package/dist/webgl/enums.js +1 -1
  85. package/dist/webgl/index.js +4 -5
  86. package/dist/webgl/interaction.js +6 -33
  87. package/dist/webgl/light.js +4 -5
  88. package/dist/webgl/loading.js +12 -46
  89. package/dist/webgl/material.js +4 -5
  90. package/dist/webgl/p5.Camera.js +4 -5
  91. package/dist/webgl/p5.DataArray.js +0 -4
  92. package/dist/webgl/p5.Framebuffer.js +4 -5
  93. package/dist/webgl/p5.Geometry.js +12 -106
  94. package/dist/webgl/p5.Quat.js +1 -1
  95. package/dist/webgl/p5.RendererGL.js +7 -18
  96. package/dist/webgl/p5.Shader.js +12 -36
  97. package/dist/webgl/p5.Texture.js +4 -5
  98. package/dist/webgl/text.js +4 -5
  99. package/dist/webgl/utils.js +4 -5
  100. package/dist/webgpu/index.js +1 -1
  101. package/dist/webgpu/p5.RendererWebGPU.js +529 -208
  102. package/dist/webgpu/shaders/color.js +32 -17
  103. package/dist/webgpu/shaders/filters/base.js +18 -7
  104. package/dist/webgpu/shaders/font.js +52 -40
  105. package/dist/webgpu/shaders/line.js +50 -36
  106. package/dist/webgpu/shaders/material.js +90 -83
  107. package/dist/webgpu/strands_wgslBackend.js +5 -2
  108. package/lib/p5.esm.js +5576 -7811
  109. package/lib/p5.esm.min.js +1 -1
  110. package/lib/p5.js +5576 -7811
  111. package/lib/p5.min.js +1 -1
  112. package/lib/p5.webgpu.esm.js +786 -453
  113. package/lib/p5.webgpu.js +786 -453
  114. package/lib/p5.webgpu.min.js +1 -1
  115. package/package.json +13 -13
  116. package/types/global.d.ts +16905 -16783
  117. package/types/p5.d.ts +11142 -11081
@@ -1,19 +1,30 @@
1
1
  const uniforms = `
2
- struct Uniforms {
2
+ // Group 0: Material Properties
3
+ struct MaterialUniforms {
4
+ uUseVertexColor: u32,
5
+ }
6
+
7
+ // Group 1: Model Transform
8
+ struct ModelUniforms {
3
9
  // @p5 ifdef Vertex getWorldInputs
4
10
  uModelMatrix: mat4x4<f32>,
5
- uViewMatrix: mat4x4<f32>,
6
11
  uModelNormalMatrix: mat3x3<f32>,
7
- uCameraNormalMatrix: mat3x3<f32>,
8
12
  // @p5 endif
9
13
  // @p5 ifndef Vertex getWorldInputs
10
14
  uModelViewMatrix: mat4x4<f32>,
11
15
  uNormalMatrix: mat3x3<f32>,
12
16
  // @p5 endif
13
- uProjectionMatrix: mat4x4<f32>,
14
17
  uMaterialColor: vec4<f32>,
15
- uUseVertexColor: u32,
16
- };
18
+ }
19
+
20
+ // Group 2: Camera and Projection
21
+ struct CameraUniforms {
22
+ uProjectionMatrix: mat4x4<f32>,
23
+ // @p5 ifdef Vertex getWorldInputs
24
+ uViewMatrix: mat4x4<f32>,
25
+ // @p5 endif
26
+ uCameraNormalMatrix: mat3x3<f32>,
27
+ }
17
28
  `;
18
29
 
19
30
  const colorVertexShader = `
@@ -32,7 +43,9 @@ struct VertexOutput {
32
43
  };
33
44
 
34
45
  ${uniforms}
35
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
46
+ @group(0) @binding(0) var<uniform> material: MaterialUniforms;
47
+ @group(1) @binding(0) var<uniform> model: ModelUniforms;
48
+ @group(2) @binding(0) var<uniform> camera: CameraUniforms;
36
49
 
37
50
  struct Vertex {
38
51
  position: vec3<f32>,
@@ -46,12 +59,12 @@ fn main(input: VertexInput) -> VertexOutput {
46
59
  HOOK_beforeVertex();
47
60
  var output: VertexOutput;
48
61
 
49
- let useVertexColor = (uniforms.uUseVertexColor != 0 && input.aVertexColor.x >= 0.0);
62
+ let useVertexColor = (material.uUseVertexColor != 0 && input.aVertexColor.x >= 0.0);
50
63
  var inputs = Vertex(
51
64
  input.aPosition,
52
65
  input.aNormal,
53
66
  input.aTexCoord,
54
- select(uniforms.uMaterialColor, input.aVertexColor, useVertexColor)
67
+ select(model.uMaterialColor, input.aVertexColor, useVertexColor)
55
68
  );
56
69
 
57
70
  // @p5 ifdef Vertex getObjectInputs
@@ -59,20 +72,20 @@ fn main(input: VertexInput) -> VertexOutput {
59
72
  // @p5 endif
60
73
 
61
74
  // @p5 ifdef Vertex getWorldInputs
62
- inputs.position = (uniforms.uModelMatrix * vec4<f32>(inputs.position, 1.0)).xyz;
63
- inputs.normal = uniforms.uModelNormalMatrix * inputs.normal;
75
+ inputs.position = (model.uModelMatrix * vec4<f32>(inputs.position, 1.0)).xyz;
76
+ inputs.normal = model.uModelNormalMatrix * inputs.normal;
64
77
  inputs = HOOK_getWorldInputs(inputs);
65
78
  // @p5 endif
66
79
 
67
80
  // @p5 ifdef Vertex getWorldInputs
68
81
  // Already multiplied by the model matrix, just apply view
69
- inputs.position = (uniforms.uViewMatrix * vec4<f32>(inputs.position, 1.0)).xyz;
70
- inputs.normal = uniforms.uCameraNormalMatrix * inputs.normal;
82
+ inputs.position = (camera.uViewMatrix * vec4<f32>(inputs.position, 1.0)).xyz;
83
+ inputs.normal = camera.uCameraNormalMatrix * inputs.normal;
71
84
  // @p5 endif
72
85
  // @p5 ifndef Vertex getWorldInputs
73
86
  // Apply both at once
74
- inputs.position = (uniforms.uModelViewMatrix * vec4<f32>(inputs.position, 1.0)).xyz;
75
- inputs.normal = uniforms.uNormalMatrix * inputs.normal;
87
+ inputs.position = (model.uModelViewMatrix * vec4<f32>(inputs.position, 1.0)).xyz;
88
+ inputs.normal = model.uNormalMatrix * inputs.normal;
76
89
  // @p5 endif
77
90
 
78
91
  // @p5 ifdef Vertex getCameraInputs
@@ -83,7 +96,7 @@ fn main(input: VertexInput) -> VertexOutput {
83
96
  output.vVertexNormal = normalize(inputs.normal);
84
97
  output.vColor = inputs.color;
85
98
 
86
- output.Position = uniforms.uProjectionMatrix * vec4<f32>(inputs.position, 1.0);
99
+ output.Position = camera.uProjectionMatrix * vec4<f32>(inputs.position, 1.0);
87
100
 
88
101
  HOOK_afterVertex();
89
102
  return output;
@@ -98,7 +111,9 @@ struct FragmentInput {
98
111
  };
99
112
 
100
113
  ${uniforms}
101
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
114
+ @group(0) @binding(0) var<uniform> material: MaterialUniforms;
115
+ @group(1) @binding(0) var<uniform> model: ModelUniforms;
116
+ @group(2) @binding(0) var<uniform> camera: CameraUniforms;
102
117
 
103
118
 
104
119
  @fragment
@@ -1,14 +1,25 @@
1
1
  const filterUniforms = `
2
- struct Uniforms {
3
- uModelViewMatrix: mat4x4<f32>,
4
- uProjectionMatrix: mat4x4<f32>,
2
+ // Group 0: Filter Properties
3
+ struct FilterUniforms {
5
4
  canvasSize: vec2<f32>,
6
5
  texelSize: vec2<f32>,
7
6
  }
8
7
 
9
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
8
+ // Group 1: Model Transform
9
+ struct ModelUniforms {
10
+ uModelViewMatrix: mat4x4<f32>,
11
+ }
12
+
13
+ // Group 2: Camera and Projection
14
+ struct CameraUniforms {
15
+ uProjectionMatrix: mat4x4<f32>,
16
+ }
17
+
18
+ @group(0) @binding(0) var<uniform> filterParams: FilterUniforms;
10
19
  @group(0) @binding(1) var tex0: texture_2d<f32>;
11
20
  @group(0) @binding(2) var tex0_sampler: sampler;
21
+ @group(1) @binding(0) var<uniform> model: ModelUniforms;
22
+ @group(2) @binding(0) var<uniform> camera: CameraUniforms;
12
23
  `;
13
24
 
14
25
  const baseFilterVertexShader = filterUniforms + `
@@ -33,7 +44,7 @@ fn main(input: VertexInput) -> VertexOutput {
33
44
  let positionVec4 = vec4<f32>(input.aPosition, 1.0);
34
45
 
35
46
  // project to 3D space
36
- output.position = uniforms.uProjectionMatrix * uniforms.uModelViewMatrix * positionVec4;
47
+ output.position = camera.uProjectionMatrix * model.uModelViewMatrix * positionVec4;
37
48
 
38
49
  return output;
39
50
  }
@@ -59,8 +70,8 @@ fn main(input: FragmentInput) -> FragmentOutput {
59
70
  var output: FragmentOutput;
60
71
  var inputs: FilterInputs;
61
72
  inputs.texCoord = input.vTexCoord;
62
- inputs.canvasSize = uniforms.canvasSize;
63
- inputs.texelSize = uniforms.texelSize;
73
+ inputs.canvasSize = filterParams.canvasSize;
74
+ inputs.texelSize = filterParams.texelSize;
64
75
 
65
76
  var outColor = HOOK_getColor(inputs, tex0, tex0_sampler);
66
77
  outColor = vec4<f32>(outColor.rgb * outColor.a, outColor.a);
@@ -1,7 +1,6 @@
1
1
  const uniforms = `
2
- struct Uniforms {
3
- uModelViewMatrix: mat4x4<f32>,
4
- uProjectionMatrix: mat4x4<f32>,
2
+ // Group 0: Font Properties
3
+ struct FontUniforms {
5
4
  uStrokeImageSize: vec2<i32>,
6
5
  uCellsImageSize: vec2<i32>,
7
6
  uGridImageSize: vec2<i32>,
@@ -10,7 +9,17 @@ struct Uniforms {
10
9
  uGlyphRect: vec4<f32>,
11
10
  uGlyphOffset: f32,
12
11
  uMaterialColor: vec4<f32>,
13
- };
12
+ }
13
+
14
+ // Group 1: Model Transform
15
+ struct ModelUniforms {
16
+ uModelViewMatrix: mat4x4<f32>,
17
+ }
18
+
19
+ // Group 2: Camera and Projection
20
+ struct CameraUniforms {
21
+ uProjectionMatrix: mat4x4<f32>,
22
+ }
14
23
  `;
15
24
 
16
25
  const fontVertexShader = `
@@ -25,7 +34,9 @@ struct VertexOutput {
25
34
  };
26
35
 
27
36
  ${uniforms}
28
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
37
+ @group(0) @binding(0) var<uniform> font: FontUniforms;
38
+ @group(1) @binding(0) var<uniform> model: ModelUniforms;
39
+ @group(2) @binding(0) var<uniform> camera: CameraUniforms;
29
40
 
30
41
  @vertex
31
42
  fn main(input: VertexInput) -> VertexOutput {
@@ -33,35 +44,35 @@ fn main(input: VertexInput) -> VertexOutput {
33
44
  var positionVec4 = vec4<f32>(input.aPosition, 1.0);
34
45
 
35
46
  // scale by the size of the glyph's rectangle
36
- positionVec4.x = positionVec4.x * (uniforms.uGlyphRect.z - uniforms.uGlyphRect.x);
37
- positionVec4.y = positionVec4.y * (uniforms.uGlyphRect.w - uniforms.uGlyphRect.y);
47
+ positionVec4.x = positionVec4.x * (font.uGlyphRect.z - font.uGlyphRect.x);
48
+ positionVec4.y = positionVec4.y * (font.uGlyphRect.w - font.uGlyphRect.y);
38
49
 
39
50
  // Expand glyph bounding boxes by 1px on each side to give a bit of room
40
51
  // for antialiasing
41
- let newOrigin = (uniforms.uModelViewMatrix * vec4<f32>(0.0, 0.0, 0.0, 1.0)).xyz;
42
- let newDX = (uniforms.uModelViewMatrix * vec4<f32>(1.0, 0.0, 0.0, 1.0)).xyz;
43
- let newDY = (uniforms.uModelViewMatrix * vec4<f32>(0.0, 1.0, 0.0, 1.0)).xyz;
52
+ let newOrigin = (model.uModelViewMatrix * vec4<f32>(0.0, 0.0, 0.0, 1.0)).xyz;
53
+ let newDX = (model.uModelViewMatrix * vec4<f32>(1.0, 0.0, 0.0, 1.0)).xyz;
54
+ let newDY = (model.uModelViewMatrix * vec4<f32>(0.0, 1.0, 0.0, 1.0)).xyz;
44
55
  let pixelScale = vec2<f32>(
45
56
  1.0 / length(newOrigin - newDX),
46
57
  1.0 / length(newOrigin - newDY)
47
58
  );
48
59
  let offset = pixelScale * normalize(input.aTexCoord - vec2<f32>(0.5, 0.5));
49
60
  let textureOffset = offset * (1.0 / vec2<f32>(
50
- uniforms.uGlyphRect.z - uniforms.uGlyphRect.x,
51
- uniforms.uGlyphRect.w - uniforms.uGlyphRect.y
61
+ font.uGlyphRect.z - font.uGlyphRect.x,
62
+ font.uGlyphRect.w - font.uGlyphRect.y
52
63
  ));
53
64
 
54
65
  // move to the corner of the glyph
55
- positionVec4.x = positionVec4.x + uniforms.uGlyphRect.x;
56
- positionVec4.y = positionVec4.y + uniforms.uGlyphRect.y;
66
+ positionVec4.x = positionVec4.x + font.uGlyphRect.x;
67
+ positionVec4.y = positionVec4.y + font.uGlyphRect.y;
57
68
 
58
69
  // move to the letter's line offset
59
- positionVec4.x = positionVec4.x + uniforms.uGlyphOffset;
70
+ positionVec4.x = positionVec4.x + font.uGlyphOffset;
60
71
 
61
72
  positionVec4.x = positionVec4.x + offset.x;
62
73
  positionVec4.y = positionVec4.y + offset.y;
63
74
 
64
- output.Position = uniforms.uProjectionMatrix * uniforms.uModelViewMatrix * positionVec4;
75
+ output.Position = camera.uProjectionMatrix * model.uModelViewMatrix * positionVec4;
65
76
  output.vTexCoord = input.aTexCoord + textureOffset;
66
77
 
67
78
  return output;
@@ -74,18 +85,19 @@ struct FragmentInput {
74
85
  };
75
86
 
76
87
  ${uniforms}
77
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
78
-
79
- @group(1) @binding(0) var uSamplerStrokes: texture_2d<f32>;
80
- @group(1) @binding(1) var uSamplerStrokes_sampler: sampler;
81
- @group(1) @binding(2) var uSamplerRowStrokes: texture_2d<f32>;
82
- @group(1) @binding(3) var uSamplerRowStrokes_sampler: sampler;
83
- @group(1) @binding(4) var uSamplerRows: texture_2d<f32>;
84
- @group(1) @binding(5) var uSamplerRows_sampler: sampler;
85
- @group(1) @binding(6) var uSamplerColStrokes: texture_2d<f32>;
86
- @group(1) @binding(7) var uSamplerColStrokes_sampler: sampler;
87
- @group(1) @binding(8) var uSamplerCols: texture_2d<f32>;
88
- @group(1) @binding(9) var uSamplerCols_sampler: sampler;
88
+ @group(0) @binding(0) var<uniform> font: FontUniforms;
89
+ @group(0) @binding(1) var uSamplerStrokes: texture_2d<f32>;
90
+ @group(0) @binding(2) var uSamplerStrokes_sampler: sampler;
91
+ @group(0) @binding(3) var uSamplerRowStrokes: texture_2d<f32>;
92
+ @group(0) @binding(4) var uSamplerRowStrokes_sampler: sampler;
93
+ @group(0) @binding(5) var uSamplerRows: texture_2d<f32>;
94
+ @group(0) @binding(6) var uSamplerRows_sampler: sampler;
95
+ @group(0) @binding(7) var uSamplerColStrokes: texture_2d<f32>;
96
+ @group(0) @binding(8) var uSamplerColStrokes_sampler: sampler;
97
+ @group(0) @binding(9) var uSamplerCols: texture_2d<f32>;
98
+ @group(0) @binding(10) var uSamplerCols_sampler: sampler;
99
+ @group(1) @binding(0) var<uniform> model: ModelUniforms;
100
+ @group(2) @binding(0) var<uniform> camera: CameraUniforms;
89
101
 
90
102
  // some helper functions
91
103
  fn ROUND_f32(v: f32) -> i32 { return i32(floor(v + 0.5)); }
@@ -217,14 +229,14 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
217
229
  let pixelScale = hardness / fwidth(input.vTexCoord);
218
230
 
219
231
  // which grid cell is this pixel in?
220
- let gridCoord = vec2<i32>(floor(input.vTexCoord * vec2<f32>(uniforms.uGridSize)));
232
+ let gridCoord = vec2<i32>(floor(input.vTexCoord * vec2<f32>(font.uGridSize)));
221
233
 
222
234
  // intersect curves in this row
223
235
  {
224
236
  // the index into the row info bitmap
225
- let rowIndex = gridCoord.y + uniforms.uGridOffset.y;
237
+ let rowIndex = gridCoord.y + font.uGridOffset.y;
226
238
  // fetch the info texel
227
- let rowInfo = getTexel(uSamplerRows, uSamplerRows_sampler, rowIndex, uniforms.uGridImageSize);
239
+ let rowInfo = getTexel(uSamplerRows, uSamplerRows_sampler, rowIndex, font.uGridImageSize);
228
240
  // unpack the rowInfo
229
241
  let rowStrokeIndex = getInt16(rowInfo.xy);
230
242
  let rowStrokeCount = getInt16(rowInfo.zw);
@@ -237,14 +249,14 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
237
249
  // each stroke is made up of 3 points: the start and control point
238
250
  // and the start of the next curve.
239
251
  // fetch the indices of this pair of strokes:
240
- let strokeIndices = getTexel(uSamplerRowStrokes, uSamplerRowStrokes_sampler, rowStrokeIndex + iRowStroke, uniforms.uCellsImageSize);
252
+ let strokeIndices = getTexel(uSamplerRowStrokes, uSamplerRowStrokes_sampler, rowStrokeIndex + iRowStroke, font.uCellsImageSize);
241
253
 
242
254
  // unpack the stroke index
243
255
  let strokePos = getInt16(strokeIndices.xy);
244
256
 
245
257
  // fetch the two strokes
246
- let stroke0 = getTexel(uSamplerStrokes, uSamplerStrokes_sampler, strokePos + 0, uniforms.uStrokeImageSize);
247
- let stroke1 = getTexel(uSamplerStrokes, uSamplerStrokes_sampler, strokePos + 1, uniforms.uStrokeImageSize);
258
+ let stroke0 = getTexel(uSamplerStrokes, uSamplerStrokes_sampler, strokePos + 0, font.uStrokeImageSize);
259
+ let stroke1 = getTexel(uSamplerStrokes, uSamplerStrokes_sampler, strokePos + 1, font.uStrokeImageSize);
248
260
 
249
261
  // calculate the coverage
250
262
  coverageX(stroke0.xy, stroke0.zw, stroke1.xy, input.vTexCoord, pixelScale, &coverage, &weight);
@@ -253,8 +265,8 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
253
265
 
254
266
  // intersect curves in this column
255
267
  {
256
- let colIndex = gridCoord.x + uniforms.uGridOffset.x;
257
- let colInfo = getTexel(uSamplerCols, uSamplerCols_sampler, colIndex, uniforms.uGridImageSize);
268
+ let colIndex = gridCoord.x + font.uGridOffset.x;
269
+ let colInfo = getTexel(uSamplerCols, uSamplerCols_sampler, colIndex, font.uGridImageSize);
258
270
  let colStrokeIndex = getInt16(colInfo.xy);
259
271
  let colStrokeCount = getInt16(colInfo.zw);
260
272
 
@@ -263,11 +275,11 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
263
275
  break;
264
276
  }
265
277
 
266
- let strokeIndices = getTexel(uSamplerColStrokes, uSamplerColStrokes_sampler, colStrokeIndex + iColStroke, uniforms.uCellsImageSize);
278
+ let strokeIndices = getTexel(uSamplerColStrokes, uSamplerColStrokes_sampler, colStrokeIndex + iColStroke, font.uCellsImageSize);
267
279
 
268
280
  let strokePos = getInt16(strokeIndices.xy);
269
- let stroke0 = getTexel(uSamplerStrokes, uSamplerStrokes_sampler, strokePos + 0, uniforms.uStrokeImageSize);
270
- let stroke1 = getTexel(uSamplerStrokes, uSamplerStrokes_sampler, strokePos + 1, uniforms.uStrokeImageSize);
281
+ let stroke0 = getTexel(uSamplerStrokes, uSamplerStrokes_sampler, strokePos + 0, font.uStrokeImageSize);
282
+ let stroke1 = getTexel(uSamplerStrokes, uSamplerStrokes_sampler, strokePos + 1, font.uStrokeImageSize);
271
283
  coverageY(stroke0.xy, stroke0.zw, stroke1.xy, input.vTexCoord, pixelScale, &coverage, &weight);
272
284
  }
273
285
  }
@@ -276,7 +288,7 @@ fn main(input: FragmentInput) -> @location(0) vec4<f32> {
276
288
  let distance = max(weight.x + weight.y, minDistance); // manhattan approx.
277
289
  let antialias = abs(dot(coverage, weight) / distance);
278
290
  let cover = min(abs(coverage.x), abs(coverage.y));
279
- var outColor = vec4<f32>(uniforms.uMaterialColor.rgb, 1.0) * uniforms.uMaterialColor.a;
291
+ var outColor = vec4<f32>(font.uMaterialColor.rgb, 1.0) * font.uMaterialColor.a;
280
292
  outColor = outColor * saturate_f32(max(antialias, cover));
281
293
  return outColor;
282
294
  }
@@ -1,5 +1,15 @@
1
1
  const uniforms = `
2
- struct Uniforms {
2
+ // Group 0: Stroke Properties
3
+ struct StrokeUniforms {
4
+ uStrokeWeight: f32,
5
+ uUseLineColor: f32,
6
+ uSimpleLines: f32,
7
+ uStrokeCap: u32,
8
+ uStrokeJoin: u32,
9
+ }
10
+
11
+ // Group 1: Model Transform
12
+ struct ModelUniforms {
3
13
  // @p5 ifdef StrokeVertex getWorldInputs
4
14
  uModelMatrix: mat4x4<f32>,
5
15
  uViewMatrix: mat4x4<f32>,
@@ -8,15 +18,15 @@ struct Uniforms {
8
18
  uModelViewMatrix: mat4x4<f32>,
9
19
  // @p5 endif
10
20
  uMaterialColor: vec4<f32>,
21
+ }
22
+
23
+ // Group 2: Camera and Projection
24
+ struct CameraUniforms {
11
25
  uProjectionMatrix: mat4x4<f32>,
12
- uStrokeWeight: f32,
13
- uUseLineColor: f32,
14
- uSimpleLines: f32,
15
26
  uViewport: vec4<f32>,
16
27
  uPerspective: u32,
17
- uStrokeCap: u32,
18
- uStrokeJoin: u32,
19
- }`;
28
+ }
29
+ `;
20
30
 
21
31
  const lineVertexShader = `
22
32
  struct StrokeVertexInput {
@@ -40,7 +50,9 @@ struct StrokeVertexOutput {
40
50
  };
41
51
 
42
52
  ${uniforms}
43
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
53
+ @group(0) @binding(0) var<uniform> stroke: StrokeUniforms;
54
+ @group(1) @binding(0) var<uniform> model: ModelUniforms;
55
+ @group(2) @binding(0) var<uniform> camera: CameraUniforms;
44
56
 
45
57
  struct StrokeVertex {
46
58
  position: vec3<f32>,
@@ -73,7 +85,7 @@ fn lineIntersection(aPoint: vec2f, aDir: vec2f, bPoint: vec2f, bDir: vec2f) -> v
73
85
  fn main(input: StrokeVertexInput) -> StrokeVertexOutput {
74
86
  HOOK_beforeVertex();
75
87
  var output: StrokeVertexOutput;
76
- let simpleLines = (uniforms.uSimpleLines != 0.);
88
+ let simpleLines = (stroke.uSimpleLines != 0.);
77
89
  if (!simpleLines) {
78
90
  if (all(input.aTangentIn == vec3<f32>()) != all(input.aTangentOut == vec3<f32>())) {
79
91
  output.vCap = 1.;
@@ -90,17 +102,17 @@ fn main(input: StrokeVertexInput) -> StrokeVertexOutput {
90
102
  }
91
103
  }
92
104
  var lineColor: vec4<f32>;
93
- if (uniforms.uUseLineColor != 0.) {
105
+ if (stroke.uUseLineColor != 0.) {
94
106
  lineColor = input.aVertexColor;
95
107
  } else {
96
- lineColor = uniforms.uMaterialColor;
108
+ lineColor = model.uMaterialColor;
97
109
  }
98
110
  var inputs = StrokeVertex(
99
111
  input.aPosition.xyz,
100
112
  input.aTangentIn,
101
113
  input.aTangentOut,
102
114
  lineColor,
103
- uniforms.uStrokeWeight
115
+ stroke.uStrokeWeight
104
116
  );
105
117
 
106
118
  // @p5 ifdef StrokeVertex getObjectInputs
@@ -108,23 +120,23 @@ fn main(input: StrokeVertexInput) -> StrokeVertexOutput {
108
120
  // @p5 endif
109
121
 
110
122
  // @p5 ifdef StrokeVertex getWorldInputs
111
- inputs.position = (uniforms.uModelMatrix * vec4<f32>(inputs.position, 1.)).xyz;
112
- inputs.tangentIn = (uniforms.uModelMatrix * vec4<f32>(input.aTangentIn, 1.)).xyz;
113
- inputs.tangentOut = (uniforms.uModelMatrix * vec4<f32>(input.aTangentOut, 1.)).xyz;
123
+ inputs.position = (model.uModelMatrix * vec4<f32>(inputs.position, 1.)).xyz;
124
+ inputs.tangentIn = (model.uModelMatrix * vec4<f32>(input.aTangentIn, 1.)).xyz;
125
+ inputs.tangentOut = (model.uModelMatrix * vec4<f32>(input.aTangentOut, 1.)).xyz;
114
126
  inputs = HOOK_getWorldInputs(inputs);
115
127
  // @p5 endif
116
128
 
117
129
  // @p5 ifdef StrokeVertex getWorldInputs
118
130
  // Already multiplied by the model matrix, just apply view
119
- inputs.position = (uniforms.uViewMatrix * vec4<f32>(inputs.position, 1.)).xyz;
120
- inputs.tangentIn = (uniforms.uViewMatrix * vec4<f32>(input.aTangentIn, 0.)).xyz;
121
- inputs.tangentOut = (uniforms.uViewMatrix * vec4<f32>(input.aTangentOut, 0.)).xyz;
131
+ inputs.position = (model.uViewMatrix * vec4<f32>(inputs.position, 1.)).xyz;
132
+ inputs.tangentIn = (model.uViewMatrix * vec4<f32>(input.aTangentIn, 0.)).xyz;
133
+ inputs.tangentOut = (model.uViewMatrix * vec4<f32>(input.aTangentOut, 0.)).xyz;
122
134
  // @p5 endif
123
135
  // @p5 ifndef StrokeVertex getWorldInputs
124
136
  // Apply both at once
125
- inputs.position = (uniforms.uModelViewMatrix * vec4<f32>(inputs.position, 1.)).xyz;
126
- inputs.tangentIn = (uniforms.uModelViewMatrix * vec4<f32>(input.aTangentIn, 0.)).xyz;
127
- inputs.tangentOut = (uniforms.uModelViewMatrix * vec4<f32>(input.aTangentOut, 0.)).xyz;
137
+ inputs.position = (model.uModelViewMatrix * vec4<f32>(inputs.position, 1.)).xyz;
138
+ inputs.tangentIn = (model.uModelViewMatrix * vec4<f32>(input.aTangentIn, 0.)).xyz;
139
+ inputs.tangentOut = (model.uModelViewMatrix * vec4<f32>(input.aTangentOut, 0.)).xyz;
128
140
  // @p5 endif
129
141
  // @p5 ifdef StrokeVertex getCameraInputs
130
142
  inputs = HOOK_getCameraInputs(inputs);
@@ -174,27 +186,27 @@ fn main(input: StrokeVertexInput) -> StrokeVertexOutput {
174
186
  posqIn.z -= dynamicZAdjustment;
175
187
  posqOut.z -= dynamicZAdjustment;
176
188
 
177
- var p = uniforms.uProjectionMatrix * posp;
178
- var qIn = uniforms.uProjectionMatrix * posqIn;
179
- var qOut = uniforms.uProjectionMatrix * posqOut;
189
+ var p = camera.uProjectionMatrix * posp;
190
+ var qIn = camera.uProjectionMatrix * posqIn;
191
+ var qOut = camera.uProjectionMatrix * posqOut;
180
192
 
181
- var tangentIn = normalize((qIn.xy * p.w - p.xy * qIn.w) * uniforms.uViewport.zw);
182
- var tangentOut = normalize((qOut.xy * p.w - p.xy * qOut.w) * uniforms.uViewport.zw);
193
+ var tangentIn = normalize((qIn.xy * p.w - p.xy * qIn.w) * camera.uViewport.zw);
194
+ var tangentOut = normalize((qOut.xy * p.w - p.xy * qOut.w) * camera.uViewport.zw);
183
195
 
184
196
  var curPerspScale = vec2<f32>();
185
- if (uniforms.uPerspective == 1) {
197
+ if (camera.uPerspective == 1) {
186
198
  // Perspective ---
187
199
  // convert from world to clip by multiplying with projection scaling factor
188
200
  // to get the right thickness (see https://github.com/processing/processing/issues/5182)
189
201
 
190
202
  // The y value of the projection matrix may be flipped if rendering to a Framebuffer.
191
203
  // Multiplying again by its sign here negates the flip to get just the scale.
192
- curPerspScale = (uniforms.uProjectionMatrix * vec4(1., sign(uniforms.uProjectionMatrix[1][1]), 0., 0.)).xy;
204
+ curPerspScale = (camera.uProjectionMatrix * vec4(1., sign(camera.uProjectionMatrix[1][1]), 0., 0.)).xy;
193
205
  } else {
194
206
  // No Perspective ---
195
207
  // multiply by W (to cancel out division by W later in the pipeline) and
196
208
  // convert from screen to clip (derived from clip to screen above)
197
- curPerspScale = p.w / (0.5 * uniforms.uViewport.zw);
209
+ curPerspScale = p.w / (0.5 * camera.uViewport.zw);
198
210
  }
199
211
 
200
212
  var offset = vec2<f32>();
@@ -217,7 +229,7 @@ fn main(input: StrokeVertexInput) -> StrokeVertexOutput {
217
229
  if (sideEnum == 2.) {
218
230
  // Calculate the position + tangent on either side of the join, and
219
231
  // find where the lines intersect to find the elbow of the join
220
- var c = (posp.xy / posp.w + vec2<f32>(1.)) * 0.5 * uniforms.uViewport.zw;
232
+ var c = (posp.xy / posp.w + vec2<f32>(1.)) * 0.5 * camera.uViewport.zw;
221
233
 
222
234
  var intersection = lineIntersection(
223
235
  c + (side * normalIn * inputs.weight / 2.),
@@ -243,7 +255,7 @@ fn main(input: StrokeVertexInput) -> StrokeVertexOutput {
243
255
  offset = side * normalOut * inputs.weight / 2.;
244
256
  }
245
257
  }
246
- if (uniforms.uStrokeJoin == 2) {
258
+ if (stroke.uStrokeJoin == 2) {
247
259
  var avgNormal = vec2<f32>(-output.vTangent.y, output.vTangent.x);
248
260
  output.vMaxDist = abs(dot(avgNormal, normalIn * inputs.weight / 2.));
249
261
  } else {
@@ -292,7 +304,9 @@ struct StrokeFragmentInput {
292
304
  }
293
305
 
294
306
  ${uniforms}
295
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
307
+ @group(0) @binding(0) var<uniform> stroke: StrokeUniforms;
308
+ @group(1) @binding(0) var<uniform> model: ModelUniforms;
309
+ @group(2) @binding(0) var<uniform> camera: CameraUniforms;
296
310
 
297
311
 
298
312
  fn distSquared(a: vec2<f32>, b: vec2<f32>) -> f32 {
@@ -321,12 +335,12 @@ fn main(input: StrokeFragmentInput) -> @location(0) vec4<f32> {
321
335
 
322
336
  if (input.vCap > 0.) {
323
337
  if (
324
- uniforms.uStrokeCap == STROKE_CAP_ROUND &&
338
+ stroke.uStrokeCap == STROKE_CAP_ROUND &&
325
339
  HOOK_shouldDiscard(distSquared(inputs.position, inputs.center) > inputs.strokeWeight * inputs.strokeWeight * 0.25)
326
340
  ) {
327
341
  discard;
328
342
  } else if (
329
- uniforms.uStrokeCap == STROKE_CAP_SQUARE &&
343
+ stroke.uStrokeCap == STROKE_CAP_SQUARE &&
330
344
  HOOK_shouldDiscard(dot(inputs.position - inputs.center, inputs.tangent) > 0.)
331
345
  ) {
332
346
  discard;
@@ -335,11 +349,11 @@ fn main(input: StrokeFragmentInput) -> @location(0) vec4<f32> {
335
349
  }
336
350
  } else if (input.vJoin > 0.) {
337
351
  if (
338
- uniforms.uStrokeJoin == STROKE_JOIN_ROUND &&
352
+ stroke.uStrokeJoin == STROKE_JOIN_ROUND &&
339
353
  HOOK_shouldDiscard(distSquared(inputs.position, inputs.center) > inputs.strokeWeight * inputs.strokeWeight * 0.25)
340
354
  ) {
341
355
  discard;
342
- } else if (uniforms.uStrokeJoin == STROKE_JOIN_BEVEL) {
356
+ } else if (stroke.uStrokeJoin == STROKE_JOIN_BEVEL) {
343
357
  let normal = vec2<f32>(-inputs.tangent.y, -inputs.tangent.x);
344
358
  if (HOOK_shouldDiscard(abs(dot(inputs.position - inputs.center, normal)) > input.vMaxDist)) {
345
359
  discard;