onejs-sl 0.6.0 → 0.7.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.
- package/CHANGELOG.md +16 -0
- package/README.md +44 -5
- package/goldens/goldens.json +69 -2
- package/package.json +2 -2
- package/src/body.ts +38 -5
- package/src/compile.ts +11 -1
- package/src/core.ts +4 -4
- package/src/hlsl.ts +21 -3
- package/src/ir.ts +70 -10
- package/src/lang/README.md +4 -3
- package/src/lang/check.ts +39 -7
- package/src/lang/classify.ts +2 -2
- package/src/lang/glsl.ts +2 -2
- package/src/lang/lower.ts +12 -3
- package/src/lang/parser.ts +1 -1
- package/src/ops.ts +7 -3
- package/src/params.ts +5 -2
- package/src/serial.ts +8 -4
- package/src/sl.ts +37 -3
- package/src/structure.ts +2 -2
- package/src/tables.ts +2 -2
- package/src/web.ts +31 -7
package/src/web.ts
CHANGED
|
@@ -12,13 +12,22 @@
|
|
|
12
12
|
* named `n<index>`. What differs is the contract with the host, which is fixed
|
|
13
13
|
* and the same for both languages:
|
|
14
14
|
*
|
|
15
|
-
* sl_Res (target width, target height, seconds,
|
|
16
|
-
* sl_Opt (1 in a Linear colour space project else 0, 1 to flip uv.y,
|
|
15
|
+
* sl_Res (target width, target height, seconds, frame)
|
|
16
|
+
* sl_Opt (1 in a Linear colour space project else 0, 1 to flip uv.y, deltaTime, 0)
|
|
17
17
|
* sl_U[16] uniform slots, each a vec4, in the program's slot order
|
|
18
18
|
* textures by slot: GLSL `sl_Tex<slot>`; WGSL `sl_tex<slot>` at binding
|
|
19
19
|
* 2 + 2 * slot with its own sampler `sl_samp<slot>` at 1 + 2 * slot,
|
|
20
20
|
* all in group 0 beside the frame block at binding 0. Only the
|
|
21
21
|
* slots the program samples are declared.
|
|
22
|
+
* the previous frame, only for a program that samples it: GLSL `sl_Prev`;
|
|
23
|
+
* WGSL `sl_prev` with its sampler `sl_prevSamp`, at the two
|
|
24
|
+
* bindings after the last texture slot's, whatever the program
|
|
25
|
+
* declares. Read at level 0 (`body.ts`, `BodyTarget.previous`),
|
|
26
|
+
* its y flipped when `sl_Opt.y` flips uv, so the texture the host
|
|
27
|
+
* drew last frame reads back the way it was written.
|
|
28
|
+
*
|
|
29
|
+
* `frame` and `deltaTime` ride in components that were 0, and a host sets
|
|
30
|
+
* them only for a program that reads them (`readsOf`).
|
|
22
31
|
*
|
|
23
32
|
* WGSL also carries its vertex stage (`sl_vs`, a full-target triangle from the
|
|
24
33
|
* vertex index) so one module is one pipeline; the GLSL host supplies its own.
|
|
@@ -30,7 +39,7 @@ import { inVaryingFlow, local, printBody, structure, type Syntax } from "./struc
|
|
|
30
39
|
import { libClosure, libIndex, LIB_FUNCTIONS, SDF_CALLS } from "./lib"
|
|
31
40
|
import { LIB_GLSL } from "./lib/glsl"
|
|
32
41
|
import { LIB_WGSL } from "./lib/wgsl"
|
|
33
|
-
import { INPUT_ID, SLOP, UNIFORM_SLOTS } from "./ops"
|
|
42
|
+
import { INPUT_ID, SLOP, TEXTURE_SLOTS, UNIFORM_SLOTS } from "./ops"
|
|
34
43
|
|
|
35
44
|
export type WebLanguage = "glsl" | "wgsl"
|
|
36
45
|
|
|
@@ -50,6 +59,8 @@ function emitWeb(p: Program, lang: WebLanguage): string {
|
|
|
50
59
|
const need = new Set<number>()
|
|
51
60
|
const smoothsteps = new Set<SLType>()
|
|
52
61
|
const sampled = new Set<number>()
|
|
62
|
+
/** Whether the body samples the previous frame, which declares its binding. */
|
|
63
|
+
let previous = false
|
|
53
64
|
const shape = structure(p)
|
|
54
65
|
const T = (t: SLType) => (W ? (t === 1 ? "f32" : `vec${t}f`) : t === 1 ? "float" : `vec${t}`)
|
|
55
66
|
/** A value's type in this language, its kind included. */
|
|
@@ -90,7 +101,10 @@ function emitWeb(p: Program, lang: WebLanguage): string {
|
|
|
90
101
|
case 1: return `(sl_uv * ${res}.xy)`
|
|
91
102
|
case 2: return `${res}.xy`
|
|
92
103
|
case 3: return `${res}.z`
|
|
93
|
-
|
|
104
|
+
case 4: return `(${res}.x / max(${res}.y, 1.0))`
|
|
105
|
+
case 5: return `${res}.w`
|
|
106
|
+
case 6: return W ? "sl.opt.z" : "sl_Opt.z"
|
|
107
|
+
default: throw new Error(`no web mapping for the input "${n.name}"`)
|
|
94
108
|
}
|
|
95
109
|
}
|
|
96
110
|
case "uniform": {
|
|
@@ -251,6 +265,13 @@ function emitWeb(p: Program, lang: WebLanguage): string {
|
|
|
251
265
|
? `textureSampleLevel(sl_tex${slot}, sl_samp${slot}, ${a[0]}, ${a[1]})`
|
|
252
266
|
: `textureLod(sl_Tex${slot}, ${a[0]}, ${a[1]})`
|
|
253
267
|
}
|
|
268
|
+
case SLOP.SAMPLE_PREVIOUS:
|
|
269
|
+
previous = true
|
|
270
|
+
// Flipped as this frame flipped the uv it wrote at, so a read at
|
|
271
|
+
// a pixel's own uv is that pixel on either backend.
|
|
272
|
+
return W
|
|
273
|
+
? `textureSampleLevel(sl_prev, sl_prevSamp, ${a[0]} * vec2f(1.0, 1.0 - 2.0 * sl.opt.y) + vec2f(0.0, sl.opt.y), 0.0)`
|
|
274
|
+
: `textureLod(sl_Prev, ${a[0]} * vec2(1.0, 1.0 - 2.0 * sl_Opt.y) + vec2(0.0, sl_Opt.y), 0.0)`
|
|
254
275
|
default:
|
|
255
276
|
throw new SLError(
|
|
256
277
|
`the ${lang.toUpperCase()} emitter has no case for opcode ${n.op}. A program using it would ` +
|
|
@@ -342,9 +363,12 @@ function emitWeb(p: Program, lang: WebLanguage): string {
|
|
|
342
363
|
const textures = p.textures.filter((t) => sampled.has(t.slot))
|
|
343
364
|
|
|
344
365
|
if (W) {
|
|
345
|
-
const bindings = textures.map((t) =>
|
|
366
|
+
const bindings = [...textures.map((t) =>
|
|
346
367
|
`@group(0) @binding(${1 + 2 * t.slot}) var sl_samp${t.slot}: sampler;\n` +
|
|
347
|
-
`@group(0) @binding(${2 + 2 * t.slot}) var sl_tex${t.slot}: texture_2d<f32>;`)
|
|
368
|
+
`@group(0) @binding(${2 + 2 * t.slot}) var sl_tex${t.slot}: texture_2d<f32>;`),
|
|
369
|
+
...previous ? [
|
|
370
|
+
`@group(0) @binding(${1 + 2 * TEXTURE_SLOTS}) var sl_prevSamp: sampler;\n` +
|
|
371
|
+
`@group(0) @binding(${2 + 2 * TEXTURE_SLOTS}) var sl_prev: texture_2d<f32>;`] : []].join("\n")
|
|
348
372
|
return `${header}
|
|
349
373
|
struct SLFrame { res: vec4f, opt: vec4f, u: array<vec4f, ${WEB_UNIFORM_SLOTS}> }
|
|
350
374
|
@group(0) @binding(0) var<uniform> sl: SLFrame;
|
|
@@ -362,7 +386,7 @@ ${body}
|
|
|
362
386
|
}
|
|
363
387
|
`
|
|
364
388
|
}
|
|
365
|
-
const samplers = textures.map((t) => `uniform sampler2D sl_Tex${t.slot};`).join("\n")
|
|
389
|
+
const samplers = [...textures.map((t) => `uniform sampler2D sl_Tex${t.slot};`), ...previous ? ["uniform sampler2D sl_Prev;"] : []].join("\n")
|
|
366
390
|
return `#version 300 es
|
|
367
391
|
${header}
|
|
368
392
|
precision highp float;
|