@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.
- package/package.json +1 -1
- package/src/core/component.ts +1 -1
- package/src/core/index.ts +1 -13
- package/src/core/math.ts +186 -0
- package/src/core/state.ts +1 -1
- package/src/core/xml.ts +56 -41
- package/src/extras/arrows/index.ts +3 -3
- package/src/extras/caustic.ts +37 -0
- package/src/extras/gradient/index.ts +63 -69
- package/src/extras/index.ts +3 -0
- package/src/extras/lines/index.ts +3 -3
- package/src/extras/orbit/index.ts +1 -1
- package/src/extras/skylab/index.ts +314 -0
- package/src/extras/text/font.ts +69 -14
- package/src/extras/text/index.ts +17 -69
- package/src/extras/text/sdf.ts +13 -2
- package/src/extras/water/index.ts +119 -0
- package/src/standard/defaults.ts +2 -0
- package/src/standard/index.ts +2 -0
- package/src/standard/raster/batch.ts +149 -0
- package/src/standard/raster/forward.ts +832 -0
- package/src/standard/raster/index.ts +191 -0
- package/src/standard/raster/shadow.ts +408 -0
- package/src/standard/{render → raytracing}/bvh/blas.ts +336 -88
- package/src/standard/raytracing/bvh/radix.ts +473 -0
- package/src/standard/raytracing/bvh/refit.ts +711 -0
- package/src/standard/{render → raytracing}/bvh/structs.ts +0 -55
- package/src/standard/{render → raytracing}/bvh/tlas.ts +155 -140
- package/src/standard/{render → raytracing}/bvh/traverse.ts +72 -64
- package/src/standard/{render → raytracing}/depth.ts +9 -9
- package/src/standard/raytracing/index.ts +409 -0
- package/src/standard/{render → raytracing}/instance.ts +31 -16
- package/src/standard/{render → raytracing}/ray.ts +1 -1
- package/src/standard/raytracing/shaders.ts +798 -0
- package/src/standard/{render → raytracing}/triangle.ts +1 -1
- package/src/standard/render/camera.ts +96 -106
- package/src/standard/render/data.ts +1 -1
- package/src/standard/render/index.ts +136 -220
- package/src/standard/render/indirect.ts +9 -10
- package/src/standard/render/light.ts +2 -2
- package/src/standard/render/mesh.ts +404 -0
- package/src/standard/render/overlay.ts +8 -5
- package/src/standard/render/pass.ts +1 -1
- package/src/standard/render/postprocess.ts +263 -242
- package/src/standard/render/scene.ts +28 -16
- package/src/standard/render/surface/index.ts +81 -12
- package/src/standard/render/surface/shaders.ts +511 -0
- package/src/standard/render/surface/structs.ts +23 -6
- package/src/standard/tween/tween.ts +44 -115
- package/src/standard/render/bvh/radix.ts +0 -476
- package/src/standard/render/forward/index.ts +0 -259
- package/src/standard/render/forward/raster.ts +0 -228
- package/src/standard/render/mesh/box.ts +0 -20
- package/src/standard/render/mesh/index.ts +0 -446
- package/src/standard/render/mesh/plane.ts +0 -11
- package/src/standard/render/mesh/sphere.ts +0 -40
- package/src/standard/render/mesh/unified.ts +0 -96
- package/src/standard/render/shaders.ts +0 -484
- package/src/standard/render/surface/compile.ts +0 -67
- package/src/standard/render/surface/noise.ts +0 -45
- package/src/standard/render/surface/wgsl.ts +0 -573
- /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
|
|
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 {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
200
|
-
|
|
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
|
-
|
|
216
|
-
|
|
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
|
-
|
|
224
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
-
|
|
242
|
-
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
-
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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:
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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,
|
|
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
|
-
|
|
39
|
+
interface AmbientLightData {
|
|
40
40
|
color: number;
|
|
41
41
|
intensity: number;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
interface DirectionalLightData {
|
|
45
45
|
color: number;
|
|
46
46
|
intensity: number;
|
|
47
47
|
directionX: number;
|