q5 2.13.1 → 2.13.3

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.
@@ -2,14 +2,15 @@ Q5.renderers.webgpu.text = ($, q) => {
2
2
  let textShader = Q5.device.createShaderModule({
3
3
  label: 'MSDF text shader',
4
4
  code: `
5
- // Positions for simple quad geometry
6
- const pos = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));
7
-
8
- struct VertexInput {
5
+ struct Uniforms {
6
+ halfWidth: f32,
7
+ halfHeight: f32
8
+ }
9
+ struct VertexParams {
9
10
  @builtin(vertex_index) vertex : u32,
10
11
  @builtin(instance_index) instance : u32
11
12
  }
12
- struct VertexOutput {
13
+ struct FragmentParams {
13
14
  @builtin(position) position : vec4f,
14
15
  @location(0) texCoord : vec2f,
15
16
  @location(1) fillColor : vec4f
@@ -27,43 +28,40 @@ struct Text {
27
28
  fillIndex: f32,
28
29
  strokeIndex: f32
29
30
  }
30
- struct Uniforms {
31
- halfWidth: f32,
32
- halfHeight: f32
33
- }
34
31
 
35
32
  @group(0) @binding(0) var<uniform> uniforms: Uniforms;
36
33
  @group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
34
+ @group(0) @binding(2) var<storage> colors : array<vec4f>;
37
35
 
38
- @group(1) @binding(0) var<storage> colors : array<vec4f>;
36
+ @group(1) @binding(0) var fontTexture: texture_2d<f32>;
37
+ @group(1) @binding(1) var fontSampler: sampler;
38
+ @group(1) @binding(2) var<storage> fontChars: array<Char>;
39
39
 
40
- @group(2) @binding(0) var fontTexture: texture_2d<f32>;
41
- @group(2) @binding(1) var fontSampler: sampler;
42
- @group(2) @binding(2) var<storage> fontChars: array<Char>;
40
+ @group(2) @binding(0) var<storage> textChars: array<vec4f>;
41
+ @group(2) @binding(1) var<storage> textMetadata: array<Text>;
43
42
 
44
- @group(3) @binding(0) var<storage> textChars: array<vec4f>;
45
- @group(3) @binding(1) var<storage> textMetadata: array<Text>;
43
+ const quad = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));
46
44
 
47
45
  @vertex
48
- fn vertexMain(input : VertexInput) -> VertexOutput {
49
- let char = textChars[input.instance];
46
+ fn vertexMain(v : VertexParams) -> FragmentParams {
47
+ let char = textChars[v.instance];
50
48
 
51
49
  let text = textMetadata[i32(char.w)];
52
50
 
53
51
  let fontChar = fontChars[i32(char.z)];
54
52
 
55
- let charPos = ((pos[input.vertex] * fontChar.size + char.xy + fontChar.offset) * text.scale) + text.pos;
53
+ let charPos = ((quad[v.vertex] * fontChar.size + char.xy + fontChar.offset) * text.scale) + text.pos;
56
54
 
57
55
  var vert = vec4f(charPos, 0.0, 1.0);
58
56
  vert = transforms[i32(text.matrixIndex)] * vert;
59
57
  vert.x /= uniforms.halfWidth;
60
58
  vert.y /= uniforms.halfHeight;
61
59
 
62
- var output : VertexOutput;
63
- output.position = vert;
64
- output.texCoord = (pos[input.vertex] * vec2f(1, -1)) * fontChar.texExtent + fontChar.texOffset;
65
- output.fillColor = colors[i32(text.fillIndex)];
66
- return output;
60
+ var f : FragmentParams;
61
+ f.position = vert;
62
+ f.texCoord = (quad[v.vertex] * vec2f(1, -1)) * fontChar.texExtent + fontChar.texOffset;
63
+ f.fillColor = colors[i32(text.fillIndex)];
64
+ return f;
67
65
  }
68
66
 
69
67
  fn sampleMsdf(texCoord: vec2f) -> f32 {
@@ -72,22 +70,22 @@ fn sampleMsdf(texCoord: vec2f) -> f32 {
72
70
  }
73
71
 
74
72
  @fragment
75
- fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
73
+ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
76
74
  // pxRange (AKA distanceRange) comes from the msdfgen tool,
77
75
  // uses the default which is 4.
78
76
  let pxRange = 4.0;
79
77
  let sz = vec2f(textureDimensions(fontTexture, 0));
80
- let dx = sz.x*length(vec2f(dpdxFine(input.texCoord.x), dpdyFine(input.texCoord.x)));
81
- let dy = sz.y*length(vec2f(dpdxFine(input.texCoord.y), dpdyFine(input.texCoord.y)));
78
+ let dx = sz.x*length(vec2f(dpdxFine(f.texCoord.x), dpdyFine(f.texCoord.x)));
79
+ let dy = sz.y*length(vec2f(dpdxFine(f.texCoord.y), dpdyFine(f.texCoord.y)));
82
80
  let toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);
83
- let sigDist = sampleMsdf(input.texCoord) - 0.5;
81
+ let sigDist = sampleMsdf(f.texCoord) - 0.5;
84
82
  let pxDist = sigDist * toPixels;
85
83
  let edgeWidth = 0.5;
86
84
  let alpha = smoothstep(-edgeWidth, edgeWidth, pxDist);
87
85
  if (alpha < 0.001) {
88
86
  discard;
89
87
  }
90
- return vec4f(input.fillColor.rgb, input.fillColor.a * alpha);
88
+ return vec4f(f.fillColor.rgb, f.fillColor.a * alpha);
91
89
  }
92
90
  `
93
91
  });
@@ -321,8 +319,8 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
321
319
  if (vert) $._textBaseline = vert;
322
320
  };
323
321
 
324
- $._charStack = [];
325
- $._textStack = [];
322
+ let charStack = [],
323
+ textStack = [];
326
324
 
327
325
  let measureText = (font, text, charCallback) => {
328
326
  let maxWidth = 0,
@@ -419,7 +417,7 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
419
417
 
420
418
  let ta = $._textAlign,
421
419
  tb = $._textBaseline,
422
- textIndex = $._textStack.length,
420
+ textIndex = textStack.length,
423
421
  o = 0, // offset
424
422
  measurements;
425
423
 
@@ -459,20 +457,20 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
459
457
  o += 4;
460
458
  });
461
459
  }
462
- $._charStack.push(charsData);
460
+ charStack.push(charsData);
463
461
 
464
- let text = [];
462
+ let txt = [];
465
463
 
466
464
  if ($._matrixDirty) $._saveMatrix();
467
465
 
468
- text[0] = x;
469
- text[1] = -y;
470
- text[2] = $._textSize / 44;
471
- text[3] = $._matrixIndex;
472
- text[4] = $._fillSet ? $._fill : 0;
473
- text[5] = $._stroke;
466
+ txt[0] = x;
467
+ txt[1] = -y;
468
+ txt[2] = $._textSize / 44;
469
+ txt[3] = $._matrixIndex;
470
+ txt[4] = $._fillSet ? $._fill : 0;
471
+ txt[5] = $._stroke;
474
472
 
475
- $._textStack.push(text);
473
+ textStack.push(txt);
476
474
  $.drawStack.push(2, measurements.printedCharCount, $._font.index);
477
475
  };
478
476
 
@@ -533,11 +531,11 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
533
531
  };
534
532
 
535
533
  $._hooks.preRender.push(() => {
536
- if (!$._charStack.length) return;
534
+ if (!charStack.length) return;
537
535
 
538
536
  // calculate total buffer size for text data
539
537
  let totalTextSize = 0;
540
- for (let charsData of $._charStack) {
538
+ for (let charsData of charStack) {
541
539
  totalTextSize += charsData.length * 4;
542
540
  }
543
541
 
@@ -549,11 +547,11 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
549
547
  });
550
548
 
551
549
  // copy all the text data into the buffer
552
- new Float32Array(charBuffer.getMappedRange()).set($._charStack.flat());
550
+ new Float32Array(charBuffer.getMappedRange()).set(charStack.flat());
553
551
  charBuffer.unmap();
554
552
 
555
553
  // calculate total buffer size for metadata
556
- let totalMetadataSize = $._textStack.length * 6 * 4;
554
+ let totalMetadataSize = textStack.length * 6 * 4;
557
555
 
558
556
  // create a single buffer for all metadata
559
557
  let textBuffer = Q5.device.createBuffer({
@@ -564,7 +562,7 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
564
562
  });
565
563
 
566
564
  // copy all metadata into the buffer
567
- new Float32Array(textBuffer.getMappedRange()).set($._textStack.flat());
565
+ new Float32Array(textBuffer.getMappedRange()).set(textStack.flat());
568
566
  textBuffer.unmap();
569
567
 
570
568
  // create a single bind group for the text buffer and metadata buffer
@@ -579,7 +577,7 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
579
577
  });
580
578
 
581
579
  $._hooks.postRender.push(() => {
582
- $._charStack.length = 0;
583
- $._textStack.length = 0;
580
+ charStack.length = 0;
581
+ textStack.length = 0;
584
582
  });
585
583
  };