@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
@@ -120,7 +120,6 @@ fn applyVignette(color: vec3f, uv: vec2f) -> vec3f {
120
120
 
121
121
  fn sampleBloom(uv: vec2f) -> vec3f {
122
122
  let texelSize = vec2f(uniforms.texelSizeX, uniforms.texelSizeY);
123
- // Normalize to reference height (1080p) for resolution-independent bloom
124
123
  let height = 1.0 / uniforms.texelSizeY;
125
124
  let resolutionScale = height / 1080.0;
126
125
  let spread = uniforms.bloomRadius * 4.0 * resolutionScale;
@@ -130,7 +129,6 @@ fn sampleBloom(uv: vec2f) -> vec3f {
130
129
  var bloom = vec3f(0.0);
131
130
  var totalWeight = 0.0;
132
131
 
133
- // 9x9 kernel with gaussian weights
134
132
  for (var y = -4; y <= 4; y++) {
135
133
  for (var x = -4; x <= 4; x++) {
136
134
  let offset = vec2f(f32(x), f32(y)) * texelSize * spread;
@@ -165,7 +163,6 @@ fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
165
163
  color = select(fxaaColor, color, maskValue >= 0.5);
166
164
  }
167
165
 
168
- // Bloom applied before tonemapping
169
166
  if (uniforms.flags & FLAG_BLOOM) != 0u {
170
167
  let bloom = sampleBloom(input.uv);
171
168
  color += bloom * uniforms.bloomIntensity;
@@ -244,12 +241,267 @@ export interface PostProcessConfig {
244
241
  getRenderSize?: () => { width: number; height: number };
245
242
  }
246
243
 
244
+ interface PostProcessGPU {
245
+ pipeline: GPURenderPipeline;
246
+ blitPipeline: GPURenderPipeline;
247
+ uniformBuffer: GPUBuffer;
248
+ uniformData: ArrayBuffer;
249
+ uniformFloats: Float32Array;
250
+ uniformUints: Uint32Array;
251
+ linearSampler: GPUSampler;
252
+ nearestSampler: GPUSampler;
253
+ }
254
+
255
+ interface PostProcessCache {
256
+ mainBindGroup: GPUBindGroup | null;
257
+ blitBindGroup: GPUBindGroup | null;
258
+ inputView: GPUTextureView | null;
259
+ sampler: GPUSampler | null;
260
+ maskView: GPUTextureView | null;
261
+ }
262
+
263
+ async function preparePostProcess(device: GPUDevice): Promise<PostProcessGPU> {
264
+ const format: GPUTextureFormat = "bgra8unorm";
265
+
266
+ const [mainModule, blitModule] = await Promise.all([
267
+ device.createShaderModule({ code: shader }),
268
+ device.createShaderModule({ code: blitShader }),
269
+ ]);
270
+
271
+ const [pipeline, blitPipeline] = await Promise.all([
272
+ device.createRenderPipelineAsync({
273
+ layout: "auto",
274
+ vertex: { module: mainModule, entryPoint: "vertexMain" },
275
+ fragment: {
276
+ module: mainModule,
277
+ entryPoint: "fragmentMain",
278
+ targets: [{ format }],
279
+ },
280
+ primitive: { topology: "triangle-list" },
281
+ }),
282
+ device.createRenderPipelineAsync({
283
+ layout: "auto",
284
+ vertex: { module: blitModule, entryPoint: "vertexMain" },
285
+ fragment: {
286
+ module: blitModule,
287
+ entryPoint: "fragmentMain",
288
+ targets: [{ format }],
289
+ },
290
+ primitive: { topology: "triangle-list" },
291
+ }),
292
+ ]);
293
+
294
+ const uniformData = new ArrayBuffer(48);
295
+
296
+ return {
297
+ pipeline,
298
+ blitPipeline,
299
+ uniformBuffer: device.createBuffer({
300
+ size: 48,
301
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
302
+ }),
303
+ uniformData,
304
+ uniformFloats: new Float32Array(uniformData),
305
+ uniformUints: new Uint32Array(uniformData),
306
+ linearSampler: device.createSampler({ magFilter: "linear", minFilter: "linear" }),
307
+ nearestSampler: device.createSampler({ magFilter: "nearest", minFilter: "nearest" }),
308
+ };
309
+ }
310
+
311
+ function blitToCanvas(
312
+ encoder: GPUCommandEncoder,
313
+ pipeline: GPURenderPipeline,
314
+ bindGroup: GPUBindGroup,
315
+ canvasView: GPUTextureView
316
+ ): void {
317
+ const pass = encoder.beginRenderPass({
318
+ colorAttachments: [
319
+ {
320
+ view: canvasView,
321
+ loadOp: "clear" as const,
322
+ storeOp: "store" as const,
323
+ clearValue: { r: 0, g: 0, b: 0, a: 1 },
324
+ },
325
+ ],
326
+ });
327
+ pass.setPipeline(pipeline);
328
+ pass.setBindGroup(0, bindGroup);
329
+ pass.draw(3);
330
+ pass.end();
331
+ }
332
+
333
+ function executeContributors(
334
+ contributors: { execute: (ctx: DrawContext) => void }[],
335
+ baseCtx: Omit<DrawContext, "inputView" | "outputView">,
336
+ pingAView: GPUTextureView,
337
+ pingBView: GPUTextureView,
338
+ currentInput: GPUTextureView,
339
+ pingPong: boolean
340
+ ): { currentInput: GPUTextureView; pingPong: boolean } {
341
+ for (const contributor of contributors) {
342
+ const currentOutput = pingPong ? pingAView : pingBView;
343
+ contributor.execute({
344
+ ...baseCtx,
345
+ inputView: currentInput,
346
+ outputView: currentOutput,
347
+ });
348
+ currentInput = currentOutput;
349
+ pingPong = !pingPong;
350
+ }
351
+ return { currentInput, pingPong };
352
+ }
353
+
354
+ function ensureBlitBindGroup(
355
+ device: GPUDevice,
356
+ gpu: PostProcessGPU,
357
+ cache: PostProcessCache,
358
+ inputView: GPUTextureView,
359
+ sampler: GPUSampler
360
+ ): GPUBindGroup {
361
+ if (inputView !== cache.inputView || sampler !== cache.sampler) {
362
+ cache.blitBindGroup = device.createBindGroup({
363
+ layout: gpu.blitPipeline.getBindGroupLayout(0),
364
+ entries: [
365
+ { binding: 0, resource: inputView },
366
+ { binding: 1, resource: sampler },
367
+ ],
368
+ });
369
+ cache.inputView = inputView;
370
+ cache.sampler = sampler;
371
+ }
372
+ return cache.blitBindGroup!;
373
+ }
374
+
375
+ function executePostProcess(
376
+ gpu: PostProcessGPU,
377
+ cache: PostProcessCache,
378
+ ctx: ExecutionContext,
379
+ config: PostProcessConfig
380
+ ): void {
381
+ const { device, encoder, canvasView, format, context } = ctx;
382
+ const width = context.canvas.width;
383
+ const height = context.canvas.height;
384
+ const colorView = ctx.getTextureView("color")!;
385
+ const maskView = ctx.getTextureView("mask")!;
386
+ const zView = ctx.getTextureView("z")!;
387
+ const eidView = ctx.getTextureView("eid")!;
388
+ const pingAView = ctx.getTextureView("pingA")!;
389
+ const pingBView = ctx.getTextureView("pingB")!;
390
+
391
+ const renderSize = config.getRenderSize?.();
392
+ const isUpscaling = renderSize && (renderSize.width !== width || renderSize.height !== height);
393
+ const sampler = isUpscaling ? gpu.nearestSampler : gpu.linearSampler;
394
+
395
+ let currentInput = colorView;
396
+ let pingPong = false;
397
+
398
+ const baseCtx = {
399
+ device,
400
+ encoder,
401
+ format,
402
+ width,
403
+ height,
404
+ sceneView: colorView,
405
+ zView,
406
+ entityIdView: eidView,
407
+ maskView,
408
+ canvasView,
409
+ };
410
+
411
+ const beforePostProcess = getDrawsByPass(config.state, Pass.BeforePost);
412
+ ({ currentInput, pingPong } = executeContributors(
413
+ beforePostProcess,
414
+ baseCtx,
415
+ pingAView,
416
+ pingBView,
417
+ currentInput,
418
+ pingPong
419
+ ));
420
+
421
+ const postProcessContributors = getDrawsByPass(config.state, Pass.Post);
422
+ const hasBuiltinEffects =
423
+ config.uniforms.tonemap ||
424
+ config.uniforms.fxaa ||
425
+ config.uniforms.vignetteStrength > 0 ||
426
+ config.uniforms.bloomIntensity > 0 ||
427
+ config.uniforms.quantize > 0;
428
+
429
+ if (hasBuiltinEffects || postProcessContributors.length > 0) {
430
+ ({ currentInput, pingPong } = executeContributors(
431
+ postProcessContributors,
432
+ baseCtx,
433
+ pingAView,
434
+ pingBView,
435
+ currentInput,
436
+ pingPong
437
+ ));
438
+
439
+ if (hasBuiltinEffects) {
440
+ let flags = 0;
441
+ if (config.uniforms.tonemap) flags |= FLAG_TONEMAP;
442
+ if (config.uniforms.fxaa) flags |= FLAG_FXAA;
443
+ if (config.uniforms.vignetteStrength > 0) flags |= FLAG_VIGNETTE;
444
+ if (config.uniforms.bloomIntensity > 0) flags |= FLAG_BLOOM;
445
+ if (config.uniforms.quantize > 0) flags |= FLAG_QUANTIZE;
446
+
447
+ gpu.uniformFloats[0] = config.uniforms.exposure;
448
+ gpu.uniformFloats[1] = config.uniforms.vignetteStrength;
449
+ gpu.uniformFloats[2] = config.uniforms.vignetteInner;
450
+ gpu.uniformFloats[3] = config.uniforms.vignetteOuter;
451
+ gpu.uniformFloats[4] = 1.0 / width;
452
+ gpu.uniformFloats[5] = 1.0 / height;
453
+ gpu.uniformUints[6] = flags;
454
+ gpu.uniformFloats[7] = config.uniforms.bloomIntensity;
455
+ gpu.uniformFloats[8] = config.uniforms.bloomThreshold;
456
+ gpu.uniformFloats[9] = config.uniforms.bloomRadius;
457
+ gpu.uniformFloats[10] = config.uniforms.quantize;
458
+
459
+ device.queue.writeBuffer(gpu.uniformBuffer, 0, gpu.uniformData);
460
+
461
+ if (
462
+ currentInput !== cache.inputView ||
463
+ sampler !== cache.sampler ||
464
+ maskView !== cache.maskView
465
+ ) {
466
+ cache.mainBindGroup = device.createBindGroup({
467
+ layout: gpu.pipeline.getBindGroupLayout(0),
468
+ entries: [
469
+ { binding: 0, resource: currentInput },
470
+ { binding: 1, resource: sampler },
471
+ { binding: 2, resource: { buffer: gpu.uniformBuffer } },
472
+ { binding: 3, resource: maskView },
473
+ ],
474
+ });
475
+ cache.inputView = currentInput;
476
+ cache.sampler = sampler;
477
+ cache.maskView = maskView;
478
+ }
479
+
480
+ blitToCanvas(encoder, gpu.pipeline, cache.mainBindGroup!, canvasView);
481
+ } else {
482
+ const bindGroup = ensureBlitBindGroup(device, gpu, cache, currentInput, sampler);
483
+ blitToCanvas(encoder, gpu.blitPipeline, bindGroup, canvasView);
484
+ }
485
+ } else {
486
+ const bindGroup = ensureBlitBindGroup(device, gpu, cache, currentInput, sampler);
487
+ blitToCanvas(encoder, gpu.blitPipeline, bindGroup, canvasView);
488
+ }
489
+
490
+ const afterPostProcess = getDrawsByPass(config.state, Pass.AfterPost);
491
+ for (const contributor of afterPostProcess) {
492
+ contributor.execute(baseCtx);
493
+ }
494
+ }
495
+
247
496
  export function createPostProcessNode(config: PostProcessConfig): ComputeNode {
248
- let pipeline: GPURenderPipeline | null = null;
249
- let blitPipeline: GPURenderPipeline | null = null;
250
- let uniformBuffer: GPUBuffer | null = null;
251
- let linearSampler: GPUSampler | null = null;
252
- let nearestSampler: GPUSampler | null = null;
497
+ let gpu: PostProcessGPU | null = null;
498
+ const cache: PostProcessCache = {
499
+ mainBindGroup: null,
500
+ blitBindGroup: null,
501
+ inputView: null,
502
+ sampler: null,
503
+ maskView: null,
504
+ };
253
505
 
254
506
  return {
255
507
  id: "postprocess",
@@ -262,243 +514,12 @@ export function createPostProcessNode(config: PostProcessConfig): ComputeNode {
262
514
  outputs: [{ id: "framebuffer", access: "write" }],
263
515
 
264
516
  async prepare(device: GPUDevice) {
265
- const format: GPUTextureFormat = "bgra8unorm";
266
-
267
- const [mainModule, blitModule] = await Promise.all([
268
- device.createShaderModule({ code: shader }),
269
- device.createShaderModule({ code: blitShader }),
270
- ]);
271
-
272
- [pipeline, blitPipeline] = await Promise.all([
273
- device.createRenderPipelineAsync({
274
- layout: "auto",
275
- vertex: { module: mainModule, entryPoint: "vertexMain" },
276
- fragment: {
277
- module: mainModule,
278
- entryPoint: "fragmentMain",
279
- targets: [{ format }],
280
- },
281
- primitive: { topology: "triangle-list" },
282
- }),
283
- device.createRenderPipelineAsync({
284
- layout: "auto",
285
- vertex: { module: blitModule, entryPoint: "vertexMain" },
286
- fragment: {
287
- module: blitModule,
288
- entryPoint: "fragmentMain",
289
- targets: [{ format }],
290
- },
291
- primitive: { topology: "triangle-list" },
292
- }),
293
- ]);
294
-
295
- uniformBuffer = device.createBuffer({
296
- size: 48,
297
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
298
- });
299
-
300
- linearSampler = device.createSampler({
301
- magFilter: "linear",
302
- minFilter: "linear",
303
- });
304
-
305
- nearestSampler = device.createSampler({
306
- magFilter: "nearest",
307
- minFilter: "nearest",
308
- });
517
+ gpu = await preparePostProcess(device);
309
518
  },
310
519
 
311
520
  execute(ctx: ExecutionContext) {
312
- const { device, encoder, canvasView, format, context } = ctx;
313
- const width = context.canvas.width;
314
- const height = context.canvas.height;
315
- const colorView = ctx.getTextureView("color")!;
316
- const maskView = ctx.getTextureView("mask")!;
317
- const depthView = ctx.getTextureView("depth")!;
318
- const eidView = ctx.getTextureView("eid")!;
319
- const pingAView = ctx.getTextureView("pingA")!;
320
- const pingBView = ctx.getTextureView("pingB")!;
321
-
322
- const renderSize = config.getRenderSize?.();
323
- const isUpscaling =
324
- renderSize && (renderSize.width !== width || renderSize.height !== height);
325
- const sampler = isUpscaling ? nearestSampler! : linearSampler!;
326
-
327
- let currentInput = colorView;
328
- let currentOutput = pingAView;
329
- let pingPong = false;
330
-
331
- const beforePostProcess = getDrawsByPass(config.state, Pass.BeforePost);
332
- for (const contributor of beforePostProcess) {
333
- const passCtx: DrawContext = {
334
- device,
335
- encoder,
336
- format,
337
- width,
338
- height,
339
- sceneView: colorView,
340
- depthView,
341
- entityIdView: eidView,
342
- maskView,
343
- canvasView,
344
- inputView: currentInput,
345
- outputView: currentOutput,
346
- };
347
- contributor.execute(passCtx);
348
-
349
- currentInput = currentOutput;
350
- currentOutput = pingPong ? pingAView : pingBView;
351
- pingPong = !pingPong;
352
- }
353
-
354
- const postProcessContributors = getDrawsByPass(config.state, Pass.Post);
355
- const hasBuiltinEffects =
356
- config.uniforms.tonemap ||
357
- config.uniforms.fxaa ||
358
- config.uniforms.vignetteStrength > 0 ||
359
- config.uniforms.bloomIntensity > 0 ||
360
- config.uniforms.quantize > 0;
361
-
362
- if (hasBuiltinEffects || postProcessContributors.length > 0) {
363
- for (const contributor of postProcessContributors) {
364
- const passCtx: DrawContext = {
365
- device,
366
- encoder,
367
- format,
368
- width,
369
- height,
370
- sceneView: colorView,
371
- depthView,
372
- entityIdView: eidView,
373
- maskView,
374
- canvasView,
375
- inputView: currentInput,
376
- outputView: currentOutput,
377
- };
378
- contributor.execute(passCtx);
379
-
380
- currentInput = currentOutput;
381
- currentOutput = pingPong ? pingAView : pingBView;
382
- pingPong = !pingPong;
383
- }
384
-
385
- if (hasBuiltinEffects) {
386
- let flags = 0;
387
- if (config.uniforms.tonemap) flags |= FLAG_TONEMAP;
388
- if (config.uniforms.fxaa) flags |= FLAG_FXAA;
389
- if (config.uniforms.vignetteStrength > 0) flags |= FLAG_VIGNETTE;
390
- if (config.uniforms.bloomIntensity > 0) flags |= FLAG_BLOOM;
391
- if (config.uniforms.quantize > 0) flags |= FLAG_QUANTIZE;
392
-
393
- const data = new ArrayBuffer(48);
394
- const floats = new Float32Array(data);
395
- const uints = new Uint32Array(data);
396
- floats[0] = config.uniforms.exposure;
397
- floats[1] = config.uniforms.vignetteStrength;
398
- floats[2] = config.uniforms.vignetteInner;
399
- floats[3] = config.uniforms.vignetteOuter;
400
- floats[4] = 1.0 / width;
401
- floats[5] = 1.0 / height;
402
- uints[6] = flags;
403
- floats[7] = config.uniforms.bloomIntensity;
404
- floats[8] = config.uniforms.bloomThreshold;
405
- floats[9] = config.uniforms.bloomRadius;
406
- floats[10] = config.uniforms.quantize;
407
-
408
- device.queue.writeBuffer(uniformBuffer!, 0, data);
409
-
410
- const bindGroup = device.createBindGroup({
411
- layout: pipeline!.getBindGroupLayout(0),
412
- entries: [
413
- { binding: 0, resource: currentInput },
414
- { binding: 1, resource: sampler },
415
- { binding: 2, resource: { buffer: uniformBuffer! } },
416
- { binding: 3, resource: maskView },
417
- ],
418
- });
419
-
420
- const pass = encoder.beginRenderPass({
421
- colorAttachments: [
422
- {
423
- view: canvasView,
424
- loadOp: "clear" as const,
425
- storeOp: "store" as const,
426
- clearValue: { r: 0, g: 0, b: 0, a: 1 },
427
- },
428
- ],
429
- });
430
-
431
- pass.setPipeline(pipeline!);
432
- pass.setBindGroup(0, bindGroup);
433
- pass.draw(3);
434
- pass.end();
435
- } else {
436
- const bindGroup = device.createBindGroup({
437
- layout: blitPipeline!.getBindGroupLayout(0),
438
- entries: [
439
- { binding: 0, resource: currentInput },
440
- { binding: 1, resource: sampler },
441
- ],
442
- });
443
-
444
- const pass = encoder.beginRenderPass({
445
- colorAttachments: [
446
- {
447
- view: canvasView,
448
- loadOp: "clear" as const,
449
- storeOp: "store" as const,
450
- clearValue: { r: 0, g: 0, b: 0, a: 1 },
451
- },
452
- ],
453
- });
454
-
455
- pass.setPipeline(blitPipeline!);
456
- pass.setBindGroup(0, bindGroup);
457
- pass.draw(3);
458
- pass.end();
459
- }
460
- } else {
461
- const bindGroup = device.createBindGroup({
462
- layout: blitPipeline!.getBindGroupLayout(0),
463
- entries: [
464
- { binding: 0, resource: currentInput },
465
- { binding: 1, resource: sampler },
466
- ],
467
- });
468
-
469
- const pass = encoder.beginRenderPass({
470
- colorAttachments: [
471
- {
472
- view: canvasView,
473
- loadOp: "clear" as const,
474
- storeOp: "store" as const,
475
- clearValue: { r: 0, g: 0, b: 0, a: 1 },
476
- },
477
- ],
478
- });
479
-
480
- pass.setPipeline(blitPipeline!);
481
- pass.setBindGroup(0, bindGroup);
482
- pass.draw(3);
483
- pass.end();
484
- }
485
-
486
- const afterPostProcess = getDrawsByPass(config.state, Pass.AfterPost);
487
- for (const contributor of afterPostProcess) {
488
- const passCtx: DrawContext = {
489
- device,
490
- encoder,
491
- format,
492
- width,
493
- height,
494
- sceneView: colorView,
495
- depthView,
496
- entityIdView: eidView,
497
- maskView,
498
- canvasView,
499
- };
500
- contributor.execute(passCtx);
501
- }
521
+ if (!gpu) return;
522
+ executePostProcess(gpu, cache, ctx, config);
502
523
  },
503
524
  };
504
525
  }
@@ -1,6 +1,7 @@
1
- export const SCENE_UNIFORM_SIZE = 512;
2
- export const DEPTH_FORMAT: GPUTextureFormat = "depth24plus";
3
- export const LINEAR_DEPTH_FORMAT: GPUTextureFormat = "r32float";
1
+ export const SCENE_UNIFORM_SIZE = 352;
2
+ export const SKY_UNIFORM_SIZE = 176;
3
+ export const Z_FORMAT: GPUTextureFormat = "depth24plus";
4
+ export const DEPTH_FORMAT: GPUTextureFormat = "r32float";
4
5
  export const MASK_FORMAT: GPUTextureFormat = "r8unorm";
5
6
  export const EID_FORMAT: GPUTextureFormat = "r32uint";
6
7
  export const COLOR_FORMAT: GPUTextureFormat = "rgba8unorm";
@@ -13,6 +14,14 @@ export function createSceneBuffer(device: GPUDevice): GPUBuffer {
13
14
  });
14
15
  }
15
16
 
17
+ export function createSkyBuffer(device: GPUDevice): GPUBuffer {
18
+ return device.createBuffer({
19
+ label: "sky",
20
+ size: SKY_UNIFORM_SIZE,
21
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
22
+ });
23
+ }
24
+
16
25
  export function ensureTextures(
17
26
  device: GPUDevice,
18
27
  format: GPUTextureFormat,
@@ -25,9 +34,9 @@ export function ensureTextures(
25
34
  if (existing && existing.width === width && existing.height === height) return;
26
35
 
27
36
  existing?.destroy();
28
- textures.get("linear-depth")?.destroy();
29
- textures.get("eid")?.destroy();
30
37
  textures.get("depth")?.destroy();
38
+ textures.get("eid")?.destroy();
39
+ textures.get("z")?.destroy();
31
40
  textures.get("mask")?.destroy();
32
41
  textures.get("pingA")?.destroy();
33
42
  textures.get("pingB")?.destroy();
@@ -42,11 +51,14 @@ export function ensureTextures(
42
51
  GPUTextureUsage.TEXTURE_BINDING,
43
52
  });
44
53
 
45
- const linearDepth = device.createTexture({
46
- label: "linear-depth",
54
+ const depth = device.createTexture({
55
+ label: "depth",
47
56
  size: { width, height },
48
- format: LINEAR_DEPTH_FORMAT,
49
- usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING,
57
+ format: DEPTH_FORMAT,
58
+ usage:
59
+ GPUTextureUsage.STORAGE_BINDING |
60
+ GPUTextureUsage.RENDER_ATTACHMENT |
61
+ GPUTextureUsage.TEXTURE_BINDING,
50
62
  });
51
63
 
52
64
  const eid = device.createTexture({
@@ -59,10 +71,10 @@ export function ensureTextures(
59
71
  GPUTextureUsage.TEXTURE_BINDING,
60
72
  });
61
73
 
62
- const depth = device.createTexture({
63
- label: "depth",
74
+ const z = device.createTexture({
75
+ label: "z",
64
76
  size: { width, height },
65
- format: DEPTH_FORMAT,
77
+ format: Z_FORMAT,
66
78
  usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
67
79
  });
68
80
 
@@ -89,12 +101,12 @@ export function ensureTextures(
89
101
 
90
102
  textures.set("color", color);
91
103
  textureViews.set("color", color.createView());
92
- textures.set("linear-depth", linearDepth);
93
- textureViews.set("linear-depth", linearDepth.createView());
94
- textures.set("eid", eid);
95
- textureViews.set("eid", eid.createView());
96
104
  textures.set("depth", depth);
97
105
  textureViews.set("depth", depth.createView());
106
+ textures.set("eid", eid);
107
+ textureViews.set("eid", eid.createView());
108
+ textures.set("z", z);
109
+ textureViews.set("z", z.createView());
98
110
  textures.set("mask", mask);
99
111
  textureViews.set("mask", mask.createView());
100
112
  textures.set("pingA", pingA);