onejs-sl 0.7.0 → 0.8.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0
4
+
5
+ A fractional `tex2Dlod` level now blends the two levels either side on every backend. No existing program's hash changes, but a host now gets two whole-level samples and a blend where it got one fractional sample, so a host that blended levels itself would blend twice, which makes this a minor.
6
+
7
+ - A fractional `tex2Dlod` level blends the two levels either side, whatever the texture's filter mode
8
+
3
9
  ## 0.7.0
4
10
 
5
11
  A program can read what it drew the frame before, and count frames (`Specs/SL_NEXT.md` 4). Every existing program keeps its hash and its shader; one that reads the new names is IR 5. A host has to forward the new `reads` to draw such a program, which makes this a minor.
package/README.md CHANGED
@@ -27,6 +27,11 @@ const plasma = sl.program(({ uv, time }) => {
27
27
  })
28
28
  ```
29
29
 
30
+ `npm install onejs-sl`. The package ships TypeScript source (its `exports`
31
+ point at `src/*.ts`): bundle it (esbuild, Vite) or run it with a TypeScript
32
+ loader (`npx tsx script.ts`). Plain `node` cannot load `.ts` from
33
+ `node_modules`.
34
+
30
35
  ## Entry points
31
36
 
32
37
  `"sideEffects": false`, and each backend is its own entry, so a host bundles
@@ -43,7 +48,9 @@ only what it calls.
43
48
  | `onejs-sl/emit/web` | `emitWGSL`, `emitGLSL`: OneJS's web frame |
44
49
  | `onejs-sl/goldens.json` | the goldens (below), as data |
45
50
 
46
- `src/entries.test.ts` pins every name, since removing one breaks a host.
51
+ [`src/entries.test.ts`](https://github.com/Singtaa/onejs-sl/blob/main/src/entries.test.ts)
52
+ (in the repository, not the npm package) pins every name, since removing one
53
+ breaks a host.
47
54
 
48
55
  ## A host's own frame: `emitBody`
49
56
 
@@ -63,8 +70,12 @@ slots the body uses and the library functions it calls. The sample's contract
63
70
  is on `BodyTarget.sample`: straight alpha in and out, rgb in the space `colour`
64
71
  names (an sRGB texture decoded before filtering when it is `linear`), and
65
72
  filtering and wrapping left to the host, which OneJS's hosts take from the
66
- bound texture's own settings. OneJS's Unity shader is
67
- one frame over it (`hlsl.ts`); Magerie's compute kernel is another, and its
73
+ bound texture's own settings. Between mip levels the body decides instead: a
74
+ fractional `tex2Dlod` level blends the two levels either side by the fraction,
75
+ whatever the texture's filter mode, since the body asks for both whole levels
76
+ and blends them itself. A level it can prove whole (a whole constant, a
77
+ `floor`, an int) costs one sample, and a level past the smallest reads the
78
+ smallest. OneJS's Unity shader is one frame over it (`hlsl.ts`); Magerie's compute kernel is another, and its
68
79
  target is in `src/body.test.ts` so an opcode cannot change without the text
69
80
  Magerie compiles changing in front of a test.
70
81
 
@@ -142,11 +153,12 @@ what a WebGL player draws.
142
153
 
143
154
  `npm run goldens` draws it on WebGPU and WebGL2 in a Chrome with its own
144
155
  profile (set `CHROME` to choose one). The two backends must agree within 1/255
145
- over every pixel, and seven anchors must match arithmetic, not each other:
156
+ over every pixel, and eight anchors must match arithmetic, not each other:
146
157
  `orient.sl` (orientation, and the linear to sRGB store), `hex.sl` (a hex colour
147
- stores as written), `texture.sl` (a texture's orientation and sRGB decode) and
158
+ stores as written), `texture.sl` (a texture's orientation and sRGB decode),
148
159
  `lod.sl` (each mip level `tex2Dlod` reads, the texture's smaller levels being
149
- solid colours). `sdf-values.sl`, `fbm-values.sl` and `ramp-values.sl` are black unless a
160
+ solid colours) and `lod-frac.sl` (a fractional level blends the two levels
161
+ either side, on a texture sampled nearest between levels). `sdf-values.sl`, `fbm-values.sl` and `ramp-values.sl` are black unless a
150
162
  shape, a noise or a ramp draws differently with its parameters as values than
151
163
  as constants.
152
164
  A fixture that reads the previous frame, `frame` or `deltaTime` is stepped
@@ -243,8 +255,9 @@ drew what had no shader yet; OneJS 3.8 deleted it.) `hlsl.ts` feeds OneJS's
243
255
  draws a program asks the compiled program for its
244
256
  `hlsl` (a lazy getter, never read in Play), records it into
245
257
  `Assets/OneJS/Recorded.sl.json`, generates the shader and
246
- moves the live material onto it. `manifest()` is still there for an app that
247
- would rather write its programs out at build time.
258
+ moves the live material onto it. `manifest()`, in `onejs-unity/sl` and
259
+ `onejs-unity/sl/compiler` rather than this package, is still there for an app
260
+ that would rather write its programs out at build time.
248
261
 
249
262
  **A third and fourth backend, for the browser.** A player cannot compile a
250
263
  shader, but the page it runs in can. `web.ts` prints every program as WGSL and
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "generatedBy": "onejs-sl goldens/run.mjs",
3
- "package": "0.7.0",
3
+ "package": "0.8.0",
4
4
  "ir": 5,
5
5
  "target": "rgba8unorm-srgb: straight alpha, 8 bit, sRGB encoded, the stored bytes of a Linear OneJS game's element",
6
6
  "size": [
@@ -54,7 +54,7 @@
54
54
  },
55
55
  "cov-arith.sl": {
56
56
  "hash": "6af8b494",
57
- "source": "// + - * / pow, unary -, rcp, min, max and clamp over continuous inputs. The\n// stepwise ops are in step.sl: together they need more than the VM's eight\n// registers.\nfloat4 main() {\n float2 q = (uv - 0.5) * 6.0;\n float a = pow(abs(q.x) * 0.3, 1.7) + rcp(abs(q.y) + 1.0) - (-q.x) * 0.1;\n float c = q.y / (abs(q.x) + 2.0) + abs(q.y) * 0.1;\n return float4(saturate(a * 0.3), clamp(c * 0.5 + 0.5, 0.0, 1.0), min(max(a * 0.2, 0.1), 0.9), 1);\n}\n",
57
+ "source": "// + - * / pow, unary -, rcp, min, max and clamp over continuous inputs. The\n// stepwise ops are in cov-step.sl, a split made when the VM had eight registers.\nfloat4 main() {\n float2 q = (uv - 0.5) * 6.0;\n float a = pow(abs(q.x) * 0.3, 1.7) + rcp(abs(q.y) + 1.0) - (-q.x) * 0.1;\n float c = q.y / (abs(q.x) + 2.0) + abs(q.y) * 0.1;\n return float4(saturate(a * 0.3), clamp(c * 0.5 + 0.5, 0.0, 1.0), min(max(a * 0.2, 0.1), 0.9), 1);\n}\n",
58
58
  "samples": {
59
59
  "0": [128,247,106,255,117,250,97,255,107,253,89,255,97,255,89,255,89,255,89,255,82,255,89,255,78,255,89,255,78,255,89,255,85,255,89,255,95,255,89,255,107,255,89,255,119,255,99,255,132,255,109,255,144,252,120,255,157,249,130,255,169,246,141,255,130,240,108,255,120,242,99,255,110,245,91,255,101,249,89,255,93,253,89,255,86,255,89,255,83,255,89,255,83,255,89,255,89,255,89,255,99,255,89,255,110,255,91,255,122,252,101,255,134,248,111,255,147,245,122,255,159,242,132,255,171,239,142,255,133,233,110,255,123,235,102,255,113,238,94,255,105,241,89,255,97,245,89,255,91,249,89,255,88,255,89,255,88,255,89,255,93,255,89,255,103,254,89,255,114,248,94,255,125,244,103,255,137,240,114,255,149,237,124,255,161,234,134,255,173,232,144,255,137,225,113,255,127,227,105,255,118,229,97,255,109,232,90,255,102,235,89,255,97,239,89,255,93,244,89,255,94,251,89,255,99,249,89,255,107,243,89,255,118,238,97,255,129,234,107,255,141,231,117,255,152,229,126,255,164,227,136,255,175,225,146,255,141,217,117,255,132,219,109,255,123,221,102,255,116,223,95,255,109,226,90,255,104,229,89,255,101,233,89,255,101,238,89,255,105,237,89,255,114,232,94,255,123,228,102,255,134,225,111,255,145,222,120,255,156,220,130,255,168,218,139,255,179,217,149,255,148,209,122,255,139,210,115,255,131,212,108,255,123,213,102,255,117,215,97,255,113,218,93,255,110,221,91,255,110,225,91,255,114,224,94,255,122,220,101,255,131,217,108,255,141,215,117,255,151,213,125,255,162,211,134,255,172,210,144,255,183,209,153,255,156,200,130,255,148,201,123,255,141,202,117,255,134,203,111,255,129,204,106,255,124,206,103,255,122,208,101,255,122,210,101,255,126,210,104,255,133,207,110,255,141,205,117,255,150,204,124,255,159,203,132,255,169,202,141,255,180,201,150,255,190,200,158,255,169,191,141,255,162,191,135,255,156,192,129,255,150,192,124,255,145,192,120,255,141,193,117,255,139,193,116,255,139,194,116,255,143,194,118,255,148,193,123,255,156,193,129,255,164,192,136,255,172,192,143,255,181,192,151,255,191,191,159,255,200,191,167,255,165,185,138,255,158,185,131,255,151,185,125,255,145,184,120,255,140,183,116,255,136,183,113,255,134,182,111,255,134,180,111,255,138,181,114,255,144,182,119,255,151,183,125,255,160,184,133,255,168,184,140,255,178,185,148,255,187,185,156,255,197,185,164,255,154,182,128,255,145,181,121,255,138,180,114,255,131,178,108,255,125,177,104,255,121,174,100,255,119,171,98,255,119,167,98,255,123,168,101,255,130,172,107,255,138,175,114,255,147,177,122,255,157,179,130,255,167,180,139,255,178,181,148,255,188,182,157,255,146,178,121,255,137,177,113,255,129,175,106,255,121,172,100,255,115,169,95,255,110,166,91,255,107,160,89,255,107,153,89,255,112,155,92,255,119,162,99,255,129,167,106,255,139,170,115,255,149,173,124,255,160,175,133,255,171,177,142,255,182,178,152,255,140,174,116,255,131,172,108,255,122,169,101,255,114,166,94,255,107,162,89,255,102,156,89,255,99,148,89,255,99,137,89,255,104,140,89,255,112,151,92,255,122,158,101,255,133,163,110,255,144,167,119,255,155,170,129,255,166,173,138,255,178,175,148,255,136,171,112,255,126,168,104,255,117,164,96,255,108,159,89,255,101,154,89,255,95,146,89,255,92,135,89,255,92,118,89,255,97,123,89,255,106,138,89,255,117,148,96,255,128,155,106,255,140,161,116,255,151,165,126,255,163,168,135,255,175,171,145,255,132,167,110,255,122,163,101,255,113,158,93,255,104,152,89,255,96,145,89,255,90,135,89,255,86,120,89,255,86,94,89,255,92,102,89,255,101,124,89,255,113,137,93,255,124,147,103,255,136,154,113,255,148,159,123,255,160,164,133,255,172,167,143,255,130,162,107,255,119,158,98,255,109,152,90,255,100,145,89,255,92,135,89,255,85,122,89,255,81,101,89,255,81,59,89,255,88,74,89,255,98,107,89,255,109,126,90,255,121,138,100,255,134,147,111,255,146,154,121,255,158,159,131,255,170,163,142,255,127,158,105,255,117,153,96,255,106,146,89,255,97,137,89,255,88,125,89,255,81,107,89,255,77,77,89,255,77,0,89,255,84,10,89,255,94,87,89,255,106,113,89,255,119,128,98,255,131,139,109,255,144,148,119,255,156,154,130,255,169,159,140,255],
60
60
  "1.25": [128,247,106,255,117,250,97,255,107,253,89,255,97,255,89,255,89,255,89,255,82,255,89,255,78,255,89,255,78,255,89,255,85,255,89,255,95,255,89,255,107,255,89,255,119,255,99,255,132,255,109,255,144,252,120,255,157,249,130,255,169,246,141,255,130,240,108,255,120,242,99,255,110,245,91,255,101,249,89,255,93,253,89,255,86,255,89,255,83,255,89,255,83,255,89,255,89,255,89,255,99,255,89,255,110,255,91,255,122,252,101,255,134,248,111,255,147,245,122,255,159,242,132,255,171,239,142,255,133,233,110,255,123,235,102,255,113,238,94,255,105,241,89,255,97,245,89,255,91,249,89,255,88,255,89,255,88,255,89,255,93,255,89,255,103,254,89,255,114,248,94,255,125,244,103,255,137,240,114,255,149,237,124,255,161,234,134,255,173,232,144,255,137,225,113,255,127,227,105,255,118,229,97,255,109,232,90,255,102,235,89,255,97,239,89,255,93,244,89,255,94,251,89,255,99,249,89,255,107,243,89,255,118,238,97,255,129,234,107,255,141,231,117,255,152,229,126,255,164,227,136,255,175,225,146,255,141,217,117,255,132,219,109,255,123,221,102,255,116,223,95,255,109,226,90,255,104,229,89,255,101,233,89,255,101,238,89,255,105,237,89,255,114,232,94,255,123,228,102,255,134,225,111,255,145,222,120,255,156,220,130,255,168,218,139,255,179,217,149,255,148,209,122,255,139,210,115,255,131,212,108,255,123,213,102,255,117,215,97,255,113,218,93,255,110,221,91,255,110,225,91,255,114,224,94,255,122,220,101,255,131,217,108,255,141,215,117,255,151,213,125,255,162,211,134,255,172,210,144,255,183,209,153,255,156,200,130,255,148,201,123,255,141,202,117,255,134,203,111,255,129,204,106,255,124,206,103,255,122,208,101,255,122,210,101,255,126,210,104,255,133,207,110,255,141,205,117,255,150,204,124,255,159,203,132,255,169,202,141,255,180,201,150,255,190,200,158,255,169,191,141,255,162,191,135,255,156,192,129,255,150,192,124,255,145,192,120,255,141,193,117,255,139,193,116,255,139,194,116,255,143,194,118,255,148,193,123,255,156,193,129,255,164,192,136,255,172,192,143,255,181,192,151,255,191,191,159,255,200,191,167,255,165,185,138,255,158,185,131,255,151,185,125,255,145,184,120,255,140,183,116,255,136,183,113,255,134,182,111,255,134,180,111,255,138,181,114,255,144,182,119,255,151,183,125,255,160,184,133,255,168,184,140,255,178,185,148,255,187,185,156,255,197,185,164,255,154,182,128,255,145,181,121,255,138,180,114,255,131,178,108,255,125,177,104,255,121,174,100,255,119,171,98,255,119,167,98,255,123,168,101,255,130,172,107,255,138,175,114,255,147,177,122,255,157,179,130,255,167,180,139,255,178,181,148,255,188,182,157,255,146,178,121,255,137,177,113,255,129,175,106,255,121,172,100,255,115,169,95,255,110,166,91,255,107,160,89,255,107,153,89,255,112,155,92,255,119,162,99,255,129,167,106,255,139,170,115,255,149,173,124,255,160,175,133,255,171,177,142,255,182,178,152,255,140,174,116,255,131,172,108,255,122,169,101,255,114,166,94,255,107,162,89,255,102,156,89,255,99,148,89,255,99,137,89,255,104,140,89,255,112,151,92,255,122,158,101,255,133,163,110,255,144,167,119,255,155,170,129,255,166,173,138,255,178,175,148,255,136,171,112,255,126,168,104,255,117,164,96,255,108,159,89,255,101,154,89,255,95,146,89,255,92,135,89,255,92,118,89,255,97,123,89,255,106,138,89,255,117,148,96,255,128,155,106,255,140,161,116,255,151,165,126,255,163,168,135,255,175,171,145,255,132,167,110,255,122,163,101,255,113,158,93,255,104,152,89,255,96,145,89,255,90,135,89,255,86,120,89,255,86,94,89,255,92,102,89,255,101,124,89,255,113,137,93,255,124,147,103,255,136,154,113,255,148,159,123,255,160,164,133,255,172,167,143,255,130,162,107,255,119,158,98,255,109,152,90,255,100,145,89,255,92,135,89,255,85,122,89,255,81,101,89,255,81,59,89,255,88,74,89,255,98,107,89,255,109,126,90,255,121,138,100,255,134,147,111,255,146,154,121,255,158,159,131,255,170,163,142,255,127,158,105,255,117,153,96,255,106,146,89,255,97,137,89,255,88,125,89,255,81,107,89,255,77,77,89,255,77,0,89,255,84,10,89,255,94,87,89,255,106,113,89,255,119,128,98,255,131,139,109,255,144,148,119,255,156,154,130,255,169,159,140,255]
@@ -102,7 +102,7 @@
102
102
  },
103
103
  "cov-trig.sl": {
104
104
  "hash": "49fcabc8",
105
- "source": "// Trigonometry over continuous inputs. exp, log, sqrt and atan2 are in\n// exp.sl: together they need more than the VM's eight registers.\nfloat4 main() {\n float2 q = (uv - 0.5) * 2.0;\n float a = sin(q.x * 5.0) * cos(q.y * 4.0) * 0.5 + 0.5;\n float b = tan(q.x * 0.6) * 0.3 + asin(q.y * 0.9) * 0.2 + acos(q.x * 0.9) * 0.1;\n return float4(a, saturate(b + 0.5), 0.5, 1);\n}\n",
105
+ "source": "// Trigonometry over continuous inputs. exp, log, sqrt and atan2 are in\n// cov-exp.sl, a split made when the VM had eight registers.\nfloat4 main() {\n float2 q = (uv - 0.5) * 2.0;\n float a = sin(q.x * 5.0) * cos(q.y * 4.0) * 0.5 + 0.5;\n float b = tan(q.x * 0.6) * 0.3 + asin(q.y * 0.9) * 0.2 + acos(q.x * 0.9) * 0.1;\n return float4(a, saturate(b + 0.5), 0.5, 1);\n}\n",
106
106
  "samples": {
107
107
  "0": [77,227,188,255,118,228,188,255,171,230,188,255,214,231,188,255,239,233,188,255,246,234,188,255,234,236,188,255,203,237,188,255,157,239,188,255,103,240,188,255,77,241,188,255,115,243,188,255,168,244,188,255,212,246,188,255,239,247,188,255,247,248,188,255,10,222,188,255,100,223,188,255,168,225,188,255,218,227,188,255,247,228,188,255,255,230,188,255,241,231,188,255,206,233,188,255,151,234,188,255,78,236,188,255,6,237,188,255,96,238,188,255,165,240,188,255,215,241,188,255,246,243,188,255,255,244,188,255,65,218,188,255,113,219,188,255,170,221,188,255,215,223,188,255,242,224,188,255,249,226,188,255,236,227,188,255,204,229,188,255,155,230,188,255,96,232,188,255,64,233,188,255,110,235,188,255,167,236,188,255,213,238,188,255,241,239,188,255,249,241,188,255,127,214,188,255,145,216,188,255,177,217,188,255,206,219,188,255,224,221,188,255,230,222,188,255,220,224,188,255,198,225,188,255,168,227,188,255,138,228,188,255,127,230,188,255,144,231,188,255,175,233,188,255,204,234,188,255,224,236,188,255,230,237,188,255,177,210,188,255,180,212,188,255,185,214,188,255,191,216,188,255,196,217,188,255,197,219,188,255,195,221,188,255,190,222,188,255,184,224,188,255,179,225,188,255,177,227,188,255,180,228,188,255,185,230,188,255,191,231,188,255,196,233,188,255,197,234,188,255,216,207,188,255,209,209,188,255,194,211,188,255,174,212,188,255,157,214,188,255,152,216,188,255,161,217,188,255,180,219,188,255,199,220,188,255,212,222,188,255,216,223,188,255,210,225,188,255,195,227,188,255,176,228,188,255,158,230,188,255,152,231,188,255,242,204,188,255,230,205,188,255,201,207,188,255,159,209,188,255,114,211,188,255,95,212,188,255,126,214,188,255,172,216,188,255,210,217,188,255,235,219,188,255,242,220,188,255,231,222,188,255,203,224,188,255,161,225,188,255,116,227,188,255,95,228,188,255,254,200,188,255,239,202,188,255,204,204,188,255,150,206,188,255,79,207,188,255,26,209,188,255,100,211,188,255,167,212,188,255,216,214,188,255,246,216,188,255,254,217,188,255,241,219,188,255,207,220,188,255,153,222,188,255,83,224,188,255,25,225,188,255,252,197,188,255,238,198,188,255,204,200,188,255,151,202,188,255,85,204,188,255,45,206,188,255,104,208,188,255,168,209,188,255,215,211,188,255,244,212,188,255,252,214,188,255,239,216,188,255,206,217,188,255,155,219,188,255,89,221,188,255,44,222,188,255,236,193,188,255,226,195,188,255,200,197,188,255,163,199,188,255,125,201,188,255,111,202,188,255,134,204,188,255,173,206,188,255,208,208,188,255,230,209,188,255,237,211,188,255,226,213,188,255,201,214,188,255,165,216,188,255,127,218,188,255,110,219,188,255,207,189,188,255,203,191,188,255,192,193,188,255,179,195,188,255,168,197,188,255,164,199,188,255,170,201,188,255,182,202,188,255,195,204,188,255,205,206,188,255,208,207,188,255,203,209,188,255,193,211,188,255,179,213,188,255,168,214,188,255,164,216,188,255,166,185,188,255,172,187,188,255,183,189,188,255,195,191,188,255,204,193,188,255,206,195,188,255,202,197,188,255,192,199,188,255,180,200,188,255,169,202,188,255,166,204,188,255,171,206,188,255,182,207,188,255,195,209,188,255,204,211,188,255,206,213,188,255,113,181,188,255,136,183,188,255,175,185,188,255,208,187,188,255,230,189,188,255,236,191,188,255,225,193,188,255,200,195,188,255,164,196,188,255,127,198,188,255,112,200,188,255,135,202,188,255,173,204,188,255,207,205,188,255,229,207,188,255,236,209,188,255,48,176,188,255,107,178,188,255,169,180,188,255,216,182,188,255,244,184,188,255,252,186,188,255,238,188,188,255,205,190,188,255,153,192,188,255,88,194,188,255,47,196,188,255,103,198,188,255,166,199,188,255,214,201,188,255,243,203,188,255,252,205,188,255,25,170,188,255,102,172,188,255,168,174,188,255,217,177,188,255,246,179,188,255,254,181,188,255,240,183,188,255,206,185,188,255,152,187,188,255,81,189,188,255,23,191,188,255,98,193,188,255,165,195,188,255,215,196,188,255,245,198,188,255,254,200,188,255,93,162,188,255,126,165,188,255,173,167,188,255,212,170,188,255,236,172,188,255,242,174,188,255,231,176,188,255,202,178,188,255,160,180,188,255,114,182,188,255,93,184,188,255,123,186,188,255,170,188,188,255,210,190,188,255,235,192,188,255,242,194,188,255],
108
108
  "1.25": [77,227,188,255,118,228,188,255,171,230,188,255,214,231,188,255,239,233,188,255,246,234,188,255,234,236,188,255,203,237,188,255,157,239,188,255,103,240,188,255,77,241,188,255,115,243,188,255,168,244,188,255,212,246,188,255,239,247,188,255,247,248,188,255,10,222,188,255,100,223,188,255,168,225,188,255,218,227,188,255,247,228,188,255,255,230,188,255,241,231,188,255,206,233,188,255,151,234,188,255,78,236,188,255,6,237,188,255,96,238,188,255,165,240,188,255,215,241,188,255,246,243,188,255,255,244,188,255,65,218,188,255,113,219,188,255,170,221,188,255,215,223,188,255,242,224,188,255,249,226,188,255,236,227,188,255,204,229,188,255,155,230,188,255,96,232,188,255,64,233,188,255,110,235,188,255,167,236,188,255,213,238,188,255,241,239,188,255,249,241,188,255,127,214,188,255,145,216,188,255,177,217,188,255,206,219,188,255,224,221,188,255,230,222,188,255,220,224,188,255,198,225,188,255,168,227,188,255,138,228,188,255,127,230,188,255,144,231,188,255,175,233,188,255,204,234,188,255,224,236,188,255,230,237,188,255,177,210,188,255,180,212,188,255,185,214,188,255,191,216,188,255,196,217,188,255,197,219,188,255,195,221,188,255,190,222,188,255,184,224,188,255,179,225,188,255,177,227,188,255,180,228,188,255,185,230,188,255,191,231,188,255,196,233,188,255,197,234,188,255,216,207,188,255,209,209,188,255,194,211,188,255,174,212,188,255,157,214,188,255,152,216,188,255,161,217,188,255,180,219,188,255,199,220,188,255,212,222,188,255,216,223,188,255,210,225,188,255,195,227,188,255,176,228,188,255,158,230,188,255,152,231,188,255,242,204,188,255,230,205,188,255,201,207,188,255,159,209,188,255,114,211,188,255,95,212,188,255,126,214,188,255,172,216,188,255,210,217,188,255,235,219,188,255,242,220,188,255,231,222,188,255,203,224,188,255,161,225,188,255,116,227,188,255,95,228,188,255,254,200,188,255,239,202,188,255,204,204,188,255,150,206,188,255,79,207,188,255,26,209,188,255,100,211,188,255,167,212,188,255,216,214,188,255,246,216,188,255,254,217,188,255,241,219,188,255,207,220,188,255,153,222,188,255,83,224,188,255,25,225,188,255,252,197,188,255,238,198,188,255,204,200,188,255,151,202,188,255,85,204,188,255,45,206,188,255,104,208,188,255,168,209,188,255,215,211,188,255,244,212,188,255,252,214,188,255,239,216,188,255,206,217,188,255,155,219,188,255,89,221,188,255,44,222,188,255,236,193,188,255,226,195,188,255,200,197,188,255,163,199,188,255,125,201,188,255,111,202,188,255,134,204,188,255,173,206,188,255,208,208,188,255,230,209,188,255,237,211,188,255,226,213,188,255,201,214,188,255,165,216,188,255,127,218,188,255,110,219,188,255,207,189,188,255,203,191,188,255,192,193,188,255,179,195,188,255,168,197,188,255,164,199,188,255,170,201,188,255,182,202,188,255,195,204,188,255,205,206,188,255,208,207,188,255,203,209,188,255,193,211,188,255,179,213,188,255,168,214,188,255,164,216,188,255,166,185,188,255,172,187,188,255,183,189,188,255,195,191,188,255,204,193,188,255,206,195,188,255,202,197,188,255,192,199,188,255,180,200,188,255,169,202,188,255,166,204,188,255,171,206,188,255,182,207,188,255,195,209,188,255,204,211,188,255,206,213,188,255,113,181,188,255,136,183,188,255,175,185,188,255,208,187,188,255,230,189,188,255,236,191,188,255,225,193,188,255,200,195,188,255,164,196,188,255,127,198,188,255,112,200,188,255,135,202,188,255,173,204,188,255,207,205,188,255,229,207,188,255,236,209,188,255,48,176,188,255,107,178,188,255,169,180,188,255,216,182,188,255,244,184,188,255,252,186,188,255,238,188,188,255,205,190,188,255,153,192,188,255,88,194,188,255,47,196,188,255,103,198,188,255,166,199,188,255,214,201,188,255,243,203,188,255,252,205,188,255,25,170,188,255,102,172,188,255,168,174,188,255,217,177,188,255,246,179,188,255,254,181,188,255,240,183,188,255,206,185,188,255,152,187,188,255,81,189,188,255,23,191,188,255,98,193,188,255,165,195,188,255,215,196,188,255,245,198,188,255,254,200,188,255,93,162,188,255,126,165,188,255,173,167,188,255,212,170,188,255,236,172,188,255,242,174,188,255,231,176,188,255,202,178,188,255,160,180,188,255,114,182,188,255,93,184,188,255,123,186,188,255,170,188,188,255,210,190,188,255,235,192,188,255,242,194,188,255]
@@ -141,7 +141,7 @@
141
141
  },
142
142
  "ember.sl": {
143
143
  "hash": "9a55af34",
144
- "source": "// A fire, in one file: one texture, one loop, one function.\n//\n// Everything a Unity shader makes you write that is not the effect is absent.\n// No Properties block, no SubShader, no CGPROGRAM, no appdata or v2f, no\n// _Time.y. `uniform` declares the slot AND the name React binds against, and\n// `texture2D` does the same for a sampler.\n//\n// This program sits at exactly 8 of the VM's 8 registers, which is why it is\n// in the corpus: the VM refused a ninth live value. Compiled, there is no such\n// ceiling, and the same file draws the same in the editor, a player and a\n// browser, with no edit in between.\ntexture2D smoke;\n\nuniform float heat = 0.55;\nuniform float2 source = float2(0.5, 0.08);\n\n// Layered noise: one texture, three scales, drifting.\n//\n// The loop UNROLLS at build time. `i` is a number the parser substitutes, so\n// both backends see straight line code and neither needs a branch, which is\n// also why the bound has to be a constant. The function inlines, so calling it\n// costs exactly what writing the three lines out would.\nfloat plume(float2 p, float t) {\n float s = 0;\n for (int i = 0; i < 3; i++) {\n s = s + tex2D(smoke, p * (1 + i * 1.9) - t).r * (0.6 / (1 + i));\n }\n return s;\n}\n\nfloat4 main() {\n float2 p = uv - source;\n // A cone: narrow across, tall up, brightest at the source.\n float cone = saturate(1 - length(p * float2(3, 1.1)));\n float fuel = saturate(cone * (0.5 + heat) * (plume(p, time * 0.4) + 0.35));\n\n // Colours as written. They are mixed in sRGB and converted once, so the\n // ramp reads as evenly as its swatches do.\n return ramp(fuel, #00000000, #b53205cc, #ff8a20, #ffe7b0);\n}\n",
144
+ "source": "// A fire, in one file: one texture, one loop, one function.\n//\n// Everything a Unity shader makes you write that is not the effect is absent.\n// No Properties block, no SubShader, no CGPROGRAM, no appdata or v2f, no\n// _Time.y. `uniform` declares the slot AND the name React binds against, and\n// `texture2D` does the same for a sampler.\n//\n// This program sat at exactly 8 of the VM's 8 registers, which is why it is\n// in the corpus: the VM refused a ninth live value. Compiled, there is no such\n// ceiling, and the same file draws the same in the editor, a player and a\n// browser, with no edit in between.\ntexture2D smoke;\n\nuniform float heat = 0.55;\nuniform float2 source = float2(0.5, 0.08);\n\n// Layered noise: one texture, three scales, drifting.\n//\n// The loop UNROLLS at build time. `i` is a number the parser substitutes, so\n// both backends see straight line code and neither needs a branch, which is\n// also why the bound has to be a constant. The function inlines, so calling it\n// costs exactly what writing the three lines out would.\nfloat plume(float2 p, float t) {\n float s = 0;\n for (int i = 0; i < 3; i++) {\n s = s + tex2D(smoke, p * (1 + i * 1.9) - t).r * (0.6 / (1 + i));\n }\n return s;\n}\n\nfloat4 main() {\n float2 p = uv - source;\n // A cone: narrow across, tall up, brightest at the source.\n float cone = saturate(1 - length(p * float2(3, 1.1)));\n float fuel = saturate(cone * (0.5 + heat) * (plume(p, time * 0.4) + 0.35));\n\n // Colours as written. They are mixed in sRGB and converted once, so the\n // ramp reads as evenly as its swatches do.\n return ramp(fuel, #00000000, #b53205cc, #ff8a20, #ffe7b0);\n}\n",
145
145
  "samples": {
146
146
  "0": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,6,2,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,1,0,15,16,2,0,22,15,2,0,22,7,1,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,1,0,13,23,3,0,30,32,5,0,38,31,5,0,37,25,3,0,31,6,1,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,21,2,0,27,38,6,0,45,46,8,0,53,46,8,0,53,42,7,0,48,26,3,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,14,34,5,0,40,52,10,0,59,61,13,0,69,61,13,0,69,58,12,0,66,45,8,0,52,6,1,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,2,0,25,46,8,0,53,66,14,1,74,75,17,1,85,75,18,1,85,73,16,1,82,63,13,0,71,27,3,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,30,4,0,36,58,12,0,66,78,18,1,88,89,22,1,100,90,22,1,101,88,21,1,99,80,19,1,90,46,8,0,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,1,0,10,40,6,0,46,69,15,1,78,91,22,1,102,103,26,1,116,104,26,1,116,102,25,1,115,95,23,1,107,62,13,0,70,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,2,0,18,48,9,0,55,79,19,1,89,103,26,1,116,117,30,1,131,117,30,1,132,116,30,1,130,110,28,1,123,77,18,1,87,12,2,0,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,2,0,25,56,11,0,63,88,21,1,99,115,30,1,129,131,34,1,147,131,34,1,147,129,34,1,145,123,32,1,138,90,22,1,101,26,3,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,3,0,30,62,13,0,70,96,24,1,108,126,33,1,141,144,38,1,162,144,38,1,162,141,37,1,158,134,35,1,151,101,25,1,114,37,6,0,44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,4,0,35,67,15,1,76,103,26,1,116,135,36,1,152,157,42,2,177,157,42,2,177,151,41,2,170,144,38,1,162,110,28,1,124,46,8,0,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,5,0,38,71,16,1,80,108,27,1,122,143,38,1,161,170,46,2,192,169,46,2,190,159,43,2,179,151,40,2,170,117,30,1,132,52,10,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,5,0,40,74,16,1,83,111,29,1,125,148,40,2,167,181,50,2,204,178,48,2,201,165,44,2,186,155,42,2,175,121,31,1,136,57,11,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,5,0,41,74,17,1,84,113,29,1,127,151,40,2,170,184,53,2,206,182,50,2,205,167,45,2,188,157,42,2,177,123,32,1,138,58,12,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,5,0,41,74,17,1,83,112,29,1,126,149,40,2,168,182,51,2,205,180,49,2,203,165,45,2,187,156,42,2,176,122,32,1,137,57,11,0,65,0,0,0,0,0,0,0,0,0,0,0,0],
147
147
  "1.25": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,6,2,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,1,0,15,16,2,0,22,15,2,0,21,5,1,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,1,0,13,23,3,0,30,32,5,0,38,30,4,0,37,20,2,0,26,3,1,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,21,2,0,27,38,6,0,45,46,8,0,53,45,8,0,52,34,5,0,41,16,2,0,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,1,0,14,34,5,0,40,52,10,0,59,61,13,0,69,60,13,0,68,48,9,0,55,29,4,0,35,2,1,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,2,0,25,46,8,0,53,66,14,1,74,75,17,1,85,74,17,1,83,61,13,0,70,42,7,0,48,15,2,0,21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,30,4,0,36,58,12,0,66,78,18,1,88,89,22,1,100,88,21,1,99,74,17,1,84,53,10,0,61,27,3,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,1,0,10,40,6,0,46,69,15,1,78,91,22,1,102,103,26,1,116,101,25,1,114,86,21,1,97,64,14,0,73,38,6,0,44,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,2,0,18,48,9,0,55,79,19,1,89,103,26,1,116,117,30,1,131,115,30,1,129,98,24,1,110,74,17,1,84,48,9,0,55,6,1,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,2,0,25,56,11,0,63,88,21,1,99,115,30,1,129,131,34,1,147,128,34,1,144,109,28,1,122,83,20,1,94,56,11,0,64,16,2,0,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,3,0,30,62,13,0,70,96,24,1,108,126,33,1,141,144,38,1,162,141,37,1,159,119,31,1,134,91,22,1,103,63,13,0,72,24,3,0,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,4,0,35,67,15,1,76,103,26,1,116,135,36,1,152,157,42,2,177,154,41,2,173,128,34,1,144,98,24,1,110,69,15,1,78,31,4,0,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,5,0,38,71,16,1,80,108,27,1,122,143,38,1,161,170,46,2,192,165,45,2,186,135,36,1,152,103,26,1,115,74,16,1,83,35,6,0,42,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,5,0,40,74,16,1,83,111,29,1,125,148,40,2,167,181,50,2,204,174,47,2,197,139,37,1,157,106,27,1,119,76,18,1,86,38,6,0,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,5,0,41,74,17,1,84,113,29,1,127,151,40,2,170,184,53,2,206,179,49,2,202,141,37,1,159,107,27,1,120,77,18,1,87,39,6,0,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,5,0,41,74,17,1,83,112,29,1,126,149,40,2,168,182,51,2,205,176,48,2,198,140,37,1,157,106,27,1,119,77,18,1,86,39,6,0,45,0,0,0,0,0,0,0,0,0,0,0,0]
@@ -197,6 +197,14 @@
197
197
  "1.25": [0,255,0,255,0,255,0,255,255,0,0,255,255,0,0,255,0,0,0,255,0,0,0,255,255,255,0,255,255,255,0,255,0,0,0,255,0,0,0,255,255,255,0,255,255,255,0,255,0,0,0,255,0,0,0,255,255,0,0,255,255,0,0,255,0,255,0,255,0,255,0,255,255,0,0,255,255,0,0,255,0,0,0,255,0,0,0,255,255,255,0,255,255,255,0,255,0,0,0,255,0,0,0,255,255,255,0,255,255,255,0,255,0,0,0,255,0,0,0,255,255,0,0,255,255,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,255,255,0,255,255,255,0,255,255,0,0,255,255,0,0,255,0,255,0,255,0,255,0,255,255,255,0,255,255,255,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,255,255,0,255,255,255,0,255,255,0,0,255,255,0,0,255,0,255,0,255,0,255,0,255,255,255,0,255,255,255,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,0,255,0,255,0,255,0,255,255,255,0,255,255,255,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,255,0,255,0,255,0,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,0,255,0,255,0,255,0,255,255,255,0,255,255,255,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,255,0,255,0,255,0,255,255,255,0,255,255,255,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,255,0,0,255,255,0,0,255,255,0,255,255,255,0,255,255,255,255,0,255,255,255,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,255,0,0,255,255,0,0,255,255,0,255,255,255,0,255,255,255,255,0,255,255,255,0,255,255,0,0,255,255,0,0,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,255,255,0,0,255,255,255,0,255,255,255,0,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,0,0,255,255,0,0,255,255,255,0,255,255,255,0,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255,255,255,0,255,255,255,0,255,0,255,0,255,0,255,255,255,255,255,255,255,255,255,0,255,0,255,0,255,0,255,255,0,0,255,255,0,0,255,0,0,255,255,0,0,255,255,255,255,0,255,255,255,0,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,0,255,0,255,0,255,0,255,255,255,255,255,255,255,255,255,0,255,0,255,0,255,0,255,255,0,0,255,255,0,0,255,0,0,255,255,0,0,255,255,255,255,0,255,255,255,0,255,0,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255]
198
198
  }
199
199
  },
200
+ "lod-frac.sl": {
201
+ "hash": "fd3f2852",
202
+ "source": "// An anchor for a fractional tex2Dlod level: the level runs from 0 at the left\n// edge to 4.5 at the right. A fraction blends the level below and the level\n// above by that fraction, whatever the texture's own filter between levels,\n// and past level 3, the smallest, both are level 3.\ntexture2D t;\nfloat4 main() { return tex2Dlod(t, uv, uv.x * 4.5); }\n",
203
+ "samples": {
204
+ "0": [103,30,184,255,159,45,131,255,197,56,59,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,38,157,255,159,49,121,255,197,57,76,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,48,92,255,159,54,102,255,197,59,96,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,61,112,255,159,62,107,255,197,63,92,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,73,168,255,159,70,125,255,197,67,70,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,88,157,255,159,80,121,255,197,72,76,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,101,92,255,159,90,102,255,197,78,96,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,115,112,255,159,101,107,255,197,85,92,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,129,168,255,159,112,125,255,197,91,70,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,144,157,255,159,124,121,255,197,99,76,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,158,92,255,159,135,102,255,197,106,96,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,173,112,255,159,147,107,255,197,114,92,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,187,168,255,159,159,125,255,197,122,70,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,202,157,255,159,171,121,255,197,130,76,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,216,92,255,159,183,102,255,197,138,96,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,222,39,255,159,187,94,255,197,141,103,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255],
205
+ "1.25": [103,30,184,255,159,45,131,255,197,56,59,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,38,157,255,159,49,121,255,197,57,76,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,48,92,255,159,54,102,255,197,59,96,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,61,112,255,159,62,107,255,197,63,92,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,73,168,255,159,70,125,255,197,67,70,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,88,157,255,159,80,121,255,197,72,76,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,101,92,255,159,90,102,255,197,78,96,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,115,112,255,159,101,107,255,197,85,92,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,129,168,255,159,112,125,255,197,91,70,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,144,157,255,159,124,121,255,197,99,76,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,158,92,255,159,135,102,255,197,106,96,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,173,112,255,159,147,107,255,197,114,92,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,187,168,255,159,159,125,255,197,122,70,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,202,157,255,159,171,121,255,197,130,76,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,216,92,255,159,183,102,255,197,138,96,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,103,222,39,255,159,187,94,255,197,141,103,255,222,72,33,255,192,139,44,255,153,180,53,255,95,211,61,255,38,209,109,255,48,176,159,255,57,131,194,255,64,42,223,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255,64,32,224,255]
206
+ }
207
+ },
200
208
  "lod.sl": {
201
209
  "hash": "ac177cc0",
202
210
  "source": "// An anchor for tex2Dlod: four bands, left to right, each reading one mip level\n// of the goldens' texture. Level 0 is the image and levels 1 to 3 are each one\n// solid colour, so a band that read the wrong level shows it.\ntexture2D t;\nfloat4 main() { return tex2Dlod(t, uv, floor(uv.x * 4)); }\n",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "onejs-sl",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "The OneJS shader language: a small typed language for per pixel programs, compiled to a portable IR and emitted as HLSL, WGSL or GLSL ES",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
package/src/body.ts CHANGED
@@ -21,7 +21,7 @@
21
21
  * gives common subexpression elimination for free.
22
22
  */
23
23
 
24
- import { INT_BOUNDS, SLError, TYPE, valueAt, type InputName, type NodeRef, type StepInputName, type Program, type SLKind, type SLType, type ValueNode } from "./ir"
24
+ import { INT_BOUNDS, SLError, TYPE, isWhole, valueAt, type InputName, type NodeRef, type StepInputName, type Program, type SLKind, type SLType, type ValueNode } from "./ir"
25
25
  import { libClosure, LIB_FUNCTIONS } from "./lib"
26
26
  import { LIB_HLSL } from "./lib/hlsl"
27
27
  import { SLOP } from "./ops"
@@ -63,9 +63,12 @@ export interface BodyTarget {
63
63
  sample: (slot: number, uv: string) => string
64
64
  /**
65
65
  * A float4 sample of the texture in `slot` at `uv` from mip level `lod`, a
66
- * float expression: 0 is the full size texture, 1 half, and a fraction
67
- * blends two levels where the texture's filter does. Otherwise the same
68
- * contract as `sample`. `tex2Dlod` in a program; HLSL's
66
+ * float expression: 0 is the full size texture and 1 half. The body only
67
+ * asks for whole levels, or for a level it cannot prove whole, floored and
68
+ * floored plus one, which it blends by the fraction itself; so a fraction
69
+ * draws the same whatever the texture's filter between levels, and a host
70
+ * has no blending to do. A level past the smallest reads the smallest.
71
+ * Otherwise the same contract as `sample`. `tex2Dlod` in a program; HLSL's
69
72
  * `tex2Dlod(s, float4(uv, 0, lod))` and Metal's `sample(s, uv, level(lod))`.
70
73
  */
71
74
  sampleLevel: (slot: number, uv: string, lod: string) => string
@@ -336,7 +339,13 @@ export function emitBody(p: Program, target: BodyTarget): Body {
336
339
  case SLOP.SAMPLE_LOD: {
337
340
  const slot = Math.round(imm[0] ?? 0)
338
341
  textures.add(slot)
339
- return target.sampleLevel(slot, a[0]!, a[1]!)
342
+ // A fraction blends the level below and the level above,
343
+ // whatever the texture's filter between levels, as the web
344
+ // emitters do (`isWhole`). Past the smallest level both read the
345
+ // smallest, as a whole level past it does.
346
+ if (isWhole(p.nodes, n.args[1]!)) return target.sampleLevel(slot, a[0]!, a[1]!)
347
+ const below = `floor(${a[1]})`
348
+ return `lerp(${target.sampleLevel(slot, a[0]!, below)}, ${target.sampleLevel(slot, a[0]!, `${below} + 1.0`)}, frac(${a[1]}))`
340
349
  }
341
350
  case SLOP.SAMPLE_PREVIOUS:
342
351
  if (target.previous === undefined) throw new SLError("this target keeps no previous frame, and the program samples it")
package/src/ir.ts CHANGED
@@ -461,9 +461,9 @@ export class Builder {
461
461
  /**
462
462
  * Nodes the result actually depends on, in order.
463
463
  *
464
- * Dead nodes are dropped rather than encoded. An author can produce them easily
464
+ * Dead nodes are dropped rather than emitted. An author can produce them easily
465
465
  * by computing something and not using it, and the hash already ignores them, so
466
- * encoding them would make the buffer disagree with its own hash about what the
466
+ * emitting them would make a shader disagree with its own hash about what the
467
467
  * program is.
468
468
  */
469
469
  export function reachable(nodes: SLNode[], result: NodeRef): NodeRef[] {
@@ -519,6 +519,42 @@ export function readsOf(p: Program): SLReads {
519
519
  return out
520
520
  }
521
521
 
522
+ /** Ops whose result is a whole number whatever they are given. */
523
+ const ALWAYS_WHOLE = new Set<number>([SLOP.FLOOR, SLOP.CEIL, SLOP.ROUND, SLOP.SIGN])
524
+ /** Ops whose result is a whole number when every operand they read is one. */
525
+ const KEEPS_WHOLE = new Set<number>([
526
+ SLOP.CAST, SLOP.ADD, SLOP.SUB, SLOP.MUL, SLOP.NEG, SLOP.ABS, SLOP.MIN, SLOP.MAX, SLOP.CLAMP, SLOP.SATURATE,
527
+ ])
528
+
529
+ /**
530
+ * Whether a value is a whole number in every component on every pixel, as far
531
+ * as its node says. An int, uint or bool is; so are a constant written whole,
532
+ * `floor`, `ceil`, `round` and `sign`, and sums, products, minimums and the
533
+ * like of whole numbers (a float32 sum or product of whole numbers is whole).
534
+ * Anything else is not known to be, a uniform float included.
535
+ *
536
+ * The emitters read it for `tex2Dlod`: a level known whole reads that level
537
+ * with one sample, and any other blends the level below and the level above by
538
+ * the fraction, so every backend draws a fraction the same way whatever the
539
+ * texture's filter between levels.
540
+ */
541
+ export function isWhole(nodes: readonly SLNode[], ref: NodeRef, seen = new Map<NodeRef, boolean>()): boolean {
542
+ const known = seen.get(ref)
543
+ if (known !== undefined) return known
544
+ const n = valueAt(nodes, ref)
545
+ let whole = false
546
+ if (n.kind !== undefined) whole = true
547
+ else if (n.k === "const") whole = n.v.every(Number.isInteger)
548
+ else if (n.k === "swizzle") whole = isWhole(nodes, n.src, seen)
549
+ else if (n.k === "call") {
550
+ if (ALWAYS_WHOLE.has(n.op)) whole = true
551
+ else if (KEEPS_WHOLE.has(n.op)) whole = n.args.every((a) => isWhole(nodes, a, seen))
552
+ else if (n.op === SLOP.CHOOSE) whole = isWhole(nodes, n.args[1]!, seen) && isWhole(nodes, n.args[2]!, seen)
553
+ }
554
+ seen.set(ref, whole)
555
+ return whole
556
+ }
557
+
522
558
  /** Structural key for hash consing. Order matters and is fixed by the node shape. */
523
559
  function keyOf(n: SLNode): string {
524
560
  const kind = "kind" in n && n.kind !== undefined ? `@${n.kind}` : ""
@@ -41,9 +41,14 @@ player. So parity is the test to keep green, not the parser's unit tests.
41
41
  | `ast.ts` | The node shapes, all of them, which is not many |
42
42
  | `parser.ts` | Pratt parser: shape only, HLSL precedence |
43
43
  | `check.ts` | Declarations, names, statement shape, budgets, recursion |
44
- | `lower.ts` | AST to IR through the EDSL: SSA, unrolling, `select`, inlining |
44
+ | `lower.ts` | AST to IR through the EDSL: SSA, unrolling, branches and loops, inlining |
45
45
  | `builtins.ts` | What each name does, keyed by the spelling `ops.ts` gives it |
46
- | `prelude.ts` | The standard library, written in the language |
46
+ | `prelude.ts`, `prelude-source.ts` | The standard library, written in the language |
47
+ | `attributes.ts` | A uniform's `[Range]`, `[Toggle]` and the rest, read into its control |
48
+ | `words.ts` | The keywords and type names, shared by the parser and `classify` |
49
+ | `classify.ts` | Every token with its class, for an editor's highlighting |
50
+ | `glsl.ts` | `fromGLSL`: a pasted GLSL shader as a `.sl` file |
51
+ | `index.ts` | This folder's exports |
47
52
  | `onejs-unity`'s `src/esbuild/sl.mjs` | The loader: `import plasma from "./plasma.sl"` |
48
53
  | `../index.ts` and `../core.ts` | The package with the parser, and without it. See below |
49
54
 
@@ -68,9 +73,11 @@ It writes two things beside the code:
68
73
  recording stays for EDSL programs and for a build older than the loader; the
69
74
  editor reads every `*.sl.json` it can find.
70
75
 
71
- An empty manifest is written only over one that is already there. Deleting the
72
- last `.sl` file has to stop its shaders being generated, and a project that has
73
- never had one should not find a new file beside its bundle.
76
+ With no `.sl` files, an empty manifest is written over one that is already
77
+ there, since deleting the last `.sl` file has to stop its shaders being
78
+ generated, and beside a bundle carrying `onejs-sl`, which has to name its hash
79
+ scheme. A project that uses no shader language finds no new file beside its
80
+ bundle.
74
81
 
75
82
  ### Why the parser is compiled rather than imported
76
83
 
@@ -110,7 +117,8 @@ here is the one nothing else uses.
110
117
  **A scalar on the left of an operator broadcasts through a swizzle.** `uv * 8`
111
118
  is `uv.mul(8)`, one constant node of two components. `8 * uv` is
112
119
  `sl.float(8).mul(uv)`, a one component constant and a broadcast. Same picture,
113
- different graph, different hash. Write the vector on the left when it matters.
120
+ different graph, and since 0.4.0 (`SL_HASH_VERSION` 2) the same hash. The
121
+ vector on the left saves a node.
114
122
 
115
123
  **Literal arithmetic folds; a builtin call never does.** `2 * 3 + 1` is the
116
124
  constant 7 before the IR sees it. `sin(0.5)` is two instructions, because
@@ -201,7 +209,7 @@ Where the fix is certain, the error carries it as `fix`: a title and the text
201
209
  for the marked range, one click in an editor. A GLSL spelling that means the
202
210
  same in HLSL (`mix`, `fract`, `vec3`, `gl_FragCoord`, `iTime`, two argument
203
211
  `atan`) and a "did you mean" both have one. `mod` does not, since GLSL's floors
204
- and `%` truncates, and neither does `int`, since float would change what
212
+ and `%` truncates, and neither does `ivec2`, since `float2` would change what
205
213
  dividing it does. That is Decision 1 kept as `Specs/SL_NEXT.md` 5 A has it:
206
214
  one spelling, and every hint a fix.
207
215
 
@@ -268,8 +276,10 @@ where they were, so the result reads as the shader it came from. What it does:
268
276
  the notes point at `rotate()`. A file with a `rotate` of its own is left
269
277
  alone, since the calls would reach it. `#define NAME value`
270
278
  becomes a const; any other directive is kept as a comment, with a note.
271
- - A name the language already means something by gets a `_` suffix, and an
272
- `int` becomes a float (a for-loop counter stays an int), each with a note.
279
+ - A name the language already means something by gets a `_` suffix, with a
280
+ note. `int`, `uint` and `bool` are kept, since they are types here too; their
281
+ vectors (`ivec2`, `uvec3`, `bvec4` and the rest) become float vectors, with a
282
+ note saying what changed.
273
283
  - What has no counterpart (`iFrameRate`, `texelFetch`, `dFdx`, a function
274
284
  returning nothing) is left in place with a note, for `errors` to point at.
275
285
 
package/src/params.ts CHANGED
@@ -162,7 +162,7 @@ export const BUILTIN_DOCS: Readonly<Record<string, string>> = {
162
162
  turbulence: "Simplex creases layered in octaves, 1 to 4: fire, smoke, marble.",
163
163
  ridged: "Turbulence made bright at its creases: ridges, lightning, cracks.",
164
164
  tex2D: "The colour of texture s at the uv t, with straight alpha.",
165
- tex2Dlod: "The colour of texture s at the uv t from mip level lod: 0 is the full size, 1 half, and so on.",
165
+ tex2Dlod: "Texture s at uv t from mip level lod: 0 is full size, 1 half, and a fraction blends the two.",
166
166
  sdf: "The signed distance from p to a shape, negative inside: `sdf.circle(p, r)`.",
167
167
  ramp: "t mapped through evenly spaced colour stops, from the first at 0 to the last at 1.",
168
168
  }
package/src/sl.ts CHANGED
@@ -1037,8 +1037,8 @@ export interface Texture {
1037
1037
  sample(uv: Vec2): Vec4
1038
1038
  /**
1039
1039
  * The colour at `uv` from mip level `lod`: 0 is the full size texture, 1
1040
- * half, and a fraction blends two levels where the texture's filter does.
1041
- * A texture with no mips has only level 0.
1040
+ * half, and a fraction blends the two levels either side, whatever the
1041
+ * texture's filter mode. A texture with no mips has only level 0.
1042
1042
  */
1043
1043
  sampleLevel(uv: Vec2, lod: Num): Vec4
1044
1044
  }
package/src/web.ts CHANGED
@@ -34,7 +34,7 @@
34
34
  */
35
35
 
36
36
  import { INT_LIMITS } from "./body"
37
- import { SLError, TYPE, valueAt, type NodeRef, type Program, type SLKind, type SLType, type ValueNode } from "./ir"
37
+ import { SLError, TYPE, isWhole, valueAt, type NodeRef, type Program, type SLKind, type SLType, type ValueNode } from "./ir"
38
38
  import { inVaryingFlow, local, printBody, structure, type Syntax } from "./structure"
39
39
  import { libClosure, libIndex, LIB_FUNCTIONS, SDF_CALLS } from "./lib"
40
40
  import { LIB_GLSL } from "./lib/glsl"
@@ -261,9 +261,16 @@ function emitWeb(p: Program, lang: WebLanguage): string {
261
261
  case SLOP.SAMPLE_LOD: {
262
262
  const slot = Math.round(imm[0] ?? 0)
263
263
  sampled.add(slot)
264
- return W
265
- ? `textureSampleLevel(sl_tex${slot}, sl_samp${slot}, ${a[0]}, ${a[1]})`
266
- : `textureLod(sl_Tex${slot}, ${a[0]}, ${a[1]})`
264
+ const at = (level: string) => W
265
+ ? `textureSampleLevel(sl_tex${slot}, sl_samp${slot}, ${a[0]}, ${level})`
266
+ : `textureLod(sl_Tex${slot}, ${a[0]}, ${level})`
267
+ // A fraction blends the level below and the level above,
268
+ // whatever the texture's filter between levels, as the HLSL
269
+ // emitter does (`isWhole`). Past the smallest level both read
270
+ // the smallest, as a whole level past it does.
271
+ if (isWhole(p.nodes, n.args[1]!)) return at(a[1]!)
272
+ const below = `floor(${a[1]})`
273
+ return `mix(${at(below)}, ${at(`${below} + 1.0`)}, fract(${a[1]}))`
267
274
  }
268
275
  case SLOP.SAMPLE_PREVIOUS:
269
276
  previous = true