matrix-engine-wgpu 1.0.1 → 1.0.2
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/LICENSE +22 -17
- package/REFERENCE.md +48 -2
- package/main.js +10 -4
- package/package.json +1 -1
- package/public/app.js +225 -39
- package/readme.md +34 -1
- package/src/engine/ball.js +17 -13
- package/src/engine/cube.js +23 -13
- package/src/engine/engine.js +8 -0
- package/src/engine/matrix-class.js +42 -0
- package/src/meWGPU.js +91 -10
package/LICENSE
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
Copyright 2019 WebGPU Samples Contributors
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
|
4
|
+
modification, are permitted provided that the following conditions are met:
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
6
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
7
|
+
this list of conditions and the following disclaimer.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
|
11
|
+
and/or other materials provided with the distribution.
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
14
|
+
contributors may be used to endorse or promote products derived from this
|
|
15
|
+
software without specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
18
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
19
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
21
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
22
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
23
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
24
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
25
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/REFERENCE.md
CHANGED
|
@@ -1,7 +1,53 @@
|
|
|
1
1
|
|
|
2
|
+
### Best solution for learning:
|
|
2
3
|
|
|
4
|
+
https://webgpufundamentals.org/webgpu/lessons/webgpu-from-webgl.html
|
|
3
5
|
|
|
4
|
-
Best solution for learning:
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
### I got answer from gman at stackoverflow.com :
|
|
8
|
+
|
|
9
|
+
https://stackoverflow.com/questions/78093302/webgpu-i-cant-draw-two-object-in-same-scene/78098135#78098135
|
|
10
|
+
|
|
11
|
+
Interest facts about webGPU tech:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
You can have different pipelines if the things you want to draw actually need different pipelines but if possible you could try to have less pipelines than more. In the example above, if you cube had a different pipeline than the sphere you'd call setPipeline with the sphere's pipeline after drawing the cube and before drawing the sphere.
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Let's assume you only have one pipeline and 2 things you want to draw with that pipeline, a cube, and a sphere. In pseudo code you might do something like this
|
|
19
|
+
|
|
20
|
+
at init time
|
|
21
|
+
create pipeline
|
|
22
|
+
create vertex buffers for cube
|
|
23
|
+
create uniform buffers for cube
|
|
24
|
+
create bindGroup for cube
|
|
25
|
+
create vertex buffers for sphere
|
|
26
|
+
create uniform buffers for sphere
|
|
27
|
+
create bindGroup for cube
|
|
28
|
+
at render time
|
|
29
|
+
create command buffer
|
|
30
|
+
begin render pass
|
|
31
|
+
set pipeline
|
|
32
|
+
set vertex buffers for cube
|
|
33
|
+
set bindGroups for cube
|
|
34
|
+
draw cube
|
|
35
|
+
set vertex buffers for sphere
|
|
36
|
+
set bindgroups for sphere
|
|
37
|
+
draw sphere
|
|
38
|
+
end render pass
|
|
39
|
+
finish command buffer
|
|
40
|
+
submit command buffer
|
|
41
|
+
|
|
42
|
+
Things to notice, there is only one command buffer. There is only 1 render pass.
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
For each render pass, you need to set loadOp and storeOp correctly.
|
|
48
|
+
Most examples that have one render pass set loadOp: 'clear' but in the example above, if render pass 2 had loadOp: 'clear' it would erase the results from render pass 1. Instead it would need to be loadOp: 'load'.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
YEs this is happening " would erase the results from render pass 1 "
|
|
52
|
+
|
|
7
53
|
|
package/main.js
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import MatrixEngineWGPU from "./src/meWGPU";
|
|
2
2
|
|
|
3
|
-
let application = new MatrixEngineWGPU(()=> {
|
|
3
|
+
let application = new MatrixEngineWGPU({ useSingleRenderPass: false }, () => {
|
|
4
4
|
|
|
5
5
|
let c = {
|
|
6
|
-
position: {
|
|
6
|
+
position: {x: -3, y: 0, z: -5},
|
|
7
|
+
rotation: {x: 0, y: 45, z: 0},
|
|
8
|
+
rotationSpeed: {x: 0, y: 0, z: 0},
|
|
7
9
|
texturesPaths: ['./res/textures/rust.jpg']
|
|
8
10
|
};
|
|
9
11
|
|
|
10
12
|
let o = {
|
|
11
|
-
position: {
|
|
13
|
+
position: {x: 3, y: 0, z: -10},
|
|
14
|
+
rotation: {x: 0, y: 45, z: 0},
|
|
15
|
+
rotationSpeed: {x: 0, y: 10, z: 0},
|
|
12
16
|
texturesPaths: ['./res/textures/rust.jpg']
|
|
13
17
|
};
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
|
|
16
20
|
application.addBall(o)
|
|
17
21
|
|
|
22
|
+
application.addCube(c)
|
|
23
|
+
|
|
18
24
|
|
|
19
25
|
})
|
|
20
26
|
|
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -3,25 +3,47 @@
|
|
|
3
3
|
|
|
4
4
|
var _meWGPU = _interopRequireDefault(require("./src/meWGPU"));
|
|
5
5
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6
|
-
let application = new _meWGPU.default(
|
|
6
|
+
let application = new _meWGPU.default({
|
|
7
|
+
useSingleRenderPass: false
|
|
8
|
+
}, () => {
|
|
7
9
|
let c = {
|
|
8
10
|
position: {
|
|
9
|
-
x: -
|
|
10
|
-
y:
|
|
11
|
-
z: -
|
|
11
|
+
x: -3,
|
|
12
|
+
y: 0,
|
|
13
|
+
z: -5
|
|
14
|
+
},
|
|
15
|
+
rotation: {
|
|
16
|
+
x: 0,
|
|
17
|
+
y: 45,
|
|
18
|
+
z: 0
|
|
19
|
+
},
|
|
20
|
+
rotationSpeed: {
|
|
21
|
+
x: 0,
|
|
22
|
+
y: 0,
|
|
23
|
+
z: 0
|
|
12
24
|
},
|
|
13
25
|
texturesPaths: ['./res/textures/rust.jpg']
|
|
14
26
|
};
|
|
15
27
|
let o = {
|
|
16
28
|
position: {
|
|
17
|
-
x:
|
|
18
|
-
y:
|
|
29
|
+
x: 3,
|
|
30
|
+
y: 0,
|
|
19
31
|
z: -10
|
|
20
32
|
},
|
|
33
|
+
rotation: {
|
|
34
|
+
x: 0,
|
|
35
|
+
y: 45,
|
|
36
|
+
z: 0
|
|
37
|
+
},
|
|
38
|
+
rotationSpeed: {
|
|
39
|
+
x: 0,
|
|
40
|
+
y: 10,
|
|
41
|
+
z: 0
|
|
42
|
+
},
|
|
21
43
|
texturesPaths: ['./res/textures/rust.jpg']
|
|
22
44
|
};
|
|
23
|
-
application.addCube(c);
|
|
24
45
|
application.addBall(o);
|
|
46
|
+
application.addCube(c);
|
|
25
47
|
});
|
|
26
48
|
window.app = application;
|
|
27
49
|
|
|
@@ -5386,6 +5408,7 @@ class MEBall {
|
|
|
5386
5408
|
constructor(canvas, device, context, o) {
|
|
5387
5409
|
this.context = context;
|
|
5388
5410
|
this.device = device;
|
|
5411
|
+
this.entityArgPass = o.entityArgPass;
|
|
5389
5412
|
this.SphereLayout = {
|
|
5390
5413
|
vertexStride: 8 * 4,
|
|
5391
5414
|
positionsOffset: 0,
|
|
@@ -5397,6 +5420,10 @@ class MEBall {
|
|
|
5397
5420
|
this.texturesPaths.push(t);
|
|
5398
5421
|
});
|
|
5399
5422
|
this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
|
|
5423
|
+
this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
5424
|
+
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
5425
|
+
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
5426
|
+
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
5400
5427
|
this.shaderModule = device.createShaderModule({
|
|
5401
5428
|
code: _shaders.BALL_SHADER
|
|
5402
5429
|
});
|
|
@@ -5483,26 +5510,23 @@ class MEBall {
|
|
|
5483
5510
|
this.renderables = [this.planet];
|
|
5484
5511
|
|
|
5485
5512
|
// this.ensureEnoughAsteroids(asteroids, this.transform);
|
|
5486
|
-
|
|
5487
5513
|
this.renderPassDescriptor = {
|
|
5488
5514
|
colorAttachments: [{
|
|
5489
5515
|
view: undefined,
|
|
5490
|
-
// Assigned later
|
|
5491
|
-
|
|
5492
5516
|
clearValue: {
|
|
5493
5517
|
r: 0.0,
|
|
5494
5518
|
g: 0.0,
|
|
5495
5519
|
b: 0.0,
|
|
5496
5520
|
a: 1.0
|
|
5497
5521
|
},
|
|
5498
|
-
loadOp:
|
|
5499
|
-
storeOp:
|
|
5522
|
+
loadOp: this.entityArgPass.loadOp,
|
|
5523
|
+
storeOp: this.entityArgPass.storeOp
|
|
5500
5524
|
}],
|
|
5501
5525
|
depthStencilAttachment: {
|
|
5502
5526
|
view: this.depthTexture.createView(),
|
|
5503
5527
|
depthClearValue: 1.0,
|
|
5504
|
-
depthLoadOp:
|
|
5505
|
-
depthStoreOp:
|
|
5528
|
+
depthLoadOp: this.entityArgPass.depthLoadOp,
|
|
5529
|
+
depthStoreOp: this.entityArgPass.depthStoreOp
|
|
5506
5530
|
}
|
|
5507
5531
|
};
|
|
5508
5532
|
const aspect = canvas.width / canvas.height;
|
|
@@ -5614,9 +5638,9 @@ class MEBall {
|
|
|
5614
5638
|
const viewMatrix = _wgpuMatrix.mat4.identity();
|
|
5615
5639
|
_wgpuMatrix.mat4.translate(viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
|
|
5616
5640
|
const now = Date.now() / 1000;
|
|
5617
|
-
_wgpuMatrix.mat4.
|
|
5618
|
-
_wgpuMatrix.mat4.
|
|
5619
|
-
_wgpuMatrix.mat4.
|
|
5641
|
+
_wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
|
|
5642
|
+
_wgpuMatrix.mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
|
|
5643
|
+
_wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
|
|
5620
5644
|
_wgpuMatrix.mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
|
|
5621
5645
|
return this.modelViewProjectionMatrix;
|
|
5622
5646
|
}
|
|
@@ -5722,6 +5746,7 @@ class MEBall {
|
|
|
5722
5746
|
indices: new Uint16Array(indices)
|
|
5723
5747
|
};
|
|
5724
5748
|
}
|
|
5749
|
+
|
|
5725
5750
|
// Render bundles function as partial, limited render passes, so we can use the
|
|
5726
5751
|
// same code both to render the scene normally and to build the render bundle.
|
|
5727
5752
|
renderScene(passEncoder) {
|
|
@@ -5778,6 +5803,8 @@ class MECube {
|
|
|
5778
5803
|
constructor(canvas, device, context, o) {
|
|
5779
5804
|
this.device = device;
|
|
5780
5805
|
this.context = context;
|
|
5806
|
+
this.entityArgPass = o.entityArgPass;
|
|
5807
|
+
console.log('passed args', o.entityArgPass);
|
|
5781
5808
|
this.shaderModule = device.createShaderModule({
|
|
5782
5809
|
code: _shaders.BALL_SHADER
|
|
5783
5810
|
});
|
|
@@ -5787,6 +5814,10 @@ class MECube {
|
|
|
5787
5814
|
});
|
|
5788
5815
|
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
5789
5816
|
this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
|
|
5817
|
+
this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
5818
|
+
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
5819
|
+
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
5820
|
+
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
5790
5821
|
this.pipeline = device.createRenderPipeline({
|
|
5791
5822
|
layout: 'auto',
|
|
5792
5823
|
vertex: {
|
|
@@ -5869,9 +5900,7 @@ class MECube {
|
|
|
5869
5900
|
this.planet.bindGroup = this.createSphereBindGroup(this.texture0, this.transform);
|
|
5870
5901
|
var asteroids = [this.createSphereRenderable(0.2, 8, 6, 0.15), this.createSphereRenderable(0.13, 8, 6, 0.15)];
|
|
5871
5902
|
this.renderables = [this.planet];
|
|
5872
|
-
|
|
5873
5903
|
// this.ensureEnoughAsteroids(asteroids, this.transform);
|
|
5874
|
-
|
|
5875
5904
|
this.renderPassDescriptor = {
|
|
5876
5905
|
colorAttachments: [{
|
|
5877
5906
|
view: undefined,
|
|
@@ -5881,14 +5910,14 @@ class MECube {
|
|
|
5881
5910
|
b: 0.0,
|
|
5882
5911
|
a: 1.0
|
|
5883
5912
|
},
|
|
5884
|
-
loadOp:
|
|
5885
|
-
storeOp:
|
|
5913
|
+
loadOp: this.entityArgPass.loadOp,
|
|
5914
|
+
storeOp: this.entityArgPass.storeOp
|
|
5886
5915
|
}],
|
|
5887
5916
|
depthStencilAttachment: {
|
|
5888
5917
|
view: this.depthTexture.createView(),
|
|
5889
5918
|
depthClearValue: 1.0,
|
|
5890
|
-
depthLoadOp:
|
|
5891
|
-
depthStoreOp:
|
|
5919
|
+
depthLoadOp: this.entityArgPass.depthLoadOp,
|
|
5920
|
+
depthStoreOp: this.entityArgPass.depthStoreOp
|
|
5892
5921
|
}
|
|
5893
5922
|
};
|
|
5894
5923
|
const aspect = canvas.width / canvas.height;
|
|
@@ -5939,7 +5968,7 @@ class MECube {
|
|
|
5939
5968
|
}
|
|
5940
5969
|
}
|
|
5941
5970
|
updateRenderBundle() {
|
|
5942
|
-
console.log('
|
|
5971
|
+
console.log('[CUBE] updateRenderBundle');
|
|
5943
5972
|
const renderBundleEncoder = this.device.createRenderBundleEncoder({
|
|
5944
5973
|
colorFormats: [this.presentationFormat],
|
|
5945
5974
|
depthStencilFormat: 'depth24plus'
|
|
@@ -5997,12 +6026,13 @@ class MECube {
|
|
|
5997
6026
|
return bindGroup;
|
|
5998
6027
|
}
|
|
5999
6028
|
getTransformationMatrix(pos) {
|
|
6029
|
+
// const now = Date.now() / 1000;
|
|
6030
|
+
|
|
6000
6031
|
const viewMatrix = _wgpuMatrix.mat4.identity();
|
|
6001
6032
|
_wgpuMatrix.mat4.translate(viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
|
|
6002
|
-
|
|
6003
|
-
_wgpuMatrix.mat4.
|
|
6004
|
-
_wgpuMatrix.mat4.
|
|
6005
|
-
_wgpuMatrix.mat4.rotateY(viewMatrix, -45, viewMatrix);
|
|
6033
|
+
_wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
|
|
6034
|
+
_wgpuMatrix.mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
|
|
6035
|
+
_wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
|
|
6006
6036
|
_wgpuMatrix.mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
|
|
6007
6037
|
return this.modelViewProjectionMatrix;
|
|
6008
6038
|
}
|
|
@@ -6145,7 +6175,7 @@ exports.default = MECube;
|
|
|
6145
6175
|
Object.defineProperty(exports, "__esModule", {
|
|
6146
6176
|
value: true
|
|
6147
6177
|
});
|
|
6148
|
-
exports.Position = void 0;
|
|
6178
|
+
exports.Rotation = exports.Position = void 0;
|
|
6149
6179
|
// Sub classes for matrix-wgpu
|
|
6150
6180
|
|
|
6151
6181
|
/**
|
|
@@ -6296,6 +6326,48 @@ class Position {
|
|
|
6296
6326
|
}
|
|
6297
6327
|
}
|
|
6298
6328
|
exports.Position = Position;
|
|
6329
|
+
class Rotation {
|
|
6330
|
+
constructor(x, y, z) {
|
|
6331
|
+
// Not in use for nwo this is from matrix-engine project [nameUniq]
|
|
6332
|
+
this.nameUniq = null;
|
|
6333
|
+
if (typeof x == 'undefined') x = 0;
|
|
6334
|
+
if (typeof y == 'undefined') y = 0;
|
|
6335
|
+
if (typeof z == 'undefined') z = 0;
|
|
6336
|
+
this.x = x;
|
|
6337
|
+
this.y = y;
|
|
6338
|
+
this.z = z;
|
|
6339
|
+
this.rotationSpeed = {
|
|
6340
|
+
x: 0,
|
|
6341
|
+
y: 0,
|
|
6342
|
+
z: 0
|
|
6343
|
+
};
|
|
6344
|
+
}
|
|
6345
|
+
getRotX() {
|
|
6346
|
+
if (this.rotationSpeed.x == 0) {
|
|
6347
|
+
return this.x;
|
|
6348
|
+
} else {
|
|
6349
|
+
this.x = this.x + this.rotationSpeed.x * 0.001;
|
|
6350
|
+
return this.x;
|
|
6351
|
+
}
|
|
6352
|
+
}
|
|
6353
|
+
getRotY() {
|
|
6354
|
+
if (this.rotationSpeed.y == 0) {
|
|
6355
|
+
return this.y;
|
|
6356
|
+
} else {
|
|
6357
|
+
this.y = this.y + this.rotationSpeed.y * 0.001;
|
|
6358
|
+
return this.y;
|
|
6359
|
+
}
|
|
6360
|
+
}
|
|
6361
|
+
getRotZ() {
|
|
6362
|
+
if (this.rotationSpeed.z == 0) {
|
|
6363
|
+
return this.z;
|
|
6364
|
+
} else {
|
|
6365
|
+
this.z = this.z + this.rotationSpeed.z * 0.001;
|
|
6366
|
+
return this.z;
|
|
6367
|
+
}
|
|
6368
|
+
}
|
|
6369
|
+
}
|
|
6370
|
+
exports.Rotation = Rotation;
|
|
6299
6371
|
|
|
6300
6372
|
},{}],6:[function(require,module,exports){
|
|
6301
6373
|
"use strict";
|
|
@@ -6307,13 +6379,26 @@ exports.default = void 0;
|
|
|
6307
6379
|
var _ball = _interopRequireDefault(require("./engine/ball.js"));
|
|
6308
6380
|
var _cube = _interopRequireDefault(require("./engine/cube.js"));
|
|
6309
6381
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6310
|
-
// import { mat4, vec3 } from 'wgpu-matrix';
|
|
6311
|
-
// import { createSphereMesh, SphereLayout } from './src/engine/ballsBuffer.js';
|
|
6312
|
-
|
|
6313
6382
|
class MatrixEngineWGPU {
|
|
6314
6383
|
mainRenderBundle = [];
|
|
6315
6384
|
rbContainer = [];
|
|
6316
|
-
|
|
6385
|
+
frame = () => {};
|
|
6386
|
+
entityArgPass = {
|
|
6387
|
+
loadOp: 'clear',
|
|
6388
|
+
storeOp: 'store',
|
|
6389
|
+
depthLoadOp: 'clear',
|
|
6390
|
+
depthStoreOp: 'store'
|
|
6391
|
+
};
|
|
6392
|
+
constructor(options, callback) {
|
|
6393
|
+
console.log('typeof options ', typeof options);
|
|
6394
|
+
console.log('typeof options ', options);
|
|
6395
|
+
if (typeof options == 'undefined' || typeof options == "function") {
|
|
6396
|
+
this.options = {
|
|
6397
|
+
useSingleRenderPass: true
|
|
6398
|
+
};
|
|
6399
|
+
callback = options;
|
|
6400
|
+
}
|
|
6401
|
+
this.options = options;
|
|
6317
6402
|
var canvas = document.createElement('canvas');
|
|
6318
6403
|
canvas.width = window.innerWidth;
|
|
6319
6404
|
canvas.height = window.innerHeight;
|
|
@@ -6340,8 +6425,41 @@ class MatrixEngineWGPU {
|
|
|
6340
6425
|
format: presentationFormat,
|
|
6341
6426
|
alphaMode: 'premultiplied'
|
|
6342
6427
|
});
|
|
6428
|
+
if (this.options.useSingleRenderPass == true) {
|
|
6429
|
+
this.makeDefaultRenderPassDescriptor();
|
|
6430
|
+
this.frame = this.frameSinglePass;
|
|
6431
|
+
} else {
|
|
6432
|
+
// must be
|
|
6433
|
+
this.frame = this.framePassPerObject;
|
|
6434
|
+
}
|
|
6343
6435
|
this.run(callback);
|
|
6344
6436
|
};
|
|
6437
|
+
makeDefaultRenderPassDescriptor = () => {
|
|
6438
|
+
this.depthTexture = this.device.createTexture({
|
|
6439
|
+
size: [this.canvas.width, this.canvas.height],
|
|
6440
|
+
format: 'depth24plus',
|
|
6441
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
6442
|
+
});
|
|
6443
|
+
this.renderPassDescriptor = {
|
|
6444
|
+
colorAttachments: [{
|
|
6445
|
+
view: undefined,
|
|
6446
|
+
clearValue: {
|
|
6447
|
+
r: 0.0,
|
|
6448
|
+
g: 0.0,
|
|
6449
|
+
b: 0.0,
|
|
6450
|
+
a: 1.0
|
|
6451
|
+
},
|
|
6452
|
+
loadOp: 'clear',
|
|
6453
|
+
storeOp: 'store'
|
|
6454
|
+
}],
|
|
6455
|
+
depthStencilAttachment: {
|
|
6456
|
+
view: this.depthTexture.createView(),
|
|
6457
|
+
depthClearValue: 1.0,
|
|
6458
|
+
depthLoadOp: 'clear',
|
|
6459
|
+
depthStoreOp: 'store'
|
|
6460
|
+
}
|
|
6461
|
+
};
|
|
6462
|
+
};
|
|
6345
6463
|
addCube = o => {
|
|
6346
6464
|
if (typeof o === 'undefined') {
|
|
6347
6465
|
var o = {
|
|
@@ -6350,7 +6468,18 @@ class MatrixEngineWGPU {
|
|
|
6350
6468
|
y: 0,
|
|
6351
6469
|
z: -4
|
|
6352
6470
|
},
|
|
6353
|
-
texturesPaths: ['./res/textures/default.png']
|
|
6471
|
+
texturesPaths: ['./res/textures/default.png'],
|
|
6472
|
+
rotation: {
|
|
6473
|
+
x: 0,
|
|
6474
|
+
y: 0,
|
|
6475
|
+
z: 0
|
|
6476
|
+
},
|
|
6477
|
+
rotationSpeed: {
|
|
6478
|
+
x: 0,
|
|
6479
|
+
y: 0,
|
|
6480
|
+
z: 0
|
|
6481
|
+
},
|
|
6482
|
+
entityArgPass: this.entityArgPass
|
|
6354
6483
|
};
|
|
6355
6484
|
} else {
|
|
6356
6485
|
if (typeof o.position === 'undefined') {
|
|
@@ -6360,9 +6489,24 @@ class MatrixEngineWGPU {
|
|
|
6360
6489
|
z: -4
|
|
6361
6490
|
};
|
|
6362
6491
|
}
|
|
6492
|
+
if (typeof o.rotation === 'undefined') {
|
|
6493
|
+
o.rotation = {
|
|
6494
|
+
x: 0,
|
|
6495
|
+
y: 0,
|
|
6496
|
+
z: 0
|
|
6497
|
+
};
|
|
6498
|
+
}
|
|
6499
|
+
if (typeof o.rotationSpeed === 'undefined') {
|
|
6500
|
+
o.rotationSpeed = {
|
|
6501
|
+
x: 0,
|
|
6502
|
+
y: 0,
|
|
6503
|
+
z: 0
|
|
6504
|
+
};
|
|
6505
|
+
}
|
|
6363
6506
|
if (typeof o.texturesPaths === 'undefined') {
|
|
6364
6507
|
o.texturesPaths = ['./res/textures/default.png'];
|
|
6365
6508
|
}
|
|
6509
|
+
o.entityArgPass = this.entityArgPass;
|
|
6366
6510
|
}
|
|
6367
6511
|
let myCube1 = new _cube.default(this.canvas, this.device, this.context, o);
|
|
6368
6512
|
this.mainRenderBundle.push(myCube1);
|
|
@@ -6375,7 +6519,18 @@ class MatrixEngineWGPU {
|
|
|
6375
6519
|
y: 0,
|
|
6376
6520
|
z: -4
|
|
6377
6521
|
},
|
|
6378
|
-
texturesPaths: ['./res/textures/default.png']
|
|
6522
|
+
texturesPaths: ['./res/textures/default.png'],
|
|
6523
|
+
rotation: {
|
|
6524
|
+
x: 0,
|
|
6525
|
+
y: 0,
|
|
6526
|
+
z: 0
|
|
6527
|
+
},
|
|
6528
|
+
rotationSpeed: {
|
|
6529
|
+
x: 0,
|
|
6530
|
+
y: 0,
|
|
6531
|
+
z: 0
|
|
6532
|
+
},
|
|
6533
|
+
entityArgPass: this.entityArgPass
|
|
6379
6534
|
};
|
|
6380
6535
|
} else {
|
|
6381
6536
|
if (typeof o.position === 'undefined') {
|
|
@@ -6385,9 +6540,24 @@ class MatrixEngineWGPU {
|
|
|
6385
6540
|
z: -4
|
|
6386
6541
|
};
|
|
6387
6542
|
}
|
|
6543
|
+
if (typeof o.rotation === 'undefined') {
|
|
6544
|
+
o.rotation = {
|
|
6545
|
+
x: 0,
|
|
6546
|
+
y: 0,
|
|
6547
|
+
z: 0
|
|
6548
|
+
};
|
|
6549
|
+
}
|
|
6550
|
+
if (typeof o.rotationSpeed === 'undefined') {
|
|
6551
|
+
o.rotationSpeed = {
|
|
6552
|
+
x: 0,
|
|
6553
|
+
y: 0,
|
|
6554
|
+
z: 0
|
|
6555
|
+
};
|
|
6556
|
+
}
|
|
6388
6557
|
if (typeof o.texturesPaths === 'undefined') {
|
|
6389
6558
|
o.texturesPaths = ['./res/textures/default.png'];
|
|
6390
6559
|
}
|
|
6560
|
+
o.entityArgPass = this.entityArgPass;
|
|
6391
6561
|
}
|
|
6392
6562
|
let myBall1 = new _ball.default(this.canvas, this.device, this.context, o);
|
|
6393
6563
|
this.mainRenderBundle.push(myBall1);
|
|
@@ -6400,22 +6570,38 @@ class MatrixEngineWGPU {
|
|
|
6400
6570
|
callback();
|
|
6401
6571
|
}, 10);
|
|
6402
6572
|
}
|
|
6403
|
-
|
|
6573
|
+
frameSinglePass = () => {
|
|
6574
|
+
console.log('single');
|
|
6404
6575
|
let commandEncoder = this.device.createCommandEncoder();
|
|
6405
6576
|
this.rbContainer = [];
|
|
6406
6577
|
let passEncoder;
|
|
6407
6578
|
this.mainRenderBundle.forEach((meItem, index) => {
|
|
6408
6579
|
meItem.draw();
|
|
6409
6580
|
this.rbContainer.push(meItem.renderBundle);
|
|
6410
|
-
if
|
|
6581
|
+
// if(index == 0) passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
|
|
6411
6582
|
});
|
|
6412
|
-
|
|
6413
|
-
|
|
6583
|
+
this.renderPassDescriptor.colorAttachments[0].view = this.context.getCurrentTexture().createView();
|
|
6584
|
+
passEncoder = commandEncoder.beginRenderPass(this.renderPassDescriptor);
|
|
6414
6585
|
passEncoder.executeBundles(this.rbContainer);
|
|
6415
6586
|
passEncoder.end();
|
|
6416
6587
|
this.device.queue.submit([commandEncoder.finish()]);
|
|
6417
6588
|
requestAnimationFrame(this.frame);
|
|
6418
6589
|
};
|
|
6590
|
+
framePassPerObject = () => {
|
|
6591
|
+
console.log('framePassPerObject');
|
|
6592
|
+
let commandEncoder = this.device.createCommandEncoder();
|
|
6593
|
+
this.rbContainer = [];
|
|
6594
|
+
let passEncoder;
|
|
6595
|
+
this.mainRenderBundle.forEach((meItem, index) => {
|
|
6596
|
+
meItem.draw();
|
|
6597
|
+
this.rbContainer.push(meItem.renderBundle);
|
|
6598
|
+
passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
|
|
6599
|
+
passEncoder.executeBundles(this.rbContainer);
|
|
6600
|
+
passEncoder.end();
|
|
6601
|
+
});
|
|
6602
|
+
this.device.queue.submit([commandEncoder.finish()]);
|
|
6603
|
+
requestAnimationFrame(this.frame);
|
|
6604
|
+
};
|
|
6419
6605
|
}
|
|
6420
6606
|
exports.default = MatrixEngineWGPU;
|
|
6421
6607
|
|
package/readme.md
CHANGED
|
@@ -23,6 +23,9 @@ I publish (this repo) npm package with name `matrix-engine-wgpu`.
|
|
|
23
23
|
|
|
24
24
|
For now i will use `createRenderBundleEncoder` for multi object scene draws.
|
|
25
25
|
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
26
29
|
Main instance script:
|
|
27
30
|
```js
|
|
28
31
|
let application = new MatrixEngineWGPU(()=> {
|
|
@@ -69,6 +72,36 @@ frame = () => {
|
|
|
69
72
|
|
|
70
73
|
## LICENCE
|
|
71
74
|
|
|
72
|
-
- MIT LICENCE - Nikola Lukic zlatnaspirala@gmail.com 2024
|
|
73
75
|
- Structural shema for project and personal learning inspired by:
|
|
74
76
|
https://webgpu.github.io/webgpu-samples/samples/renderBundles
|
|
77
|
+
|
|
78
|
+
### BSD 3-Clause
|
|
79
|
+
|
|
80
|
+
https://github.com/webgpu/webgpu-samples/blob/main/LICENSE.txt
|
|
81
|
+
|
|
82
|
+
Copyright 2019 WebGPU Samples Contributors
|
|
83
|
+
|
|
84
|
+
Redistribution and use in source and binary forms, with or without
|
|
85
|
+
modification, are permitted provided that the following conditions are met:
|
|
86
|
+
|
|
87
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
88
|
+
this list of conditions and the following disclaimer.
|
|
89
|
+
|
|
90
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
91
|
+
this list of conditions and the following disclaimer in the documentation
|
|
92
|
+
and/or other materials provided with the distribution.
|
|
93
|
+
|
|
94
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
95
|
+
contributors may be used to endorse or promote products derived from this
|
|
96
|
+
software without specific prior written permission.
|
|
97
|
+
|
|
98
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
99
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
100
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
101
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
102
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
103
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
104
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
105
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
106
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
107
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/src/engine/ball.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {BALL_SHADER} from "../shaders/shaders";
|
|
2
2
|
import {mat4, vec3} from 'wgpu-matrix';
|
|
3
|
-
import {Position} from "./matrix-class";
|
|
3
|
+
import {Position, Rotation} from "./matrix-class";
|
|
4
4
|
|
|
5
5
|
export default class MEBall {
|
|
6
6
|
|
|
@@ -8,6 +8,8 @@ export default class MEBall {
|
|
|
8
8
|
this.context = context;
|
|
9
9
|
this.device = device;
|
|
10
10
|
|
|
11
|
+
this.entityArgPass = o.entityArgPass;
|
|
12
|
+
|
|
11
13
|
this.SphereLayout = {
|
|
12
14
|
vertexStride: 8 * 4,
|
|
13
15
|
positionsOffset: 0,
|
|
@@ -22,6 +24,11 @@ export default class MEBall {
|
|
|
22
24
|
})
|
|
23
25
|
|
|
24
26
|
this.position = new Position(o.position.x, o.position.y, o.position.z)
|
|
27
|
+
this.rotation = new Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
28
|
+
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
29
|
+
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
30
|
+
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
31
|
+
|
|
25
32
|
this.shaderModule = device.createShaderModule({code: BALL_SHADER});
|
|
26
33
|
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
27
34
|
|
|
@@ -128,23 +135,20 @@ export default class MEBall {
|
|
|
128
135
|
this.renderables = [this.planet];
|
|
129
136
|
|
|
130
137
|
// this.ensureEnoughAsteroids(asteroids, this.transform);
|
|
131
|
-
|
|
132
138
|
this.renderPassDescriptor = {
|
|
133
139
|
colorAttachments: [
|
|
134
140
|
{
|
|
135
|
-
view: undefined,
|
|
136
|
-
|
|
141
|
+
view: undefined,
|
|
137
142
|
clearValue: {r: 0.0, g: 0.0, b: 0.0, a: 1.0},
|
|
138
|
-
loadOp:
|
|
139
|
-
storeOp:
|
|
143
|
+
loadOp: this.entityArgPass.loadOp,
|
|
144
|
+
storeOp: this.entityArgPass.storeOp,
|
|
140
145
|
},
|
|
141
146
|
],
|
|
142
147
|
depthStencilAttachment: {
|
|
143
148
|
view: this.depthTexture.createView(),
|
|
144
|
-
|
|
145
149
|
depthClearValue: 1.0,
|
|
146
|
-
depthLoadOp:
|
|
147
|
-
depthStoreOp:
|
|
150
|
+
depthLoadOp: this.entityArgPass.depthLoadOp,
|
|
151
|
+
depthStoreOp: this.entityArgPass.depthStoreOp,
|
|
148
152
|
},
|
|
149
153
|
};
|
|
150
154
|
|
|
@@ -281,9 +285,9 @@ export default class MEBall {
|
|
|
281
285
|
mat4.translate(viewMatrix, vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
|
|
282
286
|
const now = Date.now() / 1000;
|
|
283
287
|
|
|
284
|
-
mat4.
|
|
285
|
-
mat4.
|
|
286
|
-
mat4.
|
|
288
|
+
mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
|
|
289
|
+
mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
|
|
290
|
+
mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
|
|
287
291
|
|
|
288
292
|
mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
|
|
289
293
|
return this.modelViewProjectionMatrix;
|
|
@@ -402,12 +406,12 @@ export default class MEBall {
|
|
|
402
406
|
}
|
|
403
407
|
}
|
|
404
408
|
|
|
405
|
-
|
|
406
409
|
return {
|
|
407
410
|
vertices: new Float32Array(vertices),
|
|
408
411
|
indices: new Uint16Array(indices),
|
|
409
412
|
};
|
|
410
413
|
}
|
|
414
|
+
|
|
411
415
|
// Render bundles function as partial, limited render passes, so we can use the
|
|
412
416
|
// same code both to render the scene normally and to build the render bundle.
|
|
413
417
|
renderScene(passEncoder) {
|
package/src/engine/cube.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {BALL_SHADER} from "../shaders/shaders";
|
|
2
2
|
import {mat4, vec3} from 'wgpu-matrix';
|
|
3
|
-
import {Position} from "./matrix-class";
|
|
3
|
+
import {Position, Rotation} from "./matrix-class";
|
|
4
4
|
|
|
5
5
|
var SphereLayout = {
|
|
6
6
|
vertexStride: 8 * 4,
|
|
@@ -15,6 +15,9 @@ export default class MECube {
|
|
|
15
15
|
this.device = device;
|
|
16
16
|
this.context = context;
|
|
17
17
|
|
|
18
|
+
this.entityArgPass = o.entityArgPass;
|
|
19
|
+
|
|
20
|
+
console.log('passed args', o.entityArgPass)
|
|
18
21
|
this.shaderModule = device.createShaderModule({
|
|
19
22
|
code: BALL_SHADER,
|
|
20
23
|
});
|
|
@@ -26,7 +29,11 @@ export default class MECube {
|
|
|
26
29
|
})
|
|
27
30
|
|
|
28
31
|
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
29
|
-
this.position = new Position(o.position.x, o.position.y, o.position.z)
|
|
32
|
+
this.position = new Position(o.position.x, o.position.y, o.position.z);
|
|
33
|
+
this.rotation = new Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
34
|
+
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
35
|
+
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
36
|
+
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
30
37
|
this.pipeline = device.createRenderPipeline({
|
|
31
38
|
layout: 'auto',
|
|
32
39
|
vertex: {
|
|
@@ -109,23 +116,21 @@ export default class MECube {
|
|
|
109
116
|
];
|
|
110
117
|
|
|
111
118
|
this.renderables = [this.planet];
|
|
112
|
-
|
|
113
119
|
// this.ensureEnoughAsteroids(asteroids, this.transform);
|
|
114
|
-
|
|
115
120
|
this.renderPassDescriptor = {
|
|
116
121
|
colorAttachments: [
|
|
117
122
|
{
|
|
118
123
|
view: undefined,
|
|
119
124
|
clearValue: {r: 0.0, g: 0.0, b: 0.0, a: 1.0},
|
|
120
|
-
loadOp:
|
|
121
|
-
storeOp:
|
|
125
|
+
loadOp: this.entityArgPass.loadOp,
|
|
126
|
+
storeOp: this.entityArgPass.storeOp,
|
|
122
127
|
},
|
|
123
128
|
],
|
|
124
129
|
depthStencilAttachment: {
|
|
125
130
|
view: this.depthTexture.createView(),
|
|
126
131
|
depthClearValue: 1.0,
|
|
127
|
-
depthLoadOp:
|
|
128
|
-
depthStoreOp:
|
|
132
|
+
depthLoadOp: this.entityArgPass.depthLoadOp,
|
|
133
|
+
depthStoreOp: this.entityArgPass.depthStoreOp,
|
|
129
134
|
},
|
|
130
135
|
};
|
|
131
136
|
|
|
@@ -181,7 +186,7 @@ export default class MECube {
|
|
|
181
186
|
}
|
|
182
187
|
|
|
183
188
|
updateRenderBundle() {
|
|
184
|
-
console.log('
|
|
189
|
+
console.log('[CUBE] updateRenderBundle')
|
|
185
190
|
const renderBundleEncoder = this.device.createRenderBundleEncoder({
|
|
186
191
|
colorFormats: [this.presentationFormat],
|
|
187
192
|
depthStencilFormat: 'depth24plus',
|
|
@@ -252,14 +257,19 @@ export default class MECube {
|
|
|
252
257
|
}
|
|
253
258
|
|
|
254
259
|
getTransformationMatrix(pos) {
|
|
260
|
+
// const now = Date.now() / 1000;
|
|
261
|
+
|
|
255
262
|
const viewMatrix = mat4.identity();
|
|
263
|
+
|
|
256
264
|
mat4.translate(viewMatrix, vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
|
|
257
|
-
|
|
258
|
-
mat4.
|
|
259
|
-
mat4.
|
|
260
|
-
mat4.
|
|
265
|
+
|
|
266
|
+
mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
|
|
267
|
+
mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
|
|
268
|
+
mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
|
|
269
|
+
|
|
261
270
|
mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
|
|
262
271
|
return this.modelViewProjectionMatrix;
|
|
272
|
+
|
|
263
273
|
}
|
|
264
274
|
|
|
265
275
|
async loadTex1(device) {
|
|
@@ -169,3 +169,45 @@ export class Position {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
export class Rotation {
|
|
173
|
+
|
|
174
|
+
constructor(x, y, z) {
|
|
175
|
+
// Not in use for nwo this is from matrix-engine project [nameUniq]
|
|
176
|
+
this.nameUniq = null;
|
|
177
|
+
if(typeof x == 'undefined') x = 0;
|
|
178
|
+
if(typeof y == 'undefined') y = 0;
|
|
179
|
+
if(typeof z == 'undefined') z = 0;
|
|
180
|
+
this.x = x;
|
|
181
|
+
this.y = y;
|
|
182
|
+
this.z = z;
|
|
183
|
+
this.rotationSpeed = {x: 0, y: 0, z: 0}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
getRotX () {
|
|
187
|
+
if (this.rotationSpeed.x == 0) {
|
|
188
|
+
return this.x;
|
|
189
|
+
} else {
|
|
190
|
+
this.x = this.x + this.rotationSpeed.x* 0.001;
|
|
191
|
+
return this.x;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
getRotY () {
|
|
196
|
+
if (this.rotationSpeed.y == 0) {
|
|
197
|
+
return this.y;
|
|
198
|
+
} else {
|
|
199
|
+
this.y = this.y + this.rotationSpeed.y * 0.001;
|
|
200
|
+
return this.y;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
getRotZ () {
|
|
205
|
+
if (this.rotationSpeed.z == 0) {
|
|
206
|
+
return this.z;
|
|
207
|
+
} else {
|
|
208
|
+
this.z = this.z + this.rotationSpeed.z* 0.001;
|
|
209
|
+
return this.z;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
}
|
package/src/meWGPU.js
CHANGED
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
import MEBall from "./engine/ball.js";
|
|
2
2
|
import MECube from './engine/cube.js';
|
|
3
|
-
// import { mat4, vec3 } from 'wgpu-matrix';
|
|
4
|
-
// import { createSphereMesh, SphereLayout } from './src/engine/ballsBuffer.js';
|
|
5
3
|
|
|
6
4
|
export default class MatrixEngineWGPU {
|
|
7
5
|
|
|
8
6
|
mainRenderBundle = [];
|
|
9
7
|
rbContainer = [];
|
|
8
|
+
frame = () => {};
|
|
9
|
+
|
|
10
|
+
entityArgPass = {
|
|
11
|
+
loadOp: 'clear',
|
|
12
|
+
storeOp: 'store',
|
|
13
|
+
depthLoadOp: 'clear',
|
|
14
|
+
depthStoreOp: 'store'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
constructor(options, callback) {
|
|
18
|
+
console.log('typeof options ', typeof options )
|
|
19
|
+
console.log('typeof options ', options )
|
|
20
|
+
if (typeof options == 'undefined' || typeof options == "function") {
|
|
21
|
+
this.options = {
|
|
22
|
+
useSingleRenderPass: true
|
|
23
|
+
}
|
|
24
|
+
callback = options;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.options = options;
|
|
10
28
|
|
|
11
|
-
constructor(callback) {
|
|
12
29
|
var canvas = document.createElement('canvas')
|
|
13
30
|
canvas.width = window.innerWidth;
|
|
14
31
|
canvas.height = window.innerHeight;
|
|
15
32
|
document.body.append(canvas)
|
|
16
|
-
|
|
17
33
|
this.init({canvas, callback})
|
|
18
34
|
}
|
|
19
35
|
|
|
@@ -34,18 +50,58 @@ export default class MatrixEngineWGPU {
|
|
|
34
50
|
alphaMode: 'premultiplied',
|
|
35
51
|
});
|
|
36
52
|
|
|
53
|
+
if(this.options.useSingleRenderPass == true) {
|
|
54
|
+
this.makeDefaultRenderPassDescriptor()
|
|
55
|
+
this.frame = this.frameSinglePass;
|
|
56
|
+
} else {
|
|
57
|
+
// must be
|
|
58
|
+
this.frame = this.framePassPerObject;
|
|
59
|
+
}
|
|
60
|
+
|
|
37
61
|
this.run(callback)
|
|
38
62
|
};
|
|
39
63
|
|
|
64
|
+
makeDefaultRenderPassDescriptor = () => {
|
|
65
|
+
|
|
66
|
+
this.depthTexture = this.device.createTexture({
|
|
67
|
+
size: [this.canvas.width, this.canvas.height],
|
|
68
|
+
format: 'depth24plus',
|
|
69
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
this.renderPassDescriptor = {
|
|
73
|
+
colorAttachments: [
|
|
74
|
+
{
|
|
75
|
+
view: undefined,
|
|
76
|
+
clearValue: {r: 0.0, g: 0.0, b: 0.0, a: 1.0},
|
|
77
|
+
loadOp: 'clear',
|
|
78
|
+
storeOp: 'store',
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
depthStencilAttachment: {
|
|
82
|
+
view: this.depthTexture.createView(),
|
|
83
|
+
depthClearValue: 1.0,
|
|
84
|
+
depthLoadOp: 'clear',
|
|
85
|
+
depthStoreOp: 'store',
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
40
90
|
addCube = (o) => {
|
|
41
91
|
if(typeof o === 'undefined') {
|
|
42
92
|
var o = {
|
|
43
93
|
position: {x: 0, y: 0, z: -4},
|
|
44
|
-
texturesPaths: ['./res/textures/default.png']
|
|
94
|
+
texturesPaths: ['./res/textures/default.png'],
|
|
95
|
+
rotation: {x: 0, y: 0, z: 0},
|
|
96
|
+
rotationSpeed: {x: 0, y: 0, z: 0},
|
|
97
|
+
entityArgPass: this.entityArgPass
|
|
45
98
|
}
|
|
46
99
|
} else {
|
|
47
100
|
if(typeof o.position === 'undefined') {o.position = {x: 0, y: 0, z: -4}}
|
|
101
|
+
if(typeof o.rotation === 'undefined') {o.rotation = {x: 0, y: 0, z: 0}}
|
|
102
|
+
if(typeof o.rotationSpeed === 'undefined') {o.rotationSpeed = {x: 0, y: 0, z: 0}}
|
|
48
103
|
if(typeof o.texturesPaths === 'undefined') {o.texturesPaths = ['./res/textures/default.png']}
|
|
104
|
+
o.entityArgPass = this.entityArgPass;
|
|
49
105
|
}
|
|
50
106
|
let myCube1 = new MECube(this.canvas, this.device, this.context, o)
|
|
51
107
|
this.mainRenderBundle.push(myCube1);
|
|
@@ -55,11 +111,17 @@ export default class MatrixEngineWGPU {
|
|
|
55
111
|
if(typeof o === 'undefined') {
|
|
56
112
|
var o = {
|
|
57
113
|
position: {x: 0, y: 0, z: -4},
|
|
58
|
-
texturesPaths: ['./res/textures/default.png']
|
|
114
|
+
texturesPaths: ['./res/textures/default.png'],
|
|
115
|
+
rotation: {x: 0, y: 0, z: 0},
|
|
116
|
+
rotationSpeed: {x: 0, y: 0, z: 0},
|
|
117
|
+
entityArgPass: this.entityArgPass
|
|
59
118
|
}
|
|
60
119
|
} else {
|
|
61
120
|
if(typeof o.position === 'undefined') {o.position = {x: 0, y: 0, z: -4}}
|
|
121
|
+
if(typeof o.rotation === 'undefined') {o.rotation = {x: 0, y: 0, z: 0}}
|
|
122
|
+
if(typeof o.rotationSpeed === 'undefined') {o.rotationSpeed = {x: 0, y: 0, z: 0}}
|
|
62
123
|
if(typeof o.texturesPaths === 'undefined') {o.texturesPaths = ['./res/textures/default.png']}
|
|
124
|
+
o.entityArgPass = this.entityArgPass;
|
|
63
125
|
}
|
|
64
126
|
let myBall1 = new MEBall(this.canvas, this.device, this.context, o)
|
|
65
127
|
this.mainRenderBundle.push(myBall1);
|
|
@@ -70,23 +132,42 @@ export default class MatrixEngineWGPU {
|
|
|
70
132
|
setTimeout(() => {callback()}, 10)
|
|
71
133
|
}
|
|
72
134
|
|
|
73
|
-
|
|
135
|
+
frameSinglePass = () => {
|
|
136
|
+
console.log('single')
|
|
74
137
|
let commandEncoder = this.device.createCommandEncoder();
|
|
75
138
|
this.rbContainer = [];
|
|
76
|
-
|
|
77
139
|
let passEncoder;
|
|
78
140
|
|
|
79
141
|
this.mainRenderBundle.forEach((meItem, index) => {
|
|
80
142
|
meItem.draw();
|
|
81
143
|
this.rbContainer.push(meItem.renderBundle)
|
|
82
|
-
if(index == 0) passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
|
|
144
|
+
// if(index == 0) passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
|
|
83
145
|
})
|
|
84
146
|
|
|
85
|
-
|
|
147
|
+
this.renderPassDescriptor.colorAttachments[0].view = this.context
|
|
148
|
+
.getCurrentTexture()
|
|
149
|
+
.createView();
|
|
150
|
+
|
|
151
|
+
passEncoder = commandEncoder.beginRenderPass(this.renderPassDescriptor);
|
|
86
152
|
passEncoder.executeBundles(this.rbContainer);
|
|
87
153
|
passEncoder.end();
|
|
88
154
|
this.device.queue.submit([commandEncoder.finish()]);
|
|
155
|
+
requestAnimationFrame(this.frame);
|
|
156
|
+
}
|
|
89
157
|
|
|
158
|
+
framePassPerObject = () => {
|
|
159
|
+
console.log('framePassPerObject')
|
|
160
|
+
let commandEncoder = this.device.createCommandEncoder();
|
|
161
|
+
this.rbContainer = [];
|
|
162
|
+
let passEncoder;
|
|
163
|
+
this.mainRenderBundle.forEach((meItem, index) => {
|
|
164
|
+
meItem.draw();
|
|
165
|
+
this.rbContainer.push(meItem.renderBundle)
|
|
166
|
+
passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
|
|
167
|
+
passEncoder.executeBundles(this.rbContainer);
|
|
168
|
+
passEncoder.end();
|
|
169
|
+
})
|
|
170
|
+
this.device.queue.submit([commandEncoder.finish()]);
|
|
90
171
|
requestAnimationFrame(this.frame);
|
|
91
172
|
}
|
|
92
173
|
}
|