@yali-engine/render 0.0.0-stage → 0.4.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 (131) hide show
  1. package/dist/bvh.d.ts +66 -0
  2. package/dist/bvh.js +493 -0
  3. package/dist/bvh.js.map +1 -0
  4. package/dist/camera.d.ts +34 -0
  5. package/dist/camera.js +66 -0
  6. package/dist/camera.js.map +1 -0
  7. package/dist/cluster-build.d.ts +46 -0
  8. package/dist/cluster-build.js +179 -0
  9. package/dist/cluster-build.js.map +1 -0
  10. package/dist/cluster-pages.d.ts +70 -0
  11. package/dist/cluster-pages.js +203 -0
  12. package/dist/cluster-pages.js.map +1 -0
  13. package/dist/cluster-stream.d.ts +83 -0
  14. package/dist/cluster-stream.js +226 -0
  15. package/dist/cluster-stream.js.map +1 -0
  16. package/dist/culled-draws.d.ts +30 -0
  17. package/dist/culled-draws.js +103 -0
  18. package/dist/culled-draws.js.map +1 -0
  19. package/dist/debug-lines.d.ts +51 -0
  20. package/dist/debug-lines.js +158 -0
  21. package/dist/debug-lines.js.map +1 -0
  22. package/dist/device-profile.d.ts +100 -0
  23. package/dist/device-profile.js +131 -0
  24. package/dist/device-profile.js.map +1 -0
  25. package/dist/device.d.ts +39 -0
  26. package/dist/device.js +79 -0
  27. package/dist/device.js.map +1 -0
  28. package/dist/environment.d.ts +60 -0
  29. package/dist/environment.js +204 -0
  30. package/dist/environment.js.map +1 -0
  31. package/dist/extract.d.ts +74 -0
  32. package/dist/extract.js +194 -0
  33. package/dist/extract.js.map +1 -0
  34. package/dist/frame-graph.d.ts +112 -0
  35. package/dist/frame-graph.js +226 -0
  36. package/dist/frame-graph.js.map +1 -0
  37. package/dist/gpu-health.d.ts +74 -0
  38. package/dist/gpu-health.js +106 -0
  39. package/dist/gpu-health.js.map +1 -0
  40. package/dist/gpu-timer.d.ts +26 -0
  41. package/dist/gpu-timer.js +93 -0
  42. package/dist/gpu-timer.js.map +1 -0
  43. package/dist/headless.d.ts +28 -0
  44. package/dist/headless.js +91 -0
  45. package/dist/headless.js.map +1 -0
  46. package/dist/index.d.ts +34 -0
  47. package/dist/index.js +36 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/lights.d.ts +81 -0
  50. package/dist/lights.js +247 -0
  51. package/dist/lights.js.map +1 -0
  52. package/dist/matrix.d.ts +6 -0
  53. package/dist/matrix.js +59 -0
  54. package/dist/matrix.js.map +1 -0
  55. package/dist/meshes.d.ts +411 -0
  56. package/dist/meshes.js +545 -0
  57. package/dist/meshes.js.map +1 -0
  58. package/dist/meshlets-decoder.d.ts +20 -0
  59. package/dist/meshlets-decoder.js +47 -0
  60. package/dist/meshlets-decoder.js.map +1 -0
  61. package/dist/meshlets.d.ts +186 -0
  62. package/dist/meshlets.js +1040 -0
  63. package/dist/meshlets.js.map +1 -0
  64. package/dist/occlusion.d.ts +51 -0
  65. package/dist/occlusion.js +188 -0
  66. package/dist/occlusion.js.map +1 -0
  67. package/dist/pick-decoder.d.ts +19 -0
  68. package/dist/pick-decoder.js +45 -0
  69. package/dist/pick-decoder.js.map +1 -0
  70. package/dist/pick.d.ts +86 -0
  71. package/dist/pick.js +452 -0
  72. package/dist/pick.js.map +1 -0
  73. package/dist/pipeline-cache.d.ts +53 -0
  74. package/dist/pipeline-cache.js +96 -0
  75. package/dist/pipeline-cache.js.map +1 -0
  76. package/dist/post-options.d.ts +109 -0
  77. package/dist/post-options.js +23 -0
  78. package/dist/post-options.js.map +1 -0
  79. package/dist/post-shaders.gen.d.ts +40 -0
  80. package/dist/post-shaders.gen.js +43 -0
  81. package/dist/post-shaders.gen.js.map +1 -0
  82. package/dist/post.d.ts +101 -0
  83. package/dist/post.js +555 -0
  84. package/dist/post.js.map +1 -0
  85. package/dist/render-plugin.d.ts +239 -0
  86. package/dist/render-plugin.js +633 -0
  87. package/dist/render-plugin.js.map +1 -0
  88. package/dist/scene.d.ts +406 -0
  89. package/dist/scene.js +2005 -0
  90. package/dist/scene.js.map +1 -0
  91. package/dist/shaders.gen.d.ts +40 -0
  92. package/dist/shaders.gen.js +43 -0
  93. package/dist/shaders.gen.js.map +1 -0
  94. package/dist/shadows.d.ts +104 -0
  95. package/dist/shadows.js +227 -0
  96. package/dist/shadows.js.map +1 -0
  97. package/dist/staging-ring.d.ts +41 -0
  98. package/dist/staging-ring.js +125 -0
  99. package/dist/staging-ring.js.map +1 -0
  100. package/dist/textures.d.ts +165 -0
  101. package/dist/textures.js +361 -0
  102. package/dist/textures.js.map +1 -0
  103. package/dist/tonemap.d.ts +45 -0
  104. package/dist/tonemap.js +141 -0
  105. package/dist/tonemap.js.map +1 -0
  106. package/dist/viewport.d.ts +78 -0
  107. package/dist/viewport.js +130 -0
  108. package/dist/viewport.js.map +1 -0
  109. package/dist/webgl2/plugin.d.ts +40 -0
  110. package/dist/webgl2/plugin.js +190 -0
  111. package/dist/webgl2/plugin.js.map +1 -0
  112. package/dist/webgl2/program.d.ts +27 -0
  113. package/dist/webgl2/program.js +74 -0
  114. package/dist/webgl2/program.js.map +1 -0
  115. package/dist/webgl2/renderer.d.ts +128 -0
  116. package/dist/webgl2/renderer.js +976 -0
  117. package/dist/webgl2/renderer.js.map +1 -0
  118. package/dist/webgl2/shaders.glsl.gen.d.ts +27 -0
  119. package/dist/webgl2/shaders.glsl.gen.js +20 -0
  120. package/dist/webgl2/shaders.glsl.gen.js.map +1 -0
  121. package/dist/webgl2/textures.d.ts +11 -0
  122. package/dist/webgl2/textures.js +82 -0
  123. package/dist/webgl2/textures.js.map +1 -0
  124. package/dist/webgl2/webgl2.d.ts +1 -0
  125. package/dist/webgl2/webgl2.js +4 -0
  126. package/dist/webgl2/webgl2.js.map +1 -0
  127. package/dist/worker-mode.d.ts +85 -0
  128. package/dist/worker-mode.js +204 -0
  129. package/dist/worker-mode.js.map +1 -0
  130. package/package.json +47 -3
  131. package/README.md +0 -3
@@ -0,0 +1,141 @@
1
+ import { whiteBalance } from "./post-options.js";
2
+ import { postTonemap } from "./shaders.gen.js";
3
+ /** Each curve's number in the shaders. */
4
+ export const CURVES = { neutral: 0, aces: 1, none: 2 };
5
+ const sat = (x) => Math.min(1, Math.max(0, x));
6
+ /**
7
+ * `tone_map` of `shaders/post/curves.wesl` in TS: linear `rgb` times `exposure`, through
8
+ * `curve`, sRGB-encoded, into `out`. For colours the CPU hands the display directly (the clear
9
+ * colour when the draw tone-maps inline, ADR-0071).
10
+ */
11
+ export function toneMapColor(rgb, exposure, curve, out = [0, 0, 0]) {
12
+ const c = [0, 1, 2].map((k) => Math.max(0, rgb[k] * exposure));
13
+ if (curve === 'neutral') {
14
+ const x = Math.min(c[0], c[1], c[2]);
15
+ const offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
16
+ for (let k = 0; k < 3; k++)
17
+ c[k] -= offset;
18
+ const peak = Math.max(c[0], c[1], c[2]);
19
+ const start = 0.76;
20
+ if (peak >= start) {
21
+ const d = 1 - start;
22
+ const np = 1 - (d * d) / (peak + d - start);
23
+ const g = 1 - 1 / (0.15 * (peak - np) + 1);
24
+ for (let k = 0; k < 3; k++)
25
+ c[k] = c[k] * (np / peak) * (1 - g) + np * g;
26
+ }
27
+ }
28
+ else if (curve === 'aces') {
29
+ for (let k = 0; k < 3; k++)
30
+ c[k] = sat((c[k] * (2.51 * c[k] + 0.03)) / (c[k] * (2.43 * c[k] + 0.59) + 0.14));
31
+ }
32
+ for (let k = 0; k < 3; k++) {
33
+ const v = sat(c[k]);
34
+ out[k] = v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055;
35
+ }
36
+ return out;
37
+ }
38
+ /** Bytes of `ToneParams` (`shaders/post/tonemap.wesl`). */
39
+ export const TONE_PARAMS_BYTES = 80;
40
+ /**
41
+ * Writes `ToneParams`: exposure and curve, the bloom's weight (0: none) and the grading
42
+ * (`grading.enabled` false: none, so the pass is the plain tone map).
43
+ */
44
+ export function writeToneParams(out, exposure, curve, bloom, grading) {
45
+ out.setFloat32(0, exposure, true);
46
+ out.setUint32(4, CURVES[curve], true);
47
+ out.setFloat32(8, bloom, true);
48
+ const g = grading?.enabled ? grading : null;
49
+ out.setUint32(12, g ? 1 : 0, true);
50
+ if (!g)
51
+ return;
52
+ const wb = whiteBalance(g.temperature, g.tint);
53
+ const v3 = (at, v) => v.forEach((x, i) => out.setFloat32(at + 4 * i, x, true));
54
+ v3(16, wb);
55
+ out.setFloat32(28, g.contrast, true);
56
+ v3(32, g.lift);
57
+ out.setFloat32(44, g.saturation, true);
58
+ v3(48, g.gamma);
59
+ v3(64, g.gain);
60
+ }
61
+ /**
62
+ * The tone-mapping pass (M2 increment 5): reads the scene's linear HDR target and writes the
63
+ * swapchain through exposure, a curve (Khronos PBR Neutral by default) and the sRGB transfer
64
+ * function. One full-screen triangle; its bind group follows the graph's reallocations.
65
+ */
66
+ export class ToneMapper {
67
+ device;
68
+ /** Linear multiplier before the curve. */
69
+ exposure = 1;
70
+ curve = 'neutral';
71
+ /** The bloom chain's weight (set by the post chain; 0 without bloom). */
72
+ bloom = 0;
73
+ /** Colour grading (ADR-0092), or null. */
74
+ grading = null;
75
+ #pipeline;
76
+ #params;
77
+ #data = new ArrayBuffer(TONE_PARAMS_BYTES);
78
+ #view = new DataView(this.#data);
79
+ #last = new Uint8Array(TONE_PARAMS_BYTES);
80
+ #bytes = new Uint8Array(this.#data);
81
+ #group = null;
82
+ #generation = -1;
83
+ #fresh = true;
84
+ #format;
85
+ #sampler;
86
+ /** Bound where there is no bloom chain (the shader skips it). */
87
+ #black;
88
+ constructor(device, format) {
89
+ this.device = device;
90
+ this.#format = format;
91
+ this.#params = device.createBuffer({ label: 'yali:tonemap:params', size: TONE_PARAMS_BYTES, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
92
+ this.#sampler = device.createSampler({ label: 'yali:tonemap', magFilter: 'linear', minFilter: 'linear', addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge' });
93
+ this.#black = device.createTexture({ label: 'yali:tonemap:noBloom', size: [1, 1], format: 'rgba16float', usage: GPUTextureUsage.TEXTURE_BINDING });
94
+ }
95
+ async init(cache) {
96
+ this.#pipeline = await cache.render({
97
+ label: 'yali:tonemap',
98
+ vertex: { shader: postTonemap, entryPoint: 'vs' },
99
+ fragment: { shader: postTonemap, entryPoint: 'fs', targets: [{ format: this.#format }] },
100
+ primitive: { topology: 'triangle-list' },
101
+ });
102
+ }
103
+ /** Adds `post.tonemap`, reading `input` (and `bloom`'s chain, if any) and writing `output`. */
104
+ addPass(graph, input, output, bloom) {
105
+ graph.addPass({
106
+ name: 'post.tonemap',
107
+ kind: 'render',
108
+ reads: bloom ? [input, bloom] : [input],
109
+ color: { target: output, clear: { r: 0, g: 0, b: 0, a: 1 } },
110
+ execute: (pass, ctx) => {
111
+ if (ctx.generation !== this.#generation || !this.#group) {
112
+ this.#group = this.device.createBindGroup({
113
+ label: 'yali:tonemap',
114
+ layout: this.#pipeline.getBindGroupLayout(0),
115
+ entries: [
116
+ { binding: 0, resource: ctx.view(input) },
117
+ { binding: 1, resource: { buffer: this.#params } },
118
+ { binding: 2, resource: bloom ? ctx.view(bloom) : this.#black.createView() },
119
+ { binding: 3, resource: this.#sampler },
120
+ ],
121
+ });
122
+ this.#generation = ctx.generation;
123
+ }
124
+ writeToneParams(this.#view, this.exposure, this.curve, bloom ? this.bloom : 0, this.grading);
125
+ if (this.#fresh || !this.#bytes.every((b, i) => b === this.#last[i])) {
126
+ this.device.queue.writeBuffer(this.#params, 0, this.#data);
127
+ this.#last.set(this.#bytes);
128
+ this.#fresh = false;
129
+ }
130
+ pass.setPipeline(this.#pipeline);
131
+ pass.setBindGroup(0, this.#group);
132
+ pass.draw(3);
133
+ },
134
+ });
135
+ }
136
+ destroy() {
137
+ this.#params.destroy();
138
+ this.#black.destroy();
139
+ }
140
+ }
141
+ //# sourceMappingURL=tonemap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tonemap.js","sourceRoot":"","sources":["../src/tonemap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /** Sizing policy for the render target. */
2
+ export interface ViewportOptions {
3
+ /** Highest device-pixel ratio rendered (default 2: a 3× phone renders at 2×). */
4
+ readonly maxDpr?: number;
5
+ /** Most pixels in the render target (default 3840×2160). */
6
+ readonly maxPixels?: number;
7
+ /** Initial render scale (dynamic resolution; the governor drives it, DESIGN.md §4). */
8
+ readonly renderScale?: number;
9
+ }
10
+ /** What the page knows about the canvas's size: pushed into a worker's viewport (`setSize`). */
11
+ export interface ViewportSize {
12
+ readonly css: {
13
+ readonly width: number;
14
+ readonly height: number;
15
+ };
16
+ readonly dpr: number;
17
+ /** Exact device pixels (devicePixelContentBoxSize), when the browser reports them. */
18
+ readonly device: {
19
+ readonly width: number;
20
+ readonly height: number;
21
+ } | null;
22
+ }
23
+ /** The render target size for a CSS size, DPR and policy. Pure, so it is unit-tested. */
24
+ export declare function computeRenderSize(css: {
25
+ width: number;
26
+ height: number;
27
+ }, devicePixels: {
28
+ width: number;
29
+ height: number;
30
+ } | null, dpr: number, opts: {
31
+ maxDpr: number;
32
+ maxPixels: number;
33
+ renderScale: number;
34
+ }): {
35
+ width: number;
36
+ height: number;
37
+ effectiveDpr: number;
38
+ };
39
+ /**
40
+ * Keeps the canvas's backing store at the right size (DESIGN.md §11). It follows layout and
41
+ * DPR changes through a ResizeObserver, using exact device pixels where the browser
42
+ * provides them, so the canvas is never blurred by a rounding error. It caps DPR and total
43
+ * pixels, and exposes `renderScale` as the dynamic-resolution knob.
44
+ *
45
+ * `update()` is cheap when nothing changed; it returns true when the size did.
46
+ */
47
+ export declare class Viewport {
48
+ #private;
49
+ readonly canvas: HTMLCanvasElement | OffscreenCanvas;
50
+ /** The render size: the scene's targets. */
51
+ width: number;
52
+ height: number;
53
+ /** The output size: the canvas. The same as the render size unless `upscale`. */
54
+ outputWidth: number;
55
+ outputHeight: number;
56
+ /**
57
+ * Temporal upscaling (ADR-0135): the canvas stays at full size and `renderScale` scales only the
58
+ * render size, which TAA reconstructs up to the output. Off, `renderScale` scales the canvas itself.
59
+ */
60
+ get upscale(): boolean;
61
+ set upscale(on: boolean);
62
+ effectiveDpr: number;
63
+ constructor(canvas: HTMLCanvasElement | OffscreenCanvas, options?: ViewportOptions);
64
+ /** The dynamic-resolution scale (0.25–1). */
65
+ get renderScale(): number;
66
+ set renderScale(s: number);
67
+ /**
68
+ * Sets the size from outside (worker render mode: the page's ResizeObserver measures,
69
+ * `hostRenderWorker` forwards, `link.bind(app)` calls this). Applied on the next `update`.
70
+ */
71
+ setSize(size: ViewportSize): void;
72
+ /** Applies any pending size change to the canvas. Returns true if the size changed. */
73
+ update(): boolean;
74
+ /** Stops observing (counted by the leak check until called). */
75
+ dispose(): void;
76
+ /** Live observers (0 after dispose). */
77
+ get listeners(): number;
78
+ }
@@ -0,0 +1,130 @@
1
+ /** The render target size for a CSS size, DPR and policy. Pure, so it is unit-tested. */
2
+ export function computeRenderSize(css, devicePixels, dpr, opts) {
3
+ // Exact device pixels when the browser reports them (devicePixelContentBoxSize), else
4
+ // CSS × DPR. The DPR cap and the render scale apply on top.
5
+ const base = devicePixels ?? { width: css.width * dpr, height: css.height * dpr };
6
+ const capDpr = Math.min(1, opts.maxDpr / Math.max(dpr, 1e-6));
7
+ let scale = Math.min(capDpr, 1) * opts.renderScale;
8
+ const pixels = base.width * base.height * scale * scale;
9
+ if (pixels > opts.maxPixels)
10
+ scale *= Math.sqrt(opts.maxPixels / pixels);
11
+ const width = Math.max(1, Math.round(base.width * scale));
12
+ const height = Math.max(1, Math.round(base.height * scale));
13
+ return { width, height, effectiveDpr: css.width > 0 ? width / css.width : dpr };
14
+ }
15
+ /**
16
+ * Keeps the canvas's backing store at the right size (DESIGN.md §11). It follows layout and
17
+ * DPR changes through a ResizeObserver, using exact device pixels where the browser
18
+ * provides them, so the canvas is never blurred by a rounding error. It caps DPR and total
19
+ * pixels, and exposes `renderScale` as the dynamic-resolution knob.
20
+ *
21
+ * `update()` is cheap when nothing changed; it returns true when the size did.
22
+ */
23
+ export class Viewport {
24
+ canvas;
25
+ /** The render size: the scene's targets. */
26
+ width = 1;
27
+ height = 1;
28
+ /** The output size: the canvas. The same as the render size unless `upscale`. */
29
+ outputWidth = 1;
30
+ outputHeight = 1;
31
+ /**
32
+ * Temporal upscaling (ADR-0135): the canvas stays at full size and `renderScale` scales only the
33
+ * render size, which TAA reconstructs up to the output. Off, `renderScale` scales the canvas itself.
34
+ */
35
+ get upscale() {
36
+ return this.#upscale;
37
+ }
38
+ set upscale(on) {
39
+ if (on !== this.#upscale) {
40
+ this.#upscale = on;
41
+ this.#dirty = true;
42
+ }
43
+ }
44
+ #upscale = false;
45
+ effectiveDpr = 1;
46
+ #opts;
47
+ #css = { width: 0, height: 0 };
48
+ #device = null;
49
+ #dirty = true;
50
+ #observer = null;
51
+ /** DPR pushed by `setSize` (a worker has no `devicePixelRatio` of its own). */
52
+ #dpr = null;
53
+ constructor(canvas, options = {}) {
54
+ this.canvas = canvas;
55
+ this.#opts = { maxDpr: options.maxDpr ?? 2, maxPixels: options.maxPixels ?? 3840 * 2160, renderScale: options.renderScale ?? 1 };
56
+ // An OffscreenCanvas (worker render mode) has no layout to observe: the page pushes
57
+ // its size with setSize. Until then it renders at the canvas's own size.
58
+ if (typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas) {
59
+ this.#css = { width: canvas.width, height: canvas.height };
60
+ }
61
+ else if (typeof ResizeObserver !== 'undefined') {
62
+ const element = canvas;
63
+ this.#observer = new ResizeObserver((entries) => {
64
+ const e = entries[entries.length - 1];
65
+ const box = e.contentBoxSize?.[0];
66
+ this.#css = box ? { width: box.inlineSize, height: box.blockSize } : { width: e.contentRect.width, height: e.contentRect.height };
67
+ const dev = e.devicePixelContentBoxSize?.[0];
68
+ this.#device = dev ? { width: dev.inlineSize, height: dev.blockSize } : null;
69
+ this.#dirty = true;
70
+ });
71
+ try {
72
+ this.#observer.observe(element, { box: 'device-pixel-content-box' });
73
+ }
74
+ catch {
75
+ this.#observer.observe(element); // Safari before device-pixel-content-box
76
+ }
77
+ }
78
+ }
79
+ /** The dynamic-resolution scale (0.25–1). */
80
+ get renderScale() {
81
+ return this.#opts.renderScale;
82
+ }
83
+ set renderScale(s) {
84
+ const v = Math.min(1, Math.max(0.25, s));
85
+ if (v !== this.#opts.renderScale) {
86
+ this.#opts.renderScale = v;
87
+ this.#dirty = true;
88
+ }
89
+ }
90
+ /**
91
+ * Sets the size from outside (worker render mode: the page's ResizeObserver measures,
92
+ * `hostRenderWorker` forwards, `link.bind(app)` calls this). Applied on the next `update`.
93
+ */
94
+ setSize(size) {
95
+ this.#css = { width: size.css.width, height: size.css.height };
96
+ this.#device = size.device ? { width: size.device.width, height: size.device.height } : null;
97
+ this.#dpr = size.dpr;
98
+ this.#dirty = true;
99
+ }
100
+ /** Applies any pending size change to the canvas. Returns true if the size changed. */
101
+ update() {
102
+ if (!this.#dirty)
103
+ return false;
104
+ this.#dirty = false;
105
+ if ((!this.#observer || this.#css.width === 0) && 'clientWidth' in this.canvas && this.#dpr === null) {
106
+ this.#css = { width: this.canvas.clientWidth, height: this.canvas.clientHeight };
107
+ }
108
+ const dpr = this.#dpr ?? (typeof devicePixelRatio === 'number' ? devicePixelRatio : 1);
109
+ const out = computeRenderSize(this.#css, this.#device, dpr, this.#upscale ? { ...this.#opts, renderScale: 1 } : this.#opts);
110
+ const s = this.#upscale ? { width: Math.max(1, Math.round(out.width * this.#opts.renderScale)), height: Math.max(1, Math.round(out.height * this.#opts.renderScale)) } : out;
111
+ this.effectiveDpr = out.effectiveDpr;
112
+ if (s.width === this.width && s.height === this.height && out.width === this.outputWidth && out.height === this.outputHeight)
113
+ return false;
114
+ this.width = s.width;
115
+ this.height = s.height;
116
+ this.outputWidth = this.canvas.width = out.width;
117
+ this.outputHeight = this.canvas.height = out.height;
118
+ return true;
119
+ }
120
+ /** Stops observing (counted by the leak check until called). */
121
+ dispose() {
122
+ this.#observer?.disconnect();
123
+ this.#observer = null;
124
+ }
125
+ /** Live observers (0 after dispose). */
126
+ get listeners() {
127
+ return this.#observer ? 1 : 0;
128
+ }
129
+ }
130
+ //# sourceMappingURL=viewport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewport.js","sourceRoot":"","sources":["../src/viewport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { type AppBuilder, type Component, type World } from '@yali-engine/core';
2
+ import type { OrbitCamera } from '../camera.ts';
3
+ import type { DebugLines } from '../debug-lines.ts';
4
+ import { type DeviceFilterRule, type Tier } from '../device-profile.ts';
5
+ import type { InstanceExtractor } from '../extract.ts';
6
+ import type { MaterialStore, MeshStore } from '../meshes.ts';
7
+ import type { RenderContext, RenderPluginOptions } from '../render-plugin.ts';
8
+ import type { Viewport } from '../viewport.ts';
9
+ /** What the render plugin hands the WebGL2 backend: everything that outlives a context. */
10
+ export interface WebGL2Start {
11
+ readonly b: AppBuilder;
12
+ readonly options: RenderPluginOptions;
13
+ readonly viewport: Viewport;
14
+ readonly camera: OrbitCamera;
15
+ readonly debug: DebugLines;
16
+ readonly store: MeshStore;
17
+ readonly materials: MaterialStore;
18
+ readonly world: World | null;
19
+ readonly Mesh: Component | null;
20
+ readonly Light: Component | null;
21
+ readonly extractor: InstanceExtractor | null;
22
+ readonly rules: readonly DeviceFilterRule[];
23
+ readonly tierSizes: {
24
+ readonly texture: Readonly<Record<Tier, number>>;
25
+ readonly shadows: Readonly<Record<Tier, {
26
+ cascades: number;
27
+ size: number;
28
+ distance: number;
29
+ filter: 'soft' | 'hard';
30
+ }>>;
31
+ };
32
+ }
33
+ /**
34
+ * The WebGL2 backend (ADR-0070): where the browser has no WebGPU, the render plugin imports
35
+ * this module (so a WebGPU page carries none of it) and draws the same frame with
36
+ * `GlRenderer`. Always tier T0 (or lower by the device filter), the CPU cull, the standard
37
+ * material for every material (node materials need WGSL); everything else as on WebGPU.
38
+ * A lost context is recovered when the browser restores it.
39
+ */
40
+ export declare function startWebGL2(a: WebGL2Start): Promise<RenderContext>;
@@ -0,0 +1,190 @@
1
+ import { YaliError } from '@yali-engine/core';
2
+ import { collectDeviceProfile, selectTier } from "../device-profile.js";
3
+ import { GpuHealth } from "../gpu-health.js";
4
+ import { pickFamily, TextureStore } from "../textures.js";
5
+ import { gradingDefaults } from "../post-options.js";
6
+ import { GlRenderer } from "./renderer.js";
7
+ import { glFamilies, glTextureBackend } from "./textures.js";
8
+ const NO_BYTES = new Uint8Array(0);
9
+ const NO_WORDS = new Uint32Array(0);
10
+ /**
11
+ * The WebGL2 backend (ADR-0070): where the browser has no WebGPU, the render plugin imports
12
+ * this module (so a WebGPU page carries none of it) and draws the same frame with
13
+ * `GlRenderer`. Always tier T0 (or lower by the device filter), the CPU cull, the standard
14
+ * material for every material (node materials need WGSL); everything else as on WebGPU.
15
+ * A lost context is recovered when the browser restores it.
16
+ */
17
+ export async function startWebGL2(a) {
18
+ const { b, options, viewport, camera, store, materials, world, Light, extractor } = a;
19
+ const lc = b.app.lifecycle;
20
+ const canvas = options.canvas;
21
+ const gl = canvas.getContext('webgl2', { antialias: false, depth: false, stencil: false, alpha: false, preserveDrawingBuffer: false, powerPreference: 'high-performance' });
22
+ if (!gl)
23
+ throw new YaliError('NO_GPU', 'This browser has neither WebGPU nor WebGL2.', 'Use a current Chrome, Edge, Safari or Firefox.');
24
+ const profile = await collectDeviceProfile(null);
25
+ const tier = selectTier('webgl2', profile, a.rules, options.tier);
26
+ const disable = new Set(tier.disable);
27
+ const features = glFamilies(gl);
28
+ const family = options.textureFamily ?? (disable.has('compressed-textures') ? 'rgba8' : pickFamily(features));
29
+ const textures = new TextureStore({ family, size: options.textureSize ?? a.tierSizes.texture[tier.tier] });
30
+ textures.attachBackend(glTextureBackend(gl));
31
+ const defaults = a.tierSizes.shadows[tier.tier];
32
+ const so = options.shadows === false || (options.shadows === undefined && disable.has('shadows')) ? null : (options.shadows ?? {});
33
+ const shadowConfig = so ? { cascades: so.cascades ?? defaults.cascades, size: so.size ?? defaults.size, distance: so.distance ?? defaults.distance, splitLambda: so.splitLambda ?? 0.75, pcfRadius: (so.filter ?? defaults.filter) === 'hard' ? 0 : 1 } : null;
34
+ const t0 = performance.now();
35
+ const make = () => {
36
+ // T0 tone-maps inline unless the app asks for the HDR target (ADR-0071).
37
+ const r = new GlRenderer(gl, store, materials, textures, options.capacity ?? 65_536, shadowConfig, options.hdr ?? (tier.tier !== 't0' || !!options.post?.grading), (options.dynamicShading ?? tier.tier === 't0') ? 3 : 1);
38
+ Object.assign(r.lighting, options.lighting ?? {});
39
+ r.curve = options.toneMapping ?? 'neutral';
40
+ r.exposure = options.exposure ?? 1;
41
+ r.grading = gradingDefaults(options.post?.grading);
42
+ if (options.sky)
43
+ r.setSky(options.sky);
44
+ r.debug = a.debug;
45
+ return r;
46
+ };
47
+ let r = make();
48
+ const shaderMs = performance.now() - t0;
49
+ lc.emit({ type: 'init:adapter', backend: 'webgl2', adapterInfo: { vendor: profile.gpu.vendor ?? '', description: profile.gpu.webglRenderer ?? '' } });
50
+ lc.emit({ type: 'init:capabilities', features: [...features, ...(r.hdr ? ['color-buffer-float'] : [])], limits: { maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE), maxArrayTextureLayers: gl.getParameter(gl.MAX_ARRAY_TEXTURE_LAYERS) } });
51
+ lc.emit({ type: 'init:device-filter', matched: tier.matched });
52
+ lc.emit({ type: 'init:tier', tier: tier.tier, source: tier.source });
53
+ lc.emit({ type: 'init:shaders', pipelines: 5, ms: shaderMs });
54
+ if (!r.hdr)
55
+ console.warn('[yali render] WebGL2 without EXT_color_buffer_float: the scene renders to RGBA8, so highlights clip before the tone curve.');
56
+ const shadows = () => {
57
+ const cfg = r.shadows;
58
+ return {
59
+ enabled: !!cfg,
60
+ cascades: cfg?.cascades ?? 0,
61
+ size: cfg?.size ?? 1,
62
+ get distance() {
63
+ return cfg?.distance ?? 0;
64
+ },
65
+ set distance(v) {
66
+ if (cfg)
67
+ cfg.distance = v;
68
+ },
69
+ };
70
+ };
71
+ let lost = false;
72
+ const ctx = {
73
+ backend: 'webgl2',
74
+ gpu: null,
75
+ scene: r,
76
+ tonemap: r,
77
+ // WebGL2 has no post chain (ADR-0092): grading only, in its tone-mapping pass.
78
+ post: {
79
+ bloom: false,
80
+ fxaa: false,
81
+ taa: false,
82
+ bloomIntensity: 0,
83
+ bloomThreshold: 0,
84
+ bloomKnee: 0,
85
+ bloomRadius: 0,
86
+ taaSharpen: 0,
87
+ motionBlur: 0,
88
+ taaBlend: 0,
89
+ get grading() {
90
+ return r.grading;
91
+ },
92
+ resetHistory() { },
93
+ readMotion: () => Promise.resolve(null),
94
+ },
95
+ environment: r,
96
+ lights: r.lights,
97
+ shadows: shadows(),
98
+ Light,
99
+ meshes: store,
100
+ materials,
101
+ textures,
102
+ Mesh: a.Mesh,
103
+ graph: null,
104
+ timer: null,
105
+ pipelines: null,
106
+ viewport,
107
+ camera,
108
+ debug: a.debug,
109
+ prepasses: [],
110
+ health: new GpuHealth(),
111
+ profile,
112
+ tier: tier.tier,
113
+ recoveries: 0,
114
+ submitMs: 0,
115
+ uploadMs: 0,
116
+ // WebGL2 blocks in the driver when it is behind: no cap needed (ADR-0129).
117
+ maxFramesInFlight: 0,
118
+ framesInFlight: 0,
119
+ skippedFrames: 0,
120
+ capture: () => r.capture(),
121
+ simulateDeviceLoss() {
122
+ // A real loss is restored by the browser; a simulated one must be restored by hand.
123
+ const ext = gl.getExtension('WEBGL_lose_context');
124
+ ext?.loseContext();
125
+ setTimeout(() => ext?.restoreContext(), 50);
126
+ },
127
+ };
128
+ const profiler = b.app.profiler;
129
+ const upload = profiler.scope('render.upload', 'Submit');
130
+ const encode = profiler.scope('render.encode', 'Submit');
131
+ b.system({
132
+ name: 'render.submit',
133
+ stage: 'Submit',
134
+ run: () => {
135
+ if (lost)
136
+ return; // recovering: draw nothing
137
+ const t = performance.now();
138
+ profiler.begin(upload);
139
+ textures.pump(1);
140
+ const core = extractor?.world.core;
141
+ r.upload(core?.heap.u8 ?? NO_BYTES, core?.heap.u32 ?? NO_WORDS, extractor, camera, viewport.width, viewport.height, world, Light);
142
+ profiler.end(upload);
143
+ ctx.uploadMs = performance.now() - t;
144
+ profiler.begin(encode);
145
+ r.render(viewport.width, viewport.height);
146
+ profiler.end(encode);
147
+ ctx.submitMs = performance.now() - t;
148
+ a.debug.clear();
149
+ },
150
+ });
151
+ // Context loss: report it, and rebuild when the browser restores the context.
152
+ let restored = () => { };
153
+ const onLost = (e) => {
154
+ e.preventDefault(); // allows the restore
155
+ lost = true;
156
+ void b.app.deviceLost({ reason: 'unknown', message: 'The WebGL2 context was lost.' });
157
+ };
158
+ const onRestored = () => restored();
159
+ canvas.addEventListener('webglcontextlost', onLost);
160
+ canvas.addEventListener('webglcontextrestored', onRestored);
161
+ b.recover(async () => {
162
+ if (gl.isContextLost())
163
+ await new Promise((resolve) => (restored = resolve));
164
+ const prev = r;
165
+ textures.attachBackend(glTextureBackend(gl));
166
+ r = make();
167
+ Object.assign(r.lighting, prev.lighting);
168
+ r.shadingLevel = prev.shadingLevel;
169
+ r.exposure = prev.exposure;
170
+ r.curve = prev.curve;
171
+ r.grading = prev.grading;
172
+ r.setSky(prev.sky);
173
+ if (r.shadows && prev.shadows)
174
+ r.shadows.distance = prev.shadows.distance;
175
+ Object.assign(ctx, { scene: r, tonemap: r, environment: r, lights: r.lights, shadows: shadows() });
176
+ lost = false;
177
+ ctx.recoveries++;
178
+ return { devices: 1, pipelines: 5, buffers: r.liveBuffers, timers: 0 };
179
+ });
180
+ b.leaks(() => ({ gpuResources: lost ? 0 : r.liveBuffers, listeners: viewport.listeners }));
181
+ b.onDispose(() => {
182
+ canvas.removeEventListener('webglcontextlost', onLost);
183
+ canvas.removeEventListener('webglcontextrestored', onRestored);
184
+ viewport.dispose();
185
+ textures.detach();
186
+ r.destroy();
187
+ });
188
+ return ctx;
189
+ }
190
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/webgl2/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { GlslProgram } from './shaders.glsl.gen.ts';
2
+ /** A texture bound at a WGSL binding: what GL target it is. */
3
+ export interface GlTextureBinding {
4
+ readonly target: number;
5
+ readonly texture: WebGLTexture;
6
+ }
7
+ /** What a draw binds, by WGSL binding number (group 0): uniform buffers, textures, samplers. */
8
+ export interface GlBindings {
9
+ readonly uniforms: ReadonlyMap<number, WebGLBuffer>;
10
+ readonly textures: ReadonlyMap<number, GlTextureBinding>;
11
+ readonly samplers: ReadonlyMap<number, WebGLSampler>;
12
+ }
13
+ /**
14
+ * A linked GLSL ES 3.00 program from `tools/glsl-gen.mjs` (ADR-0070). GLSL ES 3.00 has no
15
+ * binding qualifiers, so naga reports each uniform block's and combined sampler's name and
16
+ * the WGSL binding it came from: each uniform block is bound to the binding point equal to
17
+ * its WGSL binding (the vertex and fragment stages' blocks for one binding share it), and
18
+ * each combined sampler gets a texture unit, where `bind` puts the binding's texture and the
19
+ * sampler binding's sampler object.
20
+ */
21
+ export declare class GlProgram {
22
+ #private;
23
+ readonly program: WebGLProgram;
24
+ constructor(gl: WebGL2RenderingContext, label: string, src: GlslProgram);
25
+ /** Makes the program current and binds `b`'s resources to its blocks and units. */
26
+ bind(gl: WebGL2RenderingContext, b: GlBindings): void;
27
+ }