matrix-engine-wgpu 1.0.2 → 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/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 +34 -23
- package/package.json +11 -2
- package/public/app-worker.js +47 -0
- package/public/app.js +2678 -310
- 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 +45 -37
- package/src/engine/ball.js +26 -10
- package/src/engine/cube.js +96 -81
- package/src/engine/engine.js +466 -4
- 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 +5 -4
- 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 -173
package/public/app.js
CHANGED
|
@@ -1,53 +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
|
-
useSingleRenderPass: false
|
|
11
|
+
let application = exports.application = new _world.default({
|
|
12
|
+
useSingleRenderPass: false,
|
|
13
|
+
canvasSize: 'fullscreen'
|
|
8
14
|
}, () => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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);
|
|
47
62
|
});
|
|
48
63
|
window.app = application;
|
|
49
64
|
|
|
50
|
-
},{"./src/
|
|
65
|
+
},{"./src/engine/loader-obj.js":6,"./src/world.js":15}],2:[function(require,module,exports){
|
|
51
66
|
"use strict";
|
|
52
67
|
|
|
53
68
|
Object.defineProperty(exports, "__esModule", {
|
|
@@ -5404,10 +5419,23 @@ exports.default = void 0;
|
|
|
5404
5419
|
var _shaders = require("../shaders/shaders");
|
|
5405
5420
|
var _wgpuMatrix = require("wgpu-matrix");
|
|
5406
5421
|
var _matrixClass = require("./matrix-class");
|
|
5422
|
+
var _engine = require("./engine");
|
|
5407
5423
|
class MEBall {
|
|
5408
5424
|
constructor(canvas, device, context, o) {
|
|
5409
5425
|
this.context = context;
|
|
5410
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;
|
|
5411
5439
|
this.entityArgPass = o.entityArgPass;
|
|
5412
5440
|
this.SphereLayout = {
|
|
5413
5441
|
vertexStride: 8 * 4,
|
|
@@ -5425,7 +5453,7 @@ class MEBall {
|
|
|
5425
5453
|
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
5426
5454
|
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
5427
5455
|
this.shaderModule = device.createShaderModule({
|
|
5428
|
-
code: _shaders.
|
|
5456
|
+
code: _shaders.UNLIT_SHADER
|
|
5429
5457
|
});
|
|
5430
5458
|
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
5431
5459
|
this.pipeline = device.createRenderPipeline({
|
|
@@ -5495,7 +5523,6 @@ class MEBall {
|
|
|
5495
5523
|
};
|
|
5496
5524
|
this.loadTex0(this.texturesPaths, device).then(() => {
|
|
5497
5525
|
this.loadTex1(device).then(() => {
|
|
5498
|
-
console.log('NICE THIS', this);
|
|
5499
5526
|
this.sampler = device.createSampler({
|
|
5500
5527
|
magFilter: 'linear',
|
|
5501
5528
|
minFilter: 'linear'
|
|
@@ -5504,9 +5531,9 @@ class MEBall {
|
|
|
5504
5531
|
_wgpuMatrix.mat4.identity(this.transform);
|
|
5505
5532
|
|
|
5506
5533
|
// Create one large central planet surrounded by a large ring of asteroids
|
|
5507
|
-
this.planet = this.
|
|
5534
|
+
this.planet = this.createGeometry(this.scale);
|
|
5508
5535
|
this.planet.bindGroup = this.createSphereBindGroup(this.texture0, this.transform);
|
|
5509
|
-
var asteroids = [this.
|
|
5536
|
+
var asteroids = [this.createGeometry(12, 8, 6, 0.15)];
|
|
5510
5537
|
this.renderables = [this.planet];
|
|
5511
5538
|
|
|
5512
5539
|
// this.ensureEnoughAsteroids(asteroids, this.transform);
|
|
@@ -5585,7 +5612,7 @@ class MEBall {
|
|
|
5585
5612
|
this.renderScene(renderBundleEncoder);
|
|
5586
5613
|
this.renderBundle = renderBundleEncoder.finish();
|
|
5587
5614
|
}
|
|
5588
|
-
|
|
5615
|
+
createGeometry(radius, widthSegments = 8, heightSegments = 4, randomness = 0) {
|
|
5589
5616
|
const sphereMesh = this.createSphereMesh(radius, widthSegments, heightSegments, randomness);
|
|
5590
5617
|
// Create a vertex buffer from the sphere data.
|
|
5591
5618
|
const vertices = this.device.createBuffer({
|
|
@@ -5635,9 +5662,15 @@ class MEBall {
|
|
|
5635
5662
|
return bindGroup;
|
|
5636
5663
|
}
|
|
5637
5664
|
getTransformationMatrix(pos) {
|
|
5638
|
-
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());
|
|
5639
5673
|
_wgpuMatrix.mat4.translate(viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
|
|
5640
|
-
const now = Date.now() / 1000;
|
|
5641
5674
|
_wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
|
|
5642
5675
|
_wgpuMatrix.mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
|
|
5643
5676
|
_wgpuMatrix.mat4.rotateZ(viewMatrix, Math.PI * this.rotation.getRotZ(), viewMatrix);
|
|
@@ -5783,7 +5816,7 @@ class MEBall {
|
|
|
5783
5816
|
}
|
|
5784
5817
|
exports.default = MEBall;
|
|
5785
5818
|
|
|
5786
|
-
},{"../shaders/shaders":
|
|
5819
|
+
},{"../shaders/shaders":12,"./engine":5,"./matrix-class":7,"wgpu-matrix":2}],4:[function(require,module,exports){
|
|
5787
5820
|
"use strict";
|
|
5788
5821
|
|
|
5789
5822
|
Object.defineProperty(exports, "__esModule", {
|
|
@@ -5793,6 +5826,7 @@ exports.default = void 0;
|
|
|
5793
5826
|
var _shaders = require("../shaders/shaders");
|
|
5794
5827
|
var _wgpuMatrix = require("wgpu-matrix");
|
|
5795
5828
|
var _matrixClass = require("./matrix-class");
|
|
5829
|
+
var _engine = require("./engine");
|
|
5796
5830
|
var SphereLayout = {
|
|
5797
5831
|
vertexStride: 8 * 4,
|
|
5798
5832
|
positionsOffset: 0,
|
|
@@ -5804,9 +5838,17 @@ class MECube {
|
|
|
5804
5838
|
this.device = device;
|
|
5805
5839
|
this.context = context;
|
|
5806
5840
|
this.entityArgPass = o.entityArgPass;
|
|
5807
|
-
|
|
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;
|
|
5808
5850
|
this.shaderModule = device.createShaderModule({
|
|
5809
|
-
code: _shaders.
|
|
5851
|
+
code: _shaders.UNLIT_SHADER
|
|
5810
5852
|
});
|
|
5811
5853
|
this.texturesPaths = [];
|
|
5812
5854
|
o.texturesPaths.forEach(t => {
|
|
@@ -5814,10 +5856,12 @@ class MECube {
|
|
|
5814
5856
|
});
|
|
5815
5857
|
this.presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
5816
5858
|
this.position = new _matrixClass.Position(o.position.x, o.position.y, o.position.z);
|
|
5859
|
+
console.log('cube added on pos : ', this.position);
|
|
5817
5860
|
this.rotation = new _matrixClass.Rotation(o.rotation.x, o.rotation.y, o.rotation.z);
|
|
5818
5861
|
this.rotation.rotationSpeed.x = o.rotationSpeed.x;
|
|
5819
5862
|
this.rotation.rotationSpeed.y = o.rotationSpeed.y;
|
|
5820
5863
|
this.rotation.rotationSpeed.z = o.rotationSpeed.z;
|
|
5864
|
+
this.scale = o.scale;
|
|
5821
5865
|
this.pipeline = device.createRenderPipeline({
|
|
5822
5866
|
layout: 'auto',
|
|
5823
5867
|
vertex: {
|
|
@@ -5896,9 +5940,16 @@ class MECube {
|
|
|
5896
5940
|
_wgpuMatrix.mat4.identity(this.transform);
|
|
5897
5941
|
|
|
5898
5942
|
// Create one large central planet surrounded by a large ring of asteroids
|
|
5899
|
-
this.planet = this.
|
|
5943
|
+
this.planet = this.createGeometry({
|
|
5944
|
+
scale: this.scale,
|
|
5945
|
+
useUVShema4x2: false
|
|
5946
|
+
});
|
|
5900
5947
|
this.planet.bindGroup = this.createSphereBindGroup(this.texture0, this.transform);
|
|
5901
|
-
|
|
5948
|
+
|
|
5949
|
+
// can be used like instance draws
|
|
5950
|
+
var asteroids = [
|
|
5951
|
+
// this.createGeometry(0.2, 8, 6, 0.15),
|
|
5952
|
+
];
|
|
5902
5953
|
this.renderables = [this.planet];
|
|
5903
5954
|
// this.ensureEnoughAsteroids(asteroids, this.transform);
|
|
5904
5955
|
this.renderPassDescriptor = {
|
|
@@ -5921,7 +5972,7 @@ class MECube {
|
|
|
5921
5972
|
}
|
|
5922
5973
|
};
|
|
5923
5974
|
const aspect = canvas.width / canvas.height;
|
|
5924
|
-
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);
|
|
5925
5976
|
this.modelViewProjectionMatrix = _wgpuMatrix.mat4.create();
|
|
5926
5977
|
this.frameBindGroup = device.createBindGroup({
|
|
5927
5978
|
layout: this.pipeline.getBindGroupLayout(0),
|
|
@@ -5976,27 +6027,27 @@ class MECube {
|
|
|
5976
6027
|
this.renderScene(renderBundleEncoder);
|
|
5977
6028
|
this.renderBundle = renderBundleEncoder.finish();
|
|
5978
6029
|
}
|
|
5979
|
-
|
|
5980
|
-
const
|
|
6030
|
+
createGeometry(options) {
|
|
6031
|
+
const mesh = this.createCubeVertices(options);
|
|
5981
6032
|
// Create a vertex buffer from the sphere data.
|
|
5982
6033
|
const vertices = this.device.createBuffer({
|
|
5983
|
-
size:
|
|
6034
|
+
size: mesh.vertices.byteLength,
|
|
5984
6035
|
usage: GPUBufferUsage.VERTEX,
|
|
5985
6036
|
mappedAtCreation: true
|
|
5986
6037
|
});
|
|
5987
|
-
new Float32Array(vertices.getMappedRange()).set(
|
|
6038
|
+
new Float32Array(vertices.getMappedRange()).set(mesh.vertices);
|
|
5988
6039
|
vertices.unmap();
|
|
5989
6040
|
const indices = this.device.createBuffer({
|
|
5990
|
-
size:
|
|
6041
|
+
size: mesh.indices.byteLength,
|
|
5991
6042
|
usage: GPUBufferUsage.INDEX,
|
|
5992
6043
|
mappedAtCreation: true
|
|
5993
6044
|
});
|
|
5994
|
-
new Uint16Array(indices.getMappedRange()).set(
|
|
6045
|
+
new Uint16Array(indices.getMappedRange()).set(mesh.indices);
|
|
5995
6046
|
indices.unmap();
|
|
5996
6047
|
return {
|
|
5997
6048
|
vertices,
|
|
5998
6049
|
indices,
|
|
5999
|
-
indexCount:
|
|
6050
|
+
indexCount: mesh.indices.length
|
|
6000
6051
|
};
|
|
6001
6052
|
}
|
|
6002
6053
|
createSphereBindGroup(texture, transform) {
|
|
@@ -6026,9 +6077,13 @@ class MECube {
|
|
|
6026
6077
|
return bindGroup;
|
|
6027
6078
|
}
|
|
6028
6079
|
getTransformationMatrix(pos) {
|
|
6029
|
-
|
|
6080
|
+
const now = Date.now();
|
|
6081
|
+
const deltaTime = (now - this.lastFrameMS) / this.cameraParams.responseCoef;
|
|
6082
|
+
this.lastFrameMS = now;
|
|
6030
6083
|
|
|
6031
|
-
const viewMatrix =
|
|
6084
|
+
// const viewMatrix = mat4.identity(); ORI
|
|
6085
|
+
const camera = this.cameras[this.cameraParams.type];
|
|
6086
|
+
const viewMatrix = camera.update(deltaTime, this.inputHandler());
|
|
6032
6087
|
_wgpuMatrix.mat4.translate(viewMatrix, _wgpuMatrix.vec3.fromValues(pos.x, pos.y, pos.z), viewMatrix);
|
|
6033
6088
|
_wgpuMatrix.mat4.rotateX(viewMatrix, Math.PI * this.rotation.getRotX(), viewMatrix);
|
|
6034
6089
|
_wgpuMatrix.mat4.rotateY(viewMatrix, Math.PI * this.rotation.getRotY(), viewMatrix);
|
|
@@ -6105,6 +6160,7 @@ class MECube {
|
|
|
6105
6160
|
useUVShema4x2: false
|
|
6106
6161
|
};
|
|
6107
6162
|
}
|
|
6163
|
+
if (typeof options.scale === 'undefined') options.scale = 1;
|
|
6108
6164
|
let vertices;
|
|
6109
6165
|
if (options.useUVShema4x2 == true) {
|
|
6110
6166
|
vertices = new Float32Array([
|
|
@@ -6124,20 +6180,20 @@ class MECube {
|
|
|
6124
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]);
|
|
6125
6181
|
} else {
|
|
6126
6182
|
vertices = new Float32Array([
|
|
6127
|
-
// position
|
|
6128
|
-
|
|
6183
|
+
// position | texture coordinate
|
|
6184
|
+
//------------- +----------------------
|
|
6129
6185
|
// front face select the top left image 1, 0.5,
|
|
6130
|
-
-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,
|
|
6131
6187
|
// right face select the top middle image
|
|
6132
|
-
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,
|
|
6133
6189
|
// back face select to top right image
|
|
6134
|
-
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,
|
|
6135
6191
|
// left face select the bottom left image
|
|
6136
|
-
-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,
|
|
6137
6193
|
// bottom face select the bottom middle image
|
|
6138
|
-
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,
|
|
6139
6195
|
// top face select the bottom right image
|
|
6140
|
-
-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]);
|
|
6141
6197
|
}
|
|
6142
6198
|
const indices = new Uint16Array([0, 1, 2, 2, 1, 3,
|
|
6143
6199
|
// front
|
|
@@ -6169,15 +6225,942 @@ class MECube {
|
|
|
6169
6225
|
}
|
|
6170
6226
|
exports.default = MECube;
|
|
6171
6227
|
|
|
6172
|
-
},{"../shaders/shaders":
|
|
6228
|
+
},{"../shaders/shaders":12,"./engine":5,"./matrix-class":7,"wgpu-matrix":2}],5:[function(require,module,exports){
|
|
6229
|
+
"use strict";
|
|
6230
|
+
|
|
6231
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6232
|
+
value: true
|
|
6233
|
+
});
|
|
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
|
+
}
|
|
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){
|
|
6173
7156
|
"use strict";
|
|
6174
7157
|
|
|
6175
7158
|
Object.defineProperty(exports, "__esModule", {
|
|
6176
7159
|
value: true
|
|
6177
7160
|
});
|
|
6178
7161
|
exports.Rotation = exports.Position = void 0;
|
|
7162
|
+
var _utils = require("./utils");
|
|
6179
7163
|
// Sub classes for matrix-wgpu
|
|
6180
|
-
|
|
6181
7164
|
/**
|
|
6182
7165
|
* @description Base class
|
|
6183
7166
|
* Position { x, y, z }
|
|
@@ -6344,7 +7327,7 @@ class Rotation {
|
|
|
6344
7327
|
}
|
|
6345
7328
|
getRotX() {
|
|
6346
7329
|
if (this.rotationSpeed.x == 0) {
|
|
6347
|
-
return this.x;
|
|
7330
|
+
return (0, _utils.degToRad)(this.x);
|
|
6348
7331
|
} else {
|
|
6349
7332
|
this.x = this.x + this.rotationSpeed.x * 0.001;
|
|
6350
7333
|
return this.x;
|
|
@@ -6352,7 +7335,7 @@ class Rotation {
|
|
|
6352
7335
|
}
|
|
6353
7336
|
getRotY() {
|
|
6354
7337
|
if (this.rotationSpeed.y == 0) {
|
|
6355
|
-
return this.y;
|
|
7338
|
+
return (0, _utils.degToRad)(this.y);
|
|
6356
7339
|
} else {
|
|
6357
7340
|
this.y = this.y + this.rotationSpeed.y * 0.001;
|
|
6358
7341
|
return this.y;
|
|
@@ -6360,7 +7343,7 @@ class Rotation {
|
|
|
6360
7343
|
}
|
|
6361
7344
|
getRotZ() {
|
|
6362
7345
|
if (this.rotationSpeed.z == 0) {
|
|
6363
|
-
return this.z;
|
|
7346
|
+
return (0, _utils.degToRad)(this.z);
|
|
6364
7347
|
} else {
|
|
6365
7348
|
this.z = this.z + this.rotationSpeed.z * 0.001;
|
|
6366
7349
|
return this.z;
|
|
@@ -6369,48 +7352,1492 @@ class Rotation {
|
|
|
6369
7352
|
}
|
|
6370
7353
|
exports.Rotation = Rotation;
|
|
6371
7354
|
|
|
6372
|
-
},{}],
|
|
7355
|
+
},{"./utils":10}],8:[function(require,module,exports){
|
|
6373
7356
|
"use strict";
|
|
6374
7357
|
|
|
6375
7358
|
Object.defineProperty(exports, "__esModule", {
|
|
6376
7359
|
value: true
|
|
6377
7360
|
});
|
|
6378
7361
|
exports.default = void 0;
|
|
6379
|
-
var
|
|
6380
|
-
var
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
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;
|
|
7374
|
+
|
|
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
|
+
});
|
|
8837
|
+
}
|
|
8838
|
+
init = async ({
|
|
8839
|
+
canvas,
|
|
8840
|
+
callback
|
|
6414
8841
|
}) => {
|
|
6415
8842
|
this.canvas = canvas;
|
|
6416
8843
|
this.adapter = await navigator.gpu.requestAdapter();
|
|
@@ -6463,6 +8890,7 @@ class MatrixEngineWGPU {
|
|
|
6463
8890
|
addCube = o => {
|
|
6464
8891
|
if (typeof o === 'undefined') {
|
|
6465
8892
|
var o = {
|
|
8893
|
+
scale: 1,
|
|
6466
8894
|
position: {
|
|
6467
8895
|
x: 0,
|
|
6468
8896
|
y: 0,
|
|
@@ -6479,7 +8907,9 @@ class MatrixEngineWGPU {
|
|
|
6479
8907
|
y: 0,
|
|
6480
8908
|
z: 0
|
|
6481
8909
|
},
|
|
6482
|
-
entityArgPass: this.entityArgPass
|
|
8910
|
+
entityArgPass: this.entityArgPass,
|
|
8911
|
+
cameras: this.cameras,
|
|
8912
|
+
mainCameraParams: this.mainCameraParams
|
|
6483
8913
|
};
|
|
6484
8914
|
} else {
|
|
6485
8915
|
if (typeof o.position === 'undefined') {
|
|
@@ -6506,7 +8936,14 @@ class MatrixEngineWGPU {
|
|
|
6506
8936
|
if (typeof o.texturesPaths === 'undefined') {
|
|
6507
8937
|
o.texturesPaths = ['./res/textures/default.png'];
|
|
6508
8938
|
}
|
|
8939
|
+
if (typeof o.scale === 'undefined') {
|
|
8940
|
+
o.scale = 1;
|
|
8941
|
+
}
|
|
8942
|
+
if (typeof o.mainCameraParams === 'undefined') {
|
|
8943
|
+
o.mainCameraParams = this.mainCameraParams;
|
|
8944
|
+
}
|
|
6509
8945
|
o.entityArgPass = this.entityArgPass;
|
|
8946
|
+
o.cameras = this.cameras;
|
|
6510
8947
|
}
|
|
6511
8948
|
let myCube1 = new _cube.default(this.canvas, this.device, this.context, o);
|
|
6512
8949
|
this.mainRenderBundle.push(myCube1);
|
|
@@ -6514,6 +8951,7 @@ class MatrixEngineWGPU {
|
|
|
6514
8951
|
addBall = o => {
|
|
6515
8952
|
if (typeof o === 'undefined') {
|
|
6516
8953
|
var o = {
|
|
8954
|
+
scale: 1,
|
|
6517
8955
|
position: {
|
|
6518
8956
|
x: 0,
|
|
6519
8957
|
y: 0,
|
|
@@ -6530,7 +8968,9 @@ class MatrixEngineWGPU {
|
|
|
6530
8968
|
y: 0,
|
|
6531
8969
|
z: 0
|
|
6532
8970
|
},
|
|
6533
|
-
entityArgPass: this.entityArgPass
|
|
8971
|
+
entityArgPass: this.entityArgPass,
|
|
8972
|
+
cameras: this.cameras,
|
|
8973
|
+
mainCameraParams: this.mainCameraParams
|
|
6534
8974
|
};
|
|
6535
8975
|
} else {
|
|
6536
8976
|
if (typeof o.position === 'undefined') {
|
|
@@ -6557,47 +8997,150 @@ class MatrixEngineWGPU {
|
|
|
6557
8997
|
if (typeof o.texturesPaths === 'undefined') {
|
|
6558
8998
|
o.texturesPaths = ['./res/textures/default.png'];
|
|
6559
8999
|
}
|
|
9000
|
+
if (typeof o.mainCameraParams === 'undefined') {
|
|
9001
|
+
o.mainCameraParams = this.mainCameraParams;
|
|
9002
|
+
}
|
|
9003
|
+
if (typeof o.scale === 'undefined') {
|
|
9004
|
+
o.scale = 1;
|
|
9005
|
+
}
|
|
6560
9006
|
o.entityArgPass = this.entityArgPass;
|
|
9007
|
+
o.cameras = this.cameras;
|
|
6561
9008
|
}
|
|
6562
9009
|
let myBall1 = new _ball.default(this.canvas, this.device, this.context, o);
|
|
6563
9010
|
this.mainRenderBundle.push(myBall1);
|
|
6564
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
|
+
};
|
|
6565
9100
|
run(callback) {
|
|
6566
9101
|
setTimeout(() => {
|
|
6567
9102
|
requestAnimationFrame(this.frame);
|
|
6568
|
-
},
|
|
9103
|
+
}, 500);
|
|
6569
9104
|
setTimeout(() => {
|
|
6570
9105
|
callback();
|
|
6571
|
-
},
|
|
9106
|
+
}, 20);
|
|
6572
9107
|
}
|
|
6573
9108
|
frameSinglePass = () => {
|
|
6574
|
-
console.log('single');
|
|
6575
|
-
let commandEncoder = this.device.createCommandEncoder();
|
|
6576
|
-
this.rbContainer = [];
|
|
6577
9109
|
let passEncoder;
|
|
6578
|
-
this.
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
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
|
+
}
|
|
6582
9125
|
});
|
|
6583
|
-
this.renderPassDescriptor.colorAttachments[0].view = this.context.getCurrentTexture().createView();
|
|
6584
|
-
passEncoder = commandEncoder.beginRenderPass(this.renderPassDescriptor);
|
|
6585
|
-
passEncoder.executeBundles(this.rbContainer);
|
|
6586
|
-
passEncoder.end();
|
|
6587
9126
|
this.device.queue.submit([commandEncoder.finish()]);
|
|
6588
9127
|
requestAnimationFrame(this.frame);
|
|
6589
9128
|
};
|
|
6590
9129
|
framePassPerObject = () => {
|
|
6591
|
-
console.log('framePassPerObject')
|
|
9130
|
+
// console.log('framePassPerObject')
|
|
6592
9131
|
let commandEncoder = this.device.createCommandEncoder();
|
|
6593
9132
|
this.rbContainer = [];
|
|
6594
9133
|
let passEncoder;
|
|
6595
9134
|
this.mainRenderBundle.forEach((meItem, index) => {
|
|
6596
|
-
meItem.draw();
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
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
|
+
}
|
|
6601
9144
|
});
|
|
6602
9145
|
this.device.queue.submit([commandEncoder.finish()]);
|
|
6603
9146
|
requestAnimationFrame(this.frame);
|
|
@@ -6605,179 +9148,4 @@ class MatrixEngineWGPU {
|
|
|
6605
9148
|
}
|
|
6606
9149
|
exports.default = MatrixEngineWGPU;
|
|
6607
9150
|
|
|
6608
|
-
},{"./engine/ball.js":3,"./engine/cube.js":4}],
|
|
6609
|
-
"use strict";
|
|
6610
|
-
|
|
6611
|
-
Object.defineProperty(exports, "__esModule", {
|
|
6612
|
-
value: true
|
|
6613
|
-
});
|
|
6614
|
-
exports.vertexPositionColorWGSL = exports.shaderSrc = exports.cubeTexShader = exports.basicVertWGSL = exports.basicFragWGSL = exports.BALL_SHADER = void 0;
|
|
6615
|
-
/**
|
|
6616
|
-
* @description
|
|
6617
|
-
* For microdraw pixel cube texture
|
|
6618
|
-
*/
|
|
6619
|
-
const shaderSrc = exports.shaderSrc = `struct VSUniforms {
|
|
6620
|
-
worldViewProjection: mat4x4f,
|
|
6621
|
-
worldInverseTranspose: mat4x4f,
|
|
6622
|
-
};
|
|
6623
|
-
@group(0) @binding(0) var<uniform> vsUniforms: VSUniforms;
|
|
6624
|
-
|
|
6625
|
-
struct MyVSInput {
|
|
6626
|
-
@location(0) position: vec4f,
|
|
6627
|
-
@location(1) normal: vec3f,
|
|
6628
|
-
@location(2) texcoord: vec2f,
|
|
6629
|
-
};
|
|
6630
|
-
|
|
6631
|
-
struct MyVSOutput {
|
|
6632
|
-
@builtin(position) position: vec4f,
|
|
6633
|
-
@location(0) normal: vec3f,
|
|
6634
|
-
@location(1) texcoord: vec2f,
|
|
6635
|
-
};
|
|
6636
|
-
|
|
6637
|
-
@vertex
|
|
6638
|
-
fn myVSMain(v: MyVSInput) -> MyVSOutput {
|
|
6639
|
-
var vsOut: MyVSOutput;
|
|
6640
|
-
vsOut.position = vsUniforms.worldViewProjection * v.position;
|
|
6641
|
-
vsOut.normal = (vsUniforms.worldInverseTranspose * vec4f(v.normal, 0.0)).xyz;
|
|
6642
|
-
vsOut.texcoord = v.texcoord;
|
|
6643
|
-
return vsOut;
|
|
6644
|
-
}
|
|
6645
|
-
|
|
6646
|
-
struct FSUniforms {
|
|
6647
|
-
lightDirection: vec3f,
|
|
6648
|
-
};
|
|
6649
|
-
|
|
6650
|
-
@group(0) @binding(1) var<uniform> fsUniforms: FSUniforms;
|
|
6651
|
-
@group(0) @binding(2) var diffuseSampler: sampler;
|
|
6652
|
-
@group(0) @binding(3) var diffuseTexture: texture_2d<f32>;
|
|
6653
|
-
|
|
6654
|
-
@fragment
|
|
6655
|
-
fn myFSMain(v: MyVSOutput) -> @location(0) vec4f {
|
|
6656
|
-
var diffuseColor = textureSample(diffuseTexture, diffuseSampler, v.texcoord);
|
|
6657
|
-
var a_normal = normalize(v.normal);
|
|
6658
|
-
var l = dot(a_normal, fsUniforms.lightDirection) * 0.5 + 0.5;
|
|
6659
|
-
return vec4f(diffuseColor.rgb * l, diffuseColor.a);
|
|
6660
|
-
}
|
|
6661
|
-
`;
|
|
6662
|
-
|
|
6663
|
-
/**
|
|
6664
|
-
* @description
|
|
6665
|
-
* For Cube with images
|
|
6666
|
-
*/
|
|
6667
|
-
const cubeTexShader = exports.cubeTexShader = `struct Uniforms {
|
|
6668
|
-
matrix: mat4x4f,
|
|
6669
|
-
};
|
|
6670
|
-
|
|
6671
|
-
struct Vertex {
|
|
6672
|
-
@location(0) position: vec4f,
|
|
6673
|
-
@location(1) texcoord: vec2f,
|
|
6674
|
-
};
|
|
6675
|
-
|
|
6676
|
-
struct VSOutput {
|
|
6677
|
-
@builtin(position) position: vec4f,
|
|
6678
|
-
@location(0) texcoord: vec2f,
|
|
6679
|
-
};
|
|
6680
|
-
|
|
6681
|
-
@group(0) @binding(0) var<uniform> uni: Uniforms;
|
|
6682
|
-
@group(0) @binding(1) var ourSampler: sampler;
|
|
6683
|
-
@group(0) @binding(2) var ourTexture: texture_2d<f32>;
|
|
6684
|
-
|
|
6685
|
-
@vertex fn vs(vert: Vertex) -> VSOutput {
|
|
6686
|
-
var vsOut: VSOutput;
|
|
6687
|
-
vsOut.position = uni.matrix * vert.position;
|
|
6688
|
-
vsOut.texcoord = vert.texcoord;
|
|
6689
|
-
return vsOut;
|
|
6690
|
-
}
|
|
6691
|
-
|
|
6692
|
-
@fragment fn fs(vsOut: VSOutput) -> @location(0) vec4f {
|
|
6693
|
-
return textureSample(ourTexture, ourSampler, vsOut.texcoord);
|
|
6694
|
-
}
|
|
6695
|
-
`;
|
|
6696
|
-
const basicVertWGSL = exports.basicVertWGSL = `struct Uniforms {
|
|
6697
|
-
modelViewProjectionMatrix : mat4x4<f32>,
|
|
6698
|
-
}
|
|
6699
|
-
@binding(0) @group(0) var<uniform> uniforms : Uniforms;
|
|
6700
|
-
|
|
6701
|
-
struct VertexOutput {
|
|
6702
|
-
@builtin(position) Position : vec4<f32>,
|
|
6703
|
-
@location(0) fragUV : vec2<f32>,
|
|
6704
|
-
@location(1) fragPosition: vec4<f32>,
|
|
6705
|
-
}
|
|
6706
|
-
|
|
6707
|
-
@vertex
|
|
6708
|
-
fn main(
|
|
6709
|
-
@location(0) position : vec4<f32>,
|
|
6710
|
-
@location(1) uv : vec2<f32>
|
|
6711
|
-
) -> VertexOutput {
|
|
6712
|
-
var output : VertexOutput;
|
|
6713
|
-
output.Position = uniforms.modelViewProjectionMatrix * position;
|
|
6714
|
-
output.fragUV = uv;
|
|
6715
|
-
output.fragPosition = 0.5 * (position + vec4(1.0, 1.0, 1.0, 1.0));
|
|
6716
|
-
return output;
|
|
6717
|
-
}
|
|
6718
|
-
`;
|
|
6719
|
-
const basicFragWGSL = exports.basicFragWGSL = `@group(0) @binding(1) var mySampler: sampler;
|
|
6720
|
-
@group(0) @binding(2) var myTexture: texture_2d<f32>;
|
|
6721
|
-
|
|
6722
|
-
@fragment
|
|
6723
|
-
fn main(
|
|
6724
|
-
@location(0) fragUV: vec2<f32>,
|
|
6725
|
-
@location(1) fragPosition: vec4<f32>
|
|
6726
|
-
) -> @location(0) vec4<f32> {
|
|
6727
|
-
return textureSample(myTexture, mySampler, fragUV) * fragPosition;
|
|
6728
|
-
}
|
|
6729
|
-
`;
|
|
6730
|
-
const vertexPositionColorWGSL = exports.vertexPositionColorWGSL = `@fragment
|
|
6731
|
-
fn main(
|
|
6732
|
-
@location(0) fragUV: vec2<f32>,
|
|
6733
|
-
@location(1) fragPosition: vec4<f32>
|
|
6734
|
-
) -> @location(0) vec4<f32> {
|
|
6735
|
-
return fragPosition;
|
|
6736
|
-
}`;
|
|
6737
|
-
const BALL_SHADER = exports.BALL_SHADER = `struct Uniforms {
|
|
6738
|
-
viewProjectionMatrix : mat4x4f
|
|
6739
|
-
}
|
|
6740
|
-
@group(0) @binding(0) var<uniform> uniforms : Uniforms;
|
|
6741
|
-
|
|
6742
|
-
@group(1) @binding(0) var<uniform> modelMatrix : mat4x4f;
|
|
6743
|
-
|
|
6744
|
-
struct VertexInput {
|
|
6745
|
-
@location(0) position : vec4f,
|
|
6746
|
-
@location(1) normal : vec3f,
|
|
6747
|
-
@location(2) uv : vec2f
|
|
6748
|
-
}
|
|
6749
|
-
|
|
6750
|
-
struct VertexOutput {
|
|
6751
|
-
@builtin(position) position : vec4f,
|
|
6752
|
-
@location(0) normal: vec3f,
|
|
6753
|
-
@location(1) uv : vec2f,
|
|
6754
|
-
}
|
|
6755
|
-
|
|
6756
|
-
@vertex
|
|
6757
|
-
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
6758
|
-
var output : VertexOutput;
|
|
6759
|
-
output.position = uniforms.viewProjectionMatrix * modelMatrix * input.position;
|
|
6760
|
-
output.normal = normalize((modelMatrix * vec4(input.normal, 0)).xyz);
|
|
6761
|
-
output.uv = input.uv;
|
|
6762
|
-
return output;
|
|
6763
|
-
}
|
|
6764
|
-
|
|
6765
|
-
@group(1) @binding(1) var meshSampler: sampler;
|
|
6766
|
-
@group(1) @binding(2) var meshTexture: texture_2d<f32>;
|
|
6767
|
-
|
|
6768
|
-
// Static directional lighting
|
|
6769
|
-
const lightDir = vec3f(1, 1, 1);
|
|
6770
|
-
const dirColor = vec3(1);
|
|
6771
|
-
const ambientColor = vec3f(0.05);
|
|
6772
|
-
|
|
6773
|
-
@fragment
|
|
6774
|
-
fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {
|
|
6775
|
-
let textureColor = textureSample(meshTexture, meshSampler, input.uv);
|
|
6776
|
-
|
|
6777
|
-
// Very simplified lighting algorithm.
|
|
6778
|
-
let lightColor = saturate(ambientColor + max(dot(input.normal, lightDir), 0.0) * dirColor);
|
|
6779
|
-
|
|
6780
|
-
return vec4f(textureColor.rgb * lightColor, textureColor.a);
|
|
6781
|
-
}`;
|
|
6782
|
-
|
|
6783
|
-
},{}]},{},[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]);
|