matrix-engine-wgpu 1.3.12 → 1.3.16

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.
@@ -1,496 +0,0 @@
1
- import {UNLIT_SHADER} from "../shaders/shaders";
2
- import {mat4, vec3} from 'wgpu-matrix';
3
- import {Position, Rotation} from "./matrix-class";
4
- import {createInputHandler} from "./engine";
5
-
6
- var SphereLayout = {
7
- vertexStride: 8 * 4,
8
- positionsOffset: 0,
9
- normalOffset: 3 * 4,
10
- uvOffset: 6 * 4,
11
- };
12
-
13
- export default class MECube {
14
-
15
- constructor(canvas, device, context, o) {
16
- this.device = device;
17
- this.context = context;
18
- this.entityArgPass = o.entityArgPass;
19
- this.inputHandler = createInputHandler(window, canvas);
20
- this.cameras = o.cameras;
21
- console.log('passed : o.mainCameraParams.responseCoef ', o.mainCameraParams.responseCoef)
22
- this.mainCameraParams = {
23
- type: o.mainCameraParams.type,
24
- responseCoef: o.mainCameraParams.responseCoef
25
- } // | WASD 'arcball' };
26
-
27
- this.lastFrameMS = 0;
28
- this.shaderModule = device.createShaderModule({
29
- code: UNLIT_SHADER,
30
- });
31
-
32
- this.texturesPaths = [];
33
-
34
- if(typeof o.raycast === 'undefined') {
35
- this.raycast = {
36
- enabled: false,
37
- radius: 2
38
- };
39
- } else {
40
- this.raycast = o.raycast;
41
- }
42
-
43
- // useUVShema4x2 pass this from top !
44
-
45
- o.texturesPaths.forEach((t) => {
46
- this.texturesPaths.push(t)
47
- })
48
-
49
- this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
50
- this.position = new Position(o.position.x, o.position.y, o.position.z);
51
- console.log('cube added on pos : ', this.position)
52
- this.rotation = new Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
53
- this.rotation.rotationSpeed.x = o.rotationSpeed.x;
54
- this.rotation.rotationSpeed.y = o.rotationSpeed.y;
55
- this.rotation.rotationSpeed.z = o.rotationSpeed.z;
56
-
57
- this.scale = o.scale;
58
- this.pipeline = device.createRenderPipeline({
59
- layout: 'auto',
60
- vertex: {
61
- module: this.shaderModule,
62
- entryPoint: 'vertexMain',
63
- buffers: [
64
- {
65
- arrayStride: SphereLayout.vertexStride,
66
- attributes: [
67
- // position
68
- {shaderLocation: 0, offset: SphereLayout.positionsOffset, format: 'float32x3'},
69
- // normal
70
- {shaderLocation: 1, offset: SphereLayout.normalOffset, format: 'float32x3'},
71
- // uv
72
- {shaderLocation: 2, offset: SphereLayout.uvOffset, format: 'float32x2', },
73
- ],
74
- },
75
- ],
76
- },
77
- fragment: {
78
- module: this.shaderModule,
79
- entryPoint: 'fragmentMain',
80
- targets: [{format: this.presentationFormat, },],
81
- },
82
- primitive: {
83
- topology: 'triangle-list',
84
- // Backface culling since the sphere is solid piece of geometry.
85
- // Faces pointing away from the camera will be occluded by faces
86
- // pointing toward the camera.
87
- cullMode: 'back',
88
- },
89
- // Enable depth testing so that the fragment closest to the camera
90
- // is rendered in front.
91
- depthStencil: {
92
- depthWriteEnabled: true,
93
- depthCompare: 'less',
94
- format: 'depth24plus',
95
- },
96
- });
97
-
98
- this.depthTexture = device.createTexture({
99
- size: [canvas.width, canvas.height],
100
- format: 'depth24plus',
101
- usage: GPUTextureUsage.RENDER_ATTACHMENT,
102
- });
103
-
104
- this.uniformBufferSize = 4 * 16; // 4x4 matrix
105
- this.uniformBuffer = device.createBuffer({
106
- size: this.uniformBufferSize,
107
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
108
- });
109
-
110
- // Fetch the images and upload them into a GPUTexture.
111
- this.texture0 = null;
112
- this.moonTexture = null;
113
-
114
- this.settings = {
115
- useRenderBundles: true,
116
- asteroidCount: 15,
117
- };
118
-
119
- this.loadTex0(this.texturesPaths, device).then(() => {
120
- this.loadTex1(this.texturesPaths, device).then(() => {
121
-
122
- this.sampler = device.createSampler({
123
- magFilter: 'linear',
124
- minFilter: 'linear',
125
- });
126
-
127
- this.transform = mat4.create();
128
- mat4.identity(this.transform);
129
-
130
- this.planet = this.createGeometry({
131
- scale: this.scale,
132
- useUVShema4x2: false
133
- });
134
- this.planet.bindGroup = this.createSphereBindGroup(this.texture0, this.transform);
135
-
136
- // can be used like instance draws
137
- var asteroids = [
138
- // this.createGeometry(0.2, 8, 6, 0.15),
139
- ];
140
-
141
- this.renderables = [this.planet];
142
- // this.ensureEnoughAsteroids(asteroids, this.transform);
143
- this.renderPassDescriptor = {
144
- colorAttachments: [
145
- {
146
- view: undefined,
147
- clearValue: {r: 0.0, g: 0.0, b: 0.0, a: 1.0},
148
- loadOp: this.entityArgPass.loadOp,
149
- storeOp: this.entityArgPass.storeOp,
150
- },
151
- ],
152
- depthStencilAttachment: {
153
- view: this.depthTexture.createView(),
154
- depthClearValue: 1.0,
155
- depthLoadOp: this.entityArgPass.depthLoadOp,
156
- depthStoreOp: this.entityArgPass.depthStoreOp,
157
- },
158
- };
159
-
160
- const aspect = canvas.width / canvas.height;
161
- this.projectionMatrix = mat4.perspective((2 * Math.PI) / 5, aspect, 1, 1000.0);
162
- this.modelViewProjectionMatrix = mat4.create();
163
-
164
- this.frameBindGroup = device.createBindGroup({
165
- layout: this.pipeline.getBindGroupLayout(0),
166
- entries: [
167
- {
168
- binding: 0,
169
- resource: {buffer: this.uniformBuffer, },
170
- },
171
- ],
172
- });
173
-
174
- // The render bundle can be encoded once and re-used as many times as needed.
175
- // Because it encodes all of the commands needed to render at the GPU level,
176
- // those commands will not need to execute the associated JavaScript code upon
177
- // execution or be re-validated, which can represent a significant time savings.
178
- //
179
- // However, because render bundles are immutable once created, they are only
180
- // appropriate for rendering content where the same commands will be executed
181
- // every time, with the only changes being the contents of the buffers and
182
- // textures used. Cases where the executed commands differ from frame-to-frame,
183
- // such as when using frustrum or occlusion culling, will not benefit from
184
- // using render bundles as much.
185
- this.renderBundle;
186
- this.updateRenderBundle();
187
- })
188
- })
189
- }
190
-
191
- ensureEnoughAsteroids(asteroids, transform) {
192
- for(let i = this.renderables.length;i <= this.settings.asteroidCount;++i) {
193
- // Place copies of the asteroid in a ring.
194
- const radius = Math.random() * 1.7 + 1.25;
195
- const angle = Math.random() * Math.PI * 2;
196
- const x = Math.sin(angle) * radius;
197
- const y = (Math.random() - 0.5) * 0.015;
198
- const z = Math.cos(angle) * radius;
199
-
200
- mat4.identity(transform);
201
- mat4.translate(transform, [x, y, z], transform);
202
- mat4.rotateX(transform, Math.random() * Math.PI, transform);
203
- mat4.rotateY(transform, Math.random() * Math.PI, transform);
204
- this.renderables.push({
205
- ...asteroids[i % asteroids.length],
206
- bindGroup: this.createSphereBindGroup(this.moonTexture, transform),
207
- });
208
- }
209
- }
210
-
211
- updateRenderBundle() {
212
- console.log('[CUBE] updateRenderBundle')
213
- const renderBundleEncoder = this.device.createRenderBundleEncoder({
214
- colorFormats: [this.presentationFormat],
215
- depthStencilFormat: 'depth24plus',
216
- });
217
- this.renderScene(renderBundleEncoder);
218
- this.renderBundle = renderBundleEncoder.finish();
219
- }
220
-
221
- createGeometry(options) {
222
- const mesh = this.createCubeVertices(options);
223
- // Create a vertex buffer from the sphere data.
224
- const vertices = this.device.createBuffer({
225
- size: mesh.vertices.byteLength,
226
- usage: GPUBufferUsage.VERTEX,
227
- mappedAtCreation: true,
228
- });
229
- new Float32Array(vertices.getMappedRange()).set(mesh.vertices);
230
- vertices.unmap();
231
-
232
- const indices = this.device.createBuffer({
233
- size: mesh.indices.byteLength,
234
- usage: GPUBufferUsage.INDEX,
235
- mappedAtCreation: true,
236
- });
237
- new Uint16Array(indices.getMappedRange()).set(mesh.indices);
238
- indices.unmap();
239
-
240
- return {
241
- vertices,
242
- indices,
243
- indexCount: mesh.indices.length,
244
- };
245
- }
246
-
247
- createSphereBindGroup(texture, transform) {
248
-
249
- const uniformBufferSize = 4 * 16; // 4x4 matrix
250
- const uniformBuffer = this.device.createBuffer({
251
- size: uniformBufferSize,
252
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
253
- mappedAtCreation: true,
254
- });
255
- new Float32Array(uniformBuffer.getMappedRange()).set(transform);
256
- uniformBuffer.unmap();
257
-
258
- const bindGroup = this.device.createBindGroup({
259
- layout: this.pipeline.getBindGroupLayout(1),
260
- entries: [
261
- {
262
- binding: 0,
263
- resource: {
264
- buffer: uniformBuffer,
265
- },
266
- },
267
- {
268
- binding: 1,
269
- resource: this.sampler,
270
- },
271
- {
272
- binding: 2,
273
- resource: texture.createView(),
274
- },
275
- ],
276
- });
277
-
278
- return bindGroup;
279
- }
280
-
281
-
282
- // TEST
283
- getViewMatrix() {
284
- const camera = this.cameras[this.mainCameraParams.type];
285
- const viewMatrix = camera.update(deltaTime, this.inputHandler());
286
- return viewMatrix;
287
- }
288
-
289
- getTransformationMatrix(pos) {
290
- const now = Date.now();
291
- const deltaTime = (now - this.lastFrameMS) / this.mainCameraParams.responseCoef;
292
- this.lastFrameMS = now;
293
-
294
- // const viewMatrix = mat4.identity(); ORI
295
- const camera = this.cameras[this.mainCameraParams.type];
296
- const viewMatrix = camera.update(deltaTime, this.inputHandler());
297
-
298
- mat4.translate(viewMatrix, vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
299
- mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
300
- mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
301
- mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
302
- mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
303
-
304
- return this.modelViewProjectionMatrix;
305
- }
306
-
307
- async loadTex1(textPath, device) {
308
- return new Promise(async (resolve) => {
309
- const response = await fetch(textPath[0]);
310
- const imageBitmap = await createImageBitmap(await response.blob());
311
- this.moonTexture = device.createTexture({
312
- size: [imageBitmap.width, imageBitmap.height, 1],
313
- format: 'rgba8unorm',
314
- usage:
315
- GPUTextureUsage.TEXTURE_BINDING |
316
- GPUTextureUsage.COPY_DST |
317
- GPUTextureUsage.RENDER_ATTACHMENT,
318
- });
319
- var moonTexture = this.moonTexture
320
- device.queue.copyExternalImageToTexture(
321
- {source: imageBitmap},
322
- {texture: moonTexture},
323
- [imageBitmap.width, imageBitmap.height]
324
- );
325
- resolve()
326
- })
327
- }
328
-
329
- async loadTex0(texturesPaths, device) {
330
- return new Promise(async (resolve) => {
331
- const response = await fetch(texturesPaths[0]);
332
- const imageBitmap = await createImageBitmap(await response.blob());
333
- console.log('WHAT IS THIS ', this)
334
- this.texture0 = device.createTexture({
335
- size: [imageBitmap.width, imageBitmap.height, 1],
336
- format: 'rgba8unorm',
337
- usage:
338
- GPUTextureUsage.TEXTURE_BINDING |
339
- GPUTextureUsage.COPY_DST |
340
- GPUTextureUsage.RENDER_ATTACHMENT,
341
- });
342
- var texture0 = this.texture0
343
- device.queue.copyExternalImageToTexture(
344
- {source: imageBitmap},
345
- {texture: texture0},
346
- [imageBitmap.width, imageBitmap.height]
347
- );
348
- resolve()
349
- })
350
-
351
- }
352
-
353
-
354
- // Render bundles function as partial, limited render passes, so we can use the
355
- // same code both to render the scene normally and to build the render bundle.
356
- renderScene(passEncoder) {
357
-
358
- if(typeof this.renderables === 'undefined') return;
359
- passEncoder.setPipeline(this.pipeline);
360
- passEncoder.setBindGroup(0, this.frameBindGroup);
361
-
362
- // Loop through every renderable object and draw them individually.
363
- // (Because many of these meshes are repeated, with only the transforms
364
- // differing, instancing would be highly effective here. This sample
365
- // intentionally avoids using instancing in order to emulate a more complex
366
- // scene, which helps demonstrate the potential time savings a render bundle
367
- // can provide.)
368
- let count = 0;
369
- for(const renderable of this.renderables) {
370
- passEncoder.setBindGroup(1, renderable.bindGroup);
371
- passEncoder.setVertexBuffer(0, renderable.vertices);
372
- passEncoder.setIndexBuffer(renderable.indices, 'uint16');
373
- passEncoder.drawIndexed(renderable.indexCount);
374
- if(++count > this.settings.asteroidCount) {
375
- break;
376
- }
377
- }
378
- }
379
-
380
- createCubeVertices(options) {
381
- if(typeof options === 'undefined') {
382
- var options = {
383
- scale: 1,
384
- useUVShema4x2: false
385
- }
386
- }
387
- if(typeof options.scale === 'undefined') options.scale = 1;
388
-
389
- let vertices;
390
- if(options.useUVShema4x2 == true) {
391
- vertices = new Float32Array([
392
- // position | texture coordinate
393
- //-------------+----------------------
394
- // front face select the top left image 1, 0.5,
395
- -1, 1, 1, 1, 0, 0, 0, 0,
396
- -1, -1, 1, 1, 0, 0, 0, 0.5,
397
- 1, 1, 1, 1, 0, 0, 0.25, 0,
398
- 1, -1, 1, 1, 0, 0, 0.25, 0.5,
399
- // right face select the top middle image
400
- 1, 1, -1, 1, 0, 0, 0.25, 0,
401
- 1, 1, 1, 1, 0, 0, 0.5, 0,
402
- 1, -1, -1, 1, 0, 0, 0.25, 0.5,
403
- 1, -1, 1, 1, 0, 0, 0.5, 0.5,
404
- // back face select to top right image
405
- 1, 1, -1, 1, 0, 0, 0.5, 0,
406
- 1, -1, -1, 1, 0, 0, 0.5, 0.5,
407
- -1, 1, -1, 1, 0, 0, 0.75, 0,
408
- -1, -1, -1, 1, 0, 0, 0.75, 0.5,
409
- // left face select the bottom left image
410
- -1, 1, 1, 1, 0, 0, 0, 0.5,
411
- -1, 1, -1, 1, 0, 0, 0.25, 0.5,
412
- -1, -1, 1, 1, 0, 0, 0, 1,
413
- -1, -1, -1, 1, 0, 0, 0.25, 1,
414
- // bottom face select the bottom middle image
415
- 1, -1, 1, 1, 0, 0, 0.25, 0.5,
416
- -1, -1, 1, 1, 0, 0, 0.5, 0.5,
417
- 1, -1, -1, 1, 0, 0, 0.25, 1,
418
- -1, -1, -1, 1, 0, 0, 0.5, 1,
419
- // top face select the bottom right image
420
- -1, 1, 1, 1, 0, 0, 0.5, 0.5,
421
- 1, 1, 1, 1, 0, 0, 0.75, 0.5,
422
- -1, 1, -1, 1, 0, 0, 0.5, 1,
423
- 1, 1, -1, 1, 0, 0, 0.75, 1,
424
- ]);
425
- } else {
426
- vertices = new Float32Array([
427
- // position | texture coordinate
428
- //------------- +----------------------
429
- // front face select the top left image 1, 0.5,
430
- -1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0,
431
- -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1,
432
- 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 0,
433
- 1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 1,
434
- // right face select the top middle image
435
- 1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 0,
436
- 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1,
437
- 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0,
438
- 1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 1,
439
- // back face select to top right image
440
- 1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 0,
441
- 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 1,
442
- -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0,
443
- -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
444
- // left face select the bottom left image
445
- -1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0,
446
- -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 1,
447
- -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 0,
448
- -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
449
- // bottom face select the bottom middle image
450
- 1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0,
451
- -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1,
452
- 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0,
453
- -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
454
- // top face select the bottom right image
455
- -1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0,
456
- 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1,
457
- -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0,
458
- 1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
459
- ])
460
- }
461
-
462
-
463
- const indices = new Uint16Array([
464
- 0, 1, 2, 2, 1, 3, // front
465
- 4, 5, 6, 6, 5, 7, // right
466
- 8, 9, 10, 10, 9, 11, // back
467
- 12, 13, 14, 14, 13, 15, // left
468
- 16, 17, 18, 18, 17, 19, // bottom
469
- 20, 21, 22, 22, 21, 23, // top
470
- ]);
471
-
472
- return {
473
- vertices,
474
- indices,
475
- numVertices: indices.length,
476
- };
477
- }
478
-
479
- draw = () => {
480
- if(this.moonTexture == null) {
481
- // console.log('not ready')
482
- return;
483
- }
484
- const transformationMatrix = this.getTransformationMatrix(this.position);
485
- this.device.queue.writeBuffer(
486
- this.uniformBuffer,
487
- 0,
488
- transformationMatrix.buffer,
489
- transformationMatrix.byteOffset,
490
- transformationMatrix.byteLength
491
- );
492
- this.renderPassDescriptor.colorAttachments[0].view = this.context
493
- .getCurrentTexture()
494
- .createView();
495
- }
496
- }