@woosh/meep-engine 2.75.6 → 2.75.8
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/build/meep.cjs +268 -252
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +268 -252
- package/editor/ecs/component/createObjectEditor.js +2 -2
- package/package.json +1 -1
- package/src/core/geom/3d/frustum/read_three_planes_to_array.d.ts +3 -0
- package/src/core/model/object/ImmutableObjectPool.js +14 -5
- package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +7 -9
- package/src/engine/ecs/storage/BinaryBufferSerializer.js +15 -16
- package/src/engine/ecs/storage/binary/BinaryClassUpgrader.js +10 -59
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +14 -15
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.js +3 -3
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +60 -62
- package/src/engine/ecs/storage/binary/executeBinaryClassUpgraderChain.js +46 -0
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter.js +2 -2
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +37 -31
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +8 -7
- package/src/engine/graphics/render/RendererPool.js +36 -40
- package/src/engine/graphics/render/buffer/FrameBuffer.js +25 -24
- package/src/engine/graphics/render/buffer/RenderGraph.js +21 -21
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
- package/src/engine/graphics/render/frame_graph/IRenderContext.js +31 -1
- package/src/engine/graphics/render/frame_graph/RenderGraph.js +5 -5
- package/src/engine/graphics/render/frame_graph/RenderTarget.js +9 -0
- package/src/engine/graphics/render/frame_graph/RenderTextureManager.js +57 -0
- package/src/engine/graphics/render/frame_graph/ResourceEntry.js +7 -5
- package/src/engine/graphics/render/frame_graph/TextureDescriptor.js +48 -33
- package/src/engine/graphics/render/frame_graph/TextureInitialState.js +14 -0
- package/src/engine/graphics/render/frame_graph/sample/deferred/CopyPass.js +20 -0
- package/src/engine/graphics/render/frame_graph/sample/deferred/LightingPass.js +4 -0
- package/src/engine/graphics/render/frame_graph/sample/deferred/run.js +34 -6
- package/src/engine/graphics/render/frame_graph/webgl/WebGLRenderContext.js +34 -0
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +3 -2
- package/src/engine/graphics/sh3/gi/prototypeSHGI.js +92 -0
- package/src/engine/graphics/texture/virtual/{v2/VirtualTextureMemoryMapping.js → VirtualTextureMemoryMapping.js} +2 -26
- package/src/engine/graphics/texture/virtual/{v2/VirtualTexturePage.js → VirtualTexturePage.js} +10 -10
- package/src/engine/graphics/texture/virtual/{v2/VirtualTextureTileLoader.js → VirtualTextureTileLoader.js} +7 -7
- package/src/engine/graphics/texture/virtual/{v2/VirtualTextureUsage.js → VirtualTextureUsage.js} +1 -1
- package/src/engine/graphics/texture/virtual/{v2/VirtualTextureUsageUpdater.js → VirtualTextureUsageUpdater.js} +7 -7
- package/src/engine/graphics/texture/virtual/{v2/debug → debug}/ResidencyDebugView.js +4 -4
- package/src/engine/graphics/texture/virtual/{v2/debug → debug}/UsageDebugView.js +2 -2
- package/src/engine/graphics/texture/virtual/{v2/debug → debug}/UsagePyramidDebugView.js +4 -4
- package/src/engine/graphics/texture/virtual/{v2/prototype.js → prototype.js} +7 -7
- package/src/engine/graphics/texture/virtual/{v2/tile → tile}/compose_finger_print.js +1 -1
- package/src/engine/graphics/texture/virtual/{v2/tile → tile}/compose_tile_address.js +2 -2
- package/src/engine/graphics/texture/virtual/{v2/tile → tile}/tile_address_to_finger_print.js +1 -1
- package/src/core/geom/3d/frustum/read_frustum_planes_to_array.d.ts +0 -3
- package/src/engine/ecs/storage/json/Blueprint.js +0 -129
- package/src/engine/ecs/storage/json/EntityFactory.js +0 -207
- package/src/engine/ecs/storage/json/JSONDeSerializer.js +0 -148
- package/src/engine/ecs/storage/json/JSONSerializer.js +0 -132
- package/src/engine/ecs/storage/json/README.md +0 -5
- package/src/engine/graphics/render/webgpu/sample/MeshInstance.js +0 -108
- package/src/engine/graphics/render/webgpu/sample/fragmentDeferredRendering.wgsl +0 -71
- package/src/engine/graphics/render/webgpu/sample/fragmentGBuffersDebugView.wgsl +0 -39
- package/src/engine/graphics/render/webgpu/sample/fragmentWriteGBuffers.wgsl +0 -21
- package/src/engine/graphics/render/webgpu/sample/lightUpdate.wgsl +0 -41
- package/src/engine/graphics/render/webgpu/sample/main.js +0 -605
- package/src/engine/graphics/render/webgpu/sample/vertexTextureQuad.wgsl +0 -9
- package/src/engine/graphics/render/webgpu/sample/vertexWriteGBuffers.wgsl +0 -30
- package/src/engine/graphics/texture/virtual/TileOperation.js +0 -13
- package/src/engine/graphics/texture/virtual/TileTree.js +0 -150
- package/src/engine/graphics/texture/virtual/TileTree.spec.js +0 -58
- package/src/engine/graphics/texture/virtual/TileUsage.js +0 -137
- package/src/engine/graphics/texture/virtual/VirtualTexture.js +0 -238
- package/src/engine/graphics/texture/virtual/VirtualTexture.spec.js +0 -39
- package/src/engine/graphics/texture/virtual/page/TilePage.js +0 -148
- package/src/engine/graphics/texture/virtual/page/TilePageSlot.js +0 -36
- package/src/engine/graphics/texture/virtual/tile/Tile.js +0 -44
- package/src/engine/graphics/texture/virtual/tile/Tile.spec.js +0 -11
- package/src/engine/graphics/texture/virtual/tile/TileAddress.js +0 -63
- package/src/engine/graphics/texture/virtual/tile/TileAddress.spec.js +0 -30
- package/src/engine/graphics/texture/virtual/tile/TileLoader.js +0 -178
- package/src/engine/graphics/texture/virtual/tile/TileRequest.js +0 -40
- package/src/engine/graphics/texture/virtual/tile/TileStatus.js +0 -10
- /package/src/engine/graphics/texture/virtual/{v2/NOTES.md → NOTES.md} +0 -0
- /package/src/engine/graphics/texture/virtual/{v2/VirtualTextureMaterial.js → VirtualTextureMaterial.js} +0 -0
- /package/src/engine/graphics/texture/virtual/{v2/VirtualTextureUsageShader.js → VirtualTextureUsageShader.js} +0 -0
- /package/src/engine/graphics/texture/virtual/{v2/tile → tile}/VirtualTextureTile.js +0 -0
- /package/src/engine/graphics/texture/virtual/{v2/tile → tile}/decompose_finger_print.js +0 -0
- /package/src/engine/graphics/texture/virtual/{v2/tile → tile}/finger_print_to_tile_address.js +0 -0
|
@@ -1,605 +0,0 @@
|
|
|
1
|
-
import { mat4, vec3, vec4 } from 'gl-matrix';
|
|
2
|
-
import lightUpdate from './lightUpdate.wgsl';
|
|
3
|
-
import vertexWriteGBuffers from './vertexWriteGBuffers.wgsl';
|
|
4
|
-
import fragmentWriteGBuffers from './fragmentWriteGBuffers.wgsl';
|
|
5
|
-
import vertexTextureQuad from './vertexTextureQuad.wgsl';
|
|
6
|
-
import fragmentGBuffersDebugView from './fragmentGBuffersDebugView.wgsl';
|
|
7
|
-
import fragmentDeferredRendering from './fragmentDeferredRendering.wgsl';
|
|
8
|
-
import dat from "dat.gui";
|
|
9
|
-
import { PLYLoader } from "three/examples/jsm/loaders/PLYLoader.js";
|
|
10
|
-
import { noop } from "../../../../../core/function/Functions.js";
|
|
11
|
-
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
12
|
-
import { MeshInstance } from "./MeshInstance.js";
|
|
13
|
-
|
|
14
|
-
const kMaxNumLights = 1024;
|
|
15
|
-
const lightExtentMin = vec3.fromValues(-50, -30, -50);
|
|
16
|
-
const lightExtentMax = vec3.fromValues(50, 50, 50);
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
* @param {string} path
|
|
21
|
-
* @return {Promise<THREE.BufferGeometry>}
|
|
22
|
-
*/
|
|
23
|
-
function load_geometry(path) {
|
|
24
|
-
const loader = new PLYLoader();
|
|
25
|
-
|
|
26
|
-
return new Promise((resolve, reject) => {
|
|
27
|
-
|
|
28
|
-
loader.load(path, resolve, noop, reject);
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function load_geometry_gltf(path) {
|
|
33
|
-
const loader = new GLTFLoader();
|
|
34
|
-
|
|
35
|
-
return new Promise((resolve, reject) => {
|
|
36
|
-
loader.load(path, (gltf) => {
|
|
37
|
-
let r = null;
|
|
38
|
-
|
|
39
|
-
gltf.scene.traverse(o => {
|
|
40
|
-
if (o.isMesh) {
|
|
41
|
-
r = o.geometry;
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
resolve(r);
|
|
46
|
-
|
|
47
|
-
}, noop, reject);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const init = async ({ canvasRef, gui }) => {
|
|
52
|
-
|
|
53
|
-
// const mesh = await load_geometry("data/models/stanford/dragon_recon/dragon_vrip.ply");
|
|
54
|
-
const mesh = await load_geometry_gltf("data/models/stanford/DragonAttenuation.glb");
|
|
55
|
-
|
|
56
|
-
const navigator = globalThis.navigator;
|
|
57
|
-
|
|
58
|
-
const adapter = await navigator.gpu.requestAdapter();
|
|
59
|
-
const device = await adapter.requestDevice();
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
* @type {HTMLCanvasElement}
|
|
64
|
-
*/
|
|
65
|
-
const canvas = canvasRef.current;
|
|
66
|
-
|
|
67
|
-
if (canvas === null) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
*
|
|
73
|
-
* @type {GPUCanvasContext}
|
|
74
|
-
*/
|
|
75
|
-
const context = canvas.getContext('webgpu');
|
|
76
|
-
|
|
77
|
-
const devicePixelRatio = window.devicePixelRatio || 1;
|
|
78
|
-
|
|
79
|
-
const presentationSize = [
|
|
80
|
-
canvas.clientWidth * devicePixelRatio,
|
|
81
|
-
canvas.clientHeight * devicePixelRatio,
|
|
82
|
-
];
|
|
83
|
-
|
|
84
|
-
const aspect = presentationSize[0] / presentationSize[1];
|
|
85
|
-
|
|
86
|
-
const presentationFormat = context.getPreferredFormat(adapter);
|
|
87
|
-
|
|
88
|
-
context.configure({
|
|
89
|
-
device,
|
|
90
|
-
format: presentationFormat,
|
|
91
|
-
size: presentationSize,
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const m_instance = new MeshInstance();
|
|
95
|
-
m_instance.geometry = mesh;
|
|
96
|
-
m_instance.init(device);
|
|
97
|
-
|
|
98
|
-
// GBuffer texture render targets
|
|
99
|
-
const gBufferTexture2DFloat = device.createTexture({
|
|
100
|
-
size: [...presentationSize, 3],
|
|
101
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
102
|
-
format: 'rgba32float',
|
|
103
|
-
});
|
|
104
|
-
const gBufferTextureAlbedo = device.createTexture({
|
|
105
|
-
size: presentationSize,
|
|
106
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
107
|
-
format: 'bgra8unorm',
|
|
108
|
-
});
|
|
109
|
-
const gBufferTextureViews = [
|
|
110
|
-
gBufferTexture2DFloat.createView({ baseArrayLayer: 0, arrayLayerCount: 1 }),
|
|
111
|
-
gBufferTexture2DFloat.createView({ baseArrayLayer: 1, arrayLayerCount: 1 }),
|
|
112
|
-
gBufferTextureAlbedo.createView(),
|
|
113
|
-
];
|
|
114
|
-
const vertexBuffers = [
|
|
115
|
-
{
|
|
116
|
-
arrayStride: Float32Array.BYTES_PER_ELEMENT * 8,
|
|
117
|
-
attributes: [
|
|
118
|
-
{
|
|
119
|
-
// position
|
|
120
|
-
shaderLocation: 0,
|
|
121
|
-
offset: 0,
|
|
122
|
-
format: 'float32x3',
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
// normal
|
|
126
|
-
shaderLocation: 1,
|
|
127
|
-
offset: Float32Array.BYTES_PER_ELEMENT * 3,
|
|
128
|
-
format: 'float32x3',
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
// uv
|
|
132
|
-
shaderLocation: 2,
|
|
133
|
-
offset: Float32Array.BYTES_PER_ELEMENT * 6,
|
|
134
|
-
format: 'float32x2',
|
|
135
|
-
},
|
|
136
|
-
],
|
|
137
|
-
},
|
|
138
|
-
];
|
|
139
|
-
const primitive = {
|
|
140
|
-
topology: 'triangle-list',
|
|
141
|
-
cullMode: 'back',
|
|
142
|
-
};
|
|
143
|
-
const writeGBuffersPipeline = device.createRenderPipeline({
|
|
144
|
-
vertex: {
|
|
145
|
-
module: device.createShaderModule({
|
|
146
|
-
code: vertexWriteGBuffers,
|
|
147
|
-
}),
|
|
148
|
-
entryPoint: 'main',
|
|
149
|
-
buffers: vertexBuffers,
|
|
150
|
-
},
|
|
151
|
-
fragment: {
|
|
152
|
-
module: device.createShaderModule({
|
|
153
|
-
code: fragmentWriteGBuffers,
|
|
154
|
-
}),
|
|
155
|
-
entryPoint: 'main',
|
|
156
|
-
targets: [
|
|
157
|
-
// position
|
|
158
|
-
{ format: 'rgba32float' },
|
|
159
|
-
// normal
|
|
160
|
-
{ format: 'rgba32float' },
|
|
161
|
-
// albedo
|
|
162
|
-
{ format: 'bgra8unorm' },
|
|
163
|
-
],
|
|
164
|
-
},
|
|
165
|
-
depthStencil: {
|
|
166
|
-
depthWriteEnabled: true,
|
|
167
|
-
depthCompare: 'less',
|
|
168
|
-
format: 'depth24plus',
|
|
169
|
-
},
|
|
170
|
-
primitive,
|
|
171
|
-
});
|
|
172
|
-
const gBufferTexturesBindGroupLayout = device.createBindGroupLayout({
|
|
173
|
-
entries: [
|
|
174
|
-
{
|
|
175
|
-
binding: 0,
|
|
176
|
-
visibility: GPUShaderStage.FRAGMENT,
|
|
177
|
-
texture: {
|
|
178
|
-
sampleType: 'unfilterable-float',
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
binding: 1,
|
|
183
|
-
visibility: GPUShaderStage.FRAGMENT,
|
|
184
|
-
texture: {
|
|
185
|
-
sampleType: 'unfilterable-float',
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
binding: 2,
|
|
190
|
-
visibility: GPUShaderStage.FRAGMENT,
|
|
191
|
-
texture: {
|
|
192
|
-
sampleType: 'unfilterable-float',
|
|
193
|
-
},
|
|
194
|
-
},
|
|
195
|
-
],
|
|
196
|
-
});
|
|
197
|
-
const lightsBufferBindGroupLayout = device.createBindGroupLayout({
|
|
198
|
-
entries: [
|
|
199
|
-
{
|
|
200
|
-
binding: 0,
|
|
201
|
-
visibility: GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
|
|
202
|
-
buffer: {
|
|
203
|
-
type: 'storage',
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
binding: 1,
|
|
208
|
-
visibility: GPUShaderStage.FRAGMENT | GPUShaderStage.COMPUTE,
|
|
209
|
-
buffer: {
|
|
210
|
-
type: 'uniform',
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
|
-
],
|
|
214
|
-
});
|
|
215
|
-
const canvasSizeUniformBindGroupLayout = device.createBindGroupLayout({
|
|
216
|
-
entries: [
|
|
217
|
-
{
|
|
218
|
-
binding: 0,
|
|
219
|
-
visibility: GPUShaderStage.FRAGMENT,
|
|
220
|
-
buffer: {
|
|
221
|
-
type: 'uniform',
|
|
222
|
-
},
|
|
223
|
-
},
|
|
224
|
-
],
|
|
225
|
-
});
|
|
226
|
-
const gBuffersDebugViewPipeline = device.createRenderPipeline({
|
|
227
|
-
layout: device.createPipelineLayout({
|
|
228
|
-
bindGroupLayouts: [
|
|
229
|
-
gBufferTexturesBindGroupLayout,
|
|
230
|
-
canvasSizeUniformBindGroupLayout,
|
|
231
|
-
],
|
|
232
|
-
}),
|
|
233
|
-
vertex: {
|
|
234
|
-
module: device.createShaderModule({
|
|
235
|
-
code: vertexTextureQuad,
|
|
236
|
-
}),
|
|
237
|
-
entryPoint: 'main',
|
|
238
|
-
},
|
|
239
|
-
fragment: {
|
|
240
|
-
module: device.createShaderModule({
|
|
241
|
-
code: fragmentGBuffersDebugView,
|
|
242
|
-
}),
|
|
243
|
-
entryPoint: 'main',
|
|
244
|
-
targets: [
|
|
245
|
-
{
|
|
246
|
-
format: presentationFormat,
|
|
247
|
-
},
|
|
248
|
-
],
|
|
249
|
-
},
|
|
250
|
-
primitive,
|
|
251
|
-
});
|
|
252
|
-
const deferredRenderPipeline = device.createRenderPipeline({
|
|
253
|
-
layout: device.createPipelineLayout({
|
|
254
|
-
bindGroupLayouts: [
|
|
255
|
-
gBufferTexturesBindGroupLayout,
|
|
256
|
-
lightsBufferBindGroupLayout,
|
|
257
|
-
canvasSizeUniformBindGroupLayout,
|
|
258
|
-
],
|
|
259
|
-
}),
|
|
260
|
-
vertex: {
|
|
261
|
-
module: device.createShaderModule({
|
|
262
|
-
code: vertexTextureQuad,
|
|
263
|
-
}),
|
|
264
|
-
entryPoint: 'main',
|
|
265
|
-
},
|
|
266
|
-
fragment: {
|
|
267
|
-
module: device.createShaderModule({
|
|
268
|
-
code: fragmentDeferredRendering,
|
|
269
|
-
}),
|
|
270
|
-
entryPoint: 'main',
|
|
271
|
-
targets: [
|
|
272
|
-
{
|
|
273
|
-
format: presentationFormat,
|
|
274
|
-
},
|
|
275
|
-
],
|
|
276
|
-
},
|
|
277
|
-
primitive,
|
|
278
|
-
});
|
|
279
|
-
const depthTexture = device.createTexture({
|
|
280
|
-
size: presentationSize,
|
|
281
|
-
format: 'depth24plus',
|
|
282
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
283
|
-
});
|
|
284
|
-
const writeGBufferPassDescriptor = {
|
|
285
|
-
colorAttachments: [
|
|
286
|
-
{
|
|
287
|
-
view: gBufferTextureViews[0],
|
|
288
|
-
loadValue: {
|
|
289
|
-
r: Number.MAX_VALUE,
|
|
290
|
-
g: Number.MAX_VALUE,
|
|
291
|
-
b: Number.MAX_VALUE,
|
|
292
|
-
a: 1.0,
|
|
293
|
-
},
|
|
294
|
-
storeOp: 'store',
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
view: gBufferTextureViews[1],
|
|
298
|
-
loadValue: { r: 0.0, g: 0.0, b: 1.0, a: 1.0 },
|
|
299
|
-
storeOp: 'store',
|
|
300
|
-
},
|
|
301
|
-
{
|
|
302
|
-
view: gBufferTextureViews[2],
|
|
303
|
-
loadValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
|
|
304
|
-
storeOp: 'store',
|
|
305
|
-
},
|
|
306
|
-
],
|
|
307
|
-
depthStencilAttachment: {
|
|
308
|
-
view: depthTexture.createView(),
|
|
309
|
-
depthLoadValue: 1.0,
|
|
310
|
-
depthStoreOp: 'store',
|
|
311
|
-
stencilLoadValue: 0,
|
|
312
|
-
stencilStoreOp: 'store',
|
|
313
|
-
},
|
|
314
|
-
};
|
|
315
|
-
const textureQuadPassDescriptor = {
|
|
316
|
-
colorAttachments: [
|
|
317
|
-
{
|
|
318
|
-
// view is acquired and set in render loop.
|
|
319
|
-
view: undefined,
|
|
320
|
-
loadValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
|
|
321
|
-
storeOp: 'store',
|
|
322
|
-
},
|
|
323
|
-
],
|
|
324
|
-
};
|
|
325
|
-
const settings = {
|
|
326
|
-
mode: 'rendering',
|
|
327
|
-
numLights:1,
|
|
328
|
-
};
|
|
329
|
-
const configUniformBuffer = (() => {
|
|
330
|
-
const buffer = device.createBuffer({
|
|
331
|
-
size: Uint32Array.BYTES_PER_ELEMENT,
|
|
332
|
-
mappedAtCreation: true,
|
|
333
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
334
|
-
});
|
|
335
|
-
new Uint32Array(buffer.getMappedRange())[0] = settings.numLights;
|
|
336
|
-
buffer.unmap();
|
|
337
|
-
return buffer;
|
|
338
|
-
})();
|
|
339
|
-
gui.add(settings, 'mode', ['rendering', 'gBuffers view']);
|
|
340
|
-
gui
|
|
341
|
-
.add(settings, 'numLights', 1, kMaxNumLights)
|
|
342
|
-
.step(1)
|
|
343
|
-
.onChange(() => {
|
|
344
|
-
device.queue.writeBuffer(configUniformBuffer, 0, new Uint32Array([settings.numLights]));
|
|
345
|
-
});
|
|
346
|
-
const modelUniformBuffer = device.createBuffer({
|
|
347
|
-
size: 4 * 16 * 2,
|
|
348
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
349
|
-
});
|
|
350
|
-
const cameraUniformBuffer = device.createBuffer({
|
|
351
|
-
size: 4 * 16,
|
|
352
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
353
|
-
});
|
|
354
|
-
const sceneUniformBindGroup = device.createBindGroup({
|
|
355
|
-
layout: writeGBuffersPipeline.getBindGroupLayout(0),
|
|
356
|
-
entries: [
|
|
357
|
-
{
|
|
358
|
-
binding: 0,
|
|
359
|
-
resource: {
|
|
360
|
-
buffer: modelUniformBuffer,
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
{
|
|
364
|
-
binding: 1,
|
|
365
|
-
resource: {
|
|
366
|
-
buffer: cameraUniformBuffer,
|
|
367
|
-
},
|
|
368
|
-
},
|
|
369
|
-
],
|
|
370
|
-
});
|
|
371
|
-
const canvasSizeUniformBuffer = device.createBuffer({
|
|
372
|
-
size: 4 * 2,
|
|
373
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
374
|
-
});
|
|
375
|
-
const canvasSizeUniformBindGroup = device.createBindGroup({
|
|
376
|
-
layout: canvasSizeUniformBindGroupLayout,
|
|
377
|
-
entries: [
|
|
378
|
-
{
|
|
379
|
-
binding: 0,
|
|
380
|
-
resource: {
|
|
381
|
-
buffer: canvasSizeUniformBuffer,
|
|
382
|
-
},
|
|
383
|
-
},
|
|
384
|
-
],
|
|
385
|
-
});
|
|
386
|
-
const gBufferTexturesBindGroup = device.createBindGroup({
|
|
387
|
-
layout: gBufferTexturesBindGroupLayout,
|
|
388
|
-
entries: [
|
|
389
|
-
{
|
|
390
|
-
binding: 0,
|
|
391
|
-
resource: gBufferTextureViews[0],
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
binding: 1,
|
|
395
|
-
resource: gBufferTextureViews[1],
|
|
396
|
-
},
|
|
397
|
-
{
|
|
398
|
-
binding: 2,
|
|
399
|
-
resource: gBufferTextureViews[2],
|
|
400
|
-
},
|
|
401
|
-
],
|
|
402
|
-
});
|
|
403
|
-
// Lights data are uploaded in a storage buffer
|
|
404
|
-
// which could be updated/culled/etc. with a compute shader
|
|
405
|
-
const extent = vec3.create();
|
|
406
|
-
vec3.sub(extent, lightExtentMax, lightExtentMin);
|
|
407
|
-
const lightDataStride = 8;
|
|
408
|
-
const bufferSizeInByte = Float32Array.BYTES_PER_ELEMENT * lightDataStride * kMaxNumLights;
|
|
409
|
-
const lightsBuffer = device.createBuffer({
|
|
410
|
-
size: bufferSizeInByte,
|
|
411
|
-
usage: GPUBufferUsage.STORAGE,
|
|
412
|
-
mappedAtCreation: true,
|
|
413
|
-
});
|
|
414
|
-
// We randomaly populate lights randomly in a box range
|
|
415
|
-
// And simply move them along y-axis per frame to show they are
|
|
416
|
-
// dynamic lightings
|
|
417
|
-
const lightData = new Float32Array(lightsBuffer.getMappedRange());
|
|
418
|
-
const tmpVec4 = vec4.create();
|
|
419
|
-
let offset = 0;
|
|
420
|
-
for (let i = 0; i < kMaxNumLights; i++) {
|
|
421
|
-
offset = lightDataStride * i;
|
|
422
|
-
// position
|
|
423
|
-
for (let i = 0; i < 3; i++) {
|
|
424
|
-
tmpVec4[i] = Math.random() * extent[i] + lightExtentMin[i];
|
|
425
|
-
}
|
|
426
|
-
tmpVec4[3] = 1;
|
|
427
|
-
lightData.set(tmpVec4, offset);
|
|
428
|
-
// color
|
|
429
|
-
tmpVec4[0] = Math.random() * 2;
|
|
430
|
-
tmpVec4[1] = Math.random() * 2;
|
|
431
|
-
tmpVec4[2] = Math.random() * 2;
|
|
432
|
-
// radius
|
|
433
|
-
tmpVec4[3] = 20.0;
|
|
434
|
-
lightData.set(tmpVec4, offset + 4);
|
|
435
|
-
}
|
|
436
|
-
lightsBuffer.unmap();
|
|
437
|
-
const lightExtentBuffer = device.createBuffer({
|
|
438
|
-
size: 4 * 8,
|
|
439
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
440
|
-
});
|
|
441
|
-
const lightExtentData = new Float32Array(8);
|
|
442
|
-
lightExtentData.set(lightExtentMin, 0);
|
|
443
|
-
lightExtentData.set(lightExtentMax, 4);
|
|
444
|
-
device.queue.writeBuffer(lightExtentBuffer, 0, lightExtentData.buffer, lightExtentData.byteOffset, lightExtentData.byteLength);
|
|
445
|
-
const lightUpdateComputePipeline = device.createComputePipeline({
|
|
446
|
-
compute: {
|
|
447
|
-
module: device.createShaderModule({
|
|
448
|
-
code: lightUpdate,
|
|
449
|
-
}),
|
|
450
|
-
entryPoint: 'main',
|
|
451
|
-
},
|
|
452
|
-
});
|
|
453
|
-
const lightsBufferBindGroup = device.createBindGroup({
|
|
454
|
-
layout: lightsBufferBindGroupLayout,
|
|
455
|
-
entries: [
|
|
456
|
-
{
|
|
457
|
-
binding: 0,
|
|
458
|
-
resource: {
|
|
459
|
-
buffer: lightsBuffer,
|
|
460
|
-
},
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
binding: 1,
|
|
464
|
-
resource: {
|
|
465
|
-
buffer: configUniformBuffer,
|
|
466
|
-
},
|
|
467
|
-
},
|
|
468
|
-
],
|
|
469
|
-
});
|
|
470
|
-
const lightsBufferComputeBindGroup = device.createBindGroup({
|
|
471
|
-
layout: lightUpdateComputePipeline.getBindGroupLayout(0),
|
|
472
|
-
entries: [
|
|
473
|
-
{
|
|
474
|
-
binding: 0,
|
|
475
|
-
resource: {
|
|
476
|
-
buffer: lightsBuffer,
|
|
477
|
-
},
|
|
478
|
-
},
|
|
479
|
-
{
|
|
480
|
-
binding: 1,
|
|
481
|
-
resource: {
|
|
482
|
-
buffer: configUniformBuffer,
|
|
483
|
-
},
|
|
484
|
-
},
|
|
485
|
-
{
|
|
486
|
-
binding: 2,
|
|
487
|
-
resource: {
|
|
488
|
-
buffer: lightExtentBuffer,
|
|
489
|
-
},
|
|
490
|
-
},
|
|
491
|
-
],
|
|
492
|
-
});
|
|
493
|
-
//--------------------
|
|
494
|
-
// Scene matrices
|
|
495
|
-
const eyePosition = vec3.fromValues(0, 50, -100);
|
|
496
|
-
const upVector = vec3.fromValues(0, 1, 0);
|
|
497
|
-
const origin = vec3.fromValues(0, 0, 0);
|
|
498
|
-
const projectionMatrix = mat4.create();
|
|
499
|
-
mat4.perspective(projectionMatrix, (2 * Math.PI) / 5, aspect, 1, 2000.0);
|
|
500
|
-
const viewMatrix = mat4.create();
|
|
501
|
-
mat4.lookAt(viewMatrix, eyePosition, origin, upVector);
|
|
502
|
-
const viewProjMatrix = mat4.create();
|
|
503
|
-
mat4.multiply(viewProjMatrix, projectionMatrix, viewMatrix);
|
|
504
|
-
// Move the model so it's centered.
|
|
505
|
-
const modelMatrix = mat4.create();
|
|
506
|
-
mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(0, -5, 0));
|
|
507
|
-
mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(0, -40, 0));
|
|
508
|
-
const cameraMatrixData = viewProjMatrix;
|
|
509
|
-
device.queue.writeBuffer(cameraUniformBuffer, 0, cameraMatrixData.buffer, cameraMatrixData.byteOffset, cameraMatrixData.byteLength);
|
|
510
|
-
const modelData = modelMatrix;
|
|
511
|
-
device.queue.writeBuffer(modelUniformBuffer, 0, modelData.buffer, modelData.byteOffset, modelData.byteLength);
|
|
512
|
-
const invertTransposeModelMatrix = mat4.create();
|
|
513
|
-
mat4.invert(invertTransposeModelMatrix, modelMatrix);
|
|
514
|
-
mat4.transpose(invertTransposeModelMatrix, invertTransposeModelMatrix);
|
|
515
|
-
const normalModelData = invertTransposeModelMatrix;
|
|
516
|
-
device.queue.writeBuffer(modelUniformBuffer, 64, normalModelData.buffer, normalModelData.byteOffset, normalModelData.byteLength);
|
|
517
|
-
// Pass the canvas size to shader to help sample from gBuffer textures using coord
|
|
518
|
-
const canvasSizeData = new Float32Array(presentationSize);
|
|
519
|
-
device.queue.writeBuffer(canvasSizeUniformBuffer, 0, canvasSizeData.buffer, canvasSizeData.byteOffset, canvasSizeData.byteLength);
|
|
520
|
-
|
|
521
|
-
// Rotates the camera around the origin based on time.
|
|
522
|
-
function getCameraViewProjMatrix() {
|
|
523
|
-
const eyePosition = vec3.fromValues(0, 50, -10);
|
|
524
|
-
const rad = Math.PI * (Date.now() / 5000);
|
|
525
|
-
vec3.rotateY(eyePosition, eyePosition, origin, rad);
|
|
526
|
-
const viewMatrix = mat4.create();
|
|
527
|
-
mat4.lookAt(viewMatrix, eyePosition, origin, upVector);
|
|
528
|
-
mat4.multiply(viewProjMatrix, projectionMatrix, viewMatrix);
|
|
529
|
-
return viewProjMatrix;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
function frame() {
|
|
533
|
-
// Sample is no longer the active page.
|
|
534
|
-
if (!canvas)
|
|
535
|
-
return;
|
|
536
|
-
const cameraViewProj = getCameraViewProjMatrix();
|
|
537
|
-
device.queue.writeBuffer(cameraUniformBuffer, 0, cameraViewProj.buffer, cameraViewProj.byteOffset, cameraViewProj.byteLength);
|
|
538
|
-
const commandEncoder = device.createCommandEncoder();
|
|
539
|
-
{
|
|
540
|
-
// Write position, normal, albedo etc. data to gBuffers
|
|
541
|
-
const gBufferPass = commandEncoder.beginRenderPass(writeGBufferPassDescriptor);
|
|
542
|
-
gBufferPass.setPipeline(writeGBuffersPipeline);
|
|
543
|
-
gBufferPass.setBindGroup(0, sceneUniformBindGroup);
|
|
544
|
-
|
|
545
|
-
m_instance.draw(gBufferPass);
|
|
546
|
-
|
|
547
|
-
gBufferPass.endPass();
|
|
548
|
-
}
|
|
549
|
-
{
|
|
550
|
-
// Update lights position
|
|
551
|
-
const lightPass = commandEncoder.beginComputePass();
|
|
552
|
-
lightPass.setPipeline(lightUpdateComputePipeline);
|
|
553
|
-
lightPass.setBindGroup(0, lightsBufferComputeBindGroup);
|
|
554
|
-
lightPass.dispatch(Math.ceil(kMaxNumLights / 64));
|
|
555
|
-
lightPass.endPass();
|
|
556
|
-
}
|
|
557
|
-
{
|
|
558
|
-
if (settings.mode === 'gBuffers view') {
|
|
559
|
-
// GBuffers debug view
|
|
560
|
-
// Left: position
|
|
561
|
-
// Middle: normal
|
|
562
|
-
// Right: albedo (use uv to mimic a checkerboard texture)
|
|
563
|
-
textureQuadPassDescriptor.colorAttachments[0].view = context
|
|
564
|
-
.getCurrentTexture()
|
|
565
|
-
.createView();
|
|
566
|
-
const debugViewPass = commandEncoder.beginRenderPass(textureQuadPassDescriptor);
|
|
567
|
-
debugViewPass.setPipeline(gBuffersDebugViewPipeline);
|
|
568
|
-
debugViewPass.setBindGroup(0, gBufferTexturesBindGroup);
|
|
569
|
-
debugViewPass.setBindGroup(1, canvasSizeUniformBindGroup);
|
|
570
|
-
debugViewPass.draw(6);
|
|
571
|
-
debugViewPass.endPass();
|
|
572
|
-
} else {
|
|
573
|
-
// Deferred rendering
|
|
574
|
-
textureQuadPassDescriptor.colorAttachments[0].view = context
|
|
575
|
-
.getCurrentTexture()
|
|
576
|
-
.createView();
|
|
577
|
-
const deferredRenderingPass = commandEncoder.beginRenderPass(textureQuadPassDescriptor);
|
|
578
|
-
deferredRenderingPass.setPipeline(deferredRenderPipeline);
|
|
579
|
-
deferredRenderingPass.setBindGroup(0, gBufferTexturesBindGroup);
|
|
580
|
-
deferredRenderingPass.setBindGroup(1, lightsBufferBindGroup);
|
|
581
|
-
deferredRenderingPass.setBindGroup(2, canvasSizeUniformBindGroup);
|
|
582
|
-
deferredRenderingPass.draw(6);
|
|
583
|
-
deferredRenderingPass.endPass();
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
device.queue.submit([commandEncoder.finish()]);
|
|
587
|
-
requestAnimationFrame(frame);
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
requestAnimationFrame(frame);
|
|
591
|
-
};
|
|
592
|
-
|
|
593
|
-
const canvas_el = document.createElement('canvas');
|
|
594
|
-
canvas_el.width = window.innerWidth;
|
|
595
|
-
canvas_el.height = window.innerHeight;
|
|
596
|
-
|
|
597
|
-
document.body.appendChild(canvas_el);
|
|
598
|
-
|
|
599
|
-
const gui = new dat.GUI();
|
|
600
|
-
init({
|
|
601
|
-
canvasRef: {
|
|
602
|
-
current: canvas_el,
|
|
603
|
-
},
|
|
604
|
-
gui: gui
|
|
605
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
[[stage(vertex)]]
|
|
2
|
-
fn main([[builtin(vertex_index)]] VertexIndex : u32)
|
|
3
|
-
-> [[builtin(position)]] vec4<f32> {
|
|
4
|
-
var pos = array<vec2<f32>, 6>(
|
|
5
|
-
vec2<f32>(-1.0, -1.0), vec2<f32>(1.0, -1.0), vec2<f32>(-1.0, 1.0),
|
|
6
|
-
vec2<f32>(-1.0, 1.0), vec2<f32>(1.0, -1.0), vec2<f32>(1.0, 1.0));
|
|
7
|
-
|
|
8
|
-
return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
|
|
9
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
struct Uniforms {
|
|
2
|
-
modelMatrix : mat4x4<f32>;
|
|
3
|
-
normalModelMatrix : mat4x4<f32>;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
struct Camera {
|
|
7
|
-
viewProjectionMatrix : mat4x4<f32>;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
[[group(0), binding(0)]] var<uniform> uniforms : Uniforms;
|
|
11
|
-
[[group(0), binding(1)]] var<uniform> camera : Camera;
|
|
12
|
-
|
|
13
|
-
struct VertexOutput {
|
|
14
|
-
[[builtin(position)]] Position : vec4<f32>;
|
|
15
|
-
[[location(0)]] fragPosition: vec3<f32>; // position in world space
|
|
16
|
-
[[location(1)]] fragNormal: vec3<f32>; // normal in world space
|
|
17
|
-
[[location(2)]] fragUV: vec2<f32>;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
[[stage(vertex)]]
|
|
21
|
-
fn main([[location(0)]] position : vec3<f32>,
|
|
22
|
-
[[location(1)]] normal : vec3<f32>,
|
|
23
|
-
[[location(2)]] uv : vec2<f32>) -> VertexOutput {
|
|
24
|
-
var output : VertexOutput;
|
|
25
|
-
output.fragPosition = (uniforms.modelMatrix * vec4<f32>(position, 1.0)).xyz;
|
|
26
|
-
output.Position = camera.viewProjectionMatrix * vec4<f32>(output.fragPosition, 1.0);
|
|
27
|
-
output.fragNormal = normalize((uniforms.normalModelMatrix * vec4<f32>(normal, 1.0)).xyz);
|
|
28
|
-
output.fragUV = uv;
|
|
29
|
-
return output;
|
|
30
|
-
}
|