matrix-engine-wgpu 1.3.13 → 1.3.17

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,553 +0,0 @@
1
- import {mat4, vec3} from 'wgpu-matrix';
2
- import {Position, Rotation} from "./matrix-class";
3
- import {vertexShadowWGSL} from '../shaders/vertexShadow.wgsl';
4
- import {fragmentWGSL} from '../shaders/fragment.wgsl';
5
- import {vertexWGSL} from '../shaders/vertex.wgsl';
6
- import {degToRad, genName, LOG_FUNNY_SMALL} from './utils';
7
- import Materials from './materials';
8
- import {fragmentVideoWGSL} from '../shaders/fragment.video.wgsl';
9
- import {createInputHandler} from './engine';
10
-
11
- export default class MEMeshObj extends Materials {
12
- constructor(canvas, device, context, o, sceneUniformBuffer) {
13
- super(device);
14
- if(typeof o.name === 'undefined') o.name = genName(9);
15
- if(typeof o.raycast === 'undefined') {
16
- this.raycast = {
17
- enabled: false,
18
- radius: 2
19
- };
20
- } else {
21
- this.raycast = o.raycast;
22
- }
23
-
24
- this.name = o.name;
25
- this.done = false;
26
- this.device = device;
27
- this.context = context;
28
- this.entityArgPass = o.entityArgPass;
29
-
30
- // comes from engine not from args
31
- this.clearColor = "red";
32
-
33
-
34
- // this.lightTest = new SpotLight();
35
- // this.lightTest.prepareBuffer(this.device);
36
- this.video = null;
37
-
38
- // Mesh stuff - for single mesh or t-posed (fiktive-first in loading order)
39
- this.mesh = o.mesh;
40
- this.mesh.uvs = this.mesh.textures;
41
- console.log(`%c Mesh loaded: ${o.name}`, LOG_FUNNY_SMALL);
42
-
43
- // ObjSequence animation
44
- if(typeof o.objAnim !== 'undefined' && o.objAnim != null) {
45
- this.objAnim = o.objAnim;
46
- for(var key in this.objAnim.animations) {
47
- if(key != 'active') this.objAnim.animations[key].speedCounter = 0;
48
- }
49
- console.log(`%c Mesh objAnim exist: ${o.objAnim}`, LOG_FUNNY_SMALL);
50
- this.drawElements = this.drawElementsAnim;
51
- }
52
-
53
- this.inputHandler = null;
54
- this.cameras = o.cameras;
55
-
56
- this.mainCameraParams = {
57
- type: o.mainCameraParams.type,
58
- responseCoef: o.mainCameraParams.responseCoef
59
- }
60
-
61
- this.lastFrameMS = 0;
62
- this.texturesPaths = [];
63
- o.texturesPaths.forEach((t) => {this.texturesPaths.push(t)})
64
- this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
65
- this.position = new Position(o.position.x, o.position.y, o.position.z);
66
- this.rotation = new Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
67
- this.rotation.rotationSpeed.x = o.rotationSpeed.x;
68
- this.rotation.rotationSpeed.y = o.rotationSpeed.y;
69
- this.rotation.rotationSpeed.z = o.rotationSpeed.z;
70
- this.scale = o.scale;
71
-
72
- this.runProgram = () => {
73
- return new Promise(async (resolve) => {
74
- this.shadowDepthTextureSize = 1024;
75
- const aspect = canvas.width / canvas.height;
76
- // this.projectionMatrix = mat4.perspective((2 * Math.PI) / 5, aspect, 1, 2000.0);
77
- this.modelViewProjectionMatrix = mat4.create();
78
- // console.log('cube added texturesPaths: ', this.texturesPaths)
79
- this.loadTex0(this.texturesPaths).then(() => {
80
- // console.log('loaded tex buffer for mesh:', this.texture0)
81
- resolve()
82
- })
83
- })
84
- }
85
-
86
- this.runProgram().then(() => {
87
- const aspect = canvas.width / canvas.height;
88
- // const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
89
- this.context.configure({
90
- device: this.device,
91
- format: this.presentationFormat,
92
- alphaMode: 'premultiplied',
93
- });
94
-
95
- // Create the model vertex buffer.
96
- this.vertexBuffer = this.device.createBuffer({
97
- size: this.mesh.vertices.length * Float32Array.BYTES_PER_ELEMENT,
98
- usage: GPUBufferUsage.VERTEX,
99
- mappedAtCreation: true,
100
- });
101
- {
102
- // const mapping = new Float32Array(this.vertexBuffer.getMappedRange());
103
- // // for(let i = 0;i < this.mesh.vertices.length;++i) {
104
- // // mapping.set(this.mesh.vertices[i], 6 * i);
105
- // // mapping.set(this.mesh.normals[i], 6 * i + 3);
106
- // // }
107
- // this.vertexBuffer.unmap();
108
- new Float32Array(this.vertexBuffer.getMappedRange()).set(this.mesh.vertices);
109
- this.vertexBuffer.unmap();
110
- }
111
-
112
- // NIDZA TEST SECOUND BUFFER
113
- // Create the model vertex buffer.
114
- this.vertexNormalsBuffer = this.device.createBuffer({
115
- size: this.mesh.vertexNormals.length * Float32Array.BYTES_PER_ELEMENT,
116
- usage: GPUBufferUsage.VERTEX,
117
- mappedAtCreation: true,
118
- });
119
- {
120
- new Float32Array(this.vertexNormalsBuffer.getMappedRange()).set(this.mesh.vertexNormals);
121
- this.vertexNormalsBuffer.unmap();
122
- }
123
-
124
- this.vertexTexCoordsBuffer = this.device.createBuffer({
125
- size: this.mesh.textures.length * Float32Array.BYTES_PER_ELEMENT,
126
- usage: GPUBufferUsage.VERTEX,
127
- mappedAtCreation: true,
128
- });
129
- {
130
- new Float32Array(this.vertexTexCoordsBuffer.getMappedRange()).set(this.mesh.textures);
131
- this.vertexTexCoordsBuffer.unmap();
132
- }
133
-
134
- // Create the model index buffer.
135
- this.indexCount = this.mesh.indices.length;
136
- const indexCount = this.mesh.indices.length;
137
- const size = Math.ceil(indexCount * Uint16Array.BYTES_PER_ELEMENT / 4) * 4;
138
-
139
- this.indexBuffer = this.device.createBuffer({
140
- size,
141
- usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
142
- mappedAtCreation: true
143
- });
144
-
145
- new Uint16Array(this.indexBuffer.getMappedRange()).set(this.mesh.indices);
146
- this.indexBuffer.unmap();
147
- this.indexCount = indexCount;
148
-
149
- // Create the depth texture for rendering/sampling the shadow map.
150
- this.shadowDepthTexture = this.device.createTexture({
151
- size: [this.shadowDepthTextureSize, this.shadowDepthTextureSize, 1],
152
- usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
153
- format: 'depth32float',
154
- });
155
- this.shadowDepthTextureView = this.shadowDepthTexture.createView();
156
-
157
- // Create some common descriptors used for both the shadow pipeline
158
- // and the color rendering pipeline.
159
- this.vertexBuffers = [
160
- {
161
- arrayStride: Float32Array.BYTES_PER_ELEMENT * 3,
162
- attributes: [
163
- {
164
- // position
165
- shaderLocation: 0,
166
- offset: 0,
167
- format: "float32x3",
168
- }
169
- ],
170
- },
171
- {
172
- arrayStride: Float32Array.BYTES_PER_ELEMENT * 3,
173
- attributes: [
174
- {
175
- // normal
176
- shaderLocation: 1,
177
- offset: 0,
178
- format: "float32x3",
179
- },
180
- ],
181
- },
182
- {
183
- arrayStride: Float32Array.BYTES_PER_ELEMENT * 2,
184
- attributes: [
185
- {
186
- // uvs
187
- shaderLocation: 2,
188
- offset: 0,
189
- format: "float32x2",
190
- },
191
- ],
192
- },
193
- ];
194
-
195
- this.primitive = {
196
- topology: 'triangle-list',
197
- // cullMode: 'back', // ORI
198
- cullMode: 'none', // ORI
199
- };
200
-
201
- this.uniformBufferBindGroupLayout = this.device.createBindGroupLayout({
202
- entries: [
203
- {
204
- binding: 0,
205
- visibility: GPUShaderStage.VERTEX,
206
- buffer: {
207
- type: 'uniform',
208
- },
209
- },
210
- ],
211
- });
212
-
213
- this.shadowPipeline = this.device.createRenderPipeline({
214
- layout: this.device.createPipelineLayout({
215
- bindGroupLayouts: [
216
- this.uniformBufferBindGroupLayout,
217
- this.uniformBufferBindGroupLayout,
218
- ],
219
- }),
220
- vertex: {
221
- module: this.device.createShaderModule({
222
- code: vertexShadowWGSL,
223
- }),
224
- buffers: this.vertexBuffers,
225
- },
226
- depthStencil: {
227
- depthWriteEnabled: true,
228
- depthCompare: 'less',
229
- format: 'depth32float',
230
- },
231
- primitive: this.primitive,
232
- });
233
-
234
- // Create a bind group layout which holds the scene uniforms and
235
- // the texture+sampler for depth. We create it manually because the WebPU
236
- // implementation doesn't infer this from the shader (yet).
237
- this.createLayoutForRender();
238
- this.setupPipeline();
239
-
240
- const depthTexture = this.device.createTexture({
241
- size: [canvas.width, canvas.height],
242
- // format: 'depth24plus-stencil8',
243
- format: 'depth24plus',
244
- usage: GPUTextureUsage.RENDER_ATTACHMENT,
245
- });
246
-
247
- this.renderPassDescriptor = {
248
- colorAttachments: [
249
- {
250
- // view is acquired and set in render loop.
251
- view: undefined,
252
- clearValue: this.clearColor,
253
- loadOp: 'clear', // load old fix for FF
254
- storeOp: 'store',
255
- },
256
- ],
257
- depthStencilAttachment: {
258
- view: depthTexture.createView(),
259
- depthClearValue: 1.0,
260
- depthLoadOp: 'clear',
261
- depthStoreOp: 'store',
262
- // stencilClearValue: 0,
263
- // stencilLoadOp: 'clear',
264
- // stencilStoreOp: 'store',
265
- },
266
- };
267
-
268
- this.modelUniformBuffer = this.device.createBuffer({
269
- size: 4 * 16, // 4x4 matrix
270
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
271
- });
272
-
273
- this.sceneUniformBuffer = this.device.createBuffer({
274
- // Two 4x4 viewProj matrices,
275
- // one for the camera and one for the light.
276
- // Then a vec3 for the light position.
277
- // Rounded to the nearest multiple of 16.
278
- size: 2 * 4 * 16 + 4 * 4,
279
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
280
- });
281
- // cant be global
282
- // console.log('sceneUniformBuffer', sceneUniformBuffer)
283
- // this.sceneUniformBuffer = sceneUniformBuffer;
284
-
285
- this.sceneBindGroupForShadow = this.device.createBindGroup({
286
- layout: this.uniformBufferBindGroupLayout,
287
- entries: [
288
- {
289
- binding: 0,
290
- resource: {
291
- buffer: this.sceneUniformBuffer,
292
- },
293
- },
294
- ],
295
- });
296
-
297
- this.createBindGroupForRender();
298
-
299
- this.modelBindGroup = this.device.createBindGroup({
300
- layout: this.uniformBufferBindGroupLayout,
301
- entries: [
302
- {
303
- binding: 0,
304
- resource: {
305
- buffer: this.modelUniformBuffer,
306
- },
307
- },
308
- ],
309
- });
310
-
311
- // Rotates the camera around the origin based on time.
312
- this.getTransformationMatrix = (pos) => {
313
- const now = Date.now();
314
- const deltaTime = (now - this.lastFrameMS) / this.mainCameraParams.responseCoef;
315
- this.lastFrameMS = now;
316
- // const this.viewMatrix = mat4.identity()
317
- const camera = this.cameras[this.mainCameraParams.type];
318
- this.viewMatrix = camera.update(deltaTime, this.inputHandler());
319
- const scaleVec = [1, 1, 1]; // your desired scale OPTION 1
320
- const scaleMatrix = mat4.scaling(scaleVec);
321
- // Apply scaling
322
- mat4.multiply(scaleMatrix, this.viewMatrix, this.viewMatrix);
323
-
324
- mat4.translate(this.viewMatrix, vec3.fromValues(pos.x, pos.y, pos.z), this.viewMatrix);
325
-
326
- if(this.itIsPhysicsBody == true) {
327
- mat4.rotate(
328
- this.viewMatrix,
329
- vec3.fromValues(this.rotation.axis.x, this.rotation.axis.y, this.rotation.axis.z),
330
- degToRad(this.rotation.angle), this.viewMatrix)
331
- // console.info('angle: ', this.rotation.angle, ' axis ', this.rotation.axis.x, ' , ', this.rotation.axis.y, ' , ', this.rotation.axis.z)
332
- } else {
333
- mat4.rotateX(this.viewMatrix, Math.PI * this.rotation.getRotX(), this.viewMatrix);
334
- mat4.rotateY(this.viewMatrix, Math.PI * this.rotation.getRotY(), this.viewMatrix);
335
- mat4.rotateZ(this.viewMatrix, Math.PI * this.rotation.getRotZ(), this.viewMatrix);
336
- // console.info('NOT PHYSICS angle: ', this.rotation.angle, ' axis ', this.rotation.axis.x, ' , ', this.rotation.axis.y, ' , ', this.rotation.axis.z)
337
- }
338
-
339
- // console.info('NOT camera.projectionMatrix: ', camera.projectionMatrix )
340
- mat4.multiply(camera.projectionMatrix, this.viewMatrix, this.modelViewProjectionMatrix);
341
- return this.modelViewProjectionMatrix;
342
- }
343
-
344
- this.getModelMatrix = (pos) => {
345
- let modelMatrix = mat4.identity();
346
- mat4.translate(modelMatrix, [pos.x, pos.y, pos.z], modelMatrix);
347
- if(this.itIsPhysicsBody) {
348
- mat4.rotate(modelMatrix,
349
- [this.rotation.axis.x, this.rotation.axis.y, this.rotation.axis.z],
350
- degToRad(this.rotation.angle),
351
- modelMatrix
352
- );
353
- } else {
354
- mat4.rotateX(modelMatrix, this.rotation.getRotX(), modelMatrix);
355
- mat4.rotateY(modelMatrix, this.rotation.getRotY(), modelMatrix);
356
- mat4.rotateZ(modelMatrix, this.rotation.getRotZ(), modelMatrix);
357
- }
358
- // Apply scale if you have it, e.g.:
359
- // mat4.scale(modelMatrix, modelMatrix, [this.scale.x, this.scale.y, this.scale.z]);
360
- return modelMatrix;
361
- };
362
-
363
- // looks like affect on transformations for now const 0
364
- const modelMatrix = mat4.translation([0, 0, 0]);
365
- const modelData = modelMatrix;
366
- this.device.queue.writeBuffer(
367
- this.modelUniformBuffer,
368
- 0,
369
- modelData.buffer,
370
- modelData.byteOffset,
371
- modelData.byteLength
372
- );
373
-
374
- this.shadowPassDescriptor = {
375
- colorAttachments: [],
376
- depthStencilAttachment: {
377
- view: this.shadowDepthTextureView,
378
- depthClearValue: 1.0,
379
- depthLoadOp: 'clear',
380
- depthStoreOp: 'store',
381
- },
382
- };
383
-
384
- this.done = true;
385
- }).then(() => {
386
- if(typeof this.objAnim !== 'undefined' && this.objAnim !== null) {
387
- console.log('after all load configutr mesh list buffers')
388
- this.updateMeshListBuffers()
389
- }
390
- })
391
- }
392
-
393
- setupPipeline = () => {
394
- console.log('test >>>>>>>>>>>>>>>>>>>FORMAT>✅' + this.presentationFormat);
395
- this.pipeline = this.device.createRenderPipeline({
396
- layout: this.device.createPipelineLayout({
397
- bindGroupLayouts: [this.bglForRender, this.uniformBufferBindGroupLayout],
398
- }),
399
- vertex: {
400
- entryPoint: 'main', // ✅ Add this
401
- module: this.device.createShaderModule({
402
- code: vertexWGSL,
403
- }),
404
- buffers: this.vertexBuffers,
405
- },
406
- fragment: {
407
- entryPoint: 'main', // ✅ Add this
408
- module: this.device.createShaderModule({
409
- code: (this.isVideo == true ? fragmentVideoWGSL : fragmentWGSL),
410
- }),
411
- targets: [
412
- {
413
- format: this.presentationFormat,
414
- },
415
- ],
416
- constants: {
417
- shadowDepthTextureSize: this.shadowDepthTextureSize,
418
- },
419
- },
420
- depthStencil: {
421
- depthWriteEnabled: true,
422
- depthCompare: 'less',
423
- // format: 'depth24plus-stencil8',
424
- format: 'depth24plus',
425
- },
426
- primitive: this.primitive,
427
- });
428
- }
429
-
430
- draw = () => {
431
- if(this.done == false) return;
432
- const transformationMatrix = this.getTransformationMatrix(this.position);
433
- this.device.queue.writeBuffer(this.sceneUniformBuffer, 64, transformationMatrix.buffer, transformationMatrix.byteOffset, transformationMatrix.byteLength);
434
- this.renderPassDescriptor.colorAttachments[0].view = this.context
435
- .getCurrentTexture()
436
- .createView();
437
- }
438
-
439
- drawElements = (renderPass) => {
440
- if(this.isVideo) {
441
- this.updateVideoTexture();
442
- }
443
- renderPass.setBindGroup(0, this.sceneBindGroupForRender);
444
- renderPass.setBindGroup(1, this.modelBindGroup);
445
- renderPass.setVertexBuffer(0, this.vertexBuffer);
446
- renderPass.setVertexBuffer(1, this.vertexNormalsBuffer);
447
- renderPass.setVertexBuffer(2, this.vertexTexCoordsBuffer);
448
- renderPass.setIndexBuffer(this.indexBuffer, 'uint16');
449
- renderPass.drawIndexed(this.indexCount);
450
- }
451
-
452
- createGPUBuffer(dataArray, usage) {
453
- if(!dataArray || typeof dataArray.length !== 'number') {
454
- throw new Error('Invalid data array passed to createGPUBuffer');
455
- }
456
-
457
- const size = dataArray.length * dataArray.BYTES_PER_ELEMENT;
458
- if(!Number.isFinite(size) || size <= 0) {
459
- throw new Error(`Invalid buffer size: ${size}`);
460
- }
461
-
462
- const buffer = this.device.createBuffer({
463
- size,
464
- usage,
465
- mappedAtCreation: true,
466
- });
467
-
468
- const writeArray = dataArray.constructor === Float32Array
469
- ? new Float32Array(buffer.getMappedRange())
470
- : new Uint16Array(buffer.getMappedRange());
471
-
472
- writeArray.set(dataArray);
473
- buffer.unmap();
474
-
475
- return buffer;
476
- }
477
-
478
- updateMeshListBuffers() {
479
- for(const key in this.objAnim.meshList) {
480
- const mesh = this.objAnim.meshList[key];
481
-
482
- mesh.vertexBuffer = this.device.createBuffer({
483
- size: mesh.vertices.length * Float32Array.BYTES_PER_ELEMENT,
484
- usage: GPUBufferUsage.VERTEX,
485
- mappedAtCreation: true,
486
- });
487
- new Float32Array(mesh.vertexBuffer.getMappedRange()).set(mesh.vertices);
488
- mesh.vertexBuffer.unmap();
489
-
490
- // Normals
491
- mesh.vertexNormalsBuffer = this.device.createBuffer({
492
- size: mesh.vertexNormals.length * Float32Array.BYTES_PER_ELEMENT,
493
- usage: GPUBufferUsage.VERTEX,
494
- mappedAtCreation: true,
495
- });
496
- new Float32Array(mesh.vertexNormalsBuffer.getMappedRange()).set(mesh.vertexNormals);
497
- mesh.vertexNormalsBuffer.unmap();
498
-
499
- // UVs
500
- mesh.vertexTexCoordsBuffer = this.device.createBuffer({
501
- size: mesh.textures.length * Float32Array.BYTES_PER_ELEMENT,
502
- usage: GPUBufferUsage.VERTEX,
503
- mappedAtCreation: true,
504
- });
505
- new Float32Array(mesh.vertexTexCoordsBuffer.getMappedRange()).set(mesh.textures);
506
- mesh.vertexTexCoordsBuffer.unmap();
507
-
508
- // Indices
509
- const indexCount = mesh.indices.length;
510
- const indexSize = Math.ceil(indexCount * Uint16Array.BYTES_PER_ELEMENT / 4) * 4;
511
- mesh.indexBuffer = this.device.createBuffer({
512
- size: indexSize,
513
- usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
514
- mappedAtCreation: true,
515
- });
516
- new Uint16Array(mesh.indexBuffer.getMappedRange()).set(mesh.indices);
517
- mesh.indexBuffer.unmap();
518
- mesh.indexCount = indexCount;
519
- }
520
- }
521
-
522
- drawElementsAnim = (renderPass) => {
523
- renderPass.setBindGroup(0, this.sceneBindGroupForRender);
524
- renderPass.setBindGroup(1, this.modelBindGroup);
525
- const mesh = this.objAnim.meshList[this.objAnim.id + this.objAnim.currentAni];
526
- renderPass.setVertexBuffer(0, mesh.vertexBuffer);
527
- renderPass.setVertexBuffer(1, mesh.vertexNormalsBuffer);
528
- renderPass.setVertexBuffer(2, mesh.vertexTexCoordsBuffer);
529
- renderPass.setIndexBuffer(mesh.indexBuffer, 'uint16');
530
- renderPass.drawIndexed(mesh.indexCount);
531
- if(this.objAnim.playing == true) {
532
- if(this.objAnim.animations[this.objAnim.animations.active].speedCounter >= this.objAnim.animations[this.objAnim.animations.active].speed) {
533
- this.objAnim.currentAni++;
534
- this.objAnim.animations[this.objAnim.animations.active].speedCounter = 0;
535
- } else {
536
- this.objAnim.animations[this.objAnim.animations.active].speedCounter++;
537
- }
538
- if(this.objAnim.currentAni >= this.objAnim.animations[this.objAnim.animations.active].to) {
539
- this.objAnim.currentAni = this.objAnim.animations[this.objAnim.animations.active].from;
540
- }
541
- }
542
- }
543
-
544
- drawShadows = (shadowPass) => {
545
- shadowPass.setBindGroup(0, this.sceneBindGroupForShadow);
546
- shadowPass.setBindGroup(1, this.modelBindGroup);
547
- shadowPass.setVertexBuffer(0, this.vertexBuffer);
548
- shadowPass.setVertexBuffer(1, this.vertexNormalsBuffer);
549
- shadowPass.setVertexBuffer(2, this.vertexTexCoordsBuffer);
550
- shadowPass.setIndexBuffer(this.indexBuffer, 'uint16');
551
- shadowPass.drawIndexed(this.indexCount);
552
- }
553
- }