@driftengine/core 4.1.4 → 4.2.0

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 (47) hide show
  1. package/CHANGELOG.json +3812 -3770
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +7 -1
  4. package/dist/render/backend/webgl2/renderer.d.ts +15 -0
  5. package/dist/render/backend/webgl2/renderer.js +28 -7
  6. package/dist/render/backend/webgpu/pointShadowPass.d.ts +4 -0
  7. package/dist/render/backend/webgpu/pointShadowPass.js +10 -0
  8. package/dist/render/backend/webgpu/renderer.js +11 -6
  9. package/dist/render/depthConvention.d.ts +19 -0
  10. package/dist/render/depthConvention.js +21 -0
  11. package/dist/render/livePointShadowSet.js +8 -0
  12. package/dist/render/pointShadowBudget.js +59 -5
  13. package/dist/render/pointShadowImage.d.ts +40 -0
  14. package/dist/render/pointShadowImage.js +20 -0
  15. package/dist/render/pointShadowMap.d.ts +4 -0
  16. package/dist/render/pointShadowMap.js +10 -0
  17. package/dist/render/pointShadowSystem.js +9 -0
  18. package/dist/render/renderQuality.d.ts +27 -4
  19. package/dist/render/renderQuality.js +1 -1
  20. package/dist/render/shaders/flat/main.d.ts +1 -1
  21. package/dist/render/shaders/flat/main.js +13 -5
  22. package/dist/render/shaders/flat/pointShadow.d.ts +1 -1
  23. package/dist/render/shaders/flat/pointShadow.js +42 -30
  24. package/dist/render/shaders/flat/preamble.js +26 -2
  25. package/dist/render/shaders/generated/flat.wgsl.d.ts +16 -16
  26. package/dist/render/shaders/generated/flat.wgsl.js +24 -24
  27. package/dist/render/shaders/sky.d.ts +10 -6
  28. package/dist/render/shaders/sky.js +35 -2
  29. package/dist/render/textRenderer.js +23 -4
  30. package/package.json +6 -6
  31. package/src/index.ts +11 -1
  32. package/src/render/backend/webgl2/renderer.ts +28 -7
  33. package/src/render/backend/webgpu/pointShadowPass.ts +13 -0
  34. package/src/render/backend/webgpu/renderer.ts +16 -10
  35. package/src/render/depthConvention.ts +22 -0
  36. package/src/render/livePointShadowSet.ts +7 -0
  37. package/src/render/pointShadowBudget.ts +58 -5
  38. package/src/render/pointShadowImage.ts +51 -0
  39. package/src/render/pointShadowMap.ts +13 -0
  40. package/src/render/pointShadowSystem.ts +8 -0
  41. package/src/render/renderQuality.ts +28 -5
  42. package/src/render/shaders/flat/main.ts +13 -5
  43. package/src/render/shaders/flat/pointShadow.ts +42 -30
  44. package/src/render/shaders/flat/preamble.ts +26 -2
  45. package/src/render/shaders/generated/flat.wgsl.ts +24 -24
  46. package/src/render/shaders/sky.ts +37 -2
  47. package/src/render/textRenderer.ts +23 -14
@@ -7,7 +7,24 @@ import { glslFarDepth } from '../depthConvention.ts';
7
7
  * interpolated rather than written. A sky that says 1.0 in a reversed engine is drawn at the
8
8
  * *near* plane and covers the world; measured, that was 743,669 changed pixels of 921,600.
9
9
  */
10
- export const SKY_VERT = `#version 300 es
10
+ /**
11
+ * The source, as a function of which way depth actually runs.
12
+ *
13
+ * **Because on WebGL2 that is a runtime fact and this file is imported once.** Reversed depth there
14
+ * needs `EXT_clip_control`; a context that is not granted it runs conventional depth, and the
15
+ * renderer has a `reversedDepth` field saying so precisely because the two can disagree. This
16
+ * template used to bake `glslFarDepth()` at import, which reads the compile-time `REVERSED_DEPTH` —
17
+ * so on such a context the sky was written at `0.0` while the depth test ran conventionally, where
18
+ * `0.0` is the middle of the range rather than the far plane. The sky then beat everything in the
19
+ * far half of the scene.
20
+ *
21
+ * **Reported from Firefox on Linux, which exposes no `EXT_clip_control`**: the voxel sandbox drew
22
+ * only sky, the gilded chamber a single orange frame, and a consumer's world one flat colour with
23
+ * its interface still on top. Three symptoms, one cause, and the docstring above already named the
24
+ * mechanism in the other direction.
25
+ */
26
+ function skySource(farDepth: string): string {
27
+ return `#version 300 es
11
28
  const vec2 POS[3] = vec2[3](vec2(-1., -1.), vec2(3., -1.), vec2(-1., 3.));
12
29
 
13
30
  out vec2 vNdc;
@@ -15,9 +32,27 @@ out vec2 vNdc;
15
32
  void main() {
16
33
  vNdc = POS[gl_VertexID];
17
34
  /* The far plane, whichever way depth runs: see glslFarDepth. */
18
- gl_Position = vec4(vNdc, ${glslFarDepth()}, 1.0);
35
+ gl_Position = vec4(vNdc, ${farDepth}, 1.0);
19
36
  }
20
37
  `;
38
+ }
39
+
40
+ /**
41
+ * The engine's own convention, which is what WebGPU always gets and what the WGSL is generated
42
+ * from. `scripts/wgsl.ts` reads this constant, so it stays a constant.
43
+ */
44
+ export const SKY_VERT = skySource(glslFarDepth());
45
+
46
+ /**
47
+ * The same shader for a context that may not have been granted reversed depth.
48
+ *
49
+ * WebGL2 compiles GLSL directly and is the only backend that can run either way, so it asks for
50
+ * the one matching what it got. WebGPU never calls this: it uses the generated WGSL, where the far
51
+ * plane is reversed by construction.
52
+ */
53
+ export function skyVertFor(reversed: boolean): string {
54
+ return reversed ? SKY_VERT : skySource('1.0');
55
+ }
21
56
 
22
57
  export const SKY_FRAG = `#version 300 es
23
58
  precision highp float;
@@ -1,11 +1,5 @@
1
1
  import type { TextStyle } from './textLayout.ts';
2
- import {
3
- MAX_CELLS,
4
- TEXT_CUBE,
5
- TextLayout,
6
- deviceSnappedCellSize,
7
- deviceSnappedOrigin,
8
- } from './textLayout.ts';
2
+ import { MAX_CELLS, TEXT_CUBE, TextLayout, deviceSnappedOrigin } from './textLayout.ts';
9
3
  import { compileProgram, uniformLocations } from './shader.ts';
10
4
  import { TEXT_FRAG, TEXT_VERT } from './shaders/text.ts';
11
5
 
@@ -129,13 +123,28 @@ export class TextRenderer {
129
123
  deviceSnappedOrigin(originX, viewportWidth, gl.drawingBufferWidth),
130
124
  deviceSnappedOrigin(originY, viewportHeight, gl.drawingBufferHeight),
131
125
  );
132
- /* Whole device pixels per cell, or a 5x7 face draws strokes of two different widths. The
133
- decision is shared with WebGPU; only this binding is per-backend. See `textLayout.ts`. */
134
- setFloat(
135
- gl,
136
- this.uniforms['uCellSize'],
137
- deviceSnappedCellSize(style.cellSize, viewportWidth, gl.drawingBufferWidth),
138
- );
126
+ /*
127
+ * **The cell the caller asked for, drawn faithfully.**
128
+ *
129
+ * 4.1.4 snapped this down to whole device pixels here, so a 5x7 face could not draw strokes
130
+ * of two different widths. That defect is real and the snap is the right cure for it, but
131
+ * imposing it was wrong: `textWidthPx` is the only measurement a consumer has, it takes no
132
+ * viewport and so cannot know the device ratio, and every consumer went on laying out against
133
+ * the cell it asked for while this drew a smaller one. A centred line, a right-aligned column
134
+ * and a line fitted to a box all broke at once, silently, and only where the snap was not a
135
+ * no-op: a whole cell at a whole ratio is untouched, which is why it looked right in a
136
+ * full-size landscape browser and wrong in mobile portrait, where a consumer divides an
137
+ * available width by a cell count and gets a fraction.
138
+ *
139
+ * So the snap is the caller's to ask for. `deviceSnappedCellSize` is exported; a caller that
140
+ * wants whole-pixel strokes snaps once and uses that one number to measure, to lay out and to
141
+ * draw, where the measurement and the picture agree by construction.
142
+ *
143
+ * **What this gives up** is that a fractional cell draws strokes of two widths again for a
144
+ * caller that does not opt in. **What would make it wrong** is a measurement that could snap
145
+ * on the caller's behalf, which would need the viewport `textWidthPx` is not handed.
146
+ */
147
+ setFloat(gl, this.uniforms['uCellSize'], style.cellSize);
139
148
  // Far enough that a whole line barely converges, near enough that a rotating character
140
149
  // reads as turning rather than shearing.
141
150
  setFloat(gl, this.uniforms['uDepth'], Math.max(viewportWidth, 600) * 1.4);