glre 0.47.0 → 0.49.1
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/README.md +1017 -29
- package/dist/addons.d.ts +60 -55
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +84 -79
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/native.d.ts +65 -58
- package/dist/node.cjs +42 -42
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +63 -58
- package/dist/node.js +15 -15
- package/dist/node.js.map +1 -1
- package/dist/react.d.ts +84 -79
- package/dist/solid.d.ts +84 -79
- package/package.json +1 -1
- package/src/helpers.ts +2 -2
- package/src/index.ts +9 -4
- package/src/node/create.ts +10 -9
- package/src/node/scope.ts +3 -15
- package/src/node/types.ts +20 -45
- package/src/node/utils/const.ts +27 -10
- package/src/node/utils/index.ts +15 -8
- package/src/node/utils/infer.ts +26 -20
- package/src/node/utils/parse.ts +5 -5
- package/src/types.ts +6 -4
- package/src/webgl/compute.ts +4 -4
- package/src/webgl/graphic.ts +6 -6
- package/src/webgpu/compute.ts +5 -5
- package/src/webgpu/graphic.ts +15 -27
- package/src/webgpu/index.ts +36 -17
- package/src/webgpu/utils.ts +23 -27
package/README.md
CHANGED
|
@@ -101,88 +101,1067 @@ npm install glre
|
|
|
101
101
|
<tbody>
|
|
102
102
|
<tr>
|
|
103
103
|
<td width="7500px" align="center" valign="center">
|
|
104
|
-
glre simplifies WebGL2 / WebGPU programming via TypeScript, React, Solid and more
|
|
104
|
+
glre simplifies WebGL2 / WebGPU programming via TypeScript, React, Solid and more.
|
|
105
105
|
</td>
|
|
106
106
|
<td width="2500px" valign="top">
|
|
107
107
|
<a href="https://codesandbox.io/s/glre-basic-demo-ppzo3d">
|
|
108
|
-
|
|
108
|
+
<img alt="4" src="https://i.imgur.com/Lb3h9fs.jpg"></img>
|
|
109
109
|
</a>
|
|
110
110
|
</td>
|
|
111
111
|
</tr>
|
|
112
112
|
</tbody>
|
|
113
113
|
</table>
|
|
114
114
|
|
|
115
|
+
<table>
|
|
116
|
+
<tr valign="top">
|
|
117
|
+
<td width="1000px">
|
|
118
|
+
<br />
|
|
119
|
+
|
|
120
|
+
**ESM**
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
<!-- prettier-ignore -->
|
|
125
|
+
```html
|
|
126
|
+
<script type="module">
|
|
127
|
+
import { createGL } from 'https://esm.sh/glre'
|
|
128
|
+
import { vec4, uv } from 'https://esm.sh/glre/node'
|
|
129
|
+
createGL({ fs: vec4(uv, 0, 1) }).mount()
|
|
130
|
+
</script>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
</td>
|
|
134
|
+
<td width="0px">
|
|
135
|
+
<details>
|
|
136
|
+
<summary>
|
|
137
|
+
|
|
138
|
+
React
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
</summary>
|
|
143
|
+
|
|
144
|
+
<!-- prettier-ignore -->
|
|
115
145
|
```ts
|
|
116
146
|
import { createRoot } from 'react-dom/client'
|
|
117
147
|
import { useGL } from 'glre/react'
|
|
118
148
|
import { vec4, uv } from 'glre/node'
|
|
149
|
+
|
|
119
150
|
const Canvas = () => {
|
|
120
|
-
|
|
121
|
-
|
|
151
|
+
const gl = useGL({ fragment: vec4(uv, 0, 1) })
|
|
152
|
+
return <canvas ref={gl.ref} />
|
|
122
153
|
}
|
|
123
154
|
|
|
124
|
-
|
|
155
|
+
const root = document.getElementById('root')
|
|
156
|
+
createRoot(root).render(<Canvas />)
|
|
125
157
|
```
|
|
126
158
|
|
|
159
|
+
</details>
|
|
160
|
+
</td>
|
|
161
|
+
<td width="0px">
|
|
127
162
|
<details>
|
|
128
163
|
<summary>
|
|
129
164
|
|
|
130
|
-
|
|
165
|
+
ReactNative
|
|
166
|
+
|
|
167
|
+
---
|
|
131
168
|
|
|
132
169
|
</summary>
|
|
133
170
|
|
|
171
|
+
<!-- prettier-ignore -->
|
|
134
172
|
```ts
|
|
135
173
|
import { GLView } from 'expo-gl'
|
|
136
174
|
import { registerRootComponent } from 'expo'
|
|
137
175
|
import { useGL } from 'glre/native'
|
|
138
176
|
import { vec4, uv } from 'glre/node'
|
|
177
|
+
|
|
139
178
|
const Canvas = () => {
|
|
140
|
-
|
|
141
|
-
|
|
179
|
+
const gl = useGL({ fragment: vec4(uv, 0, 1) })
|
|
180
|
+
return (
|
|
181
|
+
<GLView
|
|
182
|
+
style={{ flex: 1 }}
|
|
183
|
+
onContextCreate={gl.ref}
|
|
184
|
+
/>
|
|
185
|
+
)
|
|
142
186
|
}
|
|
143
187
|
|
|
144
188
|
registerRootComponent(Canvas)
|
|
145
189
|
```
|
|
146
190
|
|
|
147
191
|
</details>
|
|
192
|
+
</td>
|
|
193
|
+
<td width="0px">
|
|
148
194
|
<details>
|
|
149
195
|
<summary>
|
|
150
196
|
|
|
151
|
-
|
|
197
|
+
Solid.js
|
|
198
|
+
|
|
199
|
+
---
|
|
152
200
|
|
|
153
201
|
</summary>
|
|
154
202
|
|
|
203
|
+
<!-- prettier-ignore -->
|
|
155
204
|
```ts
|
|
156
205
|
import { render } from 'solid-js/web'
|
|
157
206
|
import { onGL } from 'glre/solid'
|
|
158
207
|
import { vec4, uv } from 'glre/node'
|
|
208
|
+
|
|
159
209
|
const Canvas = () => {
|
|
160
|
-
|
|
161
|
-
|
|
210
|
+
const gl = onGL({ fragment: vec4(uv, 0, 1) })
|
|
211
|
+
return <canvas ref={gl.ref} />
|
|
162
212
|
}
|
|
163
213
|
|
|
164
214
|
render(() => <Canvas />, document.getElementById('root'))
|
|
165
215
|
```
|
|
166
216
|
|
|
167
217
|
</details>
|
|
218
|
+
</td>
|
|
219
|
+
</tr>
|
|
220
|
+
</table>
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
<table>
|
|
225
|
+
<tr>
|
|
226
|
+
<td width="100%" colspan="3">
|
|
227
|
+
|
|
228
|
+
### [Varying](https://glre.dev/docs#varying)
|
|
229
|
+
|
|
230
|
+
</td>
|
|
231
|
+
</tr>
|
|
232
|
+
<tr valign="top">
|
|
233
|
+
<td width="1000px">
|
|
234
|
+
<br />
|
|
235
|
+
|
|
236
|
+
**TSL**
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
<!-- prettier-ignore -->
|
|
241
|
+
```tsx
|
|
242
|
+
function Canvas() {
|
|
243
|
+
const tri = attribute([
|
|
244
|
+
0, 0.73,
|
|
245
|
+
-1, -1,
|
|
246
|
+
1, -1,
|
|
247
|
+
])
|
|
248
|
+
const col = attribute([
|
|
249
|
+
1, 0, 0,
|
|
250
|
+
0, 1, 0,
|
|
251
|
+
0, 0, 1,
|
|
252
|
+
])
|
|
253
|
+
const gl = useGL({
|
|
254
|
+
isWebGL: true,
|
|
255
|
+
triangleCount: 1,
|
|
256
|
+
vertex: vec4(tri, 0, 1),
|
|
257
|
+
fragment: vec4(vertexStage(col), 1),
|
|
258
|
+
})
|
|
259
|
+
return <canvas ref={gl.ref} />
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
</td>
|
|
264
|
+
<td width="0px">
|
|
265
|
+
<details>
|
|
266
|
+
<summary>
|
|
267
|
+
|
|
268
|
+
WebGL
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
</summary>
|
|
273
|
+
|
|
274
|
+
<!-- prettier-ignore -->
|
|
275
|
+
```tsx
|
|
276
|
+
function Canvas() {
|
|
277
|
+
const gl = useGL({
|
|
278
|
+
isWebGL: true,
|
|
279
|
+
triangleCount: 1,
|
|
280
|
+
vertex: `
|
|
281
|
+
#version 300 es
|
|
282
|
+
in vec4 tri;
|
|
283
|
+
in vec3 col;
|
|
284
|
+
out vec3 v_col;
|
|
285
|
+
void main() {
|
|
286
|
+
gl_Position = tri;
|
|
287
|
+
v_col = col;
|
|
288
|
+
}`,
|
|
289
|
+
fragment: `
|
|
290
|
+
#version 300 es
|
|
291
|
+
precision mediump float;
|
|
292
|
+
in vec3 v_col;
|
|
293
|
+
out vec4 fragColor;
|
|
294
|
+
void main() {
|
|
295
|
+
fragColor = vec4(v_col, 1.0);
|
|
296
|
+
}`,
|
|
297
|
+
})
|
|
298
|
+
gl.attribute('tri', [
|
|
299
|
+
0, 0.73,
|
|
300
|
+
-1, -1,
|
|
301
|
+
1, -1,
|
|
302
|
+
])
|
|
303
|
+
gl.attribute('col', [
|
|
304
|
+
1, 0, 0,
|
|
305
|
+
0, 1, 0,
|
|
306
|
+
0, 0, 1,
|
|
307
|
+
])
|
|
308
|
+
return <canvas ref={gl.ref} />
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
</details>
|
|
313
|
+
</td>
|
|
314
|
+
<td width="0px">
|
|
168
315
|
<details>
|
|
169
316
|
<summary>
|
|
170
317
|
|
|
171
|
-
|
|
318
|
+
WebGPU
|
|
319
|
+
|
|
320
|
+
---
|
|
172
321
|
|
|
173
322
|
</summary>
|
|
174
323
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
324
|
+
<!-- prettier-ignore -->
|
|
325
|
+
```tsx
|
|
326
|
+
function Canvas() {
|
|
327
|
+
const gl = useGL({
|
|
328
|
+
isWebGL: false,
|
|
329
|
+
triangleCount: 1,
|
|
330
|
+
vertex: `
|
|
331
|
+
struct In {
|
|
332
|
+
@location(0) tri: vec2f,
|
|
333
|
+
@location(1) col: vec3f,
|
|
334
|
+
}
|
|
335
|
+
struct Out {
|
|
336
|
+
@builtin(position) position: vec4f,
|
|
337
|
+
@location(0) v_col: vec3f,
|
|
338
|
+
}
|
|
339
|
+
@vertex
|
|
340
|
+
fn main(in: In) -> Out {
|
|
341
|
+
var out: Out;
|
|
342
|
+
out.position = vec4f(in.tri, 0.0, 1.0);
|
|
343
|
+
out.v_col = in.col;
|
|
344
|
+
return out;
|
|
345
|
+
}`,
|
|
346
|
+
fragment: `
|
|
347
|
+
struct Out {
|
|
348
|
+
@builtin(position) position: vec4f,
|
|
349
|
+
@location(0) v_col: vec3f,
|
|
350
|
+
}
|
|
351
|
+
@fragment
|
|
352
|
+
fn main(out: Out) -> @location(0) vec4f {
|
|
353
|
+
return vec4f(out.v_col, 1.0);
|
|
354
|
+
}`,
|
|
355
|
+
})
|
|
356
|
+
gl.attribute('tri', [
|
|
357
|
+
0, 0.73,
|
|
358
|
+
-1, -1,
|
|
359
|
+
1, -1
|
|
360
|
+
])
|
|
361
|
+
gl.attribute('col', [
|
|
362
|
+
1, 0, 0,
|
|
363
|
+
0, 1, 0,
|
|
364
|
+
0, 0, 1
|
|
365
|
+
])
|
|
366
|
+
return <canvas ref={gl.ref} />
|
|
367
|
+
}
|
|
181
368
|
```
|
|
182
369
|
|
|
183
370
|
</details>
|
|
184
|
-
</
|
|
185
|
-
</
|
|
371
|
+
</td>
|
|
372
|
+
</tr>
|
|
373
|
+
<tr>
|
|
374
|
+
<td colspan="3">
|
|
375
|
+
<a href="https://glre.dev/docs#varying">
|
|
376
|
+
<img width="256px" src="./examples/docs/static/img/readme/varying.jpg" />
|
|
377
|
+
</a>
|
|
378
|
+
</td>
|
|
379
|
+
</tr>
|
|
380
|
+
</table>
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
<table>
|
|
385
|
+
<tr>
|
|
386
|
+
<td width="100%" colspan="3">
|
|
387
|
+
|
|
388
|
+
### [Uniforms](https://glre.dev/docs#uniforms)
|
|
389
|
+
|
|
390
|
+
</td>
|
|
391
|
+
</tr>
|
|
392
|
+
<tr valign="top">
|
|
393
|
+
<td width="1000px">
|
|
394
|
+
<br />
|
|
395
|
+
|
|
396
|
+
**TSL**
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
<!-- prettier-ignore -->
|
|
401
|
+
```tsx
|
|
402
|
+
function Canvas() {
|
|
403
|
+
const gl = useGL({
|
|
404
|
+
isWebGL: true,
|
|
405
|
+
fragment: vec4(
|
|
406
|
+
uv.sub(iMouse).fract(),
|
|
407
|
+
iTime.sin().mul(0.5).add(0.5),
|
|
408
|
+
1
|
|
409
|
+
),
|
|
410
|
+
})
|
|
411
|
+
return <canvas ref={gl.ref} />
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
</td>
|
|
416
|
+
<td width="0px">
|
|
417
|
+
<details>
|
|
418
|
+
<summary>
|
|
419
|
+
|
|
420
|
+
WebGL
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
</summary>
|
|
425
|
+
|
|
426
|
+
<!-- prettier-ignore -->
|
|
427
|
+
```tsx
|
|
428
|
+
function Canvas() {
|
|
429
|
+
const gl = useGL({
|
|
430
|
+
isWebGL: true,
|
|
431
|
+
fragment: `
|
|
432
|
+
#version 300 es
|
|
433
|
+
precision mediump float;
|
|
434
|
+
uniform vec2 iResolution;
|
|
435
|
+
uniform vec2 iMouse;
|
|
436
|
+
uniform float iTime;
|
|
437
|
+
out vec4 fragColor;
|
|
438
|
+
void main() {
|
|
439
|
+
vec2 uv = fract(gl_FragCoord.xy / iResolution.xy - iMouse);
|
|
440
|
+
fragColor = vec4(uv, sin(iTime) * 0.5 + 0.5, 1.0);
|
|
441
|
+
}`,
|
|
442
|
+
})
|
|
443
|
+
return <canvas ref={gl.ref} />
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
</details>
|
|
448
|
+
</td>
|
|
449
|
+
<td width="0px">
|
|
450
|
+
<details>
|
|
451
|
+
<summary>
|
|
452
|
+
|
|
453
|
+
WebGPU
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
</summary>
|
|
458
|
+
|
|
459
|
+
<!-- prettier-ignore -->
|
|
460
|
+
```tsx
|
|
461
|
+
function Canvas() {
|
|
462
|
+
const gl = useGL({
|
|
463
|
+
isWebGL: false,
|
|
464
|
+
fragment: `
|
|
465
|
+
@group(0) @binding(0) var<uniform> iResolution: vec2f;
|
|
466
|
+
@group(0) @binding(1) var<uniform> iMouse: vec2f;
|
|
467
|
+
@group(0) @binding(2) var<uniform> iTime: f32;
|
|
468
|
+
@fragment
|
|
469
|
+
fn main(@builtin(position) position: vec4f) -> @location(0) vec4f {
|
|
470
|
+
let uv = fract(position.xy / iResolution - iMouse);
|
|
471
|
+
return vec4f(uv, sin(iTime) * 0.5 + 0.5, 1.0);
|
|
472
|
+
}`,
|
|
473
|
+
})
|
|
474
|
+
return <canvas ref={gl.ref} />
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
</details>
|
|
479
|
+
</td>
|
|
480
|
+
</tr>
|
|
481
|
+
<tr>
|
|
482
|
+
<td colspan="3">
|
|
483
|
+
<a href="https://glre.dev/docs#uniforms">
|
|
484
|
+
<img width="256px" src="./examples/docs/static/img/readme/uniform.jpg" />
|
|
485
|
+
</a>
|
|
486
|
+
</td>
|
|
487
|
+
</tr>
|
|
488
|
+
</table>
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
<table>
|
|
493
|
+
<tr>
|
|
494
|
+
<td width="100%" colspan="3">
|
|
495
|
+
|
|
496
|
+
### [Attributes](https://glre.dev/docs#attributes)
|
|
497
|
+
|
|
498
|
+
</td>
|
|
499
|
+
</tr>
|
|
500
|
+
<tr valign="top">
|
|
501
|
+
<td width="1000px">
|
|
502
|
+
<br />
|
|
503
|
+
|
|
504
|
+
**TSL**
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
<!-- prettier-ignore -->
|
|
509
|
+
```tsx
|
|
510
|
+
function Canvas() {
|
|
511
|
+
const tri = attribute([
|
|
512
|
+
0, 0.73,
|
|
513
|
+
-1, -1,
|
|
514
|
+
1, -1
|
|
515
|
+
])
|
|
516
|
+
const gl = useGL({
|
|
517
|
+
isWebGL: true,
|
|
518
|
+
triangleCount: 1,
|
|
519
|
+
vertex: vec4(tri, 0, 1),
|
|
520
|
+
})
|
|
521
|
+
return <canvas ref={gl.ref} />
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
</td>
|
|
526
|
+
<td width="0px">
|
|
527
|
+
<details>
|
|
528
|
+
<summary>
|
|
529
|
+
|
|
530
|
+
WebGL
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
</summary>
|
|
535
|
+
|
|
536
|
+
<!-- prettier-ignore -->
|
|
537
|
+
```tsx
|
|
538
|
+
function Canvas() {
|
|
539
|
+
const gl = useGL({
|
|
540
|
+
isWebGL: true,
|
|
541
|
+
triangleCount: 1,
|
|
542
|
+
vertex: `
|
|
543
|
+
#version 300 es
|
|
544
|
+
in vec4 tri;
|
|
545
|
+
void main() {
|
|
546
|
+
gl_Position = tri;
|
|
547
|
+
}`,
|
|
548
|
+
})
|
|
549
|
+
gl.attribute('tri', [
|
|
550
|
+
0, 0.73,
|
|
551
|
+
-1, -1,
|
|
552
|
+
1, -1
|
|
553
|
+
])
|
|
554
|
+
return <canvas ref={gl.ref} />
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
</details>
|
|
559
|
+
</td>
|
|
560
|
+
<td width="0px">
|
|
561
|
+
<details>
|
|
562
|
+
<summary>
|
|
563
|
+
|
|
564
|
+
WebGPU
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
</summary>
|
|
569
|
+
|
|
570
|
+
<!-- prettier-ignore -->
|
|
571
|
+
```tsx
|
|
572
|
+
function Canvas() {
|
|
573
|
+
const gl = useGL({
|
|
574
|
+
isWebGL: false,
|
|
575
|
+
triangleCount: 1,
|
|
576
|
+
vertex: `
|
|
577
|
+
@vertex
|
|
578
|
+
fn main(@location(0) tri: vec2f) -> @builtin(position) vec4f {
|
|
579
|
+
return vec4f(tri, 0.0, 1.0);
|
|
580
|
+
}`,
|
|
581
|
+
})
|
|
582
|
+
gl.attribute('tri', [
|
|
583
|
+
0, 0.73,
|
|
584
|
+
-1, -1,
|
|
585
|
+
1, -1
|
|
586
|
+
])
|
|
587
|
+
return <canvas ref={gl.ref} />
|
|
588
|
+
}
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
</details>
|
|
592
|
+
</td>
|
|
593
|
+
</tr>
|
|
594
|
+
<tr>
|
|
595
|
+
<td colspan="3">
|
|
596
|
+
<a href="https://glre.dev/docs#attributes">
|
|
597
|
+
<img width="256px" src="./examples/docs/static/img/readme/attribute.jpg" />
|
|
598
|
+
</a>
|
|
599
|
+
</td>
|
|
600
|
+
</tr>
|
|
601
|
+
</table>
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
<table>
|
|
606
|
+
<tr>
|
|
607
|
+
<td width="100%" colspan="3">
|
|
608
|
+
|
|
609
|
+
### [Multiples](https://glre.dev/docs#multiples)
|
|
610
|
+
|
|
611
|
+
</td>
|
|
612
|
+
</tr>
|
|
613
|
+
<tr valign="top">
|
|
614
|
+
<td width="1000px">
|
|
615
|
+
<br />
|
|
616
|
+
|
|
617
|
+
**TSL**
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
<!-- prettier-ignore -->
|
|
622
|
+
```tsx
|
|
623
|
+
function Canvas() {
|
|
624
|
+
const tri = attribute([
|
|
625
|
+
0, 0.37,
|
|
626
|
+
-0.5, -0.5,
|
|
627
|
+
0.5, -0.5
|
|
628
|
+
])
|
|
629
|
+
const gl = useGL(
|
|
630
|
+
{
|
|
631
|
+
isWebGL: true,
|
|
632
|
+
triangleCount: 1,
|
|
633
|
+
vertex: vec4(vec2(-0.5, 0).add(tri), 0, 1),
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
triangleCount: 1,
|
|
637
|
+
vertex: vec4(vec2(0.5, 0).add(tri), 0, 1),
|
|
638
|
+
}
|
|
639
|
+
)
|
|
640
|
+
return <canvas ref={gl.ref} />
|
|
641
|
+
}
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
</td>
|
|
645
|
+
<td width="0px">
|
|
646
|
+
<details>
|
|
647
|
+
<summary>
|
|
648
|
+
|
|
649
|
+
WebGL
|
|
650
|
+
|
|
651
|
+
---
|
|
652
|
+
|
|
653
|
+
</summary>
|
|
654
|
+
|
|
655
|
+
<!-- prettier-ignore -->
|
|
656
|
+
```tsx
|
|
657
|
+
function Canvas() {
|
|
658
|
+
const gl = useGL(
|
|
659
|
+
{
|
|
660
|
+
isWebGL: true,
|
|
661
|
+
triangleCount: 1,
|
|
662
|
+
vertex: `
|
|
663
|
+
#version 300 es
|
|
664
|
+
in vec2 tri;
|
|
665
|
+
void main() {
|
|
666
|
+
gl_Position = vec4((vec2(-0.5, 0.0) + tri), 0.0, 1.0);
|
|
667
|
+
}`,
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
triangleCount: 1,
|
|
671
|
+
vertex: `
|
|
672
|
+
#version 300 es
|
|
673
|
+
in vec2 tri;
|
|
674
|
+
void main() {
|
|
675
|
+
gl_Position = vec4((vec2(0.5, 0.0) + tri), 0.0, 1.0);
|
|
676
|
+
}`,
|
|
677
|
+
}
|
|
678
|
+
)
|
|
679
|
+
gl.attribute('tri', [
|
|
680
|
+
0, 0.37,
|
|
681
|
+
-0.5, -0.5,
|
|
682
|
+
0.5, -0.5
|
|
683
|
+
])
|
|
684
|
+
return <canvas ref={gl.ref} />
|
|
685
|
+
}
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
</details>
|
|
689
|
+
</td>
|
|
690
|
+
<td width="0px">
|
|
691
|
+
<details>
|
|
692
|
+
<summary>
|
|
693
|
+
|
|
694
|
+
WebGPU
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
</summary>
|
|
699
|
+
|
|
700
|
+
<!-- prettier-ignore -->
|
|
701
|
+
```tsx
|
|
702
|
+
function Canvas() {
|
|
703
|
+
const gl = useGL(
|
|
704
|
+
{
|
|
705
|
+
isWebGL: false,
|
|
706
|
+
triangleCount: 1,
|
|
707
|
+
vertex: `
|
|
708
|
+
struct In {
|
|
709
|
+
@location(0) tri: vec2f
|
|
710
|
+
}
|
|
711
|
+
struct Out {
|
|
712
|
+
@builtin(position) position: vec4f
|
|
713
|
+
}
|
|
714
|
+
@vertex
|
|
715
|
+
fn main(in: In) -> Out {
|
|
716
|
+
var out: Out;
|
|
717
|
+
out.position = vec4f((vec2f(-0.5, 0.0) + in.tri), 0.0, 1.0);
|
|
718
|
+
return out;
|
|
719
|
+
}`,
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
triangleCount: 1,
|
|
723
|
+
vertex: `
|
|
724
|
+
struct In {
|
|
725
|
+
@location(0) tri: vec2f
|
|
726
|
+
}
|
|
727
|
+
struct Out {
|
|
728
|
+
@builtin(position) position: vec4f
|
|
729
|
+
}
|
|
730
|
+
@vertex
|
|
731
|
+
fn main(in: In) -> Out {
|
|
732
|
+
var out: Out;
|
|
733
|
+
out.position = vec4f((vec2f(0.5, 0.0) + in.tri), 0.0, 1.0);
|
|
734
|
+
return out;
|
|
735
|
+
}`,
|
|
736
|
+
}
|
|
737
|
+
)
|
|
738
|
+
gl.attribute('tri', [
|
|
739
|
+
0, 0.37,
|
|
740
|
+
-0.5, -0.5,
|
|
741
|
+
0.5, -0.5
|
|
742
|
+
])
|
|
743
|
+
return <canvas ref={gl.ref} />
|
|
744
|
+
}
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
</details>
|
|
748
|
+
</td>
|
|
749
|
+
</tr>
|
|
750
|
+
<tr>
|
|
751
|
+
<td colspan="3">
|
|
752
|
+
<a href="https://glre.dev/docs#multiples">
|
|
753
|
+
<img width="256px" src="./examples/docs/static/img/readme/multiple.jpg" />
|
|
754
|
+
</a>
|
|
755
|
+
</td>
|
|
756
|
+
</tr>
|
|
757
|
+
</table>
|
|
758
|
+
|
|
759
|
+
---
|
|
760
|
+
|
|
761
|
+
<table>
|
|
762
|
+
<tr>
|
|
763
|
+
<td width="100%" colspan="3">
|
|
764
|
+
|
|
765
|
+
### [Textures](https://glre.dev/docs#textures)
|
|
766
|
+
|
|
767
|
+
</td>
|
|
768
|
+
</tr>
|
|
769
|
+
<tr valign="top">
|
|
770
|
+
<td width="1000px">
|
|
771
|
+
<br />
|
|
772
|
+
|
|
773
|
+
**TSL**
|
|
774
|
+
|
|
775
|
+
---
|
|
776
|
+
|
|
777
|
+
<!-- prettier-ignore -->
|
|
778
|
+
```tsx
|
|
779
|
+
function Canvas() {
|
|
780
|
+
const iTexture = uniform('https://...')
|
|
781
|
+
const gl = useGL({
|
|
782
|
+
isWebGL: true,
|
|
783
|
+
fragment: texture(iTexture, uv),
|
|
784
|
+
})
|
|
785
|
+
return <canvas ref={gl.ref} />
|
|
786
|
+
}
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
</td>
|
|
790
|
+
<td width="0px">
|
|
791
|
+
<details>
|
|
792
|
+
<summary>
|
|
793
|
+
|
|
794
|
+
WebGL
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
</summary>
|
|
799
|
+
|
|
800
|
+
<!-- prettier-ignore -->
|
|
801
|
+
```tsx
|
|
802
|
+
function Canvas() {
|
|
803
|
+
const gl = useGL({
|
|
804
|
+
isWebGL: true,
|
|
805
|
+
fragment: `
|
|
806
|
+
#version 300 es
|
|
807
|
+
precision mediump float;
|
|
808
|
+
uniform vec2 iResolution;
|
|
809
|
+
uniform sampler2D iTexture;
|
|
810
|
+
out vec4 fragColor;
|
|
811
|
+
void main() {
|
|
812
|
+
vec2 uv = gl_FragCoord.xy / iResolution.xy;
|
|
813
|
+
fragColor = texture(iTexture, uv);
|
|
814
|
+
}`,
|
|
815
|
+
})
|
|
816
|
+
gl.texture('iTexture', 'https://...')
|
|
817
|
+
return <canvas ref={gl.ref} />
|
|
818
|
+
}
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
</details>
|
|
822
|
+
</td>
|
|
823
|
+
<td width="0px">
|
|
824
|
+
<details>
|
|
825
|
+
<summary>
|
|
826
|
+
|
|
827
|
+
WebGPU
|
|
828
|
+
|
|
829
|
+
---
|
|
830
|
+
|
|
831
|
+
</summary>
|
|
832
|
+
|
|
833
|
+
<!-- prettier-ignore -->
|
|
834
|
+
```tsx
|
|
835
|
+
function Canvas() {
|
|
836
|
+
const gl = useGL({
|
|
837
|
+
isWebGL: false,
|
|
838
|
+
fragment: `
|
|
839
|
+
@group(0) @binding(0) var<uniform> iResolution: vec2f;
|
|
840
|
+
@group(1) @binding(0) var iSampler: sampler;
|
|
841
|
+
@group(1) @binding(1) var iTexture: texture_2d<f32>;
|
|
842
|
+
@fragment
|
|
843
|
+
fn main(@builtin(position) position: vec4f) -> @location(0) vec4f {
|
|
844
|
+
let uv = position.xy / iResolution;
|
|
845
|
+
return textureSample(iTexture, iSampler, uv);
|
|
846
|
+
}`,
|
|
847
|
+
})
|
|
848
|
+
gl.texture('iTexture', 'https://...')
|
|
849
|
+
return <canvas ref={gl.ref} />
|
|
850
|
+
}
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
</details>
|
|
854
|
+
</td>
|
|
855
|
+
</tr>
|
|
856
|
+
<tr>
|
|
857
|
+
<td colspan="3">
|
|
858
|
+
<a href="https://glre.dev/docs#textures">
|
|
859
|
+
<img width="256px" src="./examples/docs/static/img/readme/texture.jpg" />
|
|
860
|
+
</a>
|
|
861
|
+
</td>
|
|
862
|
+
</tr>
|
|
863
|
+
</table>
|
|
864
|
+
|
|
865
|
+
---
|
|
866
|
+
|
|
867
|
+
<table>
|
|
868
|
+
<tr>
|
|
869
|
+
<td width="100%" colspan="3">
|
|
870
|
+
|
|
871
|
+
### [Instancing](https://glre.dev/docs#instancing)
|
|
872
|
+
|
|
873
|
+
</td>
|
|
874
|
+
</tr>
|
|
875
|
+
<tr valign="top">
|
|
876
|
+
<td width="1000px">
|
|
877
|
+
<br />
|
|
878
|
+
|
|
879
|
+
**TSL**
|
|
880
|
+
|
|
881
|
+
---
|
|
882
|
+
|
|
883
|
+
<!-- prettier-ignore -->
|
|
884
|
+
```tsx
|
|
885
|
+
function Canvas() {
|
|
886
|
+
const tri = attribute([
|
|
887
|
+
0, 0.73,
|
|
888
|
+
-1, -1,
|
|
889
|
+
1, -1
|
|
890
|
+
])
|
|
891
|
+
const pos = instance(
|
|
892
|
+
Array(1000 * 2)
|
|
893
|
+
.fill(0)
|
|
894
|
+
.map(Math.random)
|
|
895
|
+
)
|
|
896
|
+
const gl = useGL({
|
|
897
|
+
isWebGL: true,
|
|
898
|
+
instanceCount: 1000,
|
|
899
|
+
triangleCount: 1,
|
|
900
|
+
vertex: vec4(
|
|
901
|
+
tri.mul(0.05).sub(1).add(pos.mul(2)),
|
|
902
|
+
0,
|
|
903
|
+
1
|
|
904
|
+
),
|
|
905
|
+
})
|
|
906
|
+
return <canvas ref={gl.ref} />
|
|
907
|
+
}
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
</td>
|
|
911
|
+
<td width="0px">
|
|
912
|
+
<details>
|
|
913
|
+
<summary>
|
|
914
|
+
|
|
915
|
+
WebGL
|
|
916
|
+
|
|
917
|
+
---
|
|
918
|
+
|
|
919
|
+
</summary>
|
|
920
|
+
|
|
921
|
+
<!-- prettier-ignore -->
|
|
922
|
+
```tsx
|
|
923
|
+
function Canvas() {
|
|
924
|
+
const gl = useGL({
|
|
925
|
+
isWebGL: true,
|
|
926
|
+
instanceCount: 1000,
|
|
927
|
+
triangleCount: 1,
|
|
928
|
+
vertex: `
|
|
929
|
+
#version 300 es
|
|
930
|
+
in vec2 tri;
|
|
931
|
+
in vec2 pos;
|
|
932
|
+
void main() {
|
|
933
|
+
gl_Position = vec4((((tri * 0.05) - 1.0) + (pos * 2.0)), 0.0, 1.0);
|
|
934
|
+
}`,
|
|
935
|
+
})
|
|
936
|
+
gl.attribute('tri', [
|
|
937
|
+
0, 0.73,
|
|
938
|
+
-1, -1,
|
|
939
|
+
1, -1
|
|
940
|
+
])
|
|
941
|
+
gl.instance(
|
|
942
|
+
'pos',
|
|
943
|
+
Array(1000 * 2)
|
|
944
|
+
.fill(0)
|
|
945
|
+
.map(Math.random)
|
|
946
|
+
)
|
|
947
|
+
return <canvas ref={gl.ref} />
|
|
948
|
+
}
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
</details>
|
|
952
|
+
</td>
|
|
953
|
+
<td width="0px">
|
|
954
|
+
<details>
|
|
955
|
+
<summary>
|
|
956
|
+
|
|
957
|
+
WebGPU
|
|
958
|
+
|
|
959
|
+
---
|
|
960
|
+
|
|
961
|
+
</summary>
|
|
962
|
+
|
|
963
|
+
<!-- prettier-ignore -->
|
|
964
|
+
```tsx
|
|
965
|
+
function Canvas() {
|
|
966
|
+
const gl = useGL({
|
|
967
|
+
isWebGL: false,
|
|
968
|
+
instanceCount: 1000,
|
|
969
|
+
triangleCount: 1,
|
|
970
|
+
vertex: `
|
|
971
|
+
struct In {
|
|
972
|
+
@location(0) tri: vec2f,
|
|
973
|
+
@location(1) pos: vec2f
|
|
974
|
+
}
|
|
975
|
+
struct Out {
|
|
976
|
+
@builtin(position) position: vec4f
|
|
977
|
+
}
|
|
978
|
+
@vertex
|
|
979
|
+
fn main(in: In) -> Out {
|
|
980
|
+
var out: Out;
|
|
981
|
+
out.position = vec4f((((in.tri * 0.05) - 1.0) + (in.pos * 2.0)), 0.0, 1.0);
|
|
982
|
+
return out;
|
|
983
|
+
}`,
|
|
984
|
+
})
|
|
985
|
+
gl.attribute('tri', [
|
|
986
|
+
0, 0.73,
|
|
987
|
+
-1, -1,
|
|
988
|
+
1, -1
|
|
989
|
+
])
|
|
990
|
+
gl.instance(
|
|
991
|
+
'pos',
|
|
992
|
+
Array(1000 * 2)
|
|
993
|
+
.fill(0)
|
|
994
|
+
.map(Math.random)
|
|
995
|
+
)
|
|
996
|
+
return <canvas ref={gl.ref} />
|
|
997
|
+
}
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
</details>
|
|
1001
|
+
</td>
|
|
1002
|
+
</tr>
|
|
1003
|
+
<tr>
|
|
1004
|
+
<td colspan="3">
|
|
1005
|
+
<a href="https://glre.dev/docs#instancing">
|
|
1006
|
+
<img width="256px" src="./examples/docs/static/img/readme/instancing.jpg" />
|
|
1007
|
+
</a>
|
|
1008
|
+
</td>
|
|
1009
|
+
</tr>
|
|
1010
|
+
</table>
|
|
1011
|
+
|
|
1012
|
+
---
|
|
1013
|
+
|
|
1014
|
+
<table>
|
|
1015
|
+
<tr>
|
|
1016
|
+
<td width="100%" colspan="3">
|
|
1017
|
+
|
|
1018
|
+
### [Computing](https://glre.dev/docs#computing)
|
|
1019
|
+
|
|
1020
|
+
</td>
|
|
1021
|
+
</tr>
|
|
1022
|
+
<tr valign="top">
|
|
1023
|
+
<td width="1000px">
|
|
1024
|
+
<br />
|
|
1025
|
+
|
|
1026
|
+
**TSL**
|
|
1027
|
+
|
|
1028
|
+
---
|
|
1029
|
+
|
|
1030
|
+
<!-- prettier-ignore -->
|
|
1031
|
+
```tsx
|
|
1032
|
+
function Canvas() {
|
|
1033
|
+
const wave = storage(float(Array(1024)), 'wave')
|
|
1034
|
+
const gl = useGL({
|
|
1035
|
+
isWebGL: true,
|
|
1036
|
+
compute: Scope(() => {
|
|
1037
|
+
If(uint(0).equal(id.x), () => {
|
|
1038
|
+
wave.element(id.x).assign(iMouse.x)
|
|
1039
|
+
}).Else(() => {
|
|
1040
|
+
const prev = wave.element(id.x.sub(uint(1)))
|
|
1041
|
+
wave.element(id.x).assign(prev)
|
|
1042
|
+
})
|
|
1043
|
+
}),
|
|
1044
|
+
fragment: Scope(() => {
|
|
1045
|
+
const x = wave
|
|
1046
|
+
.element(uint(uv.y.mul(1024)))
|
|
1047
|
+
.sub(uv.x)
|
|
1048
|
+
.abs()
|
|
1049
|
+
return vec4(
|
|
1050
|
+
vec3(uv.step(vec2(smoothstep(0.01, 0, x))), 0),
|
|
1051
|
+
1
|
|
1052
|
+
)
|
|
1053
|
+
}),
|
|
1054
|
+
})
|
|
1055
|
+
return <canvas ref={gl.ref} />
|
|
1056
|
+
}
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
</td>
|
|
1060
|
+
<td width="0px">
|
|
1061
|
+
<details>
|
|
1062
|
+
<summary>
|
|
1063
|
+
|
|
1064
|
+
WebGL
|
|
1065
|
+
|
|
1066
|
+
---
|
|
1067
|
+
|
|
1068
|
+
</summary>
|
|
1069
|
+
|
|
1070
|
+
<!-- prettier-ignore -->
|
|
1071
|
+
```tsx
|
|
1072
|
+
function Canvas() {
|
|
1073
|
+
const wave = storage(float(Array(1024)), 'wave')
|
|
1074
|
+
const gl = useGL({
|
|
1075
|
+
isWebGL: true,
|
|
1076
|
+
compute: `
|
|
1077
|
+
#version 300 es
|
|
1078
|
+
precision highp float;
|
|
1079
|
+
uniform sampler2D wave;
|
|
1080
|
+
uniform vec2 iMouse;
|
|
1081
|
+
layout(location = 0) out vec4 _wave;
|
|
1082
|
+
void main() {
|
|
1083
|
+
if ((uint(0.0) == uvec3(uint(gl_FragCoord.y) * uint(32) + uint(gl_FragCoord.x), 0u, 0u).x)) {
|
|
1084
|
+
_wave = vec4(iMouse.x, 0.0, 0.0, 1.0);
|
|
1085
|
+
} else {
|
|
1086
|
+
_wave = vec4(texelFetch(wave, ivec2(int((uvec3(uint(gl_FragCoord.y) * uint(32) + uint(gl_FragCoord.x), 0u, 0u).x - uint(1.0))) % 32, int((uvec3(uint(gl_FragCoord.y) * uint(32) + uint(gl_FragCoord.x), 0u, 0u).x - uint(1.0))) / 32), 0).x, 0.0, 0.0, 1.0);
|
|
1087
|
+
};
|
|
1088
|
+
}`,
|
|
1089
|
+
fragment: `
|
|
1090
|
+
#version 300 es
|
|
1091
|
+
precision highp float;
|
|
1092
|
+
out vec4 fragColor;
|
|
1093
|
+
uniform vec2 iResolution;
|
|
1094
|
+
uniform sampler2D wave;
|
|
1095
|
+
void main() {
|
|
1096
|
+
fragColor = vec4(vec3(step((gl_FragCoord.xy / iResolution), vec2(smoothstep(0.01, 0.0, abs((texelFetch(wave, ivec2(int(uint(((gl_FragCoord.xy / iResolution).y * 1024.0))) % 32, int(uint(((gl_FragCoord.xy / iResolution).y * 1024.0))) / 32), 0).x - (gl_FragCoord.xy / iResolution).x))))), 0.0), 1.0);
|
|
1097
|
+
}`,
|
|
1098
|
+
})
|
|
1099
|
+
gl.storage('wave', Array(1024))
|
|
1100
|
+
return <canvas ref={gl.ref} />
|
|
1101
|
+
}
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
</details>
|
|
1105
|
+
</td>
|
|
1106
|
+
<td width="0px">
|
|
1107
|
+
<details>
|
|
1108
|
+
<summary>
|
|
1109
|
+
|
|
1110
|
+
WebGPU
|
|
1111
|
+
|
|
1112
|
+
---
|
|
1113
|
+
|
|
1114
|
+
</summary>
|
|
1115
|
+
|
|
1116
|
+
<!-- prettier-ignore -->
|
|
1117
|
+
```tsx
|
|
1118
|
+
function Canvas() {
|
|
1119
|
+
const wave = storage(float(Array(1024)), 'wave')
|
|
1120
|
+
const gl = useGL({
|
|
1121
|
+
isWebGL: false,
|
|
1122
|
+
compute: `
|
|
1123
|
+
struct In {
|
|
1124
|
+
@builtin(global_invocation_id) global_invocation_id: vec3u
|
|
1125
|
+
}
|
|
1126
|
+
@group(0) @binding(1) var<uniform> iMouse: vec2f;
|
|
1127
|
+
@group(2) @binding(0) var<storage, read_write> wave: array<f32>;
|
|
1128
|
+
@compute @workgroup_size(32)
|
|
1129
|
+
fn main(in: In) {
|
|
1130
|
+
if ((u32(0.0) == in.global_invocation_id.x)) {
|
|
1131
|
+
wave[in.global_invocation_id.x] = iMouse.x;
|
|
1132
|
+
} else {
|
|
1133
|
+
wave[in.global_invocation_id.x] = wave[in.global_invocation_id.x - u32(1.0)];
|
|
1134
|
+
};
|
|
1135
|
+
}`,
|
|
1136
|
+
fragment: `
|
|
1137
|
+
struct Out {
|
|
1138
|
+
@builtin(position) position: vec4f
|
|
1139
|
+
}
|
|
1140
|
+
@group(2) @binding(0) var<storage, read_write> wave: array<f32>;
|
|
1141
|
+
@group(0) @binding(0) var<uniform> iResolution: vec2f;
|
|
1142
|
+
@fragment
|
|
1143
|
+
fn main(out: Out) -> @location(0) vec4f {
|
|
1144
|
+
return vec4f(vec3f(step((out.position.xy / iResolution), vec2f(smoothstep(0.01, 0.0, abs((wave[u32(((out.position.xy / iResolution).y * 1024.0))] - (out.position.xy / iResolution).x))))), 0.0), 1.0);
|
|
1145
|
+
}`,
|
|
1146
|
+
})
|
|
1147
|
+
gl.storage('wave', Array(1024))
|
|
1148
|
+
return <canvas ref={gl.ref} />
|
|
1149
|
+
}
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
</details>
|
|
1153
|
+
</td>
|
|
1154
|
+
</tr>
|
|
1155
|
+
<tr>
|
|
1156
|
+
<td colspan="3">
|
|
1157
|
+
<a href="https://glre.dev/docs#computing">
|
|
1158
|
+
<img width="256px" src="./examples/docs/static/img/readme/computing.jpg" />
|
|
1159
|
+
</a>
|
|
1160
|
+
</td>
|
|
1161
|
+
</tr>
|
|
1162
|
+
</table>
|
|
1163
|
+
|
|
1164
|
+
---
|
|
186
1165
|
|
|
187
1166
|
## Node System
|
|
188
1167
|
|
|
@@ -192,11 +1171,12 @@ Rather than traditional string-based shader composition,
|
|
|
192
1171
|
this system materializes shaders as abstract syntax trees,
|
|
193
1172
|
enabling unprecedented code mobility across WebGL2 and WebGPU architectures.
|
|
194
1173
|
|
|
1174
|
+
<!-- prettier-ignore -->
|
|
195
1175
|
```ts
|
|
196
1176
|
// Shader logic materializes through method chaining
|
|
197
1177
|
const fragment = vec4(fract(position.xy.div(iResolution)), 0, 1)
|
|
198
|
-
|
|
199
|
-
|
|
1178
|
+
.mul(uniform(brightness))
|
|
1179
|
+
.mix(texture(backgroundMap, uv()), blend)
|
|
200
1180
|
```
|
|
201
1181
|
|
|
202
1182
|
The system operates through proxy objects that capture mathematical operations
|
|
@@ -208,6 +1188,7 @@ between shader compilation and runtime execution.
|
|
|
208
1188
|
|
|
209
1189
|
Traditional shader types dissolve into factory functions that generate node proxies:
|
|
210
1190
|
|
|
1191
|
+
<!-- prettier-ignore -->
|
|
211
1192
|
```ts
|
|
212
1193
|
// Types emerge from function calls rather than declarations
|
|
213
1194
|
const position = vec3(x, y, z) // Becomes position node
|
|
@@ -222,13 +1203,14 @@ building computation graphs that exist independently of their eventual compilati
|
|
|
222
1203
|
|
|
223
1204
|
The `Fn` constructor dissolves function boundaries, creating reusable computation patterns:
|
|
224
1205
|
|
|
1206
|
+
<!-- prettier-ignore -->
|
|
225
1207
|
```ts
|
|
226
1208
|
// Functions exist as first-class node compositions
|
|
227
1209
|
const noise = Fn(([coord]) => {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
1210
|
+
return sin(coord.x.mul(12.9898))
|
|
1211
|
+
.add(sin(coord.y.mul(78.233)))
|
|
1212
|
+
.mul(43758.5453)
|
|
1213
|
+
.fract()
|
|
232
1214
|
})
|
|
233
1215
|
|
|
234
1216
|
// Composition becomes transparent
|
|
@@ -239,17 +1221,18 @@ const surface = noise(position.xz.mul(scale)).mix(noise(position.xz.mul(scale.mu
|
|
|
239
1221
|
|
|
240
1222
|
Traditional control structures become node compositions, eliminating imperative sequence:
|
|
241
1223
|
|
|
1224
|
+
<!-- prettier-ignore -->
|
|
242
1225
|
```ts
|
|
243
1226
|
// Conditional logic as expression trees
|
|
244
1227
|
If(height.greaterThan(waterLevel), () => {
|
|
245
|
-
|
|
1228
|
+
return grassTexture.sample(worldUV)
|
|
246
1229
|
}).Else(() => {
|
|
247
|
-
|
|
1230
|
+
return waterTexture.sample(worldUV.add(wave))
|
|
248
1231
|
})
|
|
249
1232
|
|
|
250
1233
|
// Loops decompose into iteration patterns
|
|
251
1234
|
Loop(samples, ({ i }) => {
|
|
252
|
-
|
|
1235
|
+
accumulator.assign(accumulator.add(sample(position.add(offsets.element(i)))))
|
|
253
1236
|
})
|
|
254
1237
|
```
|
|
255
1238
|
|
|
@@ -257,6 +1240,7 @@ Loop(samples, ({ i }) => {
|
|
|
257
1240
|
|
|
258
1241
|
Uniforms transcend static parameter passing, becoming reactive data channels:
|
|
259
1242
|
|
|
1243
|
+
<!-- prettier-ignore -->
|
|
260
1244
|
```ts
|
|
261
1245
|
const time = uniform(0) // Creates reactive binding
|
|
262
1246
|
const amplitude = uniform(1) // Automatic GPU synchronization
|
|
@@ -272,6 +1256,7 @@ time.value = performance.now() / 1000
|
|
|
272
1256
|
|
|
273
1257
|
Vertex attributes dissolve into data stream abstractions:
|
|
274
1258
|
|
|
1259
|
+
<!-- prettier-ignore -->
|
|
275
1260
|
```ts
|
|
276
1261
|
// Attributes become typed data channels
|
|
277
1262
|
const positions = attribute(vertexData) // Raw data binding
|
|
@@ -290,3 +1275,6 @@ const viewNormal = normals.transform(normalMatrix)
|
|
|
290
1275
|
## LICENSE
|
|
291
1276
|
|
|
292
1277
|
###### MIT⚾️
|
|
1278
|
+
|
|
1279
|
+
</samp>
|
|
1280
|
+
</strong>
|