@multiplekex/shallot 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/package.json +1 -1
  2. package/src/core/component.ts +1 -1
  3. package/src/core/index.ts +1 -13
  4. package/src/core/math.ts +186 -0
  5. package/src/core/state.ts +1 -1
  6. package/src/core/xml.ts +56 -41
  7. package/src/extras/arrows/index.ts +3 -3
  8. package/src/extras/caustic.ts +37 -0
  9. package/src/extras/gradient/index.ts +63 -69
  10. package/src/extras/index.ts +3 -0
  11. package/src/extras/lines/index.ts +3 -3
  12. package/src/extras/orbit/index.ts +1 -1
  13. package/src/extras/skylab/index.ts +314 -0
  14. package/src/extras/text/font.ts +69 -14
  15. package/src/extras/text/index.ts +17 -69
  16. package/src/extras/text/sdf.ts +13 -2
  17. package/src/extras/water/index.ts +119 -0
  18. package/src/standard/defaults.ts +2 -0
  19. package/src/standard/index.ts +2 -0
  20. package/src/standard/raster/batch.ts +149 -0
  21. package/src/standard/raster/forward.ts +832 -0
  22. package/src/standard/raster/index.ts +191 -0
  23. package/src/standard/raster/shadow.ts +408 -0
  24. package/src/standard/{render → raytracing}/bvh/blas.ts +336 -88
  25. package/src/standard/raytracing/bvh/radix.ts +473 -0
  26. package/src/standard/raytracing/bvh/refit.ts +711 -0
  27. package/src/standard/{render → raytracing}/bvh/structs.ts +0 -55
  28. package/src/standard/{render → raytracing}/bvh/tlas.ts +155 -140
  29. package/src/standard/{render → raytracing}/bvh/traverse.ts +72 -64
  30. package/src/standard/{render → raytracing}/depth.ts +9 -9
  31. package/src/standard/raytracing/index.ts +409 -0
  32. package/src/standard/{render → raytracing}/instance.ts +31 -16
  33. package/src/standard/{render → raytracing}/ray.ts +1 -1
  34. package/src/standard/raytracing/shaders.ts +798 -0
  35. package/src/standard/{render → raytracing}/triangle.ts +1 -1
  36. package/src/standard/render/camera.ts +96 -106
  37. package/src/standard/render/data.ts +1 -1
  38. package/src/standard/render/index.ts +136 -220
  39. package/src/standard/render/indirect.ts +9 -10
  40. package/src/standard/render/light.ts +2 -2
  41. package/src/standard/render/mesh.ts +404 -0
  42. package/src/standard/render/overlay.ts +8 -5
  43. package/src/standard/render/pass.ts +1 -1
  44. package/src/standard/render/postprocess.ts +263 -242
  45. package/src/standard/render/scene.ts +28 -16
  46. package/src/standard/render/surface/index.ts +81 -12
  47. package/src/standard/render/surface/shaders.ts +511 -0
  48. package/src/standard/render/surface/structs.ts +23 -6
  49. package/src/standard/tween/tween.ts +44 -115
  50. package/src/standard/render/bvh/radix.ts +0 -476
  51. package/src/standard/render/forward/index.ts +0 -259
  52. package/src/standard/render/forward/raster.ts +0 -228
  53. package/src/standard/render/mesh/box.ts +0 -20
  54. package/src/standard/render/mesh/index.ts +0 -446
  55. package/src/standard/render/mesh/plane.ts +0 -11
  56. package/src/standard/render/mesh/sphere.ts +0 -40
  57. package/src/standard/render/mesh/unified.ts +0 -96
  58. package/src/standard/render/shaders.ts +0 -484
  59. package/src/standard/render/surface/compile.ts +0 -67
  60. package/src/standard/render/surface/noise.ts +0 -45
  61. package/src/standard/render/surface/wgsl.ts +0 -573
  62. /package/src/standard/{render → raytracing}/intersection.ts +0 -0
@@ -3,12 +3,10 @@ import type { Plugin, State, System } from "../../core";
3
3
  import { MAX_ENTITIES, resource } from "../../core";
4
4
  import { Canvas, Compute, ComputePlugin } from "../compute";
5
5
  import { WorldTransform } from "../transforms";
6
- import { Activity } from "../activity";
7
6
  import {
8
7
  Camera,
9
8
  Tonemap,
10
9
  FXAA,
11
- Raytracing,
12
10
  Vignette,
13
11
  Bloom,
14
12
  Quantize,
@@ -23,8 +21,36 @@ import {
23
21
  Sun,
24
22
  Viewport,
25
23
  uploadCamera,
24
+ uploadSky,
26
25
  } from "./camera";
27
26
  import { AmbientLight, DirectionalLight, packLightUniforms } from "./light";
27
+
28
+ export interface ShadowSettingsProvider {
29
+ softness: number[];
30
+ samples: number[];
31
+ isActive: (state: State, eid: number) => boolean;
32
+ }
33
+
34
+ const shadowSettingsProviders: ShadowSettingsProvider[] = [];
35
+
36
+ export function registerShadowSettings(settings: ShadowSettingsProvider): void {
37
+ shadowSettingsProviders.push(settings);
38
+ }
39
+
40
+ export function getShadowSettings(
41
+ state: State,
42
+ eid: number
43
+ ): { softness: number; samples: number } {
44
+ for (const provider of shadowSettingsProviders) {
45
+ if (provider.isActive(state, eid)) {
46
+ return {
47
+ softness: provider.softness[eid] ?? 0,
48
+ samples: Math.max(1, provider.samples[eid] ?? 16),
49
+ };
50
+ }
51
+ }
52
+ return { softness: 0, samples: 16 };
53
+ }
28
54
  import {
29
55
  Mesh,
30
56
  MeshShapes,
@@ -33,35 +59,21 @@ import {
33
59
  MeshPBR,
34
60
  MeshEmission,
35
61
  MeshVolumes,
36
- collectBatches,
37
- updateBatches,
38
- MAX_BATCH_SLOTS,
39
- type Batch,
40
- type MeshBuffers,
41
- type BatchEntities,
42
62
  createShapeAtlas,
63
+ getMeshVersion,
43
64
  } from "./mesh";
44
- import { Surface, SurfaceIds, SurfaceType, getDefaultAllSurfaces } from "./surface";
45
- import { createSceneBuffer, ensureTextures } from "./scene";
46
- import { createIndirectBuffer } from "./indirect";
47
- import { createForwardNode } from "./forward";
48
- import { createDepthConvertNode } from "./depth";
65
+ import { Surface, SurfaceIds } from "./surface";
66
+ import { createSceneBuffer, createSkyBuffer, ensureTextures } from "./scene";
49
67
  import { createPostProcessNode, type PostProcessUniforms } from "./postprocess";
50
68
  import { createOverlayNode } from "./overlay";
51
69
  import { Draws } from "./pass";
52
- import { createBLASAtlas, type BLASAtlas } from "./bvh/blas";
53
- import { createTLASBuffers, createTLASNode, type TLASBuffers } from "./bvh/tlas";
54
- import { getMesh } from "./mesh";
55
- import { createInstanceNode } from "./instance";
56
70
  import { createDataNode } from "./data";
57
71
 
58
72
  export {
59
73
  Camera,
60
74
  CameraMode,
61
- RenderMode,
62
75
  Tonemap,
63
76
  FXAA,
64
- Raytracing,
65
77
  Vignette,
66
78
  Bloom,
67
79
  Quantize,
@@ -75,42 +87,58 @@ export {
75
87
  Clouds,
76
88
  Sun,
77
89
  Viewport,
90
+ getClearColor,
91
+ hasSkyComponent,
92
+ uploadSky,
78
93
  } from "./camera";
79
94
  export { AmbientLight, DirectionalLight } from "./light";
80
- export { Mesh, MeshShape, Volume, mesh, getMesh, clearMeshes } from "./mesh";
81
- export { createBox } from "./mesh/box";
82
- export { createSphere } from "./mesh/sphere";
83
- export { createPlane } from "./mesh/plane";
84
- export type { MeshData } from "./mesh";
95
+ export {
96
+ Mesh,
97
+ MeshShape,
98
+ Volume,
99
+ mesh,
100
+ getMesh,
101
+ getMeshByName,
102
+ getMeshVersion,
103
+ meshCount,
104
+ clearMeshes,
105
+ computeShapeAABB,
106
+ createBox,
107
+ createSphere,
108
+ createPlane,
109
+ } from "./mesh";
110
+ export type { MeshData, AABB } from "./mesh";
85
111
  export { Surface, SurfaceType } from "./surface";
86
112
 
87
- export { surface, compose } from "./surface";
113
+ export { surface, getSurfaceByName, compose } from "./surface";
88
114
  export type { SurfaceData } from "./surface";
89
115
 
90
116
  export { Pass, registerDraw, unregisterDraw, getDrawsByPass, Draws } from "./pass";
91
117
  export type { Draw, DrawContext, SharedPassContext } from "./pass";
92
- export { createForwardNode, compileRasterShader, compileRTShader } from "./forward";
93
- export type { ForwardConfig, ForwardNode } from "./forward";
94
- export { createDepthConvertNode } from "./depth";
95
118
  export { createPostProcessNode } from "./postprocess";
96
119
  export type { PostProcessUniforms } from "./postprocess";
97
120
  export { createOverlayNode } from "./overlay";
98
-
99
- const EntityIds = {
100
- data: new Uint32Array(MAX_ENTITIES),
101
- };
121
+ export { COLOR_FORMAT } from "./scene";
102
122
 
103
123
  const countBuffer = new Uint32Array(1);
124
+ const time = new Float32Array(1);
125
+ const ambientData = { color: 0x888888, intensity: 1.0 };
126
+ const directionalData = {
127
+ color: 0xffffff,
128
+ intensity: 1.0,
129
+ directionX: -0.5,
130
+ directionY: -1.0,
131
+ directionZ: -0.5,
132
+ };
104
133
 
105
134
  export interface Render {
106
135
  width: number;
107
136
  height: number;
108
137
  entityCount: number;
138
+ meshVersion: number;
109
139
  scene: GPUBuffer;
140
+ sky: GPUBuffer;
110
141
  matrices: GPUBuffer;
111
- }
112
-
113
- interface RenderState extends Render {
114
142
  colors: GPUBuffer;
115
143
  sizes: GPUBuffer;
116
144
  pbr: GPUBuffer;
@@ -118,34 +146,21 @@ interface RenderState extends Render {
118
146
  shapes: GPUBuffer;
119
147
  surfaces: GPUBuffer;
120
148
  data: GPUBuffer;
121
- indirect: GPUBuffer;
122
- batches: (Batch | null)[];
123
- batchEntities: BatchEntities;
124
- buffers: Map<number, MeshBuffers>;
125
- postProcess: PostProcessUniforms;
149
+ entityCountBuffer: GPUBuffer;
126
150
  meshVertices: GPUBuffer;
127
151
  meshIndices: GPUBuffer;
128
152
  meshMeta: GPUBuffer;
129
- blasAtlas: BLASAtlas;
130
- instanceAABBs: GPUBuffer;
131
- instanceInverses: GPUBuffer;
132
- entityCountBuffer: GPUBuffer;
133
- instanceCount: GPUBuffer;
134
- tlas: TLASBuffers;
153
+ postProcess: PostProcessUniforms;
135
154
  }
136
155
 
137
156
  export const Render = resource<Render>("render");
138
157
 
139
- function getRenderState(state: State): RenderState | undefined {
140
- return Render.from(state) as RenderState | undefined;
141
- }
142
-
143
158
  const RenderSystem: System = {
144
159
  group: "draw",
145
160
  first: true,
146
161
 
147
162
  update(state: State) {
148
- const render = getRenderState(state);
163
+ const render = Render.from(state);
149
164
  const compute = Compute.from(state);
150
165
  const canvas = Canvas.from(state);
151
166
  if (!render || !compute || !canvas) return;
@@ -190,14 +205,33 @@ const RenderSystem: System = {
190
205
  resources.textureViews
191
206
  );
192
207
 
208
+ const currentMeshVersion = getMeshVersion();
209
+ if (currentMeshVersion !== render.meshVersion) {
210
+ render.meshVertices.destroy();
211
+ render.meshIndices.destroy();
212
+ render.meshMeta.destroy();
213
+ const shapeAtlas = createShapeAtlas(device);
214
+ render.meshVertices = shapeAtlas.vertices;
215
+ render.meshIndices = shapeAtlas.indices;
216
+ render.meshMeta = shapeAtlas.meta;
217
+ render.meshVersion = currentMeshVersion;
218
+ }
219
+
193
220
  render.entityCount = state.maxEid + 1;
194
221
  const uploadCount = render.entityCount;
195
222
 
196
223
  for (const eid of state.query([Camera])) {
197
224
  if (Camera.active[eid]) {
198
225
  const hasShadows = state.hasComponent(eid, Shadows);
199
- const shadowSoftness = hasShadows ? Shadows.softness[eid] : 0;
200
- const shadowSamples = hasShadows ? Math.max(1, Shadows.samples[eid]) : 0;
226
+
227
+ let shadowSoftness = 0;
228
+ let shadowSamples = 0;
229
+
230
+ if (hasShadows) {
231
+ const shadowSettings = getShadowSettings(state, eid);
232
+ shadowSoftness = shadowSettings.softness;
233
+ shadowSamples = shadowSettings.samples;
234
+ }
201
235
 
202
236
  const hasReflections = state.hasComponent(eid, Reflections);
203
237
  const reflectionDepth = hasReflections
@@ -212,54 +246,54 @@ const RenderSystem: System = {
212
246
  const hasHaze = state.hasComponent(eid, Haze);
213
247
  const hazeParams = hasHaze
214
248
  ? {
215
- density: Haze.density[eid],
216
- color: Haze.color[eid],
217
- }
249
+ density: Haze.density[eid],
250
+ color: Haze.color[eid],
251
+ }
218
252
  : undefined;
219
253
 
220
254
  const hasSky = state.hasComponent(eid, Sky);
221
255
  const skyParams = hasSky
222
256
  ? {
223
- zenith: Sky.zenith[eid],
224
- horizon: Sky.horizon[eid],
225
- }
257
+ zenith: Sky.zenith[eid],
258
+ horizon: Sky.horizon[eid],
259
+ }
226
260
  : undefined;
227
261
 
228
262
  const hasMoon = state.hasComponent(eid, Moon);
229
263
  const moonParams = hasMoon
230
264
  ? {
231
- phase: Moon.phase[eid],
232
- glow: Moon.glow[eid],
233
- azimuth: Moon.azimuth[eid],
234
- elevation: Moon.elevation[eid],
235
- }
265
+ phase: Moon.phase[eid],
266
+ glow: Moon.glow[eid],
267
+ azimuth: Moon.azimuth[eid],
268
+ elevation: Moon.elevation[eid],
269
+ }
236
270
  : undefined;
237
271
 
238
272
  const hasStars = state.hasComponent(eid, Stars);
239
273
  const starsParams = hasStars
240
274
  ? {
241
- intensity: Stars.intensity[eid],
242
- amount: Stars.amount[eid],
243
- }
275
+ intensity: Stars.intensity[eid],
276
+ amount: Stars.amount[eid],
277
+ }
244
278
  : undefined;
245
279
 
246
280
  const hasClouds = state.hasComponent(eid, Clouds);
247
281
  const cloudsParams = hasClouds
248
282
  ? {
249
- coverage: Clouds.coverage[eid],
250
- density: Clouds.density[eid],
251
- height: Clouds.height[eid],
252
- color: Clouds.color[eid],
253
- }
283
+ coverage: Clouds.coverage[eid],
284
+ density: Clouds.density[eid],
285
+ height: Clouds.height[eid],
286
+ color: Clouds.color[eid],
287
+ }
254
288
  : undefined;
255
289
 
256
290
  const hasSun = state.hasComponent(eid, Sun);
257
291
  const sunParams = hasSun
258
292
  ? {
259
- size: Sun.size[eid],
260
- glow: Sun.glow[eid],
261
- color: Sun.color[eid],
262
- }
293
+ size: Sun.size[eid],
294
+ glow: Sun.glow[eid],
295
+ color: Sun.color[eid],
296
+ }
263
297
  : undefined;
264
298
 
265
299
  uploadCamera(
@@ -272,7 +306,15 @@ const RenderSystem: System = {
272
306
  shadowSamples,
273
307
  reflectionDepth,
274
308
  refractionDepth,
275
- uploadCount,
309
+ uploadCount
310
+ );
311
+
312
+ time[0] = state.time.elapsed;
313
+ device.queue.writeBuffer(render.scene, 240, time);
314
+
315
+ uploadSky(
316
+ device,
317
+ render.sky,
276
318
  hazeParams,
277
319
  skyParams,
278
320
  moonParams,
@@ -311,31 +353,26 @@ const RenderSystem: System = {
311
353
  }
312
354
  }
313
355
 
314
- let ambientData = { color: 0x888888, intensity: 1.0 };
315
- let directionalData = {
316
- color: 0xffffff,
317
- intensity: 1.0,
318
- directionX: -0.5,
319
- directionY: -1.0,
320
- directionZ: -0.5,
321
- };
356
+ ambientData.color = 0x888888;
357
+ ambientData.intensity = 1.0;
358
+ directionalData.color = 0xffffff;
359
+ directionalData.intensity = 1.0;
360
+ directionalData.directionX = -0.5;
361
+ directionalData.directionY = -1.0;
362
+ directionalData.directionZ = -0.5;
322
363
 
323
364
  for (const eid of state.query([AmbientLight])) {
324
- ambientData = {
325
- color: AmbientLight.color[eid],
326
- intensity: AmbientLight.intensity[eid],
327
- };
365
+ ambientData.color = AmbientLight.color[eid];
366
+ ambientData.intensity = AmbientLight.intensity[eid];
328
367
  break;
329
368
  }
330
369
 
331
370
  for (const eid of state.query([DirectionalLight])) {
332
- directionalData = {
333
- color: DirectionalLight.color[eid],
334
- intensity: DirectionalLight.intensity[eid],
335
- directionX: DirectionalLight.directionX[eid],
336
- directionY: DirectionalLight.directionY[eid],
337
- directionZ: DirectionalLight.directionZ[eid],
338
- };
371
+ directionalData.color = DirectionalLight.color[eid];
372
+ directionalData.intensity = DirectionalLight.intensity[eid];
373
+ directionalData.directionX = DirectionalLight.directionX[eid];
374
+ directionalData.directionY = DirectionalLight.directionY[eid];
375
+ directionalData.directionZ = DirectionalLight.directionZ[eid];
339
376
  break;
340
377
  }
341
378
 
@@ -350,7 +387,6 @@ const RenderSystem: System = {
350
387
  uploadCount * 16
351
388
  );
352
389
 
353
- const meshEntities = state.query([Mesh, WorldTransform]);
354
390
  device.queue.writeBuffer(render.colors, 0, MeshColors.data, 0, uploadCount * 4);
355
391
  device.queue.writeBuffer(render.sizes, 0, MeshSizes.data, 0, uploadCount * 4);
356
392
  device.queue.writeBuffer(render.pbr, 0, MeshPBR.data, 0, uploadCount * 4);
@@ -359,21 +395,6 @@ const RenderSystem: System = {
359
395
  countBuffer[0] = uploadCount;
360
396
  device.queue.writeBuffer(render.entityCountBuffer, 0, countBuffer);
361
397
 
362
- let meshCount = 0;
363
- for (const eid of meshEntities) {
364
- EntityIds.data[meshCount] = eid;
365
- meshCount++;
366
- }
367
- device.queue.writeBuffer(
368
- render.tlas.entityIds,
369
- 0,
370
- EntityIds.data,
371
- 0,
372
- Math.max(meshCount, 1)
373
- );
374
- countBuffer[0] = meshCount;
375
- device.queue.writeBuffer(render.instanceCount, 0, countBuffer);
376
-
377
398
  for (const eid of state.query([Surface])) {
378
399
  const surfaceType = Surface.type[eid] & 0xff;
379
400
  const volume = (MeshVolumes.data[eid] ?? 0) & 0xf;
@@ -381,13 +402,6 @@ const RenderSystem: System = {
381
402
  SurfaceIds.data[eid] = surfaceType | (volume << 8) | (shapeId << 16);
382
403
  }
383
404
  device.queue.writeBuffer(render.surfaces, 0, SurfaceIds.data, 0, uploadCount);
384
-
385
- collectBatches(
386
- meshEntities,
387
- (eid) => Surface.type[eid] ?? SurfaceType.Default,
388
- render.batchEntities
389
- );
390
- updateBatches(device, render.batchEntities, render, render.indirect);
391
405
  },
392
406
  };
393
407
 
@@ -410,7 +424,6 @@ export const RenderPlugin: Plugin = {
410
424
  DirectionalLight,
411
425
  Tonemap,
412
426
  FXAA,
413
- Raytracing,
414
427
  Vignette,
415
428
  Bloom,
416
429
  Quantize,
@@ -441,10 +454,10 @@ export const RenderPlugin: Plugin = {
441
454
  });
442
455
 
443
456
  const shapeAtlas = createShapeAtlas(device);
444
- const blasAtlas = createBLASAtlas(device, getMesh);
445
457
 
446
- const renderState: RenderState = {
458
+ const renderState: Render = {
447
459
  scene: createSceneBuffer(device),
460
+ sky: createSkyBuffer(device),
448
461
  matrices: createPropertyBuffer(MAX_ENTITIES * 64, "matrices"),
449
462
  colors: createPropertyBuffer(MAX_ENTITIES * 16, "colors"),
450
463
  sizes: createPropertyBuffer(MAX_ENTITIES * 16, "sizes"),
@@ -453,11 +466,8 @@ export const RenderPlugin: Plugin = {
453
466
  shapes: createPropertyBuffer(MAX_ENTITIES * 4, "shapes"),
454
467
  surfaces: createPropertyBuffer(MAX_ENTITIES * 4, "surfaces"),
455
468
  data: createPropertyBuffer(MAX_ENTITIES * 64, "data"),
456
- indirect: createIndirectBuffer(device, MAX_BATCH_SLOTS),
457
- batches: Array(MAX_BATCH_SLOTS).fill(null),
458
- batchEntities: Array(MAX_BATCH_SLOTS).fill(null),
459
- buffers: new Map(),
460
469
  entityCount: 1,
470
+ meshVersion: getMeshVersion(),
461
471
  postProcess: {
462
472
  tonemap: false,
463
473
  exposure: 1.0,
@@ -473,20 +483,11 @@ export const RenderPlugin: Plugin = {
473
483
  meshVertices: shapeAtlas.vertices,
474
484
  meshIndices: shapeAtlas.indices,
475
485
  meshMeta: shapeAtlas.meta,
476
- blasAtlas,
477
- instanceAABBs: createPropertyBuffer(MAX_ENTITIES * 32, "instanceAABBs"),
478
- instanceInverses: createPropertyBuffer(MAX_ENTITIES * 64, "instanceInverses"),
479
486
  entityCountBuffer: device.createBuffer({
480
487
  label: "entityCount",
481
488
  size: 4,
482
489
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
483
490
  }),
484
- instanceCount: device.createBuffer({
485
- label: "instanceCount",
486
- size: 4,
487
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
488
- }),
489
- tlas: createTLASBuffers(device),
490
491
  width: 0,
491
492
  height: 0,
492
493
  };
@@ -498,18 +499,6 @@ export const RenderPlugin: Plugin = {
498
499
  };
499
500
  state.setResource(Draws, drawState);
500
501
 
501
- const instanceNode = createInstanceNode({
502
- matrices: renderState.matrices,
503
- sizes: renderState.sizes,
504
- shapes: renderState.shapes,
505
- shapeAABBs: renderState.blasAtlas.shapeAABBs,
506
- entityCount: renderState.entityCountBuffer,
507
- instanceAABBs: renderState.instanceAABBs,
508
- instanceInverses: renderState.instanceInverses,
509
- getEntityCount: () => renderState.entityCount,
510
- });
511
- compute.graph.add(instanceNode);
512
-
513
502
  const dataNode = createDataNode({
514
503
  colors: renderState.colors,
515
504
  pbr: renderState.pbr,
@@ -521,79 +510,6 @@ export const RenderPlugin: Plugin = {
521
510
  });
522
511
  compute.graph.add(dataNode);
523
512
 
524
- const tlasNode = createTLASNode({
525
- instanceAABBs: renderState.instanceAABBs,
526
- instanceCount: renderState.instanceCount,
527
- tlas: renderState.tlas,
528
- getEntityCount: () => renderState.entityCount,
529
- });
530
- compute.graph.add(tlasNode);
531
-
532
- const getRaytracing = () => {
533
- for (const eid of state.query([Camera])) {
534
- if (Camera.active[eid]) {
535
- return state.hasComponent(eid, Raytracing);
536
- }
537
- }
538
- return false;
539
- };
540
-
541
- const getClearColor = () => {
542
- for (const eid of state.query([Camera])) {
543
- if (Camera.active[eid]) {
544
- const packed = Camera.clearColor[eid];
545
- return {
546
- r: ((packed >> 16) & 0xff) / 255,
547
- g: ((packed >> 8) & 0xff) / 255,
548
- b: (packed & 0xff) / 255,
549
- };
550
- }
551
- }
552
- return { r: 0, g: 0, b: 0 };
553
- };
554
-
555
- const getSky = () => {
556
- for (const eid of state.query([Camera])) {
557
- if (Camera.active[eid]) {
558
- return state.hasComponent(eid, Sky);
559
- }
560
- }
561
- return false;
562
- };
563
-
564
- const forwardNode = createForwardNode({
565
- scene: renderState.scene,
566
- matrices: renderState.matrices,
567
- colors: renderState.colors,
568
- sizes: renderState.sizes,
569
- pbr: renderState.pbr,
570
- emission: renderState.emission,
571
- shapes: renderState.shapes,
572
- surfaces: renderState.surfaces,
573
- data: renderState.data,
574
- getSurfaces: getDefaultAllSurfaces,
575
- getRaytracing,
576
- getClearColor,
577
- getSky,
578
- acquire: (message) => Activity.from(state)?.acquire(message),
579
- batches: () => renderState.batches,
580
- tlasNodes: renderState.tlas.bvhNodes,
581
- tlasInstanceIds: renderState.tlas.instanceIds,
582
- blasNodes: renderState.blasAtlas.nodesBuffer,
583
- blasTriIds: renderState.blasAtlas.triIdsBuffer,
584
- blasTriangles: renderState.blasAtlas.trianglesBuffer,
585
- blasMeta: renderState.blasAtlas.metaBuffer,
586
- instanceInverses: renderState.instanceInverses,
587
- });
588
- compute.graph.add(forwardNode);
589
-
590
- compute.graph.add(
591
- createDepthConvertNode({
592
- scene: renderState.scene,
593
- getRaytracing,
594
- })
595
- );
596
-
597
513
  compute.graph.add(createOverlayNode({ state }));
598
514
 
599
515
  compute.graph.add(
@@ -20,21 +20,20 @@ export function createIndirectBuffer(device: GPUDevice, slotCount: number): GPUB
20
20
  });
21
21
  }
22
22
 
23
+ const indirectData = new ArrayBuffer(INDIRECT_SIZE);
24
+ const indirectView = new DataView(indirectData);
25
+
23
26
  export function writeIndirect(
24
27
  device: GPUDevice,
25
28
  buffer: GPUBuffer,
26
29
  slot: number,
27
30
  args: IndirectArgs
28
31
  ): void {
29
- const offset = slot * INDIRECT_SIZE;
30
- const data = new ArrayBuffer(INDIRECT_SIZE);
31
- const view = new DataView(data);
32
-
33
- view.setUint32(0, args.indexCount, true);
34
- view.setUint32(4, args.instanceCount, true);
35
- view.setUint32(8, args.firstIndex, true);
36
- view.setInt32(12, args.baseVertex, true);
37
- view.setUint32(16, args.firstInstance, true);
32
+ indirectView.setUint32(0, args.indexCount, true);
33
+ indirectView.setUint32(4, args.instanceCount, true);
34
+ indirectView.setUint32(8, args.firstIndex, true);
35
+ indirectView.setInt32(12, args.baseVertex, true);
36
+ indirectView.setUint32(16, args.firstInstance, true);
38
37
 
39
- device.queue.writeBuffer(buffer, offset, data);
38
+ device.queue.writeBuffer(buffer, slot * INDIRECT_SIZE, indirectData);
40
39
  }
@@ -36,12 +36,12 @@ export function normalizeDirection(x: number, y: number, z: number): [number, nu
36
36
  return [x / len, y / len, z / len];
37
37
  }
38
38
 
39
- export interface AmbientLightData {
39
+ interface AmbientLightData {
40
40
  color: number;
41
41
  intensity: number;
42
42
  }
43
43
 
44
- export interface DirectionalLightData {
44
+ interface DirectionalLightData {
45
45
  color: number;
46
46
  intensity: number;
47
47
  directionX: number;