matrix-engine-wgpu 1.0.1 → 1.0.4
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/app-worker.js +45 -0
- package/empty.js +12 -0
- package/examples/load-obj-file.js +48 -0
- package/examples/unlit-textures.js +27 -0
- package/examples.js +7 -0
- package/index.js +18 -5
- package/main.js +29 -12
- package/package.json +11 -2
- package/public/app-worker.js +47 -0
- package/public/app.js +2833 -279
- package/public/css/style.css +1 -2
- package/public/empty.html +25 -0
- package/public/empty.js +9107 -0
- package/public/examples.html +25 -0
- package/public/examples.js +9180 -0
- package/public/res/meshes/blender/piramyd.blend +0 -0
- package/public/res/meshes/blender/piramyd.blend1 +0 -0
- package/public/res/meshes/blender/piramyd.js +42 -0
- package/public/res/meshes/blender/piramyd.mtl +10 -0
- package/public/res/meshes/blender/piramyd.obj +18696 -0
- package/public/res/meshes/blender/piramyd1.js +42 -0
- package/public/res/meshes/blender/welcomeTextblend.blend +0 -0
- package/public/res/meshes/dragon/stanfordDragonData.js +5 -0
- package/public/res/meshes/obj/armor.obj +319 -0
- package/public/res/meshes/obj/armor.png +0 -0
- package/public/worker.html +25 -0
- package/readme.md +77 -36
- package/src/engine/ball.js +43 -23
- package/src/engine/cube.js +112 -87
- package/src/engine/engine.js +470 -0
- package/src/engine/final/adaptJSON1.js +53 -0
- package/src/engine/final/utils2.js +63 -0
- package/src/engine/loader-obj.js +469 -0
- package/src/engine/matrix-class.js +44 -1
- package/src/engine/matrix-mesh.js +49 -0
- package/src/engine/mesh-obj.js +526 -0
- package/src/engine/mesh.js +477 -0
- package/src/engine/utils.js +2 -0
- package/src/shaders/fragment.wgsl.js +48 -0
- package/src/shaders/shaders.js +4 -124
- package/src/shaders/vertex.wgsl.js +49 -0
- package/src/shaders/vertexShadow.wgsl.js +20 -0
- package/src/world.js +263 -0
- package/src/meWGPU.js +0 -92
package/public/app.js
CHANGED
|
@@ -1,31 +1,68 @@
|
|
|
1
1
|
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.application = void 0;
|
|
8
|
+
var _world = _interopRequireDefault(require("./src/world.js"));
|
|
9
|
+
var _loaderObj = require("./src/engine/loader-obj.js");
|
|
5
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6
|
-
let application = new
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
let application = exports.application = new _world.default({
|
|
12
|
+
useSingleRenderPass: false,
|
|
13
|
+
canvasSize: 'fullscreen'
|
|
14
|
+
}, () => {
|
|
15
|
+
function onLoadObj(m) {
|
|
16
|
+
console.log('Loaded objs:', m);
|
|
17
|
+
application.addMeshObj({
|
|
18
|
+
position: {
|
|
19
|
+
x: -3,
|
|
20
|
+
y: 0,
|
|
21
|
+
z: -5
|
|
22
|
+
},
|
|
23
|
+
rotation: {
|
|
24
|
+
x: 0,
|
|
25
|
+
y: 0,
|
|
26
|
+
z: 0
|
|
27
|
+
},
|
|
28
|
+
rotationSpeed: {
|
|
29
|
+
x: 0,
|
|
30
|
+
y: 10,
|
|
31
|
+
z: 0
|
|
32
|
+
},
|
|
33
|
+
texturesPaths: ['./res/meshes/obj/armor.png'],
|
|
34
|
+
name: 'Armor',
|
|
35
|
+
mesh: m.armor
|
|
36
|
+
});
|
|
37
|
+
application.addMeshObj({
|
|
38
|
+
position: {
|
|
39
|
+
x: 3,
|
|
40
|
+
y: 0,
|
|
41
|
+
z: -5
|
|
42
|
+
},
|
|
43
|
+
rotation: {
|
|
44
|
+
x: -90,
|
|
45
|
+
y: 0,
|
|
46
|
+
z: 0
|
|
47
|
+
},
|
|
48
|
+
rotationSpeed: {
|
|
49
|
+
x: 0,
|
|
50
|
+
y: 0,
|
|
51
|
+
z: 0
|
|
52
|
+
},
|
|
53
|
+
texturesPaths: ['./res/meshes/obj/armor.png'],
|
|
54
|
+
name: 'MyText',
|
|
55
|
+
mesh: m.welcomeText
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
(0, _loaderObj.downloadMeshes)({
|
|
59
|
+
welcomeText: "./res/meshes/blender/piramyd.obj",
|
|
60
|
+
armor: "./res/meshes/obj/armor.obj"
|
|
61
|
+
}, onLoadObj);
|
|
25
62
|
});
|
|
26
63
|
window.app = application;
|
|
27
64
|
|
|
28
|
-
},{"./src/
|
|
65
|
+
},{"./src/engine/loader-obj.js":6,"./src/world.js":15}],2:[function(require,module,exports){
|
|
29
66
|
"use strict";
|
|
30
67
|
|
|
31
68
|
Object.defineProperty(exports, "__esModule", {
|
|
@@ -5382,10 +5419,24 @@ exports.default = void 0;
|
|
|
5382
5419
|
var _shaders = require("../shaders/shaders");
|
|
5383
5420
|
var _wgpuMatrix = require("wgpu-matrix");
|
|
5384
5421
|
var _matrixClass = require("./matrix-class");
|
|
5422
|
+
var _engine = require("./engine");
|
|
5385
5423
|
class MEBall {
|
|
5386
5424
|
constructor(canvas, device, context, o) {
|
|
5387
5425
|
this.context = context;
|
|
5388
5426
|
this.device = device;
|
|
5427
|
+
|
|
5428
|
+
// The input handler
|
|
5429
|
+
this.inputHandler = (0, _engine.createInputHandler)(window, canvas);
|
|
5430
|
+
this.cameras = o.cameras;
|
|
5431
|
+
this.scale = o.scale;
|
|
5432
|
+
console.log('passed : o.mainCameraParams.responseCoef ', o.mainCameraParams.responseCoef);
|
|
5433
|
+
this.cameraParams = {
|
|
5434
|
+
type: o.mainCameraParams.type,
|
|
5435
|
+
responseCoef: o.mainCameraParams.responseCoef
|
|
5436
|
+
}; // | WASD 'arcball' };
|
|
5437
|
+
|
|
5438
|
+
this.lastFrameMS = 0;
|
|
5439
|
+
this.entityArgPass = o.entityArgPass;
|
|
5389
5440
|
this.SphereLayout = {
|
|
5390
5441
|
vertexStride: 8 * 4,
|
|
5391
5442
|
positionsOffset: 0,
|
|
@@ -5397,8 +5448,12 @@ class MEBall {
|
|
|
5397
5448
|
this.texturesPaths.push(t);
|
|
5398
5449
|
});
|
|
5399
5450
|
this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
|
|
5451
|
+
this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
5452
|
+
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
5453
|
+
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
5454
|
+
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
5400
5455
|
this.shaderModule = device.createShaderModule({
|
|
5401
|
-
code: _shaders.
|
|
5456
|
+
code: _shaders.UNLIT_SHADER
|
|
5402
5457
|
});
|
|
5403
5458
|
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
5404
5459
|
this.pipeline = device.createRenderPipeline({
|
|
@@ -5468,7 +5523,6 @@ class MEBall {
|
|
|
5468
5523
|
};
|
|
5469
5524
|
this.loadTex0(this.texturesPaths, device).then(() => {
|
|
5470
5525
|
this.loadTex1(device).then(() => {
|
|
5471
|
-
console.log('NICE THIS', this);
|
|
5472
5526
|
this.sampler = device.createSampler({
|
|
5473
5527
|
magFilter: 'linear',
|
|
5474
5528
|
minFilter: 'linear'
|
|
@@ -5477,32 +5531,29 @@ class MEBall {
|
|
|
5477
5531
|
_wgpuMatrix.mat4.identity(this.transform);
|
|
5478
5532
|
|
|
5479
5533
|
// Create one large central planet surrounded by a large ring of asteroids
|
|
5480
|
-
this.planet = this.
|
|
5534
|
+
this.planet = this.createGeometry(this.scale);
|
|
5481
5535
|
this.planet.bindGroup = this.createSphereBindGroup(this.texture0, this.transform);
|
|
5482
|
-
var asteroids = [this.
|
|
5536
|
+
var asteroids = [this.createGeometry(12, 8, 6, 0.15)];
|
|
5483
5537
|
this.renderables = [this.planet];
|
|
5484
5538
|
|
|
5485
5539
|
// this.ensureEnoughAsteroids(asteroids, this.transform);
|
|
5486
|
-
|
|
5487
5540
|
this.renderPassDescriptor = {
|
|
5488
5541
|
colorAttachments: [{
|
|
5489
5542
|
view: undefined,
|
|
5490
|
-
// Assigned later
|
|
5491
|
-
|
|
5492
5543
|
clearValue: {
|
|
5493
5544
|
r: 0.0,
|
|
5494
5545
|
g: 0.0,
|
|
5495
5546
|
b: 0.0,
|
|
5496
5547
|
a: 1.0
|
|
5497
5548
|
},
|
|
5498
|
-
loadOp:
|
|
5499
|
-
storeOp:
|
|
5549
|
+
loadOp: this.entityArgPass.loadOp,
|
|
5550
|
+
storeOp: this.entityArgPass.storeOp
|
|
5500
5551
|
}],
|
|
5501
5552
|
depthStencilAttachment: {
|
|
5502
5553
|
view: this.depthTexture.createView(),
|
|
5503
5554
|
depthClearValue: 1.0,
|
|
5504
|
-
depthLoadOp:
|
|
5505
|
-
depthStoreOp:
|
|
5555
|
+
depthLoadOp: this.entityArgPass.depthLoadOp,
|
|
5556
|
+
depthStoreOp: this.entityArgPass.depthStoreOp
|
|
5506
5557
|
}
|
|
5507
5558
|
};
|
|
5508
5559
|
const aspect = canvas.width / canvas.height;
|
|
@@ -5561,7 +5612,7 @@ class MEBall {
|
|
|
5561
5612
|
this.renderScene(renderBundleEncoder);
|
|
5562
5613
|
this.renderBundle = renderBundleEncoder.finish();
|
|
5563
5614
|
}
|
|
5564
|
-
|
|
5615
|
+
createGeometry(radius, widthSegments = 8, heightSegments = 4, randomness = 0) {
|
|
5565
5616
|
const sphereMesh = this.createSphereMesh(radius, widthSegments, heightSegments, randomness);
|
|
5566
5617
|
// Create a vertex buffer from the sphere data.
|
|
5567
5618
|
const vertices = this.device.createBuffer({
|
|
@@ -5611,12 +5662,18 @@ class MEBall {
|
|
|
5611
5662
|
return bindGroup;
|
|
5612
5663
|
}
|
|
5613
5664
|
getTransformationMatrix(pos) {
|
|
5614
|
-
const viewMatrix =
|
|
5665
|
+
// const viewMatrix = mat4.identity();
|
|
5666
|
+
const now = Date.now();
|
|
5667
|
+
const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
|
|
5668
|
+
this.lastFrameMS = now;
|
|
5669
|
+
|
|
5670
|
+
// const viewMatrix = mat4.identity(); ORI
|
|
5671
|
+
const camera = this.cameras[this.cameraParams.type];
|
|
5672
|
+
const viewMatrix = camera.update(deltaTime, this.inputHandler());
|
|
5615
5673
|
_wgpuMatrix.mat4.translate(viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
|
|
5616
|
-
|
|
5617
|
-
_wgpuMatrix.mat4.
|
|
5618
|
-
_wgpuMatrix.mat4.
|
|
5619
|
-
_wgpuMatrix.mat4.rotateY(viewMatrix, now * 0.05, viewMatrix);
|
|
5674
|
+
_wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
|
|
5675
|
+
_wgpuMatrix.mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
|
|
5676
|
+
_wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
|
|
5620
5677
|
_wgpuMatrix.mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
|
|
5621
5678
|
return this.modelViewProjectionMatrix;
|
|
5622
5679
|
}
|
|
@@ -5722,6 +5779,7 @@ class MEBall {
|
|
|
5722
5779
|
indices: new Uint16Array(indices)
|
|
5723
5780
|
};
|
|
5724
5781
|
}
|
|
5782
|
+
|
|
5725
5783
|
// Render bundles function as partial, limited render passes, so we can use the
|
|
5726
5784
|
// same code both to render the scene normally and to build the render bundle.
|
|
5727
5785
|
renderScene(passEncoder) {
|
|
@@ -5758,7 +5816,7 @@ class MEBall {
|
|
|
5758
5816
|
}
|
|
5759
5817
|
exports.default = MEBall;
|
|
5760
5818
|
|
|
5761
|
-
},{"../shaders/shaders":
|
|
5819
|
+
},{"../shaders/shaders":12,"./engine":5,"./matrix-class":7,"wgpu-matrix":2}],4:[function(require,module,exports){
|
|
5762
5820
|
"use strict";
|
|
5763
5821
|
|
|
5764
5822
|
Object.defineProperty(exports, "__esModule", {
|
|
@@ -5768,6 +5826,7 @@ exports.default = void 0;
|
|
|
5768
5826
|
var _shaders = require("../shaders/shaders");
|
|
5769
5827
|
var _wgpuMatrix = require("wgpu-matrix");
|
|
5770
5828
|
var _matrixClass = require("./matrix-class");
|
|
5829
|
+
var _engine = require("./engine");
|
|
5771
5830
|
var SphereLayout = {
|
|
5772
5831
|
vertexStride: 8 * 4,
|
|
5773
5832
|
positionsOffset: 0,
|
|
@@ -5778,8 +5837,18 @@ class MECube {
|
|
|
5778
5837
|
constructor(canvas, device, context, o) {
|
|
5779
5838
|
this.device = device;
|
|
5780
5839
|
this.context = context;
|
|
5840
|
+
this.entityArgPass = o.entityArgPass;
|
|
5841
|
+
this.inputHandler = (0, _engine.createInputHandler)(window, canvas);
|
|
5842
|
+
this.cameras = o.cameras;
|
|
5843
|
+
console.log('passed : o.mainCameraParams.responseCoef ', o.mainCameraParams.responseCoef);
|
|
5844
|
+
this.cameraParams = {
|
|
5845
|
+
type: o.mainCameraParams.type,
|
|
5846
|
+
responseCoef: o.mainCameraParams.responseCoef
|
|
5847
|
+
}; // | WASD 'arcball' };
|
|
5848
|
+
|
|
5849
|
+
this.lastFrameMS = 0;
|
|
5781
5850
|
this.shaderModule = device.createShaderModule({
|
|
5782
|
-
code: _shaders.
|
|
5851
|
+
code: _shaders.UNLIT_SHADER
|
|
5783
5852
|
});
|
|
5784
5853
|
this.texturesPaths = [];
|
|
5785
5854
|
o.texturesPaths.forEach(t => {
|
|
@@ -5787,6 +5856,12 @@ class MECube {
|
|
|
5787
5856
|
});
|
|
5788
5857
|
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
5789
5858
|
this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
|
|
5859
|
+
console.log('cube added on pos : ', this.position);
|
|
5860
|
+
this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
5861
|
+
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
5862
|
+
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
5863
|
+
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
5864
|
+
this.scale = o.scale;
|
|
5790
5865
|
this.pipeline = device.createRenderPipeline({
|
|
5791
5866
|
layout: 'auto',
|
|
5792
5867
|
vertex: {
|
|
@@ -5865,13 +5940,18 @@ class MECube {
|
|
|
5865
5940
|
_wgpuMatrix.mat4.identity(this.transform);
|
|
5866
5941
|
|
|
5867
5942
|
// Create one large central planet surrounded by a large ring of asteroids
|
|
5868
|
-
this.planet = this.
|
|
5943
|
+
this.planet = this.createGeometry({
|
|
5944
|
+
scale: this.scale,
|
|
5945
|
+
useUVShema4x2: false
|
|
5946
|
+
});
|
|
5869
5947
|
this.planet.bindGroup = this.createSphereBindGroup(this.texture0, this.transform);
|
|
5870
|
-
var asteroids = [this.createSphereRenderable(0.2, 8, 6, 0.15), this.createSphereRenderable(0.13, 8, 6, 0.15)];
|
|
5871
|
-
this.renderables = [this.planet];
|
|
5872
5948
|
|
|
5949
|
+
// can be used like instance draws
|
|
5950
|
+
var asteroids = [
|
|
5951
|
+
// this.createGeometry(0.2, 8, 6, 0.15),
|
|
5952
|
+
];
|
|
5953
|
+
this.renderables = [this.planet];
|
|
5873
5954
|
// this.ensureEnoughAsteroids(asteroids, this.transform);
|
|
5874
|
-
|
|
5875
5955
|
this.renderPassDescriptor = {
|
|
5876
5956
|
colorAttachments: [{
|
|
5877
5957
|
view: undefined,
|
|
@@ -5881,18 +5961,18 @@ class MECube {
|
|
|
5881
5961
|
b: 0.0,
|
|
5882
5962
|
a: 1.0
|
|
5883
5963
|
},
|
|
5884
|
-
loadOp:
|
|
5885
|
-
storeOp:
|
|
5964
|
+
loadOp: this.entityArgPass.loadOp,
|
|
5965
|
+
storeOp: this.entityArgPass.storeOp
|
|
5886
5966
|
}],
|
|
5887
5967
|
depthStencilAttachment: {
|
|
5888
5968
|
view: this.depthTexture.createView(),
|
|
5889
5969
|
depthClearValue: 1.0,
|
|
5890
|
-
depthLoadOp:
|
|
5891
|
-
depthStoreOp:
|
|
5970
|
+
depthLoadOp: this.entityArgPass.depthLoadOp,
|
|
5971
|
+
depthStoreOp: this.entityArgPass.depthStoreOp
|
|
5892
5972
|
}
|
|
5893
5973
|
};
|
|
5894
5974
|
const aspect = canvas.width / canvas.height;
|
|
5895
|
-
this.projectionMatrix = _wgpuMatrix.mat4.perspective(2 * Math.PI / 5, aspect, 1,
|
|
5975
|
+
this.projectionMatrix = _wgpuMatrix.mat4.perspective(2 * Math.PI / 5, aspect, 1, 1000.0);
|
|
5896
5976
|
this.modelViewProjectionMatrix = _wgpuMatrix.mat4.create();
|
|
5897
5977
|
this.frameBindGroup = device.createBindGroup({
|
|
5898
5978
|
layout: this.pipeline.getBindGroupLayout(0),
|
|
@@ -5939,7 +6019,7 @@ class MECube {
|
|
|
5939
6019
|
}
|
|
5940
6020
|
}
|
|
5941
6021
|
updateRenderBundle() {
|
|
5942
|
-
console.log('
|
|
6022
|
+
console.log('[CUBE] updateRenderBundle');
|
|
5943
6023
|
const renderBundleEncoder = this.device.createRenderBundleEncoder({
|
|
5944
6024
|
colorFormats: [this.presentationFormat],
|
|
5945
6025
|
depthStencilFormat: 'depth24plus'
|
|
@@ -5947,27 +6027,27 @@ class MECube {
|
|
|
5947
6027
|
this.renderScene(renderBundleEncoder);
|
|
5948
6028
|
this.renderBundle = renderBundleEncoder.finish();
|
|
5949
6029
|
}
|
|
5950
|
-
|
|
5951
|
-
const
|
|
6030
|
+
createGeometry(options) {
|
|
6031
|
+
const mesh = this.createCubeVertices(options);
|
|
5952
6032
|
// Create a vertex buffer from the sphere data.
|
|
5953
6033
|
const vertices = this.device.createBuffer({
|
|
5954
|
-
size:
|
|
6034
|
+
size: mesh.vertices.byteLength,
|
|
5955
6035
|
usage: GPUBufferUsage.VERTEX,
|
|
5956
6036
|
mappedAtCreation: true
|
|
5957
6037
|
});
|
|
5958
|
-
new Float32Array(vertices.getMappedRange()).set(
|
|
6038
|
+
new Float32Array(vertices.getMappedRange()).set(mesh.vertices);
|
|
5959
6039
|
vertices.unmap();
|
|
5960
6040
|
const indices = this.device.createBuffer({
|
|
5961
|
-
size:
|
|
6041
|
+
size: mesh.indices.byteLength,
|
|
5962
6042
|
usage: GPUBufferUsage.INDEX,
|
|
5963
6043
|
mappedAtCreation: true
|
|
5964
6044
|
});
|
|
5965
|
-
new Uint16Array(indices.getMappedRange()).set(
|
|
6045
|
+
new Uint16Array(indices.getMappedRange()).set(mesh.indices);
|
|
5966
6046
|
indices.unmap();
|
|
5967
6047
|
return {
|
|
5968
6048
|
vertices,
|
|
5969
6049
|
indices,
|
|
5970
|
-
indexCount:
|
|
6050
|
+
indexCount: mesh.indices.length
|
|
5971
6051
|
};
|
|
5972
6052
|
}
|
|
5973
6053
|
createSphereBindGroup(texture, transform) {
|
|
@@ -5997,12 +6077,17 @@ class MECube {
|
|
|
5997
6077
|
return bindGroup;
|
|
5998
6078
|
}
|
|
5999
6079
|
getTransformationMatrix(pos) {
|
|
6000
|
-
const
|
|
6080
|
+
const now = Date.now();
|
|
6081
|
+
const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
|
|
6082
|
+
this.lastFrameMS = now;
|
|
6083
|
+
|
|
6084
|
+
// const viewMatrix = mat4.identity(); ORI
|
|
6085
|
+
const camera = this.cameras[this.cameraParams.type];
|
|
6086
|
+
const viewMatrix = camera.update(deltaTime, this.inputHandler());
|
|
6001
6087
|
_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);
|
|
6088
|
+
_wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
|
|
6089
|
+
_wgpuMatrix.mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
|
|
6090
|
+
_wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
|
|
6006
6091
|
_wgpuMatrix.mat4.multiply(this.projectionMatrix, viewMatrix, this.modelViewProjectionMatrix);
|
|
6007
6092
|
return this.modelViewProjectionMatrix;
|
|
6008
6093
|
}
|
|
@@ -6075,6 +6160,7 @@ class MECube {
|
|
|
6075
6160
|
useUVShema4x2: false
|
|
6076
6161
|
};
|
|
6077
6162
|
}
|
|
6163
|
+
if (typeof options.scale === 'undefined') options.scale = 1;
|
|
6078
6164
|
let vertices;
|
|
6079
6165
|
if (options.useUVShema4x2 == true) {
|
|
6080
6166
|
vertices = new Float32Array([
|
|
@@ -6094,20 +6180,20 @@ class MECube {
|
|
|
6094
6180
|
-1, 1, 1, 1, 0, 0, 0.5, 0.5, 1, 1, 1, 1, 0, 0, 0.75, 0.5, -1, 1, -1, 1, 0, 0, 0.5, 1, 1, 1, -1, 1, 0, 0, 0.75, 1]);
|
|
6095
6181
|
} else {
|
|
6096
6182
|
vertices = new Float32Array([
|
|
6097
|
-
// position
|
|
6098
|
-
|
|
6183
|
+
// position | texture coordinate
|
|
6184
|
+
//------------- +----------------------
|
|
6099
6185
|
// front face select the top left image 1, 0.5,
|
|
6100
|
-
-1, 1, 1, 1, 0, 0, 0, 0, -1, -1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, -1, 1, 1, 0, 0, 1, 1,
|
|
6186
|
+
-1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0, -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1, 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 0, 1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 1,
|
|
6101
6187
|
// right face select the top middle image
|
|
6102
|
-
1, 1, -1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, -1, -1, 1, 0, 0, 1, 0, 1, -1, 1, 1, 0, 0, 1, 1,
|
|
6188
|
+
1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 0, 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1, 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0, 1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 1,
|
|
6103
6189
|
// back face select to top right image
|
|
6104
|
-
1, 1, -1, 1, 0, 0, 0, 0, 1, -1, -1, 1, 0, 0, 0, 1, -1, 1, -1, 1, 0, 0, 1, 0, -1, -1, -1, 1, 0, 0, 1, 1,
|
|
6190
|
+
1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 0, 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 1, -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0, -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
|
|
6105
6191
|
// left face select the bottom left image
|
|
6106
|
-
-1, 1, 1, 1, 0, 0, 0, 0, -1, 1, -1, 1, 0, 0, 0, 1, -1, -1, 1, 1, 0, 0, 1, 0, -1, -1, -1, 1, 0, 0, 1, 1,
|
|
6192
|
+
-1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0, -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 0, 1, -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 1, 0, -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
|
|
6107
6193
|
// bottom face select the bottom middle image
|
|
6108
|
-
1, -1, 1, 1, 0, 0, 0, 0, -1, -1, 1, 1, 0, 0, 0, 1, 1, -1, -1, 1, 0, 0, 1, 0, -1, -1, -1, 1, 0, 0, 1, 1,
|
|
6194
|
+
1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0, -1 * options.scale, -1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1, 1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0, -1 * options.scale, -1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1,
|
|
6109
6195
|
// top face select the bottom right image
|
|
6110
|
-
-1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, -1, 1, -1, 1, 0, 0, 1, 0, 1, 1, -1, 1, 0, 0, 1, 1]);
|
|
6196
|
+
-1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 0, 1 * options.scale, 1 * options.scale, 1 * options.scale, 1, 0, 0, 0, 1, -1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 0, 1 * options.scale, 1 * options.scale, -1 * options.scale, 1, 0, 0, 1, 1]);
|
|
6111
6197
|
}
|
|
6112
6198
|
const indices = new Uint16Array([0, 1, 2, 2, 1, 3,
|
|
6113
6199
|
// front
|
|
@@ -6139,15 +6225,942 @@ class MECube {
|
|
|
6139
6225
|
}
|
|
6140
6226
|
exports.default = MECube;
|
|
6141
6227
|
|
|
6142
|
-
},{"../shaders/shaders":
|
|
6228
|
+
},{"../shaders/shaders":12,"./engine":5,"./matrix-class":7,"wgpu-matrix":2}],5:[function(require,module,exports){
|
|
6143
6229
|
"use strict";
|
|
6144
6230
|
|
|
6145
6231
|
Object.defineProperty(exports, "__esModule", {
|
|
6146
6232
|
value: true
|
|
6147
6233
|
});
|
|
6148
|
-
exports.
|
|
6149
|
-
|
|
6234
|
+
exports.WASDCamera = exports.ArcballCamera = void 0;
|
|
6235
|
+
exports.createInputHandler = createInputHandler;
|
|
6236
|
+
var _wgpuMatrix = require("wgpu-matrix");
|
|
6237
|
+
// Note: The code in this file does not use the 'dst' output parameter of functions in the
|
|
6238
|
+
// 'wgpu-matrix' library, so produces many temporary vectors and matrices.
|
|
6239
|
+
// This is intentional, as this sample prefers readability over performance.
|
|
6240
|
+
|
|
6241
|
+
// import Input from './input';
|
|
6242
|
+
|
|
6243
|
+
// // Common interface for camera implementations
|
|
6244
|
+
// export default interface Camera {
|
|
6245
|
+
// // update updates the camera using the user-input and returns the view matrix.
|
|
6246
|
+
// update(delta_time: number, input: Input): Mat4;
|
|
6247
|
+
|
|
6248
|
+
// // The camera matrix.
|
|
6249
|
+
// // This is the inverse of the view matrix.
|
|
6250
|
+
// matrix: Mat4;
|
|
6251
|
+
// // Alias to column vector 0 of the camera matrix.
|
|
6252
|
+
// right: Vec4;
|
|
6253
|
+
// // Alias to column vector 1 of the camera matrix.
|
|
6254
|
+
// up: Vec4;
|
|
6255
|
+
// // Alias to column vector 2 of the camera matrix.
|
|
6256
|
+
// back: Vec4;
|
|
6257
|
+
// // Alias to column vector 3 of the camera matrix.
|
|
6258
|
+
// position: Vec4;
|
|
6259
|
+
// }
|
|
6260
|
+
|
|
6261
|
+
// The common functionality between camera implementations
|
|
6262
|
+
class CameraBase {
|
|
6263
|
+
// The camera matrix
|
|
6264
|
+
matrix_ = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
|
|
6265
|
+
|
|
6266
|
+
// The calculated view matrix readonly
|
|
6267
|
+
view_ = _wgpuMatrix.mat4.create();
|
|
6268
|
+
|
|
6269
|
+
// Aliases to column vectors of the matrix
|
|
6270
|
+
right_ = new Float32Array(this.matrix_.buffer, 4 * 0, 4);
|
|
6271
|
+
up_ = new Float32Array(this.matrix_.buffer, 4 * 4, 4);
|
|
6272
|
+
back_ = new Float32Array(this.matrix_.buffer, 4 * 8, 4);
|
|
6273
|
+
position_ = new Float32Array(this.matrix_.buffer, 4 * 12, 4);
|
|
6274
|
+
|
|
6275
|
+
// Returns the camera matrix
|
|
6276
|
+
get matrix() {
|
|
6277
|
+
return this.matrix_;
|
|
6278
|
+
}
|
|
6279
|
+
// Assigns `mat` to the camera matrix
|
|
6280
|
+
set matrix(mat) {
|
|
6281
|
+
_wgpuMatrix.mat4.copy(mat, this.matrix_);
|
|
6282
|
+
}
|
|
6283
|
+
|
|
6284
|
+
// Returns the camera view matrix
|
|
6285
|
+
get view() {
|
|
6286
|
+
return this.view_;
|
|
6287
|
+
}
|
|
6288
|
+
// Assigns `mat` to the camera view
|
|
6289
|
+
set view(mat) {
|
|
6290
|
+
_wgpuMatrix.mat4.copy(mat, this.view_);
|
|
6291
|
+
}
|
|
6292
|
+
|
|
6293
|
+
// Returns column vector 0 of the camera matrix
|
|
6294
|
+
get right() {
|
|
6295
|
+
return this.right_;
|
|
6296
|
+
}
|
|
6297
|
+
// Assigns `vec` to the first 3 elements of column vector 0 of the camera matrix
|
|
6298
|
+
set right(vec) {
|
|
6299
|
+
_wgpuMatrix.vec3.copy(vec, this.right_);
|
|
6300
|
+
}
|
|
6301
|
+
|
|
6302
|
+
// Returns column vector 1 of the camera matrix
|
|
6303
|
+
get up() {
|
|
6304
|
+
return this.up_;
|
|
6305
|
+
}
|
|
6306
|
+
// Assigns `vec` to the first 3 elements of column vector 1 of the camera matrix \ Vec3
|
|
6307
|
+
set up(vec) {
|
|
6308
|
+
_wgpuMatrix.vec3.copy(vec, this.up_);
|
|
6309
|
+
}
|
|
6310
|
+
|
|
6311
|
+
// Returns column vector 2 of the camera matrix
|
|
6312
|
+
get back() {
|
|
6313
|
+
return this.back_;
|
|
6314
|
+
}
|
|
6315
|
+
// Assigns `vec` to the first 3 elements of column vector 2 of the camera matrix
|
|
6316
|
+
set back(vec) {
|
|
6317
|
+
_wgpuMatrix.vec3.copy(vec, this.back_);
|
|
6318
|
+
}
|
|
6319
|
+
|
|
6320
|
+
// Returns column vector 3 of the camera matrix
|
|
6321
|
+
get position() {
|
|
6322
|
+
return this.position_;
|
|
6323
|
+
}
|
|
6324
|
+
// Assigns `vec` to the first 3 elements of column vector 3 of the camera matrix
|
|
6325
|
+
set position(vec) {
|
|
6326
|
+
_wgpuMatrix.vec3.copy(vec, this.position_);
|
|
6327
|
+
}
|
|
6328
|
+
}
|
|
6329
|
+
|
|
6330
|
+
// WASDCamera is a camera implementation that behaves similar to first-person-shooter PC games.
|
|
6331
|
+
class WASDCamera extends CameraBase {
|
|
6332
|
+
// The camera absolute pitch angle
|
|
6333
|
+
pitch = 0;
|
|
6334
|
+
// The camera absolute yaw angle
|
|
6335
|
+
yaw = 0;
|
|
6336
|
+
|
|
6337
|
+
// The movement veloicty readonly
|
|
6338
|
+
velocity_ = _wgpuMatrix.vec3.create();
|
|
6339
|
+
|
|
6340
|
+
// Speed multiplier for camera movement
|
|
6341
|
+
movementSpeed = 10;
|
|
6342
|
+
|
|
6343
|
+
// Speed multiplier for camera rotation
|
|
6344
|
+
rotationSpeed = 1;
|
|
6345
|
+
|
|
6346
|
+
// Movement velocity drag coeffient [0 .. 1]
|
|
6347
|
+
// 0: Continues forever
|
|
6348
|
+
// 1: Instantly stops moving
|
|
6349
|
+
frictionCoefficient = 0.99;
|
|
6350
|
+
|
|
6351
|
+
// Returns velocity vector
|
|
6352
|
+
get velocity() {
|
|
6353
|
+
return this.velocity_;
|
|
6354
|
+
}
|
|
6355
|
+
// Assigns `vec` to the velocity vector
|
|
6356
|
+
set velocity(vec) {
|
|
6357
|
+
_wgpuMatrix.vec3.copy(vec, this.velocity_);
|
|
6358
|
+
}
|
|
6359
|
+
|
|
6360
|
+
// Construtor
|
|
6361
|
+
constructor(options) {
|
|
6362
|
+
super();
|
|
6363
|
+
if (options && (options.position || options.target)) {
|
|
6364
|
+
const position = options.position ?? _wgpuMatrix.vec3.create(0, 0, 0);
|
|
6365
|
+
const target = options.target ?? _wgpuMatrix.vec3.create(0, 0, 0);
|
|
6366
|
+
const forward = _wgpuMatrix.vec3.normalize(_wgpuMatrix.vec3.sub(target, position));
|
|
6367
|
+
this.recalculateAngles(forward);
|
|
6368
|
+
this.position = position;
|
|
6369
|
+
console.log('camera postion:', position);
|
|
6370
|
+
}
|
|
6371
|
+
}
|
|
6372
|
+
|
|
6373
|
+
// Returns the camera matrix
|
|
6374
|
+
get matrix() {
|
|
6375
|
+
return super.matrix;
|
|
6376
|
+
}
|
|
6377
|
+
|
|
6378
|
+
// Assigns `mat` to the camera matrix, and recalcuates the camera angles
|
|
6379
|
+
set matrix(mat) {
|
|
6380
|
+
super.matrix = mat;
|
|
6381
|
+
this.recalculateAngles(this.back);
|
|
6382
|
+
}
|
|
6383
|
+
update(deltaTime, input) {
|
|
6384
|
+
const sign = (positive, negative) => (positive ? 1 : 0) - (negative ? 1 : 0);
|
|
6385
|
+
|
|
6386
|
+
// Apply the delta rotation to the pitch and yaw angles
|
|
6387
|
+
this.yaw -= input.analog.x * deltaTime * this.rotationSpeed;
|
|
6388
|
+
this.pitch -= input.analog.y * deltaTime * this.rotationSpeed;
|
|
6389
|
+
|
|
6390
|
+
// Wrap yaw between [0° .. 360°], just to prevent large accumulation.
|
|
6391
|
+
this.yaw = mod(this.yaw, Math.PI * 2);
|
|
6392
|
+
// Clamp pitch between [-90° .. +90°] to prevent somersaults.
|
|
6393
|
+
this.pitch = clamp(this.pitch, -Math.PI / 2, Math.PI / 2);
|
|
6394
|
+
|
|
6395
|
+
// Save the current position, as we're about to rebuild the camera matrix.
|
|
6396
|
+
const position = _wgpuMatrix.vec3.copy(this.position);
|
|
6397
|
+
|
|
6398
|
+
// Reconstruct the camera's rotation, and store into the camera matrix.
|
|
6399
|
+
super.matrix = _wgpuMatrix.mat4.rotateX(_wgpuMatrix.mat4.rotationY(this.yaw), this.pitch);
|
|
6400
|
+
|
|
6401
|
+
// Calculate the new target velocity
|
|
6402
|
+
const digital = input.digital;
|
|
6403
|
+
const deltaRight = sign(digital.right, digital.left);
|
|
6404
|
+
const deltaUp = sign(digital.up, digital.down);
|
|
6405
|
+
const targetVelocity = _wgpuMatrix.vec3.create();
|
|
6406
|
+
const deltaBack = sign(digital.backward, digital.forward);
|
|
6407
|
+
_wgpuMatrix.vec3.addScaled(targetVelocity, this.right, deltaRight, targetVelocity);
|
|
6408
|
+
_wgpuMatrix.vec3.addScaled(targetVelocity, this.up, deltaUp, targetVelocity);
|
|
6409
|
+
_wgpuMatrix.vec3.addScaled(targetVelocity, this.back, deltaBack, targetVelocity);
|
|
6410
|
+
_wgpuMatrix.vec3.normalize(targetVelocity, targetVelocity);
|
|
6411
|
+
_wgpuMatrix.vec3.mulScalar(targetVelocity, this.movementSpeed, targetVelocity);
|
|
6412
|
+
|
|
6413
|
+
// Mix new target velocity
|
|
6414
|
+
this.velocity = lerp(targetVelocity, this.velocity, Math.pow(1 - this.frictionCoefficient, deltaTime));
|
|
6415
|
+
|
|
6416
|
+
// Integrate velocity to calculate new position
|
|
6417
|
+
this.position = _wgpuMatrix.vec3.addScaled(position, this.velocity, deltaTime);
|
|
6418
|
+
|
|
6419
|
+
// Invert the camera matrix to build the view matrix
|
|
6420
|
+
this.view = _wgpuMatrix.mat4.invert(this.matrix);
|
|
6421
|
+
return this.view;
|
|
6422
|
+
}
|
|
6423
|
+
|
|
6424
|
+
// Recalculates the yaw and pitch values from a directional vector
|
|
6425
|
+
recalculateAngles(dir) {
|
|
6426
|
+
this.yaw = Math.atan2(dir[0], dir[2]);
|
|
6427
|
+
this.pitch = -Math.asin(dir[1]);
|
|
6428
|
+
}
|
|
6429
|
+
}
|
|
6430
|
+
|
|
6431
|
+
// ArcballCamera implements a basic orbiting camera around the world origin
|
|
6432
|
+
exports.WASDCamera = WASDCamera;
|
|
6433
|
+
class ArcballCamera extends CameraBase {
|
|
6434
|
+
// The camera distance from the target
|
|
6435
|
+
distance = 0;
|
|
6436
|
+
|
|
6437
|
+
// The current angular velocity
|
|
6438
|
+
angularVelocity = 0;
|
|
6439
|
+
|
|
6440
|
+
// The current rotation axis
|
|
6441
|
+
axis_ = _wgpuMatrix.vec3.create();
|
|
6442
|
+
|
|
6443
|
+
// Returns the rotation axis
|
|
6444
|
+
get axis() {
|
|
6445
|
+
return this.axis_;
|
|
6446
|
+
}
|
|
6447
|
+
// Assigns `vec` to the rotation axis
|
|
6448
|
+
set axis(vec) {
|
|
6449
|
+
_wgpuMatrix.vec3.copy(vec, this.axis_);
|
|
6450
|
+
}
|
|
6451
|
+
|
|
6452
|
+
// Speed multiplier for camera rotation
|
|
6453
|
+
rotationSpeed = 1;
|
|
6454
|
+
|
|
6455
|
+
// Speed multiplier for camera zoom
|
|
6456
|
+
zoomSpeed = 0.1;
|
|
6457
|
+
|
|
6458
|
+
// Rotation velocity drag coeffient [0 .. 1]
|
|
6459
|
+
// 0: Spins forever
|
|
6460
|
+
// 1: Instantly stops spinning
|
|
6461
|
+
frictionCoefficient = 0.999;
|
|
6462
|
+
|
|
6463
|
+
// Construtor
|
|
6464
|
+
constructor(options) {
|
|
6465
|
+
super();
|
|
6466
|
+
if (options && options.position) {
|
|
6467
|
+
this.position = options.position;
|
|
6468
|
+
this.distance = _wgpuMatrix.vec3.len(this.position);
|
|
6469
|
+
this.back = _wgpuMatrix.vec3.normalize(this.position);
|
|
6470
|
+
this.recalcuateRight();
|
|
6471
|
+
this.recalcuateUp();
|
|
6472
|
+
}
|
|
6473
|
+
}
|
|
6474
|
+
|
|
6475
|
+
// Returns the camera matrix
|
|
6476
|
+
get matrix() {
|
|
6477
|
+
return super.matrix;
|
|
6478
|
+
}
|
|
6479
|
+
|
|
6480
|
+
// Assigns `mat` to the camera matrix, and recalcuates the distance
|
|
6481
|
+
set matrix(mat) {
|
|
6482
|
+
super.matrix = mat;
|
|
6483
|
+
this.distance = _wgpuMatrix.vec3.len(this.position);
|
|
6484
|
+
}
|
|
6485
|
+
update(deltaTime, input) {
|
|
6486
|
+
const epsilon = 0.0000001;
|
|
6487
|
+
if (input.analog.touching) {
|
|
6488
|
+
// Currently being dragged.
|
|
6489
|
+
this.angularVelocity = 0;
|
|
6490
|
+
} else {
|
|
6491
|
+
// Dampen any existing angular velocity
|
|
6492
|
+
this.angularVelocity *= Math.pow(1 - this.frictionCoefficient, deltaTime);
|
|
6493
|
+
}
|
|
6494
|
+
|
|
6495
|
+
// Calculate the movement vector
|
|
6496
|
+
const movement = _wgpuMatrix.vec3.create();
|
|
6497
|
+
_wgpuMatrix.vec3.addScaled(movement, this.right, input.analog.x, movement);
|
|
6498
|
+
_wgpuMatrix.vec3.addScaled(movement, this.up, -input.analog.y, movement);
|
|
6499
|
+
|
|
6500
|
+
// Cross the movement vector with the view direction to calculate the rotation axis x magnitude
|
|
6501
|
+
const crossProduct = _wgpuMatrix.vec3.cross(movement, this.back);
|
|
6502
|
+
|
|
6503
|
+
// Calculate the magnitude of the drag
|
|
6504
|
+
const magnitude = _wgpuMatrix.vec3.len(crossProduct);
|
|
6505
|
+
if (magnitude > epsilon) {
|
|
6506
|
+
// Normalize the crossProduct to get the rotation axis
|
|
6507
|
+
this.axis = _wgpuMatrix.vec3.scale(crossProduct, 1 / magnitude);
|
|
6508
|
+
|
|
6509
|
+
// Remember the current angular velocity. This is used when the touch is released for a fling.
|
|
6510
|
+
this.angularVelocity = magnitude * this.rotationSpeed;
|
|
6511
|
+
}
|
|
6512
|
+
|
|
6513
|
+
// The rotation around this.axis to apply to the camera matrix this update
|
|
6514
|
+
const rotationAngle = this.angularVelocity * deltaTime;
|
|
6515
|
+
if (rotationAngle > epsilon) {
|
|
6516
|
+
// Rotate the matrix around axis
|
|
6517
|
+
// Note: The rotation is not done as a matrix-matrix multiply as the repeated multiplications
|
|
6518
|
+
// will quickly introduce substantial error into the matrix.
|
|
6519
|
+
this.back = _wgpuMatrix.vec3.normalize(rotate(this.back, this.axis, rotationAngle));
|
|
6520
|
+
this.recalcuateRight();
|
|
6521
|
+
this.recalcuateUp();
|
|
6522
|
+
}
|
|
6523
|
+
|
|
6524
|
+
// recalculate `this.position` from `this.back` considering zoom
|
|
6525
|
+
if (input.analog.zoom !== 0) {
|
|
6526
|
+
this.distance *= 1 + input.analog.zoom * this.zoomSpeed;
|
|
6527
|
+
}
|
|
6528
|
+
this.position = _wgpuMatrix.vec3.scale(this.back, this.distance);
|
|
6529
|
+
|
|
6530
|
+
// Invert the camera matrix to build the view matrix
|
|
6531
|
+
this.view = _wgpuMatrix.mat4.invert(this.matrix);
|
|
6532
|
+
return this.view;
|
|
6533
|
+
}
|
|
6534
|
+
|
|
6535
|
+
// Assigns `this.right` with the cross product of `this.up` and `this.back`
|
|
6536
|
+
recalcuateRight() {
|
|
6537
|
+
this.right = _wgpuMatrix.vec3.normalize(_wgpuMatrix.vec3.cross(this.up, this.back));
|
|
6538
|
+
}
|
|
6539
|
+
|
|
6540
|
+
// Assigns `this.up` with the cross product of `this.back` and `this.right`
|
|
6541
|
+
recalcuateUp() {
|
|
6542
|
+
this.up = _wgpuMatrix.vec3.normalize(_wgpuMatrix.vec3.cross(this.back, this.right));
|
|
6543
|
+
}
|
|
6544
|
+
}
|
|
6545
|
+
|
|
6546
|
+
// Returns `x` clamped between [`min` .. `max`]
|
|
6547
|
+
exports.ArcballCamera = ArcballCamera;
|
|
6548
|
+
function clamp(x, min, max) {
|
|
6549
|
+
return Math.min(Math.max(x, min), max);
|
|
6550
|
+
}
|
|
6551
|
+
|
|
6552
|
+
// Returns `x` float-modulo `div`
|
|
6553
|
+
function mod(x, div) {
|
|
6554
|
+
return x - Math.floor(Math.abs(x) / div) * div * Math.sign(x);
|
|
6555
|
+
}
|
|
6556
|
+
|
|
6557
|
+
// Returns `vec` rotated `angle` radians around `axis`
|
|
6558
|
+
function rotate(vec, axis, angle) {
|
|
6559
|
+
return _wgpuMatrix.vec3.transformMat4Upper3x3(vec, _wgpuMatrix.mat4.rotation(axis, angle));
|
|
6560
|
+
}
|
|
6150
6561
|
|
|
6562
|
+
// Returns the linear interpolation between 'a' and 'b' using 's'
|
|
6563
|
+
function lerp(a, b, s) {
|
|
6564
|
+
return _wgpuMatrix.vec3.addScaled(a, _wgpuMatrix.vec3.sub(b, a), s);
|
|
6565
|
+
}
|
|
6566
|
+
|
|
6567
|
+
// IMPUT
|
|
6568
|
+
|
|
6569
|
+
// // Input holds as snapshot of input state
|
|
6570
|
+
// export default interface Input {
|
|
6571
|
+
// // Digital input (e.g keyboard state)
|
|
6572
|
+
// readonly digital: {
|
|
6573
|
+
// readonly forward: boolean;
|
|
6574
|
+
// readonly backward: boolean;
|
|
6575
|
+
// readonly left: boolean;
|
|
6576
|
+
// readonly right: boolean;
|
|
6577
|
+
// readonly up: boolean;
|
|
6578
|
+
// readonly down: boolean;
|
|
6579
|
+
// };
|
|
6580
|
+
// // Analog input (e.g mouse, touchscreen)
|
|
6581
|
+
// readonly analog: {
|
|
6582
|
+
// readonly x: number;
|
|
6583
|
+
// readonly y: number;
|
|
6584
|
+
// readonly zoom: number;
|
|
6585
|
+
// readonly touching: boolean;
|
|
6586
|
+
// };
|
|
6587
|
+
// }
|
|
6588
|
+
|
|
6589
|
+
// InputHandler is a function that when called, returns the current Input state.
|
|
6590
|
+
// export type InputHandler = () => Input;
|
|
6591
|
+
|
|
6592
|
+
// createInputHandler returns an InputHandler by attaching event handlers to the window and canvas.
|
|
6593
|
+
function createInputHandler(window, canvas) {
|
|
6594
|
+
let digital = {
|
|
6595
|
+
forward: false,
|
|
6596
|
+
backward: false,
|
|
6597
|
+
left: false,
|
|
6598
|
+
right: false,
|
|
6599
|
+
up: false,
|
|
6600
|
+
down: false
|
|
6601
|
+
};
|
|
6602
|
+
let analog = {
|
|
6603
|
+
x: 0,
|
|
6604
|
+
y: 0,
|
|
6605
|
+
zoom: 0
|
|
6606
|
+
};
|
|
6607
|
+
let mouseDown = false;
|
|
6608
|
+
const setDigital = (e, value) => {
|
|
6609
|
+
switch (e.code) {
|
|
6610
|
+
case 'KeyW':
|
|
6611
|
+
digital.forward = value;
|
|
6612
|
+
e.preventDefault();
|
|
6613
|
+
e.stopPropagation();
|
|
6614
|
+
break;
|
|
6615
|
+
case 'KeyS':
|
|
6616
|
+
digital.backward = value;
|
|
6617
|
+
e.preventDefault();
|
|
6618
|
+
e.stopPropagation();
|
|
6619
|
+
break;
|
|
6620
|
+
case 'KeyA':
|
|
6621
|
+
digital.left = value;
|
|
6622
|
+
e.preventDefault();
|
|
6623
|
+
e.stopPropagation();
|
|
6624
|
+
break;
|
|
6625
|
+
case 'KeyD':
|
|
6626
|
+
digital.right = value;
|
|
6627
|
+
e.preventDefault();
|
|
6628
|
+
e.stopPropagation();
|
|
6629
|
+
break;
|
|
6630
|
+
case 'Space':
|
|
6631
|
+
digital.up = value;
|
|
6632
|
+
e.preventDefault();
|
|
6633
|
+
e.stopPropagation();
|
|
6634
|
+
break;
|
|
6635
|
+
case 'ShiftLeft':
|
|
6636
|
+
case 'ControlLeft':
|
|
6637
|
+
case 'KeyC':
|
|
6638
|
+
digital.down = value;
|
|
6639
|
+
e.preventDefault();
|
|
6640
|
+
e.stopPropagation();
|
|
6641
|
+
break;
|
|
6642
|
+
}
|
|
6643
|
+
};
|
|
6644
|
+
window.addEventListener('keydown', e => setDigital(e, true));
|
|
6645
|
+
window.addEventListener('keyup', e => setDigital(e, false));
|
|
6646
|
+
canvas.style.touchAction = 'pinch-zoom';
|
|
6647
|
+
canvas.addEventListener('pointerdown', () => {
|
|
6648
|
+
mouseDown = true;
|
|
6649
|
+
});
|
|
6650
|
+
canvas.addEventListener('pointerup', () => {
|
|
6651
|
+
mouseDown = false;
|
|
6652
|
+
});
|
|
6653
|
+
canvas.addEventListener('pointermove', e => {
|
|
6654
|
+
mouseDown = e.pointerType == 'mouse' ? (e.buttons & 1) !== 0 : true;
|
|
6655
|
+
if (mouseDown) {
|
|
6656
|
+
// console.log('TEST ', analog)
|
|
6657
|
+
analog.x += e.movementX / 10;
|
|
6658
|
+
analog.y += e.movementY / 10;
|
|
6659
|
+
}
|
|
6660
|
+
});
|
|
6661
|
+
canvas.addEventListener('wheel', e => {
|
|
6662
|
+
mouseDown = (e.buttons & 1) !== 0;
|
|
6663
|
+
if (mouseDown) {
|
|
6664
|
+
// The scroll value varies substantially between user agents / browsers.
|
|
6665
|
+
// Just use the sign.
|
|
6666
|
+
analog.zoom += Math.sign(e.deltaY);
|
|
6667
|
+
e.preventDefault();
|
|
6668
|
+
e.stopPropagation();
|
|
6669
|
+
}
|
|
6670
|
+
}, {
|
|
6671
|
+
passive: false
|
|
6672
|
+
});
|
|
6673
|
+
return () => {
|
|
6674
|
+
const out = {
|
|
6675
|
+
digital,
|
|
6676
|
+
analog: {
|
|
6677
|
+
x: analog.x,
|
|
6678
|
+
y: analog.y,
|
|
6679
|
+
zoom: analog.zoom,
|
|
6680
|
+
touching: mouseDown
|
|
6681
|
+
}
|
|
6682
|
+
};
|
|
6683
|
+
// Clear the analog values, as these accumulate.
|
|
6684
|
+
analog.x = 0;
|
|
6685
|
+
analog.y = 0;
|
|
6686
|
+
analog.zoom = 0;
|
|
6687
|
+
return out;
|
|
6688
|
+
};
|
|
6689
|
+
}
|
|
6690
|
+
|
|
6691
|
+
},{"wgpu-matrix":2}],6:[function(require,module,exports){
|
|
6692
|
+
"use strict";
|
|
6693
|
+
|
|
6694
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6695
|
+
value: true
|
|
6696
|
+
});
|
|
6697
|
+
exports.makeObjSeqArg = exports.initMeshBuffers = exports.downloadMeshes = exports.constructMesh = void 0;
|
|
6698
|
+
exports.play = play;
|
|
6699
|
+
/**
|
|
6700
|
+
* The main Mesh class. The constructor will parse through the OBJ file data
|
|
6701
|
+
* and collect the vertex, vertex normal, texture, and face information. This
|
|
6702
|
+
* information can then be used later on when creating your VBOs. See
|
|
6703
|
+
* OBJ.initMeshBuffers for an example of how to use the newly created Mesh
|
|
6704
|
+
*
|
|
6705
|
+
* @class Mesh
|
|
6706
|
+
* @constructor
|
|
6707
|
+
*
|
|
6708
|
+
* @param {String} objectData a string representation of an OBJ file with newlines preserved.
|
|
6709
|
+
*/
|
|
6710
|
+
|
|
6711
|
+
class constructMesh {
|
|
6712
|
+
constructor(objectData, inputArg) {
|
|
6713
|
+
this.inputArg = inputArg;
|
|
6714
|
+
this.objectData = objectData;
|
|
6715
|
+
this.create(objectData, inputArg);
|
|
6716
|
+
this.setScale = s => {
|
|
6717
|
+
this.inputArg.scale = s;
|
|
6718
|
+
this.create(this.objectData, this.inputArg);
|
|
6719
|
+
};
|
|
6720
|
+
this.updateBuffers = () => {
|
|
6721
|
+
this.inputArg.scale = 1;
|
|
6722
|
+
this.create(this.objectData, this.inputArg);
|
|
6723
|
+
};
|
|
6724
|
+
}
|
|
6725
|
+
create = (objectData, inputArg, callback) => {
|
|
6726
|
+
if (typeof callback === 'undefined') callback = function () {};
|
|
6727
|
+
let initOrientation = [0, 1, 2];
|
|
6728
|
+
/*
|
|
6729
|
+
The OBJ file format does a sort of compression when saving a model in a
|
|
6730
|
+
program like Blender. There are at least 3 sections (4 including textures)
|
|
6731
|
+
within the file. Each line in a section begins with the same string:
|
|
6732
|
+
* 'v': indicates vertex section
|
|
6733
|
+
* 'vn': indicates vertex normal section
|
|
6734
|
+
* 'f': indicates the faces section
|
|
6735
|
+
* 'vt': indicates vertex texture section (if textures were used on the model)
|
|
6736
|
+
Each of the above sections (except for the faces section) is a list/set of
|
|
6737
|
+
unique vertices.
|
|
6738
|
+
Each line of the faces section contains a list of
|
|
6739
|
+
(vertex, [texture], normal) groups
|
|
6740
|
+
Some examples:
|
|
6741
|
+
// the texture index is optional, both formats are possible for models
|
|
6742
|
+
// without a texture applied
|
|
6743
|
+
f 1/25 18/46 12/31
|
|
6744
|
+
f 1//25 18//46 12//31
|
|
6745
|
+
// A 3 vertex face with texture indices
|
|
6746
|
+
f 16/92/11 14/101/22 1/69/1
|
|
6747
|
+
// A 4 vertex face
|
|
6748
|
+
f 16/92/11 40/109/40 38/114/38 14/101/22
|
|
6749
|
+
The first two lines are examples of a 3 vertex face without a texture applied.
|
|
6750
|
+
The second is an example of a 3 vertex face with a texture applied.
|
|
6751
|
+
The third is an example of a 4 vertex face. Note: a face can contain N
|
|
6752
|
+
number of vertices.
|
|
6753
|
+
Each number that appears in one of the groups is a 1-based index
|
|
6754
|
+
corresponding to an item from the other sections (meaning that indexing
|
|
6755
|
+
starts at one and *not* zero).
|
|
6756
|
+
For example:
|
|
6757
|
+
`f 16/92/11` is saying to
|
|
6758
|
+
- take the 16th element from the [v] vertex array
|
|
6759
|
+
- take the 92nd element from the [vt] texture array
|
|
6760
|
+
- take the 11th element from the [vn] normal array
|
|
6761
|
+
and together they make a unique vertex.
|
|
6762
|
+
Using all 3+ unique Vertices from the face line will produce a polygon.
|
|
6763
|
+
Now, you could just go through the OBJ file and create a new vertex for
|
|
6764
|
+
each face line and WebGL will draw what appears to be the same model.
|
|
6765
|
+
However, vertices will be overlapped and duplicated all over the place.
|
|
6766
|
+
Consider a cube in 3D space centered about the origin and each side is
|
|
6767
|
+
2 units long. The front face (with the positive Z-axis pointing towards
|
|
6768
|
+
you) would have a Top Right vertex (looking orthogonal to its normal)
|
|
6769
|
+
mapped at (1,1,1) The right face would have a Top Left vertex (looking
|
|
6770
|
+
orthogonal to its normal) at (1,1,1) and the top face would have a Bottom
|
|
6771
|
+
Right vertex (looking orthogonal to its normal) at (1,1,1). Each face
|
|
6772
|
+
has a vertex at the same coordinates, however, three distinct vertices
|
|
6773
|
+
will be drawn at the same spot.
|
|
6774
|
+
To solve the issue of duplicate Vertices (the `(vertex, [texture], normal)`
|
|
6775
|
+
groups), while iterating through the face lines, when a group is encountered
|
|
6776
|
+
the whole group string ('16/92/11') is checked to see if it exists in the
|
|
6777
|
+
packed.hashindices object, and if it doesn't, the indices it specifies
|
|
6778
|
+
are used to look up each attribute in the corresponding attribute arrays
|
|
6779
|
+
already created. The values are then copied to the corresponding unpacked
|
|
6780
|
+
array (flattened to play nice with WebGL's ELEMENT_ARRAY_BUFFER indexing),
|
|
6781
|
+
the group string is added to the hashindices set and the current unpacked
|
|
6782
|
+
index is used as this hashindices value so that the group of elements can
|
|
6783
|
+
be reused. The unpacked index is incremented. If the group string already
|
|
6784
|
+
exists in the hashindices object, its corresponding value is the index of
|
|
6785
|
+
that group and is appended to the unpacked indices array.
|
|
6786
|
+
*/
|
|
6787
|
+
var verts = [],
|
|
6788
|
+
vertNormals = [],
|
|
6789
|
+
textures = [],
|
|
6790
|
+
unpacked = {};
|
|
6791
|
+
// unpacking stuff
|
|
6792
|
+
unpacked.verts = [];
|
|
6793
|
+
unpacked.norms = [];
|
|
6794
|
+
unpacked.textures = [];
|
|
6795
|
+
unpacked.hashindices = {};
|
|
6796
|
+
unpacked.indices = [];
|
|
6797
|
+
unpacked.index = 0;
|
|
6798
|
+
// array of lines separated by the newline
|
|
6799
|
+
var lines = objectData.split('\n');
|
|
6800
|
+
|
|
6801
|
+
// update swap orientation
|
|
6802
|
+
if (inputArg.swap[0] !== null) {
|
|
6803
|
+
swap(inputArg.swap[0], inputArg.swap[1], initOrientation);
|
|
6804
|
+
}
|
|
6805
|
+
var VERTEX_RE = /^v\s/;
|
|
6806
|
+
var NORMAL_RE = /^vn\s/;
|
|
6807
|
+
var TEXTURE_RE = /^vt\s/;
|
|
6808
|
+
var FACE_RE = /^f\s/;
|
|
6809
|
+
var WHITESPACE_RE = /\s+/;
|
|
6810
|
+
for (var i = 0; i < lines.length; i++) {
|
|
6811
|
+
var line = lines[i].trim();
|
|
6812
|
+
var elements = line.split(WHITESPACE_RE);
|
|
6813
|
+
elements.shift();
|
|
6814
|
+
if (VERTEX_RE.test(line)) {
|
|
6815
|
+
// if this is a vertex
|
|
6816
|
+
verts.push.apply(verts, elements);
|
|
6817
|
+
} else if (NORMAL_RE.test(line)) {
|
|
6818
|
+
// if this is a vertex normal
|
|
6819
|
+
vertNormals.push.apply(vertNormals, elements);
|
|
6820
|
+
} else if (TEXTURE_RE.test(line)) {
|
|
6821
|
+
// if this is a texture
|
|
6822
|
+
textures.push.apply(textures, elements);
|
|
6823
|
+
} else if (FACE_RE.test(line)) {
|
|
6824
|
+
// if this is a face
|
|
6825
|
+
/*
|
|
6826
|
+
split this face into an array of vertex groups
|
|
6827
|
+
for example:
|
|
6828
|
+
f 16/92/11 14/101/22 1/69/1
|
|
6829
|
+
becomes:
|
|
6830
|
+
['16/92/11', '14/101/22', '1/69/1'];
|
|
6831
|
+
*/
|
|
6832
|
+
var quad = false;
|
|
6833
|
+
for (var j = 0, eleLen = elements.length; j < eleLen; j++) {
|
|
6834
|
+
// Triangulating quads
|
|
6835
|
+
// quad: 'f v0/t0/vn0 v1/t1/vn1 v2/t2/vn2 v3/t3/vn3/'
|
|
6836
|
+
// corresponding triangles:
|
|
6837
|
+
// 'f v0/t0/vn0 v1/t1/vn1 v2/t2/vn2'
|
|
6838
|
+
// 'f v2/t2/vn2 v3/t3/vn3 v0/t0/vn0'
|
|
6839
|
+
if (j === 3 && !quad) {
|
|
6840
|
+
// add v2/t2/vn2 in again before continuing to 3
|
|
6841
|
+
j = 2;
|
|
6842
|
+
quad = true;
|
|
6843
|
+
}
|
|
6844
|
+
if (elements[j] in unpacked.hashindices) {
|
|
6845
|
+
unpacked.indices.push(unpacked.hashindices[elements[j]]);
|
|
6846
|
+
} else {
|
|
6847
|
+
/*
|
|
6848
|
+
Each element of the face line array is a vertex which has its
|
|
6849
|
+
attributes delimited by a forward slash. This will separate
|
|
6850
|
+
each attribute into another array:
|
|
6851
|
+
'19/92/11'
|
|
6852
|
+
becomes:
|
|
6853
|
+
vertex = ['19', '92', '11'];
|
|
6854
|
+
where
|
|
6855
|
+
vertex[0] is the vertex index
|
|
6856
|
+
vertex[1] is the texture index
|
|
6857
|
+
vertex[2] is the normal index
|
|
6858
|
+
Think of faces having Vertices which are comprised of the
|
|
6859
|
+
attributes location (v), texture (vt), and normal (vn).
|
|
6860
|
+
*/
|
|
6861
|
+
var vertex = elements[j].split('/');
|
|
6862
|
+
/*
|
|
6863
|
+
The verts, textures, and vertNormals arrays each contain a
|
|
6864
|
+
flattend array of coordinates.
|
|
6865
|
+
Because it gets confusing by referring to vertex and then
|
|
6866
|
+
vertex (both are different in my descriptions) I will explain
|
|
6867
|
+
what's going on using the vertexNormals array:
|
|
6868
|
+
vertex[2] will contain the one-based index of the vertexNormals
|
|
6869
|
+
section (vn). One is subtracted from this index number to play
|
|
6870
|
+
nice with javascript's zero-based array indexing.
|
|
6871
|
+
Because vertexNormal is a flattened array of x, y, z values,
|
|
6872
|
+
simple pointer arithmetic is used to skip to the start of the
|
|
6873
|
+
vertexNormal, then the offset is added to get the correct
|
|
6874
|
+
component: +0 is x, +1 is y, +2 is z.
|
|
6875
|
+
This same process is repeated for verts and textures.
|
|
6876
|
+
*/
|
|
6877
|
+
// vertex position
|
|
6878
|
+
unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[0]] * inputArg.scale);
|
|
6879
|
+
unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[1]] * inputArg.scale);
|
|
6880
|
+
unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[2]] * inputArg.scale);
|
|
6881
|
+
|
|
6882
|
+
// vertex textures
|
|
6883
|
+
if (textures.length) {
|
|
6884
|
+
unpacked.textures.push(+textures[(vertex[1] - 1) * 2 + 0]);
|
|
6885
|
+
unpacked.textures.push(+textures[(vertex[1] - 1) * 2 + 1]);
|
|
6886
|
+
}
|
|
6887
|
+
// vertex normals
|
|
6888
|
+
unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 0]);
|
|
6889
|
+
unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 1]);
|
|
6890
|
+
unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 2]);
|
|
6891
|
+
// add the newly created vertex to the list of indices
|
|
6892
|
+
unpacked.hashindices[elements[j]] = unpacked.index;
|
|
6893
|
+
unpacked.indices.push(unpacked.index);
|
|
6894
|
+
// increment the counter
|
|
6895
|
+
unpacked.index += 1;
|
|
6896
|
+
}
|
|
6897
|
+
if (j === 3 && quad) {
|
|
6898
|
+
// add v0/t0/vn0 onto the second triangle
|
|
6899
|
+
unpacked.indices.push(unpacked.hashindices[elements[0]]);
|
|
6900
|
+
}
|
|
6901
|
+
}
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6904
|
+
this.vertices = unpacked.verts;
|
|
6905
|
+
this.vertexNormals = unpacked.norms;
|
|
6906
|
+
this.textures = unpacked.textures;
|
|
6907
|
+
this.indices = unpacked.indices;
|
|
6908
|
+
callback();
|
|
6909
|
+
return this;
|
|
6910
|
+
};
|
|
6911
|
+
}
|
|
6912
|
+
exports.constructMesh = constructMesh;
|
|
6913
|
+
var Ajax = function () {
|
|
6914
|
+
// this is just a helper class to ease ajax calls
|
|
6915
|
+
var _this = this;
|
|
6916
|
+
this.xmlhttp = new XMLHttpRequest();
|
|
6917
|
+
this.get = function (url, callback) {
|
|
6918
|
+
_this.xmlhttp.onreadystatechange = function () {
|
|
6919
|
+
if (_this.xmlhttp.readyState === 4) {
|
|
6920
|
+
callback(_this.xmlhttp.responseText, _this.xmlhttp.status);
|
|
6921
|
+
}
|
|
6922
|
+
};
|
|
6923
|
+
_this.xmlhttp.open('GET', url, true);
|
|
6924
|
+
_this.xmlhttp.send();
|
|
6925
|
+
};
|
|
6926
|
+
};
|
|
6927
|
+
|
|
6928
|
+
/**
|
|
6929
|
+
* Takes in an object of `mesh_name`, `'/url/to/OBJ/file'` pairs and a callback
|
|
6930
|
+
* function. Each OBJ file will be ajaxed in and automatically converted to
|
|
6931
|
+
* an OBJ.Mesh. When all files have successfully downloaded the callback
|
|
6932
|
+
* function provided will be called and passed in an object containing
|
|
6933
|
+
* the newly created meshes.
|
|
6934
|
+
*
|
|
6935
|
+
* **Note:** In order to use this function as a way to download meshes, a
|
|
6936
|
+
* webserver of some sort must be used.
|
|
6937
|
+
*
|
|
6938
|
+
* @param {Object} nameAndURLs an object where the key is the name of the mesh and the value is the url to that mesh's OBJ file
|
|
6939
|
+
*
|
|
6940
|
+
* @param {Function} completionCallback should contain a function that will take one parameter: an object array where the keys will be the unique object name and the value will be a Mesh object
|
|
6941
|
+
*
|
|
6942
|
+
* @param {Object} meshes In case other meshes are loaded separately or if a previously declared variable is desired to be used, pass in a (possibly empty) json object of the pattern: { '<mesh_name>': OBJ.Mesh }
|
|
6943
|
+
*
|
|
6944
|
+
*/
|
|
6945
|
+
var downloadMeshes = function (nameAndURLs, completionCallback, inputArg) {
|
|
6946
|
+
// the total number of meshes. this is used to implement "blocking"
|
|
6947
|
+
var semaphore = Object.keys(nameAndURLs).length;
|
|
6948
|
+
// if error is true, an alert will given
|
|
6949
|
+
var error = false;
|
|
6950
|
+
// this is used to check if all meshes have been downloaded
|
|
6951
|
+
// if meshes is supplied, then it will be populated, otherwise
|
|
6952
|
+
// a new object is created. this will be passed into the completionCallback
|
|
6953
|
+
if (typeof inputArg === 'undefined') {
|
|
6954
|
+
var inputArg = {
|
|
6955
|
+
scale: 1,
|
|
6956
|
+
swap: [null]
|
|
6957
|
+
};
|
|
6958
|
+
}
|
|
6959
|
+
if (typeof inputArg.scale === 'undefined') inputArg.scale = 0.1;
|
|
6960
|
+
if (typeof inputArg.swap === 'undefined') inputArg.swap = [null];
|
|
6961
|
+
var meshes = {};
|
|
6962
|
+
|
|
6963
|
+
// loop over the mesh_name,url key,value pairs
|
|
6964
|
+
for (var mesh_name in nameAndURLs) {
|
|
6965
|
+
if (nameAndURLs.hasOwnProperty(mesh_name)) {
|
|
6966
|
+
new Ajax().get(nameAndURLs[mesh_name], function (name) {
|
|
6967
|
+
return function (data, status) {
|
|
6968
|
+
if (status === 200) {
|
|
6969
|
+
meshes[name] = new constructMesh(data, inputArg);
|
|
6970
|
+
} else {
|
|
6971
|
+
error = true;
|
|
6972
|
+
console.error('An error has occurred and the mesh "' + name + '" could not be downloaded.');
|
|
6973
|
+
}
|
|
6974
|
+
// the request has finished, decrement the counter
|
|
6975
|
+
semaphore--;
|
|
6976
|
+
if (semaphore === 0) {
|
|
6977
|
+
if (error) {
|
|
6978
|
+
// if an error has occurred, the user is notified here and the
|
|
6979
|
+
// callback is not called
|
|
6980
|
+
console.error('An error has occurred and one or meshes has not been ' + 'downloaded. The execution of the script has terminated.');
|
|
6981
|
+
throw '';
|
|
6982
|
+
}
|
|
6983
|
+
// there haven't been any errors in retrieving the meshes
|
|
6984
|
+
// call the callback
|
|
6985
|
+
completionCallback(meshes);
|
|
6986
|
+
}
|
|
6987
|
+
};
|
|
6988
|
+
}(mesh_name));
|
|
6989
|
+
}
|
|
6990
|
+
}
|
|
6991
|
+
};
|
|
6992
|
+
|
|
6993
|
+
/**
|
|
6994
|
+
* Takes in the WebGL context and a Mesh, then creates and appends the buffers
|
|
6995
|
+
* to the mesh object as attributes.
|
|
6996
|
+
*
|
|
6997
|
+
* @param {WebGLRenderingContext} gl the `canvas.getContext('webgl')` context instance
|
|
6998
|
+
* @param {Mesh} mesh a single `OBJ.Mesh` instance
|
|
6999
|
+
*
|
|
7000
|
+
* The newly created mesh attributes are:
|
|
7001
|
+
*
|
|
7002
|
+
* Attrbute | Description
|
|
7003
|
+
* :--- | ---
|
|
7004
|
+
* **normalBuffer** |contains the model's Vertex Normals
|
|
7005
|
+
* normalBuffer.itemSize |set to 3 items
|
|
7006
|
+
* normalBuffer.numItems |the total number of vertex normals
|
|
7007
|
+
* |
|
|
7008
|
+
* **textureBuffer** |contains the model's Texture Coordinates
|
|
7009
|
+
* textureBuffer.itemSize |set to 2 items
|
|
7010
|
+
* textureBuffer.numItems |the number of texture coordinates
|
|
7011
|
+
* |
|
|
7012
|
+
* **vertexBuffer** |contains the model's Vertex Position Coordinates (does not include w)
|
|
7013
|
+
* vertexBuffer.itemSize |set to 3 items
|
|
7014
|
+
* vertexBuffer.numItems |the total number of vertices
|
|
7015
|
+
* |
|
|
7016
|
+
* **indexBuffer** |contains the indices of the faces
|
|
7017
|
+
* indexBuffer.itemSize |is set to 1
|
|
7018
|
+
* indexBuffer.numItems |the total number of indices
|
|
7019
|
+
*
|
|
7020
|
+
* A simple example (a lot of steps are missing, so don't copy and paste):
|
|
7021
|
+
*
|
|
7022
|
+
* var gl = canvas.getContext('webgl'),
|
|
7023
|
+
* mesh = OBJ.Mesh(obj_file_data);
|
|
7024
|
+
* // compile the shaders and create a shader program
|
|
7025
|
+
* var shaderProgram = gl.createProgram();
|
|
7026
|
+
* // compilation stuff here
|
|
7027
|
+
* ...
|
|
7028
|
+
* // make sure you have vertex, vertex normal, and texture coordinate
|
|
7029
|
+
* // attributes located in your shaders and attach them to the shader program
|
|
7030
|
+
* shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
|
|
7031
|
+
* gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
|
|
7032
|
+
*
|
|
7033
|
+
* shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
|
|
7034
|
+
* gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
|
|
7035
|
+
*
|
|
7036
|
+
* shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
|
|
7037
|
+
* gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
|
|
7038
|
+
*
|
|
7039
|
+
* // create and initialize the vertex, vertex normal, and texture coordinate buffers
|
|
7040
|
+
* // and save on to the mesh object
|
|
7041
|
+
* OBJ.initMeshBuffers(gl, mesh);
|
|
7042
|
+
*
|
|
7043
|
+
* // now to render the mesh
|
|
7044
|
+
* gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexBuffer);
|
|
7045
|
+
* gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, mesh.vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
|
7046
|
+
* // it's possible that the mesh doesn't contain
|
|
7047
|
+
* // any texture coordinates (e.g. suzanne.obj in the development branch).
|
|
7048
|
+
* // in this case, the texture vertexAttribArray will need to be disabled
|
|
7049
|
+
* // before the call to drawElements
|
|
7050
|
+
* if(!mesh.textures.length){
|
|
7051
|
+
* gl.disableVertexAttribArray(shaderProgram.textureCoordAttribute);
|
|
7052
|
+
* }
|
|
7053
|
+
* else{
|
|
7054
|
+
* // if the texture vertexAttribArray has been previously
|
|
7055
|
+
* // disabled, then it needs to be re-enabled
|
|
7056
|
+
* gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
|
|
7057
|
+
* gl.bindBuffer(gl.ARRAY_BUFFER, mesh.textureBuffer);
|
|
7058
|
+
* gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, mesh.textureBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
|
7059
|
+
* }
|
|
7060
|
+
*
|
|
7061
|
+
* gl.bindBuffer(gl.ARRAY_BUFFER, mesh.normalBuffer);
|
|
7062
|
+
* gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, mesh.normalBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
|
7063
|
+
*
|
|
7064
|
+
* gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.mesh.indexBuffer);
|
|
7065
|
+
* gl.drawElements(gl.TRIANGLES, model.mesh.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
|
7066
|
+
*/
|
|
7067
|
+
exports.downloadMeshes = downloadMeshes;
|
|
7068
|
+
var initMeshBuffers = function (gl, mesh) {
|
|
7069
|
+
// mesh.vertexNormals
|
|
7070
|
+
// mesh.textures
|
|
7071
|
+
// mesh.vertices
|
|
7072
|
+
// mesh.indices
|
|
7073
|
+
};
|
|
7074
|
+
|
|
7075
|
+
/**
|
|
7076
|
+
* @description
|
|
7077
|
+
* Construct sequence list argument for downloadMeshes.
|
|
7078
|
+
* This is adaptation for blender obj animation export.
|
|
7079
|
+
* For example:
|
|
7080
|
+
* matrixEngine.objLoader.downloadMeshes(
|
|
7081
|
+
matrixEngine.objLoader.makeObjSeqArg(
|
|
7082
|
+
{
|
|
7083
|
+
id: objName,
|
|
7084
|
+
joinMultiPahts: [
|
|
7085
|
+
{
|
|
7086
|
+
path: "res/bvh-skeletal-base/swat-guy/seq-walk/low/swat",
|
|
7087
|
+
id: objName,
|
|
7088
|
+
from: 1, to: 34
|
|
7089
|
+
},
|
|
7090
|
+
{
|
|
7091
|
+
path: "res/bvh-skeletal-base/swat-guy/seq-walk-pistol/low/swat-walk-pistol",
|
|
7092
|
+
id: objName,
|
|
7093
|
+
from: 35, to: 54
|
|
7094
|
+
}
|
|
7095
|
+
]
|
|
7096
|
+
}),
|
|
7097
|
+
onLoadObj
|
|
7098
|
+
);
|
|
7099
|
+
*/
|
|
7100
|
+
exports.initMeshBuffers = initMeshBuffers;
|
|
7101
|
+
const makeObjSeqArg = arg => {
|
|
7102
|
+
// Adaptation for blender (animation) obj exporter.
|
|
7103
|
+
var local = {};
|
|
7104
|
+
function localCalc(arg, noInitial = false) {
|
|
7105
|
+
var zeros = '00000';
|
|
7106
|
+
var l = {};
|
|
7107
|
+
var helper = arg.from;
|
|
7108
|
+
for (let j = arg.from, z = 1; j <= arg.to; j++) {
|
|
7109
|
+
if (z > 9 && z < 99) {
|
|
7110
|
+
zeros = '0000';
|
|
7111
|
+
} else if (z > 99 && z < 999) {
|
|
7112
|
+
zeros = '000';
|
|
7113
|
+
} // no need more then 999
|
|
7114
|
+
|
|
7115
|
+
if (helper == arg.from && noInitial === false) {
|
|
7116
|
+
l[arg.id] = arg.path + '_' + zeros + z + '.obj';
|
|
7117
|
+
} else {
|
|
7118
|
+
l[arg.id + (helper - 1)] = arg.path + '_' + zeros + z + '.obj';
|
|
7119
|
+
}
|
|
7120
|
+
helper++;
|
|
7121
|
+
z++;
|
|
7122
|
+
}
|
|
7123
|
+
return l;
|
|
7124
|
+
}
|
|
7125
|
+
if (typeof arg.path === 'string') {
|
|
7126
|
+
local = localCalc(arg);
|
|
7127
|
+
} else if (typeof arg.path === 'undefined') {
|
|
7128
|
+
if (typeof arg.joinMultiPahts !== 'undefined') {
|
|
7129
|
+
console.log("ITS joinMultiPahts!");
|
|
7130
|
+
var localFinal = {};
|
|
7131
|
+
arg.joinMultiPahts.forEach((arg, index) => {
|
|
7132
|
+
if (index === 0) {
|
|
7133
|
+
localFinal = Object.assign(local, localCalc(arg));
|
|
7134
|
+
} else {
|
|
7135
|
+
localFinal = Object.assign(local, localCalc(arg, true));
|
|
7136
|
+
}
|
|
7137
|
+
});
|
|
7138
|
+
console.log("joinMultiPahts LOCAL => ", localFinal);
|
|
7139
|
+
return localFinal;
|
|
7140
|
+
}
|
|
7141
|
+
}
|
|
7142
|
+
return local;
|
|
7143
|
+
};
|
|
7144
|
+
|
|
7145
|
+
/**
|
|
7146
|
+
* @description
|
|
7147
|
+
* Switching obj seq animations frames range.
|
|
7148
|
+
*/
|
|
7149
|
+
exports.makeObjSeqArg = makeObjSeqArg;
|
|
7150
|
+
function play(nameAni) {
|
|
7151
|
+
this.animation.anims.active = nameAni;
|
|
7152
|
+
this.animation.currentAni = this.animation.anims[this.animation.anims.active].from;
|
|
7153
|
+
}
|
|
7154
|
+
|
|
7155
|
+
},{}],7:[function(require,module,exports){
|
|
7156
|
+
"use strict";
|
|
7157
|
+
|
|
7158
|
+
Object.defineProperty(exports, "__esModule", {
|
|
7159
|
+
value: true
|
|
7160
|
+
});
|
|
7161
|
+
exports.Rotation = exports.Position = void 0;
|
|
7162
|
+
var _utils = require("./utils");
|
|
7163
|
+
// Sub classes for matrix-wgpu
|
|
6151
7164
|
/**
|
|
6152
7165
|
* @description Base class
|
|
6153
7166
|
* Position { x, y, z }
|
|
@@ -6296,32 +7309,1531 @@ class Position {
|
|
|
6296
7309
|
}
|
|
6297
7310
|
}
|
|
6298
7311
|
exports.Position = Position;
|
|
7312
|
+
class Rotation {
|
|
7313
|
+
constructor(x, y, z) {
|
|
7314
|
+
// Not in use for nwo this is from matrix-engine project [nameUniq]
|
|
7315
|
+
this.nameUniq = null;
|
|
7316
|
+
if (typeof x == 'undefined') x = 0;
|
|
7317
|
+
if (typeof y == 'undefined') y = 0;
|
|
7318
|
+
if (typeof z == 'undefined') z = 0;
|
|
7319
|
+
this.x = x;
|
|
7320
|
+
this.y = y;
|
|
7321
|
+
this.z = z;
|
|
7322
|
+
this.rotationSpeed = {
|
|
7323
|
+
x: 0,
|
|
7324
|
+
y: 0,
|
|
7325
|
+
z: 0
|
|
7326
|
+
};
|
|
7327
|
+
}
|
|
7328
|
+
getRotX() {
|
|
7329
|
+
if (this.rotationSpeed.x == 0) {
|
|
7330
|
+
return (0, _utils.degToRad)(this.x);
|
|
7331
|
+
} else {
|
|
7332
|
+
this.x = this.x + this.rotationSpeed.x * 0.001;
|
|
7333
|
+
return this.x;
|
|
7334
|
+
}
|
|
7335
|
+
}
|
|
7336
|
+
getRotY() {
|
|
7337
|
+
if (this.rotationSpeed.y == 0) {
|
|
7338
|
+
return (0, _utils.degToRad)(this.y);
|
|
7339
|
+
} else {
|
|
7340
|
+
this.y = this.y + this.rotationSpeed.y * 0.001;
|
|
7341
|
+
return this.y;
|
|
7342
|
+
}
|
|
7343
|
+
}
|
|
7344
|
+
getRotZ() {
|
|
7345
|
+
if (this.rotationSpeed.z == 0) {
|
|
7346
|
+
return (0, _utils.degToRad)(this.z);
|
|
7347
|
+
} else {
|
|
7348
|
+
this.z = this.z + this.rotationSpeed.z * 0.001;
|
|
7349
|
+
return this.z;
|
|
7350
|
+
}
|
|
7351
|
+
}
|
|
7352
|
+
}
|
|
7353
|
+
exports.Rotation = Rotation;
|
|
6299
7354
|
|
|
6300
|
-
},{}],
|
|
7355
|
+
},{"./utils":10}],8:[function(require,module,exports){
|
|
6301
7356
|
"use strict";
|
|
6302
7357
|
|
|
6303
7358
|
Object.defineProperty(exports, "__esModule", {
|
|
6304
7359
|
value: true
|
|
6305
7360
|
});
|
|
6306
7361
|
exports.default = void 0;
|
|
6307
|
-
var
|
|
6308
|
-
var
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
7362
|
+
var _wgpuMatrix = require("wgpu-matrix");
|
|
7363
|
+
var _matrixClass = require("./matrix-class");
|
|
7364
|
+
var _engine = require("./engine");
|
|
7365
|
+
var _vertexShadow = require("../shaders/vertexShadow.wgsl");
|
|
7366
|
+
var _fragment = require("../shaders/fragment.wgsl");
|
|
7367
|
+
var _vertex = require("../shaders/vertex.wgsl");
|
|
7368
|
+
class MEMeshObj {
|
|
7369
|
+
constructor(canvas, device, context, o) {
|
|
7370
|
+
this.done = false;
|
|
7371
|
+
this.device = device;
|
|
7372
|
+
this.context = context;
|
|
7373
|
+
this.entityArgPass = o.entityArgPass;
|
|
6312
7374
|
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
7375
|
+
// Mesh stuff
|
|
7376
|
+
this.mesh = o.mesh;
|
|
7377
|
+
this.mesh.uvs = this.mesh.textures;
|
|
7378
|
+
console.log('mesh obj: ', this.mesh);
|
|
7379
|
+
this.inputHandler = (0, _engine.createInputHandler)(window, canvas);
|
|
7380
|
+
this.cameras = o.cameras;
|
|
7381
|
+
this.cameraParams = {
|
|
7382
|
+
type: o.mainCameraParams.type,
|
|
7383
|
+
responseCoef: o.mainCameraParams.responseCoef
|
|
7384
|
+
};
|
|
7385
|
+
this.lastFrameMS = 0;
|
|
7386
|
+
this.texturesPaths = [];
|
|
7387
|
+
o.texturesPaths.forEach(t => {
|
|
7388
|
+
this.texturesPaths.push(t);
|
|
7389
|
+
});
|
|
7390
|
+
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
7391
|
+
this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
|
|
7392
|
+
this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
7393
|
+
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
7394
|
+
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
7395
|
+
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
7396
|
+
this.scale = o.scale;
|
|
7397
|
+
this.runProgram = () => {
|
|
7398
|
+
return new Promise(async resolve => {
|
|
7399
|
+
this.shadowDepthTextureSize = 1024;
|
|
7400
|
+
const aspect = canvas.width / canvas.height;
|
|
7401
|
+
this.projectionMatrix = _wgpuMatrix.mat4.perspective(2 * Math.PI / 5, aspect, 1, 2000.0);
|
|
7402
|
+
this.modelViewProjectionMatrix = _wgpuMatrix.mat4.create();
|
|
7403
|
+
// console.log('cube added texturesPaths: ', this.texturesPaths)
|
|
7404
|
+
this.loadTex0(this.texturesPaths, device).then(() => {
|
|
7405
|
+
console.log('loaded tex buffer for mesh:', this.texture0);
|
|
7406
|
+
resolve();
|
|
7407
|
+
});
|
|
7408
|
+
});
|
|
7409
|
+
};
|
|
7410
|
+
this.runProgram().then(() => {
|
|
7411
|
+
const aspect = canvas.width / canvas.height;
|
|
7412
|
+
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
7413
|
+
this.context.configure({
|
|
7414
|
+
device: this.device,
|
|
7415
|
+
format: presentationFormat,
|
|
7416
|
+
alphaMode: 'premultiplied'
|
|
7417
|
+
});
|
|
7418
|
+
|
|
7419
|
+
// Create the model vertex buffer.
|
|
7420
|
+
this.vertexBuffer = this.device.createBuffer({
|
|
7421
|
+
size: this.mesh.vertices.length * Float32Array.BYTES_PER_ELEMENT,
|
|
7422
|
+
usage: GPUBufferUsage.VERTEX,
|
|
7423
|
+
mappedAtCreation: true
|
|
7424
|
+
});
|
|
7425
|
+
{
|
|
7426
|
+
// const mapping = new Float32Array(this.vertexBuffer.getMappedRange());
|
|
7427
|
+
// // for(let i = 0;i < this.mesh.vertices.length;++i) {
|
|
7428
|
+
// // mapping.set(this.mesh.vertices[i], 6 * i);
|
|
7429
|
+
// // mapping.set(this.mesh.normals[i], 6 * i + 3);
|
|
7430
|
+
// // }
|
|
7431
|
+
// this.vertexBuffer.unmap();
|
|
7432
|
+
new Float32Array(this.vertexBuffer.getMappedRange()).set(this.mesh.vertices);
|
|
7433
|
+
this.vertexBuffer.unmap();
|
|
7434
|
+
}
|
|
7435
|
+
|
|
7436
|
+
// NIDZA TEST SECOUND BUFFER
|
|
7437
|
+
// Create the model vertex buffer.
|
|
7438
|
+
this.vertexNormalsBuffer = this.device.createBuffer({
|
|
7439
|
+
size: this.mesh.vertexNormals.length * Float32Array.BYTES_PER_ELEMENT,
|
|
7440
|
+
usage: GPUBufferUsage.VERTEX,
|
|
7441
|
+
mappedAtCreation: true
|
|
7442
|
+
});
|
|
7443
|
+
{
|
|
7444
|
+
new Float32Array(this.vertexNormalsBuffer.getMappedRange()).set(this.mesh.vertexNormals);
|
|
7445
|
+
this.vertexNormalsBuffer.unmap();
|
|
7446
|
+
}
|
|
7447
|
+
this.vertexTexCoordsBuffer = this.device.createBuffer({
|
|
7448
|
+
size: this.mesh.textures.length * Float32Array.BYTES_PER_ELEMENT,
|
|
7449
|
+
usage: GPUBufferUsage.VERTEX,
|
|
7450
|
+
mappedAtCreation: true
|
|
7451
|
+
});
|
|
7452
|
+
{
|
|
7453
|
+
new Float32Array(this.vertexTexCoordsBuffer.getMappedRange()).set(this.mesh.textures);
|
|
7454
|
+
this.vertexTexCoordsBuffer.unmap();
|
|
7455
|
+
}
|
|
7456
|
+
|
|
7457
|
+
// Create the model index buffer.
|
|
7458
|
+
this.indexCount = this.mesh.indices.length;
|
|
7459
|
+
this.indexBuffer = this.device.createBuffer({
|
|
7460
|
+
size: this.indexCount * Uint16Array.BYTES_PER_ELEMENT,
|
|
7461
|
+
usage: GPUBufferUsage.INDEX,
|
|
7462
|
+
mappedAtCreation: true
|
|
7463
|
+
});
|
|
7464
|
+
{
|
|
7465
|
+
// const mapping = new Uint16Array(this.indexBuffer.getMappedRange());
|
|
7466
|
+
// for(let i = 0;i < this.mesh.indices.length;++i) {
|
|
7467
|
+
// mapping.set(this.mesh.indices[i], i);
|
|
7468
|
+
// }
|
|
7469
|
+
new Uint16Array(this.indexBuffer.getMappedRange()).set(this.mesh.indices);
|
|
7470
|
+
this.indexBuffer.unmap();
|
|
7471
|
+
}
|
|
7472
|
+
|
|
7473
|
+
// Create the depth texture for rendering/sampling the shadow map.
|
|
7474
|
+
this.shadowDepthTexture = this.device.createTexture({
|
|
7475
|
+
size: [this.shadowDepthTextureSize, this.shadowDepthTextureSize, 1],
|
|
7476
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
7477
|
+
format: 'depth32float'
|
|
7478
|
+
});
|
|
7479
|
+
this.shadowDepthTextureView = this.shadowDepthTexture.createView();
|
|
7480
|
+
|
|
7481
|
+
// Create some common descriptors used for both the shadow pipeline
|
|
7482
|
+
// and the color rendering pipeline.
|
|
7483
|
+
this.vertexBuffers = [{
|
|
7484
|
+
arrayStride: Float32Array.BYTES_PER_ELEMENT * 3,
|
|
7485
|
+
attributes: [{
|
|
7486
|
+
// position
|
|
7487
|
+
shaderLocation: 0,
|
|
7488
|
+
offset: 0,
|
|
7489
|
+
format: "float32x3"
|
|
7490
|
+
}]
|
|
7491
|
+
}, {
|
|
7492
|
+
arrayStride: Float32Array.BYTES_PER_ELEMENT * 3,
|
|
7493
|
+
attributes: [{
|
|
7494
|
+
// normal
|
|
7495
|
+
shaderLocation: 1,
|
|
7496
|
+
offset: 0,
|
|
7497
|
+
format: "float32x3"
|
|
7498
|
+
}]
|
|
7499
|
+
}, {
|
|
7500
|
+
arrayStride: Float32Array.BYTES_PER_ELEMENT * 2,
|
|
7501
|
+
attributes: [{
|
|
7502
|
+
// uvs
|
|
7503
|
+
shaderLocation: 2,
|
|
7504
|
+
offset: 0,
|
|
7505
|
+
format: "float32x2"
|
|
7506
|
+
}]
|
|
7507
|
+
}];
|
|
7508
|
+
const primitive = {
|
|
7509
|
+
topology: 'triangle-list',
|
|
7510
|
+
cullMode: 'back'
|
|
7511
|
+
};
|
|
7512
|
+
this.uniformBufferBindGroupLayout = this.device.createBindGroupLayout({
|
|
7513
|
+
entries: [{
|
|
7514
|
+
binding: 0,
|
|
7515
|
+
visibility: GPUShaderStage.VERTEX,
|
|
7516
|
+
buffer: {
|
|
7517
|
+
type: 'uniform'
|
|
7518
|
+
}
|
|
7519
|
+
}]
|
|
7520
|
+
});
|
|
7521
|
+
this.shadowPipeline = this.device.createRenderPipeline({
|
|
7522
|
+
layout: this.device.createPipelineLayout({
|
|
7523
|
+
bindGroupLayouts: [this.uniformBufferBindGroupLayout, this.uniformBufferBindGroupLayout]
|
|
7524
|
+
}),
|
|
7525
|
+
vertex: {
|
|
7526
|
+
module: this.device.createShaderModule({
|
|
7527
|
+
code: _vertexShadow.vertexShadowWGSL
|
|
7528
|
+
}),
|
|
7529
|
+
buffers: this.vertexBuffers
|
|
7530
|
+
},
|
|
7531
|
+
depthStencil: {
|
|
7532
|
+
depthWriteEnabled: true,
|
|
7533
|
+
depthCompare: 'less',
|
|
7534
|
+
format: 'depth32float'
|
|
7535
|
+
},
|
|
7536
|
+
primitive
|
|
7537
|
+
});
|
|
7538
|
+
|
|
7539
|
+
// Create a bind group layout which holds the scene uniforms and
|
|
7540
|
+
// the texture+sampler for depth. We create it manually because the WebPU
|
|
7541
|
+
// implementation doesn't infer this from the shader (yet).
|
|
7542
|
+
this.bglForRender = this.device.createBindGroupLayout({
|
|
7543
|
+
entries: [{
|
|
7544
|
+
binding: 0,
|
|
7545
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7546
|
+
buffer: {
|
|
7547
|
+
type: 'uniform'
|
|
7548
|
+
}
|
|
7549
|
+
}, {
|
|
7550
|
+
binding: 1,
|
|
7551
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7552
|
+
texture: {
|
|
7553
|
+
sampleType: 'depth'
|
|
7554
|
+
}
|
|
7555
|
+
}, {
|
|
7556
|
+
binding: 2,
|
|
7557
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7558
|
+
sampler: {
|
|
7559
|
+
type: 'comparison'
|
|
7560
|
+
}
|
|
7561
|
+
}, {
|
|
7562
|
+
binding: 3,
|
|
7563
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7564
|
+
texture: {
|
|
7565
|
+
sampleType: 'float'
|
|
7566
|
+
}
|
|
7567
|
+
}, {
|
|
7568
|
+
binding: 4,
|
|
7569
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7570
|
+
sampler: {
|
|
7571
|
+
type: 'filtering'
|
|
7572
|
+
}
|
|
7573
|
+
}]
|
|
7574
|
+
});
|
|
7575
|
+
this.pipeline = this.device.createRenderPipeline({
|
|
7576
|
+
layout: this.device.createPipelineLayout({
|
|
7577
|
+
bindGroupLayouts: [this.bglForRender, this.uniformBufferBindGroupLayout]
|
|
7578
|
+
}),
|
|
7579
|
+
vertex: {
|
|
7580
|
+
module: this.device.createShaderModule({
|
|
7581
|
+
code: _vertex.vertexWGSL
|
|
7582
|
+
}),
|
|
7583
|
+
buffers: this.vertexBuffers
|
|
7584
|
+
},
|
|
7585
|
+
fragment: {
|
|
7586
|
+
module: this.device.createShaderModule({
|
|
7587
|
+
code: _fragment.fragmentWGSL
|
|
7588
|
+
}),
|
|
7589
|
+
targets: [{
|
|
7590
|
+
format: presentationFormat
|
|
7591
|
+
}],
|
|
7592
|
+
constants: {
|
|
7593
|
+
shadowDepthTextureSize: this.shadowDepthTextureSize
|
|
7594
|
+
}
|
|
7595
|
+
},
|
|
7596
|
+
depthStencil: {
|
|
7597
|
+
depthWriteEnabled: true,
|
|
7598
|
+
depthCompare: 'less',
|
|
7599
|
+
format: 'depth24plus-stencil8'
|
|
7600
|
+
},
|
|
7601
|
+
primitive
|
|
7602
|
+
});
|
|
7603
|
+
const depthTexture = this.device.createTexture({
|
|
7604
|
+
size: [canvas.width, canvas.height],
|
|
7605
|
+
format: 'depth24plus-stencil8',
|
|
7606
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
7607
|
+
});
|
|
7608
|
+
this.renderPassDescriptor = {
|
|
7609
|
+
colorAttachments: [{
|
|
7610
|
+
// view is acquired and set in render loop.
|
|
7611
|
+
view: undefined,
|
|
7612
|
+
clearValue: {
|
|
7613
|
+
r: 0.5,
|
|
7614
|
+
g: 0.5,
|
|
7615
|
+
b: 0.5,
|
|
7616
|
+
a: 1.0
|
|
7617
|
+
},
|
|
7618
|
+
loadOp: 'load',
|
|
7619
|
+
storeOp: 'store'
|
|
7620
|
+
}],
|
|
7621
|
+
depthStencilAttachment: {
|
|
7622
|
+
view: depthTexture.createView(),
|
|
7623
|
+
depthClearValue: 1.0,
|
|
7624
|
+
depthLoadOp: 'clear',
|
|
7625
|
+
depthStoreOp: 'store',
|
|
7626
|
+
stencilClearValue: 0,
|
|
7627
|
+
stencilLoadOp: 'clear',
|
|
7628
|
+
stencilStoreOp: 'store'
|
|
7629
|
+
}
|
|
7630
|
+
};
|
|
7631
|
+
this.modelUniformBuffer = this.device.createBuffer({
|
|
7632
|
+
size: 4 * 16,
|
|
7633
|
+
// 4x4 matrix
|
|
7634
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
7635
|
+
});
|
|
7636
|
+
this.sceneUniformBuffer = this.device.createBuffer({
|
|
7637
|
+
// Two 4x4 viewProj matrices,
|
|
7638
|
+
// one for the camera and one for the light.
|
|
7639
|
+
// Then a vec3 for the light position.
|
|
7640
|
+
// Rounded to the nearest multiple of 16.
|
|
7641
|
+
size: 2 * 4 * 16 + 4 * 4,
|
|
7642
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
7643
|
+
});
|
|
7644
|
+
this.sceneBindGroupForShadow = this.device.createBindGroup({
|
|
7645
|
+
layout: this.uniformBufferBindGroupLayout,
|
|
7646
|
+
entries: [{
|
|
7647
|
+
binding: 0,
|
|
7648
|
+
resource: {
|
|
7649
|
+
buffer: this.sceneUniformBuffer
|
|
7650
|
+
}
|
|
7651
|
+
}]
|
|
7652
|
+
});
|
|
7653
|
+
this.sceneBindGroupForRender = this.device.createBindGroup({
|
|
7654
|
+
layout: this.bglForRender,
|
|
7655
|
+
entries: [{
|
|
7656
|
+
binding: 0,
|
|
7657
|
+
resource: {
|
|
7658
|
+
buffer: this.sceneUniformBuffer
|
|
7659
|
+
}
|
|
7660
|
+
}, {
|
|
7661
|
+
binding: 1,
|
|
7662
|
+
resource: this.shadowDepthTextureView
|
|
7663
|
+
}, {
|
|
7664
|
+
binding: 2,
|
|
7665
|
+
resource: this.device.createSampler({
|
|
7666
|
+
compare: 'less'
|
|
7667
|
+
})
|
|
7668
|
+
}, {
|
|
7669
|
+
binding: 3,
|
|
7670
|
+
resource: this.texture0.createView()
|
|
7671
|
+
}, {
|
|
7672
|
+
binding: 4,
|
|
7673
|
+
resource: this.sampler
|
|
7674
|
+
}]
|
|
7675
|
+
});
|
|
7676
|
+
this.modelBindGroup = this.device.createBindGroup({
|
|
7677
|
+
layout: this.uniformBufferBindGroupLayout,
|
|
7678
|
+
entries: [{
|
|
7679
|
+
binding: 0,
|
|
7680
|
+
resource: {
|
|
7681
|
+
buffer: this.modelUniformBuffer
|
|
7682
|
+
}
|
|
7683
|
+
}]
|
|
7684
|
+
});
|
|
7685
|
+
|
|
7686
|
+
// Rotates the camera around the origin based on time.
|
|
7687
|
+
this.getTransformationMatrix = pos => {
|
|
7688
|
+
const now = Date.now();
|
|
7689
|
+
const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
|
|
7690
|
+
this.lastFrameMS = now;
|
|
7691
|
+
|
|
7692
|
+
// const this.viewMatrix = mat4.identity()
|
|
7693
|
+
const camera = this.cameras[this.cameraParams.type];
|
|
7694
|
+
this.viewMatrix = camera.update(deltaTime, this.inputHandler());
|
|
7695
|
+
_wgpuMatrix.mat4.translate(this.viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), this.viewMatrix);
|
|
7696
|
+
_wgpuMatrix.mat4.rotateX(this.viewMatrix, Math.PI * this.rotation.getRotX(), this.viewMatrix);
|
|
7697
|
+
_wgpuMatrix.mat4.rotateY(this.viewMatrix, Math.PI * this.rotation.getRotY(), this.viewMatrix);
|
|
7698
|
+
_wgpuMatrix.mat4.rotateZ(this.viewMatrix, Math.PI * this.rotation.getRotZ(), this.viewMatrix);
|
|
7699
|
+
_wgpuMatrix.mat4.multiply(this.projectionMatrix, this.viewMatrix, this.modelViewProjectionMatrix);
|
|
7700
|
+
return this.modelViewProjectionMatrix;
|
|
7701
|
+
};
|
|
7702
|
+
this.upVector = _wgpuMatrix.vec3.fromValues(0, 1, 0);
|
|
7703
|
+
this.origin = _wgpuMatrix.vec3.fromValues(0, 0, 0);
|
|
7704
|
+
const lightPosition = _wgpuMatrix.vec3.fromValues(50, 100, -100);
|
|
7705
|
+
const lightViewMatrix = _wgpuMatrix.mat4.lookAt(lightPosition, this.origin, this.upVector);
|
|
7706
|
+
const lightProjectionMatrix = _wgpuMatrix.mat4.create();
|
|
7707
|
+
{
|
|
7708
|
+
const left = -80;
|
|
7709
|
+
const right = 80;
|
|
7710
|
+
const bottom = -80;
|
|
7711
|
+
const top = 80;
|
|
7712
|
+
const near = -200;
|
|
7713
|
+
const far = 300;
|
|
7714
|
+
_wgpuMatrix.mat4.ortho(left, right, bottom, top, near, far, lightProjectionMatrix);
|
|
7715
|
+
}
|
|
7716
|
+
const lightViewProjMatrix = _wgpuMatrix.mat4.multiply(lightProjectionMatrix, lightViewMatrix);
|
|
7717
|
+
|
|
7718
|
+
// looks like affect on transformations for now const 0
|
|
7719
|
+
const modelMatrix = _wgpuMatrix.mat4.translation([0, 0, 0]);
|
|
7720
|
+
// The camera/light aren't moving, so write them into buffers now.
|
|
7721
|
+
{
|
|
7722
|
+
const lightMatrixData = lightViewProjMatrix; // as Float32Array;
|
|
7723
|
+
this.device.queue.writeBuffer(this.sceneUniformBuffer, 0, lightMatrixData.buffer, lightMatrixData.byteOffset, lightMatrixData.byteLength);
|
|
7724
|
+
const lightData = lightPosition;
|
|
7725
|
+
this.device.queue.writeBuffer(this.sceneUniformBuffer, 128, lightData.buffer, lightData.byteOffset, lightData.byteLength);
|
|
7726
|
+
const modelData = modelMatrix;
|
|
7727
|
+
this.device.queue.writeBuffer(this.modelUniformBuffer, 0, modelData.buffer, modelData.byteOffset, modelData.byteLength);
|
|
7728
|
+
}
|
|
7729
|
+
this.shadowPassDescriptor = {
|
|
7730
|
+
colorAttachments: [],
|
|
7731
|
+
depthStencilAttachment: {
|
|
7732
|
+
view: this.shadowDepthTextureView,
|
|
7733
|
+
depthClearValue: 1.0,
|
|
7734
|
+
depthLoadOp: 'clear',
|
|
7735
|
+
depthStoreOp: 'store'
|
|
7736
|
+
}
|
|
7737
|
+
};
|
|
7738
|
+
this.done = true;
|
|
7739
|
+
});
|
|
7740
|
+
}
|
|
7741
|
+
async loadTex0(texturesPaths, device) {
|
|
7742
|
+
this.sampler = device.createSampler({
|
|
7743
|
+
magFilter: 'linear',
|
|
7744
|
+
minFilter: 'linear'
|
|
7745
|
+
});
|
|
7746
|
+
return new Promise(async resolve => {
|
|
7747
|
+
const response = await fetch(texturesPaths[0]);
|
|
7748
|
+
const imageBitmap = await createImageBitmap(await response.blob());
|
|
7749
|
+
this.texture0 = device.createTexture({
|
|
7750
|
+
size: [imageBitmap.width, imageBitmap.height, 1],
|
|
7751
|
+
format: 'rgba8unorm',
|
|
7752
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
|
|
7753
|
+
});
|
|
7754
|
+
device.queue.copyExternalImageToTexture({
|
|
7755
|
+
source: imageBitmap
|
|
7756
|
+
}, {
|
|
7757
|
+
texture: this.texture0
|
|
7758
|
+
}, [imageBitmap.width, imageBitmap.height]);
|
|
7759
|
+
resolve();
|
|
7760
|
+
});
|
|
7761
|
+
}
|
|
7762
|
+
draw = commandEncoder => {
|
|
7763
|
+
if (this.done == false) return;
|
|
7764
|
+
const transformationMatrix = this.getTransformationMatrix(this.position);
|
|
7765
|
+
this.device.queue.writeBuffer(this.sceneUniformBuffer, 64, transformationMatrix.buffer, transformationMatrix.byteOffset, transformationMatrix.byteLength);
|
|
7766
|
+
this.renderPassDescriptor.colorAttachments[0].view = this.context.getCurrentTexture().createView();
|
|
7767
|
+
{
|
|
7768
|
+
const shadowPass = commandEncoder.beginRenderPass(this.shadowPassDescriptor);
|
|
7769
|
+
shadowPass.setPipeline(this.shadowPipeline);
|
|
7770
|
+
shadowPass.setBindGroup(0, this.sceneBindGroupForShadow);
|
|
7771
|
+
shadowPass.setBindGroup(1, this.modelBindGroup);
|
|
7772
|
+
shadowPass.setVertexBuffer(0, this.vertexBuffer);
|
|
7773
|
+
shadowPass.setVertexBuffer(1, this.vertexNormalsBuffer);
|
|
7774
|
+
shadowPass.setVertexBuffer(2, this.vertexTexCoordsBuffer);
|
|
7775
|
+
shadowPass.setIndexBuffer(this.indexBuffer, 'uint16');
|
|
7776
|
+
shadowPass.drawIndexed(this.indexCount);
|
|
7777
|
+
shadowPass.end();
|
|
7778
|
+
}
|
|
7779
|
+
{
|
|
7780
|
+
const renderPass = commandEncoder.beginRenderPass(this.renderPassDescriptor);
|
|
7781
|
+
renderPass.setPipeline(this.pipeline);
|
|
7782
|
+
renderPass.setBindGroup(0, this.sceneBindGroupForRender);
|
|
7783
|
+
renderPass.setBindGroup(1, this.modelBindGroup);
|
|
7784
|
+
renderPass.setVertexBuffer(0, this.vertexBuffer);
|
|
7785
|
+
renderPass.setVertexBuffer(1, this.vertexNormalsBuffer);
|
|
7786
|
+
renderPass.setVertexBuffer(2, this.vertexTexCoordsBuffer);
|
|
7787
|
+
renderPass.setIndexBuffer(this.indexBuffer, 'uint16');
|
|
7788
|
+
renderPass.drawIndexed(this.indexCount);
|
|
7789
|
+
renderPass.end();
|
|
7790
|
+
}
|
|
7791
|
+
};
|
|
7792
|
+
}
|
|
7793
|
+
exports.default = MEMeshObj;
|
|
7794
|
+
|
|
7795
|
+
},{"../shaders/fragment.wgsl":11,"../shaders/vertex.wgsl":13,"../shaders/vertexShadow.wgsl":14,"./engine":5,"./matrix-class":7,"wgpu-matrix":2}],9:[function(require,module,exports){
|
|
7796
|
+
"use strict";
|
|
7797
|
+
|
|
7798
|
+
Object.defineProperty(exports, "__esModule", {
|
|
7799
|
+
value: true
|
|
7800
|
+
});
|
|
7801
|
+
exports.default = void 0;
|
|
7802
|
+
var _wgpuMatrix = require("wgpu-matrix");
|
|
7803
|
+
var _matrixClass = require("./matrix-class");
|
|
7804
|
+
var _engine = require("./engine");
|
|
7805
|
+
var _vertexShadow = require("../shaders/vertexShadow.wgsl");
|
|
7806
|
+
var _fragment = require("../shaders/fragment.wgsl");
|
|
7807
|
+
var _vertex = require("../shaders/vertex.wgsl");
|
|
7808
|
+
var _loaderObj = require("./loader-obj");
|
|
7809
|
+
class MEMesh {
|
|
7810
|
+
constructor(canvas, device, context, o) {
|
|
7811
|
+
this.done = false;
|
|
7812
|
+
this.device = device;
|
|
7813
|
+
this.context = context;
|
|
7814
|
+
this.entityArgPass = o.entityArgPass;
|
|
7815
|
+
this.mesh = o.mesh;
|
|
7816
|
+
this.inputHandler = (0, _engine.createInputHandler)(window, canvas);
|
|
7817
|
+
this.cameras = o.cameras;
|
|
7818
|
+
console.log('passed : o.mainCameraParams.responseCoef ', o.mainCameraParams.responseCoef);
|
|
7819
|
+
this.cameraParams = {
|
|
7820
|
+
type: o.mainCameraParams.type,
|
|
7821
|
+
responseCoef: o.mainCameraParams.responseCoef
|
|
7822
|
+
};
|
|
7823
|
+
this.lastFrameMS = 0;
|
|
7824
|
+
this.texturesPaths = [];
|
|
7825
|
+
o.texturesPaths.forEach(t => {
|
|
7826
|
+
this.texturesPaths.push(t);
|
|
7827
|
+
});
|
|
7828
|
+
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
7829
|
+
this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
|
|
7830
|
+
console.log('cube added on pos : ', this.position);
|
|
7831
|
+
this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
7832
|
+
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
7833
|
+
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
7834
|
+
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
7835
|
+
this.scale = o.scale;
|
|
7836
|
+
|
|
7837
|
+
// new
|
|
7838
|
+
this.runProgram = () => {
|
|
7839
|
+
return new Promise(async resolve => {
|
|
7840
|
+
this.shadowDepthTextureSize = 1024;
|
|
7841
|
+
const aspect = canvas.width / canvas.height;
|
|
7842
|
+
this.projectionMatrix = _wgpuMatrix.mat4.perspective(2 * Math.PI / 5, aspect, 1, 2000.0);
|
|
7843
|
+
this.modelViewProjectionMatrix = _wgpuMatrix.mat4.create();
|
|
7844
|
+
this.loadTex0(this.texturesPaths, device).then(() => {
|
|
7845
|
+
resolve();
|
|
7846
|
+
console.log('load tex for mesh', this.texture0);
|
|
7847
|
+
});
|
|
7848
|
+
});
|
|
7849
|
+
};
|
|
7850
|
+
this.runProgram().then(() => {
|
|
7851
|
+
const aspect = canvas.width / canvas.height;
|
|
7852
|
+
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
7853
|
+
this.context.configure({
|
|
7854
|
+
device: this.device,
|
|
7855
|
+
format: presentationFormat,
|
|
7856
|
+
alphaMode: 'premultiplied'
|
|
7857
|
+
});
|
|
7858
|
+
|
|
7859
|
+
// Create the model vertex buffer.
|
|
7860
|
+
this.vertexBuffer = this.device.createBuffer({
|
|
7861
|
+
size: this.mesh.positions.length * 3 * 2 * Float32Array.BYTES_PER_ELEMENT,
|
|
7862
|
+
usage: GPUBufferUsage.VERTEX,
|
|
7863
|
+
mappedAtCreation: true
|
|
7864
|
+
});
|
|
7865
|
+
{
|
|
7866
|
+
const mapping = new Float32Array(this.vertexBuffer.getMappedRange());
|
|
7867
|
+
for (let i = 0; i < this.mesh.positions.length; ++i) {
|
|
7868
|
+
mapping.set(this.mesh.positions[i], 6 * i);
|
|
7869
|
+
mapping.set(this.mesh.normals[i], 6 * i + 3);
|
|
7870
|
+
}
|
|
7871
|
+
this.vertexBuffer.unmap();
|
|
7872
|
+
}
|
|
7873
|
+
|
|
7874
|
+
// Create the model index buffer.
|
|
7875
|
+
this.indexCount = this.mesh.triangles.length * 3;
|
|
7876
|
+
this.indexBuffer = this.device.createBuffer({
|
|
7877
|
+
size: this.indexCount * Uint16Array.BYTES_PER_ELEMENT,
|
|
7878
|
+
usage: GPUBufferUsage.INDEX,
|
|
7879
|
+
mappedAtCreation: true
|
|
7880
|
+
});
|
|
7881
|
+
{
|
|
7882
|
+
const mapping = new Uint16Array(this.indexBuffer.getMappedRange());
|
|
7883
|
+
for (let i = 0; i < this.mesh.triangles.length; ++i) {
|
|
7884
|
+
mapping.set(this.mesh.triangles[i], 3 * i);
|
|
7885
|
+
}
|
|
7886
|
+
this.indexBuffer.unmap();
|
|
7887
|
+
}
|
|
7888
|
+
|
|
7889
|
+
// Create the depth texture for rendering/sampling the shadow map.
|
|
7890
|
+
this.shadowDepthTexture = this.device.createTexture({
|
|
7891
|
+
size: [this.shadowDepthTextureSize, this.shadowDepthTextureSize, 1],
|
|
7892
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
7893
|
+
format: 'depth32float'
|
|
7894
|
+
});
|
|
7895
|
+
this.shadowDepthTextureView = this.shadowDepthTexture.createView();
|
|
7896
|
+
|
|
7897
|
+
// Create some common descriptors used for both the shadow pipeline
|
|
7898
|
+
// and the color rendering pipeline.
|
|
7899
|
+
this.vertexBuffers = [{
|
|
7900
|
+
arrayStride: Float32Array.BYTES_PER_ELEMENT * 6,
|
|
7901
|
+
attributes: [{
|
|
7902
|
+
// position
|
|
7903
|
+
shaderLocation: 0,
|
|
7904
|
+
offset: 0,
|
|
7905
|
+
format: 'float32x3'
|
|
7906
|
+
}, {
|
|
7907
|
+
// normal
|
|
7908
|
+
shaderLocation: 1,
|
|
7909
|
+
offset: Float32Array.BYTES_PER_ELEMENT * 3,
|
|
7910
|
+
format: 'float32x3'
|
|
7911
|
+
}]
|
|
7912
|
+
}];
|
|
7913
|
+
const primitive = {
|
|
7914
|
+
topology: 'triangle-list',
|
|
7915
|
+
cullMode: 'back'
|
|
7916
|
+
};
|
|
7917
|
+
this.uniformBufferBindGroupLayout = this.device.createBindGroupLayout({
|
|
7918
|
+
entries: [{
|
|
7919
|
+
binding: 0,
|
|
7920
|
+
visibility: GPUShaderStage.VERTEX,
|
|
7921
|
+
buffer: {
|
|
7922
|
+
type: 'uniform'
|
|
7923
|
+
}
|
|
7924
|
+
}]
|
|
7925
|
+
});
|
|
7926
|
+
this.shadowPipeline = this.device.createRenderPipeline({
|
|
7927
|
+
layout: this.device.createPipelineLayout({
|
|
7928
|
+
bindGroupLayouts: [this.uniformBufferBindGroupLayout, this.uniformBufferBindGroupLayout]
|
|
7929
|
+
}),
|
|
7930
|
+
vertex: {
|
|
7931
|
+
module: this.device.createShaderModule({
|
|
7932
|
+
code: _vertexShadow.vertexShadowWGSL
|
|
7933
|
+
}),
|
|
7934
|
+
buffers: this.vertexBuffers
|
|
7935
|
+
},
|
|
7936
|
+
depthStencil: {
|
|
7937
|
+
depthWriteEnabled: true,
|
|
7938
|
+
depthCompare: 'less',
|
|
7939
|
+
format: 'depth32float'
|
|
7940
|
+
},
|
|
7941
|
+
primitive
|
|
7942
|
+
});
|
|
7943
|
+
|
|
7944
|
+
// Create a bind group layout which holds the scene uniforms and
|
|
7945
|
+
// the texture+sampler for depth. We create it manually because the WebPU
|
|
7946
|
+
// implementation doesn't infer this from the shader (yet).
|
|
7947
|
+
this.bglForRender = this.device.createBindGroupLayout({
|
|
7948
|
+
entries: [{
|
|
7949
|
+
binding: 0,
|
|
7950
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7951
|
+
buffer: {
|
|
7952
|
+
type: 'uniform'
|
|
7953
|
+
}
|
|
7954
|
+
}, {
|
|
7955
|
+
binding: 1,
|
|
7956
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7957
|
+
texture: {
|
|
7958
|
+
sampleType: 'depth'
|
|
7959
|
+
}
|
|
7960
|
+
}, {
|
|
7961
|
+
binding: 2,
|
|
7962
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7963
|
+
sampler: {
|
|
7964
|
+
type: 'comparison'
|
|
7965
|
+
}
|
|
7966
|
+
}, {
|
|
7967
|
+
binding: 3,
|
|
7968
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7969
|
+
texture: {
|
|
7970
|
+
sampleType: 'float'
|
|
7971
|
+
}
|
|
7972
|
+
}, {
|
|
7973
|
+
binding: 4,
|
|
7974
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
7975
|
+
sampler: {
|
|
7976
|
+
type: 'filtering'
|
|
7977
|
+
}
|
|
7978
|
+
}]
|
|
7979
|
+
});
|
|
7980
|
+
this.pipeline = this.device.createRenderPipeline({
|
|
7981
|
+
layout: this.device.createPipelineLayout({
|
|
7982
|
+
bindGroupLayouts: [this.bglForRender, this.uniformBufferBindGroupLayout]
|
|
7983
|
+
}),
|
|
7984
|
+
vertex: {
|
|
7985
|
+
module: this.device.createShaderModule({
|
|
7986
|
+
code: _vertex.vertexWGSL
|
|
7987
|
+
}),
|
|
7988
|
+
buffers: this.vertexBuffers
|
|
7989
|
+
},
|
|
7990
|
+
fragment: {
|
|
7991
|
+
module: this.device.createShaderModule({
|
|
7992
|
+
code: _fragment.fragmentWGSL
|
|
7993
|
+
}),
|
|
7994
|
+
targets: [{
|
|
7995
|
+
format: presentationFormat
|
|
7996
|
+
}],
|
|
7997
|
+
constants: {
|
|
7998
|
+
shadowDepthTextureSize: this.shadowDepthTextureSize
|
|
7999
|
+
}
|
|
8000
|
+
},
|
|
8001
|
+
depthStencil: {
|
|
8002
|
+
depthWriteEnabled: true,
|
|
8003
|
+
depthCompare: 'less',
|
|
8004
|
+
format: 'depth24plus-stencil8'
|
|
8005
|
+
},
|
|
8006
|
+
primitive
|
|
8007
|
+
});
|
|
8008
|
+
const depthTexture = this.device.createTexture({
|
|
8009
|
+
size: [canvas.width, canvas.height],
|
|
8010
|
+
format: 'depth24plus-stencil8',
|
|
8011
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
8012
|
+
});
|
|
8013
|
+
this.renderPassDescriptor = {
|
|
8014
|
+
colorAttachments: [{
|
|
8015
|
+
// view is acquired and set in render loop.
|
|
8016
|
+
view: undefined,
|
|
8017
|
+
clearValue: {
|
|
8018
|
+
r: 0.5,
|
|
8019
|
+
g: 0.5,
|
|
8020
|
+
b: 0.5,
|
|
8021
|
+
a: 1.0
|
|
8022
|
+
},
|
|
8023
|
+
loadOp: 'load',
|
|
8024
|
+
storeOp: 'store'
|
|
8025
|
+
}],
|
|
8026
|
+
depthStencilAttachment: {
|
|
8027
|
+
view: depthTexture.createView(),
|
|
8028
|
+
depthClearValue: 1.0,
|
|
8029
|
+
depthLoadOp: 'clear',
|
|
8030
|
+
depthStoreOp: 'store',
|
|
8031
|
+
stencilClearValue: 0,
|
|
8032
|
+
stencilLoadOp: 'clear',
|
|
8033
|
+
stencilStoreOp: 'store'
|
|
8034
|
+
}
|
|
8035
|
+
};
|
|
8036
|
+
this.modelUniformBuffer = this.device.createBuffer({
|
|
8037
|
+
size: 4 * 16,
|
|
8038
|
+
// 4x4 matrix
|
|
8039
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
8040
|
+
});
|
|
8041
|
+
this.sceneUniformBuffer = this.device.createBuffer({
|
|
8042
|
+
// Two 4x4 viewProj matrices,
|
|
8043
|
+
// one for the camera and one for the light.
|
|
8044
|
+
// Then a vec3 for the light position.
|
|
8045
|
+
// Rounded to the nearest multiple of 16.
|
|
8046
|
+
size: 2 * 4 * 16 + 4 * 4,
|
|
8047
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
8048
|
+
});
|
|
8049
|
+
this.sceneBindGroupForShadow = this.device.createBindGroup({
|
|
8050
|
+
layout: this.uniformBufferBindGroupLayout,
|
|
8051
|
+
entries: [{
|
|
8052
|
+
binding: 0,
|
|
8053
|
+
resource: {
|
|
8054
|
+
buffer: this.sceneUniformBuffer
|
|
8055
|
+
}
|
|
8056
|
+
}]
|
|
8057
|
+
});
|
|
8058
|
+
this.sceneBindGroupForRender = this.device.createBindGroup({
|
|
8059
|
+
layout: this.bglForRender,
|
|
8060
|
+
entries: [{
|
|
8061
|
+
binding: 0,
|
|
8062
|
+
resource: {
|
|
8063
|
+
buffer: this.sceneUniformBuffer
|
|
8064
|
+
}
|
|
8065
|
+
}, {
|
|
8066
|
+
binding: 1,
|
|
8067
|
+
resource: this.shadowDepthTextureView
|
|
8068
|
+
}, {
|
|
8069
|
+
binding: 2,
|
|
8070
|
+
resource: this.device.createSampler({
|
|
8071
|
+
compare: 'less'
|
|
8072
|
+
})
|
|
8073
|
+
}, {
|
|
8074
|
+
binding: 3,
|
|
8075
|
+
resource: this.texture0.createView()
|
|
8076
|
+
}, {
|
|
8077
|
+
binding: 4,
|
|
8078
|
+
resource: this.sampler
|
|
8079
|
+
}]
|
|
8080
|
+
});
|
|
8081
|
+
this.modelBindGroup = this.device.createBindGroup({
|
|
8082
|
+
layout: this.uniformBufferBindGroupLayout,
|
|
8083
|
+
entries: [{
|
|
8084
|
+
binding: 0,
|
|
8085
|
+
resource: {
|
|
8086
|
+
buffer: this.modelUniformBuffer
|
|
8087
|
+
}
|
|
8088
|
+
}]
|
|
8089
|
+
});
|
|
8090
|
+
|
|
8091
|
+
// Rotates the camera around the origin based on time.
|
|
8092
|
+
this.getTransformationMatrix = pos => {
|
|
8093
|
+
const now = Date.now();
|
|
8094
|
+
const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
|
|
8095
|
+
this.lastFrameMS = now;
|
|
8096
|
+
const camera = this.cameras[this.cameraParams.type];
|
|
8097
|
+
this.viewMatrix = camera.update(deltaTime, this.inputHandler());
|
|
8098
|
+
_wgpuMatrix.mat4.translate(this.viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), this.viewMatrix);
|
|
8099
|
+
_wgpuMatrix.mat4.rotateX(this.viewMatrix, Math.PI * this.rotation.getRotX(), this.viewMatrix);
|
|
8100
|
+
_wgpuMatrix.mat4.rotateY(this.viewMatrix, Math.PI * this.rotation.getRotY(), this.viewMatrix);
|
|
8101
|
+
_wgpuMatrix.mat4.rotateZ(this.viewMatrix, Math.PI * this.rotation.getRotZ(), this.viewMatrix);
|
|
8102
|
+
_wgpuMatrix.mat4.multiply(this.projectionMatrix, this.viewMatrix, this.modelViewProjectionMatrix);
|
|
8103
|
+
return this.modelViewProjectionMatrix;
|
|
8104
|
+
};
|
|
8105
|
+
this.upVector = _wgpuMatrix.vec3.fromValues(0, 1, 0);
|
|
8106
|
+
this.origin = _wgpuMatrix.vec3.fromValues(0, 0, 0);
|
|
8107
|
+
const lightPosition = _wgpuMatrix.vec3.fromValues(50, 100, -100);
|
|
8108
|
+
const lightViewMatrix = _wgpuMatrix.mat4.lookAt(lightPosition, this.origin, this.upVector);
|
|
8109
|
+
const lightProjectionMatrix = _wgpuMatrix.mat4.create();
|
|
8110
|
+
{
|
|
8111
|
+
const left = -80;
|
|
8112
|
+
const right = 80;
|
|
8113
|
+
const bottom = -80;
|
|
8114
|
+
const top = 80;
|
|
8115
|
+
const near = -200;
|
|
8116
|
+
const far = 300;
|
|
8117
|
+
_wgpuMatrix.mat4.ortho(left, right, bottom, top, near, far, lightProjectionMatrix);
|
|
8118
|
+
}
|
|
8119
|
+
const lightViewProjMatrix = _wgpuMatrix.mat4.multiply(lightProjectionMatrix, lightViewMatrix);
|
|
8120
|
+
|
|
8121
|
+
// looks like affect on transformations for now const 0
|
|
8122
|
+
const modelMatrix = _wgpuMatrix.mat4.translation([0, 0, 0]);
|
|
8123
|
+
// The camera/light aren't moving, so write them into buffers now.
|
|
8124
|
+
{
|
|
8125
|
+
const lightMatrixData = lightViewProjMatrix; // as Float32Array;
|
|
8126
|
+
this.device.queue.writeBuffer(this.sceneUniformBuffer, 0, lightMatrixData.buffer, lightMatrixData.byteOffset, lightMatrixData.byteLength);
|
|
8127
|
+
const lightData = lightPosition;
|
|
8128
|
+
this.device.queue.writeBuffer(this.sceneUniformBuffer, 128, lightData.buffer, lightData.byteOffset, lightData.byteLength);
|
|
8129
|
+
const modelData = modelMatrix;
|
|
8130
|
+
this.device.queue.writeBuffer(this.modelUniformBuffer, 0, modelData.buffer, modelData.byteOffset, modelData.byteLength);
|
|
8131
|
+
}
|
|
8132
|
+
this.shadowPassDescriptor = {
|
|
8133
|
+
colorAttachments: [],
|
|
8134
|
+
depthStencilAttachment: {
|
|
8135
|
+
view: this.shadowDepthTextureView,
|
|
8136
|
+
depthClearValue: 1.0,
|
|
8137
|
+
depthLoadOp: 'clear',
|
|
8138
|
+
depthStoreOp: 'store'
|
|
8139
|
+
}
|
|
8140
|
+
};
|
|
8141
|
+
this.done = true;
|
|
8142
|
+
});
|
|
8143
|
+
}
|
|
8144
|
+
async loadTex0(texturesPaths, device) {
|
|
8145
|
+
this.sampler = device.createSampler({
|
|
8146
|
+
magFilter: 'linear',
|
|
8147
|
+
minFilter: 'linear'
|
|
8148
|
+
});
|
|
8149
|
+
return new Promise(async resolve => {
|
|
8150
|
+
const response = await fetch(texturesPaths[0]);
|
|
8151
|
+
const imageBitmap = await createImageBitmap(await response.blob());
|
|
8152
|
+
this.texture0 = device.createTexture({
|
|
8153
|
+
size: [imageBitmap.width, imageBitmap.height, 1],
|
|
8154
|
+
format: 'rgba8unorm',
|
|
8155
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
|
|
8156
|
+
});
|
|
8157
|
+
device.queue.copyExternalImageToTexture({
|
|
8158
|
+
source: imageBitmap
|
|
8159
|
+
}, {
|
|
8160
|
+
texture: this.texture0
|
|
8161
|
+
}, [imageBitmap.width, imageBitmap.height]);
|
|
8162
|
+
resolve();
|
|
8163
|
+
});
|
|
8164
|
+
}
|
|
8165
|
+
draw = commandEncoder => {
|
|
8166
|
+
if (this.done == false) return;
|
|
8167
|
+
const transformationMatrix = this.getTransformationMatrix(this.position);
|
|
8168
|
+
this.device.queue.writeBuffer(this.sceneUniformBuffer, 64, transformationMatrix.buffer, transformationMatrix.byteOffset, transformationMatrix.byteLength);
|
|
8169
|
+
this.renderPassDescriptor.colorAttachments[0].view = this.context.getCurrentTexture().createView();
|
|
8170
|
+
{
|
|
8171
|
+
const shadowPass = commandEncoder.beginRenderPass(this.shadowPassDescriptor);
|
|
8172
|
+
shadowPass.setPipeline(this.shadowPipeline);
|
|
8173
|
+
shadowPass.setBindGroup(0, this.sceneBindGroupForShadow);
|
|
8174
|
+
shadowPass.setBindGroup(1, this.modelBindGroup);
|
|
8175
|
+
shadowPass.setVertexBuffer(0, this.vertexBuffer);
|
|
8176
|
+
shadowPass.setIndexBuffer(this.indexBuffer, 'uint16');
|
|
8177
|
+
shadowPass.drawIndexed(this.indexCount);
|
|
8178
|
+
shadowPass.end();
|
|
8179
|
+
}
|
|
8180
|
+
{
|
|
8181
|
+
const renderPass = commandEncoder.beginRenderPass(this.renderPassDescriptor);
|
|
8182
|
+
renderPass.setPipeline(this.pipeline);
|
|
8183
|
+
renderPass.setBindGroup(0, this.sceneBindGroupForRender);
|
|
8184
|
+
renderPass.setBindGroup(1, this.modelBindGroup);
|
|
8185
|
+
renderPass.setVertexBuffer(0, this.vertexBuffer);
|
|
8186
|
+
renderPass.setIndexBuffer(this.indexBuffer, 'uint16');
|
|
8187
|
+
renderPass.drawIndexed(this.indexCount);
|
|
8188
|
+
renderPass.end();
|
|
8189
|
+
}
|
|
8190
|
+
};
|
|
8191
|
+
}
|
|
8192
|
+
exports.default = MEMesh;
|
|
8193
|
+
|
|
8194
|
+
},{"../shaders/fragment.wgsl":11,"../shaders/vertex.wgsl":13,"../shaders/vertexShadow.wgsl":14,"./engine":5,"./loader-obj":6,"./matrix-class":7,"wgpu-matrix":2}],10:[function(require,module,exports){
|
|
8195
|
+
"use strict";
|
|
8196
|
+
|
|
8197
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8198
|
+
value: true
|
|
8199
|
+
});
|
|
8200
|
+
exports.degToRad = degToRad;
|
|
8201
|
+
exports.vec3 = exports.mat4 = void 0;
|
|
8202
|
+
const vec3 = exports.vec3 = {
|
|
8203
|
+
cross(a, b, dst) {
|
|
8204
|
+
dst = dst || new Float32Array(3);
|
|
8205
|
+
const t0 = a[1] * b[2] - a[2] * b[1];
|
|
8206
|
+
const t1 = a[2] * b[0] - a[0] * b[2];
|
|
8207
|
+
const t2 = a[0] * b[1] - a[1] * b[0];
|
|
8208
|
+
dst[0] = t0;
|
|
8209
|
+
dst[1] = t1;
|
|
8210
|
+
dst[2] = t2;
|
|
8211
|
+
return dst;
|
|
8212
|
+
},
|
|
8213
|
+
subtract(a, b, dst) {
|
|
8214
|
+
dst = dst || new Float32Array(3);
|
|
8215
|
+
dst[0] = a[0] - b[0];
|
|
8216
|
+
dst[1] = a[1] - b[1];
|
|
8217
|
+
dst[2] = a[2] - b[2];
|
|
8218
|
+
return dst;
|
|
8219
|
+
},
|
|
8220
|
+
normalize(v, dst) {
|
|
8221
|
+
dst = dst || new Float32Array(3);
|
|
8222
|
+
const length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
8223
|
+
// make sure we don't divide by 0.
|
|
8224
|
+
if (length > 0.00001) {
|
|
8225
|
+
dst[0] = v[0] / length;
|
|
8226
|
+
dst[1] = v[1] / length;
|
|
8227
|
+
dst[2] = v[2] / length;
|
|
8228
|
+
} else {
|
|
8229
|
+
dst[0] = 0;
|
|
8230
|
+
dst[1] = 0;
|
|
8231
|
+
dst[2] = 0;
|
|
8232
|
+
}
|
|
8233
|
+
return dst;
|
|
8234
|
+
}
|
|
8235
|
+
};
|
|
8236
|
+
const mat4 = exports.mat4 = {
|
|
8237
|
+
projection(width, height, depth, dst) {
|
|
8238
|
+
// Note: This matrix flips the Y axis so that 0 is at the top.
|
|
8239
|
+
return mat4.ortho(0, width, height, 0, depth, -depth, dst);
|
|
8240
|
+
},
|
|
8241
|
+
perspective(fieldOfViewYInRadians, aspect, zNear, zFar, dst) {
|
|
8242
|
+
dst = dst || new Float32Array(16);
|
|
8243
|
+
const f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewYInRadians);
|
|
8244
|
+
const rangeInv = 1 / (zNear - zFar);
|
|
8245
|
+
dst[0] = f / aspect;
|
|
8246
|
+
dst[1] = 0;
|
|
8247
|
+
dst[2] = 0;
|
|
8248
|
+
dst[3] = 0;
|
|
8249
|
+
dst[4] = 0;
|
|
8250
|
+
dst[5] = f;
|
|
8251
|
+
dst[6] = 0;
|
|
8252
|
+
dst[7] = 0;
|
|
8253
|
+
dst[8] = 0;
|
|
8254
|
+
dst[9] = 0;
|
|
8255
|
+
dst[10] = zFar * rangeInv;
|
|
8256
|
+
dst[11] = -1;
|
|
8257
|
+
dst[12] = 0;
|
|
8258
|
+
dst[13] = 0;
|
|
8259
|
+
dst[14] = zNear * zFar * rangeInv;
|
|
8260
|
+
dst[15] = 0;
|
|
8261
|
+
return dst;
|
|
8262
|
+
},
|
|
8263
|
+
ortho(left, right, bottom, top, near, far, dst) {
|
|
8264
|
+
dst = dst || new Float32Array(16);
|
|
8265
|
+
dst[0] = 2 / (right - left);
|
|
8266
|
+
dst[1] = 0;
|
|
8267
|
+
dst[2] = 0;
|
|
8268
|
+
dst[3] = 0;
|
|
8269
|
+
dst[4] = 0;
|
|
8270
|
+
dst[5] = 2 / (top - bottom);
|
|
8271
|
+
dst[6] = 0;
|
|
8272
|
+
dst[7] = 0;
|
|
8273
|
+
dst[8] = 0;
|
|
8274
|
+
dst[9] = 0;
|
|
8275
|
+
dst[10] = 1 / (near - far);
|
|
8276
|
+
dst[11] = 0;
|
|
8277
|
+
dst[12] = (right + left) / (left - right);
|
|
8278
|
+
dst[13] = (top + bottom) / (bottom - top);
|
|
8279
|
+
dst[14] = near / (near - far);
|
|
8280
|
+
dst[15] = 1;
|
|
8281
|
+
return dst;
|
|
8282
|
+
},
|
|
8283
|
+
identity(dst) {
|
|
8284
|
+
dst = dst || new Float32Array(16);
|
|
8285
|
+
dst[0] = 1;
|
|
8286
|
+
dst[1] = 0;
|
|
8287
|
+
dst[2] = 0;
|
|
8288
|
+
dst[3] = 0;
|
|
8289
|
+
dst[4] = 0;
|
|
8290
|
+
dst[5] = 1;
|
|
8291
|
+
dst[6] = 0;
|
|
8292
|
+
dst[7] = 0;
|
|
8293
|
+
dst[8] = 0;
|
|
8294
|
+
dst[9] = 0;
|
|
8295
|
+
dst[10] = 1;
|
|
8296
|
+
dst[11] = 0;
|
|
8297
|
+
dst[12] = 0;
|
|
8298
|
+
dst[13] = 0;
|
|
8299
|
+
dst[14] = 0;
|
|
8300
|
+
dst[15] = 1;
|
|
8301
|
+
return dst;
|
|
8302
|
+
},
|
|
8303
|
+
multiply(a, b, dst) {
|
|
8304
|
+
dst = dst || new Float32Array(16);
|
|
8305
|
+
const b00 = b[0 * 4 + 0];
|
|
8306
|
+
const b01 = b[0 * 4 + 1];
|
|
8307
|
+
const b02 = b[0 * 4 + 2];
|
|
8308
|
+
const b03 = b[0 * 4 + 3];
|
|
8309
|
+
const b10 = b[1 * 4 + 0];
|
|
8310
|
+
const b11 = b[1 * 4 + 1];
|
|
8311
|
+
const b12 = b[1 * 4 + 2];
|
|
8312
|
+
const b13 = b[1 * 4 + 3];
|
|
8313
|
+
const b20 = b[2 * 4 + 0];
|
|
8314
|
+
const b21 = b[2 * 4 + 1];
|
|
8315
|
+
const b22 = b[2 * 4 + 2];
|
|
8316
|
+
const b23 = b[2 * 4 + 3];
|
|
8317
|
+
const b30 = b[3 * 4 + 0];
|
|
8318
|
+
const b31 = b[3 * 4 + 1];
|
|
8319
|
+
const b32 = b[3 * 4 + 2];
|
|
8320
|
+
const b33 = b[3 * 4 + 3];
|
|
8321
|
+
const a00 = a[0 * 4 + 0];
|
|
8322
|
+
const a01 = a[0 * 4 + 1];
|
|
8323
|
+
const a02 = a[0 * 4 + 2];
|
|
8324
|
+
const a03 = a[0 * 4 + 3];
|
|
8325
|
+
const a10 = a[1 * 4 + 0];
|
|
8326
|
+
const a11 = a[1 * 4 + 1];
|
|
8327
|
+
const a12 = a[1 * 4 + 2];
|
|
8328
|
+
const a13 = a[1 * 4 + 3];
|
|
8329
|
+
const a20 = a[2 * 4 + 0];
|
|
8330
|
+
const a21 = a[2 * 4 + 1];
|
|
8331
|
+
const a22 = a[2 * 4 + 2];
|
|
8332
|
+
const a23 = a[2 * 4 + 3];
|
|
8333
|
+
const a30 = a[3 * 4 + 0];
|
|
8334
|
+
const a31 = a[3 * 4 + 1];
|
|
8335
|
+
const a32 = a[3 * 4 + 2];
|
|
8336
|
+
const a33 = a[3 * 4 + 3];
|
|
8337
|
+
dst[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;
|
|
8338
|
+
dst[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;
|
|
8339
|
+
dst[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;
|
|
8340
|
+
dst[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;
|
|
8341
|
+
dst[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;
|
|
8342
|
+
dst[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;
|
|
8343
|
+
dst[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;
|
|
8344
|
+
dst[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;
|
|
8345
|
+
dst[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;
|
|
8346
|
+
dst[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;
|
|
8347
|
+
dst[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;
|
|
8348
|
+
dst[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;
|
|
8349
|
+
dst[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;
|
|
8350
|
+
dst[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;
|
|
8351
|
+
dst[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;
|
|
8352
|
+
dst[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;
|
|
8353
|
+
return dst;
|
|
8354
|
+
},
|
|
8355
|
+
cameraAim(eye, target, up, dst) {
|
|
8356
|
+
dst = dst || new Float32Array(16);
|
|
8357
|
+
const zAxis = vec3.normalize(vec3.subtract(eye, target));
|
|
8358
|
+
const xAxis = vec3.normalize(vec3.cross(up, zAxis));
|
|
8359
|
+
const yAxis = vec3.normalize(vec3.cross(zAxis, xAxis));
|
|
8360
|
+
dst[0] = xAxis[0];
|
|
8361
|
+
dst[1] = xAxis[1];
|
|
8362
|
+
dst[2] = xAxis[2];
|
|
8363
|
+
dst[3] = 0;
|
|
8364
|
+
dst[4] = yAxis[0];
|
|
8365
|
+
dst[5] = yAxis[1];
|
|
8366
|
+
dst[6] = yAxis[2];
|
|
8367
|
+
dst[7] = 0;
|
|
8368
|
+
dst[8] = zAxis[0];
|
|
8369
|
+
dst[9] = zAxis[1];
|
|
8370
|
+
dst[10] = zAxis[2];
|
|
8371
|
+
dst[11] = 0;
|
|
8372
|
+
dst[12] = eye[0];
|
|
8373
|
+
dst[13] = eye[1];
|
|
8374
|
+
dst[14] = eye[2];
|
|
8375
|
+
dst[15] = 1;
|
|
8376
|
+
return dst;
|
|
8377
|
+
},
|
|
8378
|
+
inverse(m, dst) {
|
|
8379
|
+
dst = dst || new Float32Array(16);
|
|
8380
|
+
const m00 = m[0 * 4 + 0];
|
|
8381
|
+
const m01 = m[0 * 4 + 1];
|
|
8382
|
+
const m02 = m[0 * 4 + 2];
|
|
8383
|
+
const m03 = m[0 * 4 + 3];
|
|
8384
|
+
const m10 = m[1 * 4 + 0];
|
|
8385
|
+
const m11 = m[1 * 4 + 1];
|
|
8386
|
+
const m12 = m[1 * 4 + 2];
|
|
8387
|
+
const m13 = m[1 * 4 + 3];
|
|
8388
|
+
const m20 = m[2 * 4 + 0];
|
|
8389
|
+
const m21 = m[2 * 4 + 1];
|
|
8390
|
+
const m22 = m[2 * 4 + 2];
|
|
8391
|
+
const m23 = m[2 * 4 + 3];
|
|
8392
|
+
const m30 = m[3 * 4 + 0];
|
|
8393
|
+
const m31 = m[3 * 4 + 1];
|
|
8394
|
+
const m32 = m[3 * 4 + 2];
|
|
8395
|
+
const m33 = m[3 * 4 + 3];
|
|
8396
|
+
const tmp0 = m22 * m33;
|
|
8397
|
+
const tmp1 = m32 * m23;
|
|
8398
|
+
const tmp2 = m12 * m33;
|
|
8399
|
+
const tmp3 = m32 * m13;
|
|
8400
|
+
const tmp4 = m12 * m23;
|
|
8401
|
+
const tmp5 = m22 * m13;
|
|
8402
|
+
const tmp6 = m02 * m33;
|
|
8403
|
+
const tmp7 = m32 * m03;
|
|
8404
|
+
const tmp8 = m02 * m23;
|
|
8405
|
+
const tmp9 = m22 * m03;
|
|
8406
|
+
const tmp10 = m02 * m13;
|
|
8407
|
+
const tmp11 = m12 * m03;
|
|
8408
|
+
const tmp12 = m20 * m31;
|
|
8409
|
+
const tmp13 = m30 * m21;
|
|
8410
|
+
const tmp14 = m10 * m31;
|
|
8411
|
+
const tmp15 = m30 * m11;
|
|
8412
|
+
const tmp16 = m10 * m21;
|
|
8413
|
+
const tmp17 = m20 * m11;
|
|
8414
|
+
const tmp18 = m00 * m31;
|
|
8415
|
+
const tmp19 = m30 * m01;
|
|
8416
|
+
const tmp20 = m00 * m21;
|
|
8417
|
+
const tmp21 = m20 * m01;
|
|
8418
|
+
const tmp22 = m00 * m11;
|
|
8419
|
+
const tmp23 = m10 * m01;
|
|
8420
|
+
const t0 = tmp0 * m11 + tmp3 * m21 + tmp4 * m31 - (tmp1 * m11 + tmp2 * m21 + tmp5 * m31);
|
|
8421
|
+
const t1 = tmp1 * m01 + tmp6 * m21 + tmp9 * m31 - (tmp0 * m01 + tmp7 * m21 + tmp8 * m31);
|
|
8422
|
+
const t2 = tmp2 * m01 + tmp7 * m11 + tmp10 * m31 - (tmp3 * m01 + tmp6 * m11 + tmp11 * m31);
|
|
8423
|
+
const t3 = tmp5 * m01 + tmp8 * m11 + tmp11 * m21 - (tmp4 * m01 + tmp9 * m11 + tmp10 * m21);
|
|
8424
|
+
const d = 1 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);
|
|
8425
|
+
dst[0] = d * t0;
|
|
8426
|
+
dst[1] = d * t1;
|
|
8427
|
+
dst[2] = d * t2;
|
|
8428
|
+
dst[3] = d * t3;
|
|
8429
|
+
dst[4] = d * (tmp1 * m10 + tmp2 * m20 + tmp5 * m30 - (tmp0 * m10 + tmp3 * m20 + tmp4 * m30));
|
|
8430
|
+
dst[5] = d * (tmp0 * m00 + tmp7 * m20 + tmp8 * m30 - (tmp1 * m00 + tmp6 * m20 + tmp9 * m30));
|
|
8431
|
+
dst[6] = d * (tmp3 * m00 + tmp6 * m10 + tmp11 * m30 - (tmp2 * m00 + tmp7 * m10 + tmp10 * m30));
|
|
8432
|
+
dst[7] = d * (tmp4 * m00 + tmp9 * m10 + tmp10 * m20 - (tmp5 * m00 + tmp8 * m10 + tmp11 * m20));
|
|
8433
|
+
dst[8] = d * (tmp12 * m13 + tmp15 * m23 + tmp16 * m33 - (tmp13 * m13 + tmp14 * m23 + tmp17 * m33));
|
|
8434
|
+
dst[9] = d * (tmp13 * m03 + tmp18 * m23 + tmp21 * m33 - (tmp12 * m03 + tmp19 * m23 + tmp20 * m33));
|
|
8435
|
+
dst[10] = d * (tmp14 * m03 + tmp19 * m13 + tmp22 * m33 - (tmp15 * m03 + tmp18 * m13 + tmp23 * m33));
|
|
8436
|
+
dst[11] = d * (tmp17 * m03 + tmp20 * m13 + tmp23 * m23 - (tmp16 * m03 + tmp21 * m13 + tmp22 * m23));
|
|
8437
|
+
dst[12] = d * (tmp14 * m22 + tmp17 * m32 + tmp13 * m12 - (tmp16 * m32 + tmp12 * m12 + tmp15 * m22));
|
|
8438
|
+
dst[13] = d * (tmp20 * m32 + tmp12 * m02 + tmp19 * m22 - (tmp18 * m22 + tmp21 * m32 + tmp13 * m02));
|
|
8439
|
+
dst[14] = d * (tmp18 * m12 + tmp23 * m32 + tmp15 * m02 - (tmp22 * m32 + tmp14 * m02 + tmp19 * m12));
|
|
8440
|
+
dst[15] = d * (tmp22 * m22 + tmp16 * m02 + tmp21 * m12 - (tmp20 * m12 + tmp23 * m22 + tmp17 * m02));
|
|
8441
|
+
return dst;
|
|
8442
|
+
},
|
|
8443
|
+
lookAt(eye, target, up, dst) {
|
|
8444
|
+
return mat4.inverse(mat4.cameraAim(eye, target, up, dst), dst);
|
|
8445
|
+
},
|
|
8446
|
+
translation([tx, ty, tz], dst) {
|
|
8447
|
+
dst = dst || new Float32Array(16);
|
|
8448
|
+
dst[0] = 1;
|
|
8449
|
+
dst[1] = 0;
|
|
8450
|
+
dst[2] = 0;
|
|
8451
|
+
dst[3] = 0;
|
|
8452
|
+
dst[4] = 0;
|
|
8453
|
+
dst[5] = 1;
|
|
8454
|
+
dst[6] = 0;
|
|
8455
|
+
dst[7] = 0;
|
|
8456
|
+
dst[8] = 0;
|
|
8457
|
+
dst[9] = 0;
|
|
8458
|
+
dst[10] = 1;
|
|
8459
|
+
dst[11] = 0;
|
|
8460
|
+
dst[12] = tx;
|
|
8461
|
+
dst[13] = ty;
|
|
8462
|
+
dst[14] = tz;
|
|
8463
|
+
dst[15] = 1;
|
|
8464
|
+
return dst;
|
|
8465
|
+
},
|
|
8466
|
+
rotationX(angleInRadians, dst) {
|
|
8467
|
+
const c = Math.cos(angleInRadians);
|
|
8468
|
+
const s = Math.sin(angleInRadians);
|
|
8469
|
+
dst = dst || new Float32Array(16);
|
|
8470
|
+
dst[0] = 1;
|
|
8471
|
+
dst[1] = 0;
|
|
8472
|
+
dst[2] = 0;
|
|
8473
|
+
dst[3] = 0;
|
|
8474
|
+
dst[4] = 0;
|
|
8475
|
+
dst[5] = c;
|
|
8476
|
+
dst[6] = s;
|
|
8477
|
+
dst[7] = 0;
|
|
8478
|
+
dst[8] = 0;
|
|
8479
|
+
dst[9] = -s;
|
|
8480
|
+
dst[10] = c;
|
|
8481
|
+
dst[11] = 0;
|
|
8482
|
+
dst[12] = 0;
|
|
8483
|
+
dst[13] = 0;
|
|
8484
|
+
dst[14] = 0;
|
|
8485
|
+
dst[15] = 1;
|
|
8486
|
+
return dst;
|
|
8487
|
+
},
|
|
8488
|
+
rotationY(angleInRadians, dst) {
|
|
8489
|
+
const c = Math.cos(angleInRadians);
|
|
8490
|
+
const s = Math.sin(angleInRadians);
|
|
8491
|
+
dst = dst || new Float32Array(16);
|
|
8492
|
+
dst[0] = c;
|
|
8493
|
+
dst[1] = 0;
|
|
8494
|
+
dst[2] = -s;
|
|
8495
|
+
dst[3] = 0;
|
|
8496
|
+
dst[4] = 0;
|
|
8497
|
+
dst[5] = 1;
|
|
8498
|
+
dst[6] = 0;
|
|
8499
|
+
dst[7] = 0;
|
|
8500
|
+
dst[8] = s;
|
|
8501
|
+
dst[9] = 0;
|
|
8502
|
+
dst[10] = c;
|
|
8503
|
+
dst[11] = 0;
|
|
8504
|
+
dst[12] = 0;
|
|
8505
|
+
dst[13] = 0;
|
|
8506
|
+
dst[14] = 0;
|
|
8507
|
+
dst[15] = 1;
|
|
8508
|
+
return dst;
|
|
8509
|
+
},
|
|
8510
|
+
rotationZ(angleInRadians, dst) {
|
|
8511
|
+
const c = Math.cos(angleInRadians);
|
|
8512
|
+
const s = Math.sin(angleInRadians);
|
|
8513
|
+
dst = dst || new Float32Array(16);
|
|
8514
|
+
dst[0] = c;
|
|
8515
|
+
dst[1] = s;
|
|
8516
|
+
dst[2] = 0;
|
|
8517
|
+
dst[3] = 0;
|
|
8518
|
+
dst[4] = -s;
|
|
8519
|
+
dst[5] = c;
|
|
8520
|
+
dst[6] = 0;
|
|
8521
|
+
dst[7] = 0;
|
|
8522
|
+
dst[8] = 0;
|
|
8523
|
+
dst[9] = 0;
|
|
8524
|
+
dst[10] = 1;
|
|
8525
|
+
dst[11] = 0;
|
|
8526
|
+
dst[12] = 0;
|
|
8527
|
+
dst[13] = 0;
|
|
8528
|
+
dst[14] = 0;
|
|
8529
|
+
dst[15] = 1;
|
|
8530
|
+
return dst;
|
|
8531
|
+
},
|
|
8532
|
+
scaling([sx, sy, sz], dst) {
|
|
8533
|
+
dst = dst || new Float32Array(16);
|
|
8534
|
+
dst[0] = sx;
|
|
8535
|
+
dst[1] = 0;
|
|
8536
|
+
dst[2] = 0;
|
|
8537
|
+
dst[3] = 0;
|
|
8538
|
+
dst[4] = 0;
|
|
8539
|
+
dst[5] = sy;
|
|
8540
|
+
dst[6] = 0;
|
|
8541
|
+
dst[7] = 0;
|
|
8542
|
+
dst[8] = 0;
|
|
8543
|
+
dst[9] = 0;
|
|
8544
|
+
dst[10] = sz;
|
|
8545
|
+
dst[11] = 0;
|
|
8546
|
+
dst[12] = 0;
|
|
8547
|
+
dst[13] = 0;
|
|
8548
|
+
dst[14] = 0;
|
|
8549
|
+
dst[15] = 1;
|
|
8550
|
+
return dst;
|
|
8551
|
+
},
|
|
8552
|
+
translate(m, translation, dst) {
|
|
8553
|
+
return mat4.multiply(m, mat4.translation(translation), dst);
|
|
8554
|
+
},
|
|
8555
|
+
rotateX(m, angleInRadians, dst) {
|
|
8556
|
+
return mat4.multiply(m, mat4.rotationX(angleInRadians), dst);
|
|
8557
|
+
},
|
|
8558
|
+
rotateY(m, angleInRadians, dst) {
|
|
8559
|
+
return mat4.multiply(m, mat4.rotationY(angleInRadians), dst);
|
|
8560
|
+
},
|
|
8561
|
+
rotateZ(m, angleInRadians, dst) {
|
|
8562
|
+
return mat4.multiply(m, mat4.rotationZ(angleInRadians), dst);
|
|
8563
|
+
},
|
|
8564
|
+
scale(m, scale, dst) {
|
|
8565
|
+
return mat4.multiply(m, mat4.scaling(scale), dst);
|
|
8566
|
+
}
|
|
8567
|
+
};
|
|
8568
|
+
function degToRad(degrees) {
|
|
8569
|
+
return degrees * Math.PI / 180;
|
|
8570
|
+
}
|
|
8571
|
+
;
|
|
8572
|
+
|
|
8573
|
+
},{}],11:[function(require,module,exports){
|
|
8574
|
+
"use strict";
|
|
8575
|
+
|
|
8576
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8577
|
+
value: true
|
|
8578
|
+
});
|
|
8579
|
+
exports.fragmentWGSL = void 0;
|
|
8580
|
+
let fragmentWGSL = exports.fragmentWGSL = `override shadowDepthTextureSize: f32 = 1024.0;
|
|
8581
|
+
|
|
8582
|
+
struct Scene {
|
|
8583
|
+
lightViewProjMatrix : mat4x4f,
|
|
8584
|
+
cameraViewProjMatrix : mat4x4f,
|
|
8585
|
+
lightPos : vec3f,
|
|
8586
|
+
}
|
|
8587
|
+
|
|
8588
|
+
@group(0) @binding(0) var<uniform> scene : Scene;
|
|
8589
|
+
@group(0) @binding(1) var shadowMap: texture_depth_2d;
|
|
8590
|
+
@group(0) @binding(2) var shadowSampler: sampler_comparison;
|
|
8591
|
+
@group(0) @binding(3) var meshTexture: texture_2d<f32>;
|
|
8592
|
+
@group(0) @binding(4) var meshSampler: sampler;
|
|
8593
|
+
|
|
8594
|
+
struct FragmentInput {
|
|
8595
|
+
@location(0) shadowPos : vec3f,
|
|
8596
|
+
@location(1) fragPos : vec3f,
|
|
8597
|
+
@location(2) fragNorm : vec3f,
|
|
8598
|
+
@location(3) uv : vec2f,
|
|
8599
|
+
}
|
|
8600
|
+
|
|
8601
|
+
const albedo = vec3f(0.9);
|
|
8602
|
+
const ambientFactor = 0.2;
|
|
8603
|
+
|
|
8604
|
+
@fragment
|
|
8605
|
+
fn main(input : FragmentInput) -> @location(0) vec4f {
|
|
8606
|
+
// Percentage-closer filtering. Sample texels in the region
|
|
8607
|
+
// to smooth the result.
|
|
8608
|
+
var visibility = 0.0;
|
|
8609
|
+
let oneOverShadowDepthTextureSize = 1.0 / shadowDepthTextureSize;
|
|
8610
|
+
for (var y = -1; y <= 1; y++) {
|
|
8611
|
+
for (var x = -1; x <= 1; x++) {
|
|
8612
|
+
let offset = vec2f(vec2(x, y)) * oneOverShadowDepthTextureSize;
|
|
8613
|
+
|
|
8614
|
+
visibility += textureSampleCompare(
|
|
8615
|
+
shadowMap, shadowSampler,
|
|
8616
|
+
input.shadowPos.xy + offset, input.shadowPos.z - 0.007
|
|
8617
|
+
);
|
|
8618
|
+
}
|
|
8619
|
+
}
|
|
8620
|
+
visibility /= 9.0;
|
|
8621
|
+
|
|
8622
|
+
let lambertFactor = max(dot(normalize(scene.lightPos - input.fragPos), normalize(input.fragNorm)), 0.0);
|
|
8623
|
+
let lightingFactor = min(ambientFactor + visibility * lambertFactor, 1.0);
|
|
8624
|
+
let textureColor = textureSample(meshTexture, meshSampler, input.uv);
|
|
8625
|
+
|
|
8626
|
+
return vec4(textureColor.rgb * lightingFactor * albedo, 1.0);
|
|
8627
|
+
}`;
|
|
8628
|
+
|
|
8629
|
+
},{}],12:[function(require,module,exports){
|
|
8630
|
+
"use strict";
|
|
8631
|
+
|
|
8632
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8633
|
+
value: true
|
|
8634
|
+
});
|
|
8635
|
+
exports.UNLIT_SHADER = void 0;
|
|
8636
|
+
/**
|
|
8637
|
+
* @description
|
|
8638
|
+
* UNIT Texures -
|
|
8639
|
+
* Good for performance
|
|
8640
|
+
*/
|
|
8641
|
+
const UNLIT_SHADER = exports.UNLIT_SHADER = `struct Uniforms {
|
|
8642
|
+
viewProjectionMatrix : mat4x4f
|
|
8643
|
+
}
|
|
8644
|
+
@group(0) @binding(0) var<uniform> uniforms : Uniforms;
|
|
8645
|
+
|
|
8646
|
+
@group(1) @binding(0) var<uniform> modelMatrix : mat4x4f;
|
|
8647
|
+
|
|
8648
|
+
struct VertexInput {
|
|
8649
|
+
@location(0) position : vec4f,
|
|
8650
|
+
@location(1) normal : vec3f,
|
|
8651
|
+
@location(2) uv : vec2f
|
|
8652
|
+
}
|
|
8653
|
+
|
|
8654
|
+
struct VertexOutput {
|
|
8655
|
+
@builtin(position) position : vec4f,
|
|
8656
|
+
@location(0) normal: vec3f,
|
|
8657
|
+
@location(1) uv : vec2f,
|
|
8658
|
+
}
|
|
8659
|
+
|
|
8660
|
+
@vertex
|
|
8661
|
+
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
8662
|
+
var output : VertexOutput;
|
|
8663
|
+
output.position = uniforms.viewProjectionMatrix * modelMatrix * input.position;
|
|
8664
|
+
output.normal = normalize((modelMatrix * vec4(input.normal, 0)).xyz);
|
|
8665
|
+
output.uv = input.uv;
|
|
8666
|
+
return output;
|
|
8667
|
+
}
|
|
8668
|
+
|
|
8669
|
+
@group(1) @binding(1) var meshSampler: sampler;
|
|
8670
|
+
@group(1) @binding(2) var meshTexture: texture_2d<f32>;
|
|
8671
|
+
|
|
8672
|
+
// Static directional lighting
|
|
8673
|
+
const lightDir = vec3f(1, 1, 1);
|
|
8674
|
+
const dirColor = vec3(1);
|
|
8675
|
+
const ambientColor = vec3f(0.05);
|
|
8676
|
+
|
|
8677
|
+
@fragment
|
|
8678
|
+
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
|
|
8679
|
+
let textureColor = textureSample(meshTexture, meshSampler, input.uv);
|
|
8680
|
+
|
|
8681
|
+
// Very simplified lighting algorithm.
|
|
8682
|
+
let lightColor = saturate(ambientColor + max(dot(input.normal, lightDir), 0.0) * dirColor);
|
|
8683
|
+
|
|
8684
|
+
return vec4f(textureColor.rgb * lightColor, textureColor.a);
|
|
8685
|
+
}`;
|
|
8686
|
+
|
|
8687
|
+
},{}],13:[function(require,module,exports){
|
|
8688
|
+
"use strict";
|
|
8689
|
+
|
|
8690
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8691
|
+
value: true
|
|
8692
|
+
});
|
|
8693
|
+
exports.vertexWGSL = void 0;
|
|
8694
|
+
let vertexWGSL = exports.vertexWGSL = `struct Scene {
|
|
8695
|
+
lightViewProjMatrix: mat4x4f,
|
|
8696
|
+
cameraViewProjMatrix: mat4x4f,
|
|
8697
|
+
lightPos: vec3f,
|
|
8698
|
+
}
|
|
8699
|
+
|
|
8700
|
+
struct Model {
|
|
8701
|
+
modelMatrix: mat4x4f,
|
|
8702
|
+
}
|
|
8703
|
+
|
|
8704
|
+
@group(0) @binding(0) var<uniform> scene : Scene;
|
|
8705
|
+
@group(1) @binding(0) var<uniform> model : Model;
|
|
8706
|
+
|
|
8707
|
+
struct VertexOutput {
|
|
8708
|
+
@location(0) shadowPos: vec3f,
|
|
8709
|
+
@location(1) fragPos: vec3f,
|
|
8710
|
+
@location(2) fragNorm: vec3f,
|
|
8711
|
+
@location(3) uv : vec2f,
|
|
8712
|
+
|
|
8713
|
+
@builtin(position) Position: vec4f,
|
|
8714
|
+
}
|
|
8715
|
+
|
|
8716
|
+
@vertex
|
|
8717
|
+
fn main(
|
|
8718
|
+
@location(0) position: vec3f,
|
|
8719
|
+
@location(1) normal: vec3f,
|
|
8720
|
+
@location(2) uv : vec2f
|
|
8721
|
+
) -> VertexOutput {
|
|
8722
|
+
var output : VertexOutput;
|
|
8723
|
+
|
|
8724
|
+
// XY is in (-1, 1) space, Z is in (0, 1) space
|
|
8725
|
+
let posFromLight = scene.lightViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
|
|
8726
|
+
|
|
8727
|
+
// Convert XY to (0, 1)
|
|
8728
|
+
// Y is flipped because texture coords are Y-down.
|
|
8729
|
+
output.shadowPos = vec3(
|
|
8730
|
+
posFromLight.xy * vec2(0.5, -0.5) + vec2(0.5),
|
|
8731
|
+
posFromLight.z
|
|
8732
|
+
);
|
|
8733
|
+
|
|
8734
|
+
output.Position = scene.cameraViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
|
|
8735
|
+
output.fragPos = output.Position.xyz;
|
|
8736
|
+
output.fragNorm = normal;
|
|
8737
|
+
// nidza
|
|
8738
|
+
output.uv = uv;
|
|
8739
|
+
|
|
8740
|
+
return output;
|
|
8741
|
+
}
|
|
8742
|
+
`;
|
|
8743
|
+
|
|
8744
|
+
},{}],14:[function(require,module,exports){
|
|
8745
|
+
"use strict";
|
|
8746
|
+
|
|
8747
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8748
|
+
value: true
|
|
8749
|
+
});
|
|
8750
|
+
exports.vertexShadowWGSL = void 0;
|
|
8751
|
+
let vertexShadowWGSL = exports.vertexShadowWGSL = `struct Scene {
|
|
8752
|
+
lightViewProjMatrix: mat4x4f,
|
|
8753
|
+
cameraViewProjMatrix: mat4x4f,
|
|
8754
|
+
lightPos: vec3f,
|
|
8755
|
+
}
|
|
8756
|
+
|
|
8757
|
+
struct Model {
|
|
8758
|
+
modelMatrix: mat4x4f,
|
|
8759
|
+
}
|
|
8760
|
+
|
|
8761
|
+
@group(0) @binding(0) var<uniform> scene : Scene;
|
|
8762
|
+
@group(1) @binding(0) var<uniform> model : Model;
|
|
8763
|
+
|
|
8764
|
+
@vertex
|
|
8765
|
+
fn main(
|
|
8766
|
+
@location(0) position: vec3f
|
|
8767
|
+
) -> @builtin(position) vec4f {
|
|
8768
|
+
return scene.lightViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
|
|
8769
|
+
}
|
|
8770
|
+
`;
|
|
8771
|
+
|
|
8772
|
+
},{}],15:[function(require,module,exports){
|
|
8773
|
+
"use strict";
|
|
8774
|
+
|
|
8775
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8776
|
+
value: true
|
|
8777
|
+
});
|
|
8778
|
+
exports.default = void 0;
|
|
8779
|
+
var _wgpuMatrix = require("wgpu-matrix");
|
|
8780
|
+
var _ball = _interopRequireDefault(require("./engine/ball.js"));
|
|
8781
|
+
var _cube = _interopRequireDefault(require("./engine/cube.js"));
|
|
8782
|
+
var _engine = require("./engine/engine.js");
|
|
8783
|
+
var _mesh = _interopRequireDefault(require("./engine/mesh.js"));
|
|
8784
|
+
var _meshObj = _interopRequireDefault(require("./engine/mesh-obj.js"));
|
|
8785
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
8786
|
+
class MatrixEngineWGPU {
|
|
8787
|
+
mainRenderBundle = [];
|
|
8788
|
+
rbContainer = [];
|
|
8789
|
+
frame = () => {};
|
|
8790
|
+
entityHolder = [];
|
|
8791
|
+
entityArgPass = {
|
|
8792
|
+
loadOp: 'clear',
|
|
8793
|
+
storeOp: 'store',
|
|
8794
|
+
depthLoadOp: 'clear',
|
|
8795
|
+
depthStoreOp: 'store'
|
|
8796
|
+
};
|
|
8797
|
+
|
|
8798
|
+
// The input handler
|
|
8799
|
+
constructor(options, callback) {
|
|
8800
|
+
// console.log('typeof options ', typeof options )
|
|
8801
|
+
if (typeof options == 'undefined' || typeof options == "function") {
|
|
8802
|
+
this.options = {
|
|
8803
|
+
useSingleRenderPass: true,
|
|
8804
|
+
canvasSize: 'fullscreen'
|
|
8805
|
+
};
|
|
8806
|
+
callback = options;
|
|
8807
|
+
}
|
|
8808
|
+
this.options = options;
|
|
8809
|
+
var canvas = document.createElement('canvas');
|
|
8810
|
+
if (this.options.canvasSize == 'fullscreen') {
|
|
8811
|
+
canvas.width = window.innerWidth;
|
|
8812
|
+
canvas.height = window.innerHeight;
|
|
8813
|
+
} else {
|
|
8814
|
+
canvas.width = this.options.canvasSize.w;
|
|
8815
|
+
canvas.height = this.options.canvasSize.h;
|
|
8816
|
+
}
|
|
8817
|
+
document.body.append(canvas);
|
|
8818
|
+
|
|
8819
|
+
// The camera types
|
|
8820
|
+
const initialCameraPosition = _wgpuMatrix.vec3.create(0, 0, 0);
|
|
8821
|
+
this.mainCameraParams = {
|
|
8822
|
+
type: 'WASD',
|
|
8823
|
+
responseCoef: 2000
|
|
8824
|
+
};
|
|
8825
|
+
this.cameras = {
|
|
8826
|
+
arcball: new _engine.ArcballCamera({
|
|
8827
|
+
position: initialCameraPosition
|
|
8828
|
+
}),
|
|
8829
|
+
WASD: new _engine.WASDCamera({
|
|
8830
|
+
position: initialCameraPosition
|
|
8831
|
+
})
|
|
8832
|
+
};
|
|
8833
|
+
this.init({
|
|
8834
|
+
canvas,
|
|
8835
|
+
callback
|
|
8836
|
+
});
|
|
6325
8837
|
}
|
|
6326
8838
|
init = async ({
|
|
6327
8839
|
canvas,
|
|
@@ -6340,17 +8852,64 @@ class MatrixEngineWGPU {
|
|
|
6340
8852
|
format: presentationFormat,
|
|
6341
8853
|
alphaMode: 'premultiplied'
|
|
6342
8854
|
});
|
|
8855
|
+
if (this.options.useSingleRenderPass == true) {
|
|
8856
|
+
this.makeDefaultRenderPassDescriptor();
|
|
8857
|
+
this.frame = this.frameSinglePass;
|
|
8858
|
+
} else {
|
|
8859
|
+
// must be
|
|
8860
|
+
this.frame = this.framePassPerObject;
|
|
8861
|
+
}
|
|
6343
8862
|
this.run(callback);
|
|
6344
8863
|
};
|
|
8864
|
+
makeDefaultRenderPassDescriptor = () => {
|
|
8865
|
+
this.depthTexture = this.device.createTexture({
|
|
8866
|
+
size: [this.canvas.width, this.canvas.height],
|
|
8867
|
+
format: 'depth24plus',
|
|
8868
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
8869
|
+
});
|
|
8870
|
+
this.renderPassDescriptor = {
|
|
8871
|
+
colorAttachments: [{
|
|
8872
|
+
view: undefined,
|
|
8873
|
+
clearValue: {
|
|
8874
|
+
r: 0.0,
|
|
8875
|
+
g: 0.0,
|
|
8876
|
+
b: 0.0,
|
|
8877
|
+
a: 1.0
|
|
8878
|
+
},
|
|
8879
|
+
loadOp: 'clear',
|
|
8880
|
+
storeOp: 'store'
|
|
8881
|
+
}],
|
|
8882
|
+
depthStencilAttachment: {
|
|
8883
|
+
view: this.depthTexture.createView(),
|
|
8884
|
+
depthClearValue: 1.0,
|
|
8885
|
+
depthLoadOp: 'clear',
|
|
8886
|
+
depthStoreOp: 'store'
|
|
8887
|
+
}
|
|
8888
|
+
};
|
|
8889
|
+
};
|
|
6345
8890
|
addCube = o => {
|
|
6346
8891
|
if (typeof o === 'undefined') {
|
|
6347
8892
|
var o = {
|
|
8893
|
+
scale: 1,
|
|
6348
8894
|
position: {
|
|
6349
8895
|
x: 0,
|
|
6350
8896
|
y: 0,
|
|
6351
8897
|
z: -4
|
|
6352
8898
|
},
|
|
6353
|
-
texturesPaths: ['./res/textures/default.png']
|
|
8899
|
+
texturesPaths: ['./res/textures/default.png'],
|
|
8900
|
+
rotation: {
|
|
8901
|
+
x: 0,
|
|
8902
|
+
y: 0,
|
|
8903
|
+
z: 0
|
|
8904
|
+
},
|
|
8905
|
+
rotationSpeed: {
|
|
8906
|
+
x: 0,
|
|
8907
|
+
y: 0,
|
|
8908
|
+
z: 0
|
|
8909
|
+
},
|
|
8910
|
+
entityArgPass: this.entityArgPass,
|
|
8911
|
+
cameras: this.cameras,
|
|
8912
|
+
mainCameraParams: this.mainCameraParams
|
|
6354
8913
|
};
|
|
6355
8914
|
} else {
|
|
6356
8915
|
if (typeof o.position === 'undefined') {
|
|
@@ -6360,9 +8919,31 @@ class MatrixEngineWGPU {
|
|
|
6360
8919
|
z: -4
|
|
6361
8920
|
};
|
|
6362
8921
|
}
|
|
8922
|
+
if (typeof o.rotation === 'undefined') {
|
|
8923
|
+
o.rotation = {
|
|
8924
|
+
x: 0,
|
|
8925
|
+
y: 0,
|
|
8926
|
+
z: 0
|
|
8927
|
+
};
|
|
8928
|
+
}
|
|
8929
|
+
if (typeof o.rotationSpeed === 'undefined') {
|
|
8930
|
+
o.rotationSpeed = {
|
|
8931
|
+
x: 0,
|
|
8932
|
+
y: 0,
|
|
8933
|
+
z: 0
|
|
8934
|
+
};
|
|
8935
|
+
}
|
|
6363
8936
|
if (typeof o.texturesPaths === 'undefined') {
|
|
6364
8937
|
o.texturesPaths = ['./res/textures/default.png'];
|
|
6365
8938
|
}
|
|
8939
|
+
if (typeof o.scale === 'undefined') {
|
|
8940
|
+
o.scale = 1;
|
|
8941
|
+
}
|
|
8942
|
+
if (typeof o.mainCameraParams === 'undefined') {
|
|
8943
|
+
o.mainCameraParams = this.mainCameraParams;
|
|
8944
|
+
}
|
|
8945
|
+
o.entityArgPass = this.entityArgPass;
|
|
8946
|
+
o.cameras = this.cameras;
|
|
6366
8947
|
}
|
|
6367
8948
|
let myCube1 = new _cube.default(this.canvas, this.device, this.context, o);
|
|
6368
8949
|
this.mainRenderBundle.push(myCube1);
|
|
@@ -6370,12 +8951,26 @@ class MatrixEngineWGPU {
|
|
|
6370
8951
|
addBall = o => {
|
|
6371
8952
|
if (typeof o === 'undefined') {
|
|
6372
8953
|
var o = {
|
|
8954
|
+
scale: 1,
|
|
6373
8955
|
position: {
|
|
6374
8956
|
x: 0,
|
|
6375
8957
|
y: 0,
|
|
6376
8958
|
z: -4
|
|
6377
8959
|
},
|
|
6378
|
-
texturesPaths: ['./res/textures/default.png']
|
|
8960
|
+
texturesPaths: ['./res/textures/default.png'],
|
|
8961
|
+
rotation: {
|
|
8962
|
+
x: 0,
|
|
8963
|
+
y: 0,
|
|
8964
|
+
z: 0
|
|
8965
|
+
},
|
|
8966
|
+
rotationSpeed: {
|
|
8967
|
+
x: 0,
|
|
8968
|
+
y: 0,
|
|
8969
|
+
z: 0
|
|
8970
|
+
},
|
|
8971
|
+
entityArgPass: this.entityArgPass,
|
|
8972
|
+
cameras: this.cameras,
|
|
8973
|
+
mainCameraParams: this.mainCameraParams
|
|
6379
8974
|
};
|
|
6380
8975
|
} else {
|
|
6381
8976
|
if (typeof o.position === 'undefined') {
|
|
@@ -6385,213 +8980,172 @@ class MatrixEngineWGPU {
|
|
|
6385
8980
|
z: -4
|
|
6386
8981
|
};
|
|
6387
8982
|
}
|
|
8983
|
+
if (typeof o.rotation === 'undefined') {
|
|
8984
|
+
o.rotation = {
|
|
8985
|
+
x: 0,
|
|
8986
|
+
y: 0,
|
|
8987
|
+
z: 0
|
|
8988
|
+
};
|
|
8989
|
+
}
|
|
8990
|
+
if (typeof o.rotationSpeed === 'undefined') {
|
|
8991
|
+
o.rotationSpeed = {
|
|
8992
|
+
x: 0,
|
|
8993
|
+
y: 0,
|
|
8994
|
+
z: 0
|
|
8995
|
+
};
|
|
8996
|
+
}
|
|
6388
8997
|
if (typeof o.texturesPaths === 'undefined') {
|
|
6389
8998
|
o.texturesPaths = ['./res/textures/default.png'];
|
|
6390
8999
|
}
|
|
9000
|
+
if (typeof o.mainCameraParams === 'undefined') {
|
|
9001
|
+
o.mainCameraParams = this.mainCameraParams;
|
|
9002
|
+
}
|
|
9003
|
+
if (typeof o.scale === 'undefined') {
|
|
9004
|
+
o.scale = 1;
|
|
9005
|
+
}
|
|
9006
|
+
o.entityArgPass = this.entityArgPass;
|
|
9007
|
+
o.cameras = this.cameras;
|
|
6391
9008
|
}
|
|
6392
9009
|
let myBall1 = new _ball.default(this.canvas, this.device, this.context, o);
|
|
6393
9010
|
this.mainRenderBundle.push(myBall1);
|
|
6394
9011
|
};
|
|
9012
|
+
addMesh = o => {
|
|
9013
|
+
if (typeof o.position === 'undefined') {
|
|
9014
|
+
o.position = {
|
|
9015
|
+
x: 0,
|
|
9016
|
+
y: 0,
|
|
9017
|
+
z: -4
|
|
9018
|
+
};
|
|
9019
|
+
}
|
|
9020
|
+
if (typeof o.rotation === 'undefined') {
|
|
9021
|
+
o.rotation = {
|
|
9022
|
+
x: 0,
|
|
9023
|
+
y: 0,
|
|
9024
|
+
z: 0
|
|
9025
|
+
};
|
|
9026
|
+
}
|
|
9027
|
+
if (typeof o.rotationSpeed === 'undefined') {
|
|
9028
|
+
o.rotationSpeed = {
|
|
9029
|
+
x: 0,
|
|
9030
|
+
y: 0,
|
|
9031
|
+
z: 0
|
|
9032
|
+
};
|
|
9033
|
+
}
|
|
9034
|
+
if (typeof o.texturesPaths === 'undefined') {
|
|
9035
|
+
o.texturesPaths = ['./res/textures/default.png'];
|
|
9036
|
+
}
|
|
9037
|
+
if (typeof o.mainCameraParams === 'undefined') {
|
|
9038
|
+
o.mainCameraParams = this.mainCameraParams;
|
|
9039
|
+
}
|
|
9040
|
+
if (typeof o.scale === 'undefined') {
|
|
9041
|
+
o.scale = 1;
|
|
9042
|
+
}
|
|
9043
|
+
o.entityArgPass = this.entityArgPass;
|
|
9044
|
+
o.cameras = this.cameras;
|
|
9045
|
+
if (typeof o.name === 'undefined') {
|
|
9046
|
+
o.name = 'random' + Math.random();
|
|
9047
|
+
}
|
|
9048
|
+
if (typeof o.mesh === 'undefined') {
|
|
9049
|
+
throw console.error('arg mesh is empty...');
|
|
9050
|
+
return;
|
|
9051
|
+
}
|
|
9052
|
+
console.log('Mesh procedure', o);
|
|
9053
|
+
let myMesh1 = new _mesh.default(this.canvas, this.device, this.context, o);
|
|
9054
|
+
this.mainRenderBundle.push(myMesh1);
|
|
9055
|
+
};
|
|
9056
|
+
addMeshObj = o => {
|
|
9057
|
+
if (typeof o.position === 'undefined') {
|
|
9058
|
+
o.position = {
|
|
9059
|
+
x: 0,
|
|
9060
|
+
y: 0,
|
|
9061
|
+
z: -4
|
|
9062
|
+
};
|
|
9063
|
+
}
|
|
9064
|
+
if (typeof o.rotation === 'undefined') {
|
|
9065
|
+
o.rotation = {
|
|
9066
|
+
x: 0,
|
|
9067
|
+
y: 0,
|
|
9068
|
+
z: 0
|
|
9069
|
+
};
|
|
9070
|
+
}
|
|
9071
|
+
if (typeof o.rotationSpeed === 'undefined') {
|
|
9072
|
+
o.rotationSpeed = {
|
|
9073
|
+
x: 0,
|
|
9074
|
+
y: 0,
|
|
9075
|
+
z: 0
|
|
9076
|
+
};
|
|
9077
|
+
}
|
|
9078
|
+
if (typeof o.texturesPaths === 'undefined') {
|
|
9079
|
+
o.texturesPaths = ['./res/textures/default.png'];
|
|
9080
|
+
}
|
|
9081
|
+
if (typeof o.mainCameraParams === 'undefined') {
|
|
9082
|
+
o.mainCameraParams = this.mainCameraParams;
|
|
9083
|
+
}
|
|
9084
|
+
if (typeof o.scale === 'undefined') {
|
|
9085
|
+
o.scale = 1;
|
|
9086
|
+
}
|
|
9087
|
+
o.entityArgPass = this.entityArgPass;
|
|
9088
|
+
o.cameras = this.cameras;
|
|
9089
|
+
if (typeof o.name === 'undefined') {
|
|
9090
|
+
o.name = 'random' + Math.random();
|
|
9091
|
+
}
|
|
9092
|
+
if (typeof o.mesh === 'undefined') {
|
|
9093
|
+
throw console.error('arg mesh is empty...');
|
|
9094
|
+
return;
|
|
9095
|
+
}
|
|
9096
|
+
console.log('Mesh procedure', o);
|
|
9097
|
+
let myMesh1 = new _meshObj.default(this.canvas, this.device, this.context, o);
|
|
9098
|
+
this.mainRenderBundle.push(myMesh1);
|
|
9099
|
+
};
|
|
6395
9100
|
run(callback) {
|
|
6396
9101
|
setTimeout(() => {
|
|
6397
9102
|
requestAnimationFrame(this.frame);
|
|
6398
|
-
},
|
|
9103
|
+
}, 500);
|
|
6399
9104
|
setTimeout(() => {
|
|
6400
9105
|
callback();
|
|
6401
|
-
},
|
|
9106
|
+
}, 20);
|
|
6402
9107
|
}
|
|
6403
|
-
|
|
9108
|
+
frameSinglePass = () => {
|
|
9109
|
+
let passEncoder;
|
|
9110
|
+
let commandEncoder = this.device.createCommandEncoder();
|
|
9111
|
+
if (typeof this.mainRenderBundle != 'undefined') this.mainRenderBundle.forEach((meItem, index) => {
|
|
9112
|
+
meItem.position.update();
|
|
9113
|
+
meItem.draw(commandEncoder);
|
|
9114
|
+
|
|
9115
|
+
//
|
|
9116
|
+
if (typeof meItem.done == 'undefined') {
|
|
9117
|
+
this.rbContainer.push(meItem.renderBundle);
|
|
9118
|
+
this.renderPassDescriptor.colorAttachments[0].view = this.context.getCurrentTexture().createView();
|
|
9119
|
+
// console.log('prolazi ')
|
|
9120
|
+
passEncoder = commandEncoder.beginRenderPass(this.renderPassDescriptor);
|
|
9121
|
+
passEncoder.executeBundles(this.rbContainer);
|
|
9122
|
+
passEncoder.end();
|
|
9123
|
+
// this.device.queue.submit([commandEncoder.finish()]);
|
|
9124
|
+
}
|
|
9125
|
+
});
|
|
9126
|
+
this.device.queue.submit([commandEncoder.finish()]);
|
|
9127
|
+
requestAnimationFrame(this.frame);
|
|
9128
|
+
};
|
|
9129
|
+
framePassPerObject = () => {
|
|
9130
|
+
// console.log('framePassPerObject')
|
|
6404
9131
|
let commandEncoder = this.device.createCommandEncoder();
|
|
6405
9132
|
this.rbContainer = [];
|
|
6406
9133
|
let passEncoder;
|
|
6407
9134
|
this.mainRenderBundle.forEach((meItem, index) => {
|
|
6408
|
-
meItem.draw();
|
|
6409
|
-
|
|
6410
|
-
|
|
9135
|
+
meItem.draw(commandEncoder);
|
|
9136
|
+
if (meItem.renderBundle) {
|
|
9137
|
+
this.rbContainer.push(meItem.renderBundle);
|
|
9138
|
+
passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
|
|
9139
|
+
passEncoder.executeBundles(this.rbContainer);
|
|
9140
|
+
passEncoder.end();
|
|
9141
|
+
} else {
|
|
9142
|
+
meItem.draw(commandEncoder);
|
|
9143
|
+
}
|
|
6411
9144
|
});
|
|
6412
|
-
|
|
6413
|
-
// passEncoder.executeBundles([NIK.renderBundle, NIK2.renderBundle]);
|
|
6414
|
-
passEncoder.executeBundles(this.rbContainer);
|
|
6415
|
-
passEncoder.end();
|
|
6416
9145
|
this.device.queue.submit([commandEncoder.finish()]);
|
|
6417
9146
|
requestAnimationFrame(this.frame);
|
|
6418
9147
|
};
|
|
6419
9148
|
}
|
|
6420
9149
|
exports.default = MatrixEngineWGPU;
|
|
6421
9150
|
|
|
6422
|
-
},{"./engine/ball.js":3,"./engine/cube.js":4}],
|
|
6423
|
-
"use strict";
|
|
6424
|
-
|
|
6425
|
-
Object.defineProperty(exports, "__esModule", {
|
|
6426
|
-
value: true
|
|
6427
|
-
});
|
|
6428
|
-
exports.vertexPositionColorWGSL = exports.shaderSrc = exports.cubeTexShader = exports.basicVertWGSL = exports.basicFragWGSL = exports.BALL_SHADER = void 0;
|
|
6429
|
-
/**
|
|
6430
|
-
* @description
|
|
6431
|
-
* For microdraw pixel cube texture
|
|
6432
|
-
*/
|
|
6433
|
-
const shaderSrc = exports.shaderSrc = `struct VSUniforms {
|
|
6434
|
-
worldViewProjection: mat4x4f,
|
|
6435
|
-
worldInverseTranspose: mat4x4f,
|
|
6436
|
-
};
|
|
6437
|
-
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
6438
|
-
|
|
6439
|
-
struct MyVSInput {
|
|
6440
|
-
@location(0) position: vec4f,
|
|
6441
|
-
@location(1) normal: vec3f,
|
|
6442
|
-
@location(2) texcoord: vec2f,
|
|
6443
|
-
};
|
|
6444
|
-
|
|
6445
|
-
struct MyVSOutput {
|
|
6446
|
-
@builtin(position) position: vec4f,
|
|
6447
|
-
@location(0) normal: vec3f,
|
|
6448
|
-
@location(1) texcoord: vec2f,
|
|
6449
|
-
};
|
|
6450
|
-
|
|
6451
|
-
@vertex
|
|
6452
|
-
fn myVSMain(v: MyVSInput) -> MyVSOutput {
|
|
6453
|
-
var vsOut: MyVSOutput;
|
|
6454
|
-
vsOut.position = vsUniforms.worldViewProjection * v.position;
|
|
6455
|
-
vsOut.normal = (vsUniforms.worldInverseTranspose * vec4f(v.normal, 0.0)).xyz;
|
|
6456
|
-
vsOut.texcoord = v.texcoord;
|
|
6457
|
-
return vsOut;
|
|
6458
|
-
}
|
|
6459
|
-
|
|
6460
|
-
struct FSUniforms {
|
|
6461
|
-
lightDirection: vec3f,
|
|
6462
|
-
};
|
|
6463
|
-
|
|
6464
|
-
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
6465
|
-
@group(0) @binding(2) var diffuseSampler: sampler;
|
|
6466
|
-
@group(0) @binding(3) var diffuseTexture: texture_2d<f32>;
|
|
6467
|
-
|
|
6468
|
-
@fragment
|
|
6469
|
-
fn myFSMain(v: MyVSOutput) -> @location(0) vec4f {
|
|
6470
|
-
var diffuseColor = textureSample(diffuseTexture, diffuseSampler, v.texcoord);
|
|
6471
|
-
var a_normal = normalize(v.normal);
|
|
6472
|
-
var l = dot(a_normal, fsUniforms.lightDirection) * 0.5 + 0.5;
|
|
6473
|
-
return vec4f(diffuseColor.rgb * l, diffuseColor.a);
|
|
6474
|
-
}
|
|
6475
|
-
`;
|
|
6476
|
-
|
|
6477
|
-
/**
|
|
6478
|
-
* @description
|
|
6479
|
-
* For Cube with images
|
|
6480
|
-
*/
|
|
6481
|
-
const cubeTexShader = exports.cubeTexShader = `struct Uniforms {
|
|
6482
|
-
matrix: mat4x4f,
|
|
6483
|
-
};
|
|
6484
|
-
|
|
6485
|
-
struct Vertex {
|
|
6486
|
-
@location(0) position: vec4f,
|
|
6487
|
-
@location(1) texcoord: vec2f,
|
|
6488
|
-
};
|
|
6489
|
-
|
|
6490
|
-
struct VSOutput {
|
|
6491
|
-
@builtin(position) position: vec4f,
|
|
6492
|
-
@location(0) texcoord: vec2f,
|
|
6493
|
-
};
|
|
6494
|
-
|
|
6495
|
-
@group(0) @binding(0) var<uniform> uni: Uniforms;
|
|
6496
|
-
@group(0) @binding(1) var ourSampler: sampler;
|
|
6497
|
-
@group(0) @binding(2) var ourTexture: texture_2d<f32>;
|
|
6498
|
-
|
|
6499
|
-
@vertex fn vs(vert: Vertex) -> VSOutput {
|
|
6500
|
-
var vsOut: VSOutput;
|
|
6501
|
-
vsOut.position = uni.matrix * vert.position;
|
|
6502
|
-
vsOut.texcoord = vert.texcoord;
|
|
6503
|
-
return vsOut;
|
|
6504
|
-
}
|
|
6505
|
-
|
|
6506
|
-
@fragment fn fs(vsOut: VSOutput) -> @location(0) vec4f {
|
|
6507
|
-
return textureSample(ourTexture, ourSampler, vsOut.texcoord);
|
|
6508
|
-
}
|
|
6509
|
-
`;
|
|
6510
|
-
const basicVertWGSL = exports.basicVertWGSL = `struct Uniforms {
|
|
6511
|
-
modelViewProjectionMatrix : mat4x4<f32>,
|
|
6512
|
-
}
|
|
6513
|
-
@binding(0) @group(0) var<uniform> uniforms : Uniforms;
|
|
6514
|
-
|
|
6515
|
-
struct VertexOutput {
|
|
6516
|
-
@builtin(position) Position : vec4<f32>,
|
|
6517
|
-
@location(0) fragUV : vec2<f32>,
|
|
6518
|
-
@location(1) fragPosition: vec4<f32>,
|
|
6519
|
-
}
|
|
6520
|
-
|
|
6521
|
-
@vertex
|
|
6522
|
-
fn main(
|
|
6523
|
-
@location(0) position : vec4<f32>,
|
|
6524
|
-
@location(1) uv : vec2<f32>
|
|
6525
|
-
) -> VertexOutput {
|
|
6526
|
-
var output : VertexOutput;
|
|
6527
|
-
output.Position = uniforms.modelViewProjectionMatrix * position;
|
|
6528
|
-
output.fragUV = uv;
|
|
6529
|
-
output.fragPosition = 0.5 * (position + vec4(1.0, 1.0, 1.0, 1.0));
|
|
6530
|
-
return output;
|
|
6531
|
-
}
|
|
6532
|
-
`;
|
|
6533
|
-
const basicFragWGSL = exports.basicFragWGSL = `@group(0) @binding(1) var mySampler: sampler;
|
|
6534
|
-
@group(0) @binding(2) var myTexture: texture_2d<f32>;
|
|
6535
|
-
|
|
6536
|
-
@fragment
|
|
6537
|
-
fn main(
|
|
6538
|
-
@location(0) fragUV: vec2<f32>,
|
|
6539
|
-
@location(1) fragPosition: vec4<f32>
|
|
6540
|
-
) -> @location(0) vec4<f32> {
|
|
6541
|
-
return textureSample(myTexture, mySampler, fragUV) * fragPosition;
|
|
6542
|
-
}
|
|
6543
|
-
`;
|
|
6544
|
-
const vertexPositionColorWGSL = exports.vertexPositionColorWGSL = `@fragment
|
|
6545
|
-
fn main(
|
|
6546
|
-
@location(0) fragUV: vec2<f32>,
|
|
6547
|
-
@location(1) fragPosition: vec4<f32>
|
|
6548
|
-
) -> @location(0) vec4<f32> {
|
|
6549
|
-
return fragPosition;
|
|
6550
|
-
}`;
|
|
6551
|
-
const BALL_SHADER = exports.BALL_SHADER = `struct Uniforms {
|
|
6552
|
-
viewProjectionMatrix : mat4x4f
|
|
6553
|
-
}
|
|
6554
|
-
@group(0) @binding(0) var<uniform> uniforms : Uniforms;
|
|
6555
|
-
|
|
6556
|
-
@group(1) @binding(0) var<uniform> modelMatrix : mat4x4f;
|
|
6557
|
-
|
|
6558
|
-
struct VertexInput {
|
|
6559
|
-
@location(0) position : vec4f,
|
|
6560
|
-
@location(1) normal : vec3f,
|
|
6561
|
-
@location(2) uv : vec2f
|
|
6562
|
-
}
|
|
6563
|
-
|
|
6564
|
-
struct VertexOutput {
|
|
6565
|
-
@builtin(position) position : vec4f,
|
|
6566
|
-
@location(0) normal: vec3f,
|
|
6567
|
-
@location(1) uv : vec2f,
|
|
6568
|
-
}
|
|
6569
|
-
|
|
6570
|
-
@vertex
|
|
6571
|
-
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
6572
|
-
var output : VertexOutput;
|
|
6573
|
-
output.position = uniforms.viewProjectionMatrix * modelMatrix * input.position;
|
|
6574
|
-
output.normal = normalize((modelMatrix * vec4(input.normal, 0)).xyz);
|
|
6575
|
-
output.uv = input.uv;
|
|
6576
|
-
return output;
|
|
6577
|
-
}
|
|
6578
|
-
|
|
6579
|
-
@group(1) @binding(1) var meshSampler: sampler;
|
|
6580
|
-
@group(1) @binding(2) var meshTexture: texture_2d<f32>;
|
|
6581
|
-
|
|
6582
|
-
// Static directional lighting
|
|
6583
|
-
const lightDir = vec3f(1, 1, 1);
|
|
6584
|
-
const dirColor = vec3(1);
|
|
6585
|
-
const ambientColor = vec3f(0.05);
|
|
6586
|
-
|
|
6587
|
-
@fragment
|
|
6588
|
-
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
|
|
6589
|
-
let textureColor = textureSample(meshTexture, meshSampler, input.uv);
|
|
6590
|
-
|
|
6591
|
-
// Very simplified lighting algorithm.
|
|
6592
|
-
let lightColor = saturate(ambientColor + max(dot(input.normal, lightDir), 0.0) * dirColor);
|
|
6593
|
-
|
|
6594
|
-
return vec4f(textureColor.rgb * lightColor, textureColor.a);
|
|
6595
|
-
}`;
|
|
6596
|
-
|
|
6597
|
-
},{}]},{},[1]);
|
|
9151
|
+
},{"./engine/ball.js":3,"./engine/cube.js":4,"./engine/engine.js":5,"./engine/mesh-obj.js":8,"./engine/mesh.js":9,"wgpu-matrix":2}]},{},[1]);
|