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.
Files changed (44) hide show
  1. package/app-worker.js +45 -0
  2. package/empty.js +12 -0
  3. package/examples/load-obj-file.js +48 -0
  4. package/examples/unlit-textures.js +27 -0
  5. package/examples.js +7 -0
  6. package/index.js +18 -5
  7. package/main.js +34 -23
  8. package/package.json +11 -2
  9. package/public/app-worker.js +47 -0
  10. package/public/app.js +2678 -310
  11. package/public/css/style.css +1 -2
  12. package/public/empty.html +25 -0
  13. package/public/empty.js +9107 -0
  14. package/public/examples.html +25 -0
  15. package/public/examples.js +9180 -0
  16. package/public/res/meshes/blender/piramyd.blend +0 -0
  17. package/public/res/meshes/blender/piramyd.blend1 +0 -0
  18. package/public/res/meshes/blender/piramyd.js +42 -0
  19. package/public/res/meshes/blender/piramyd.mtl +10 -0
  20. package/public/res/meshes/blender/piramyd.obj +18696 -0
  21. package/public/res/meshes/blender/piramyd1.js +42 -0
  22. package/public/res/meshes/blender/welcomeTextblend.blend +0 -0
  23. package/public/res/meshes/dragon/stanfordDragonData.js +5 -0
  24. package/public/res/meshes/obj/armor.obj +319 -0
  25. package/public/res/meshes/obj/armor.png +0 -0
  26. package/public/worker.html +25 -0
  27. package/readme.md +45 -37
  28. package/src/engine/ball.js +26 -10
  29. package/src/engine/cube.js +96 -81
  30. package/src/engine/engine.js +466 -4
  31. package/src/engine/final/adaptJSON1.js +53 -0
  32. package/src/engine/final/utils2.js +63 -0
  33. package/src/engine/loader-obj.js +469 -0
  34. package/src/engine/matrix-class.js +5 -4
  35. package/src/engine/matrix-mesh.js +49 -0
  36. package/src/engine/mesh-obj.js +526 -0
  37. package/src/engine/mesh.js +477 -0
  38. package/src/engine/utils.js +2 -0
  39. package/src/shaders/fragment.wgsl.js +48 -0
  40. package/src/shaders/shaders.js +4 -124
  41. package/src/shaders/vertex.wgsl.js +49 -0
  42. package/src/shaders/vertexShadow.wgsl.js +20 -0
  43. package/src/world.js +263 -0
  44. package/src/meWGPU.js +0 -173
@@ -0,0 +1,49 @@
1
+ export let vertexWGSL = `struct Scene {
2
+ lightViewProjMatrix: mat4x4f,
3
+ cameraViewProjMatrix: mat4x4f,
4
+ lightPos: vec3f,
5
+ }
6
+
7
+ struct Model {
8
+ modelMatrix: mat4x4f,
9
+ }
10
+
11
+ @group(0) @binding(0) var<uniform> scene : Scene;
12
+ @group(1) @binding(0) var<uniform> model : Model;
13
+
14
+ struct VertexOutput {
15
+ @location(0) shadowPos: vec3f,
16
+ @location(1) fragPos: vec3f,
17
+ @location(2) fragNorm: vec3f,
18
+ @location(3) uv : vec2f,
19
+
20
+ @builtin(position) Position: vec4f,
21
+ }
22
+
23
+ @vertex
24
+ fn main(
25
+ @location(0) position: vec3f,
26
+ @location(1) normal: vec3f,
27
+ @location(2) uv : vec2f
28
+ ) -> VertexOutput {
29
+ var output : VertexOutput;
30
+
31
+ // XY is in (-1, 1) space, Z is in (0, 1) space
32
+ let posFromLight = scene.lightViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
33
+
34
+ // Convert XY to (0, 1)
35
+ // Y is flipped because texture coords are Y-down.
36
+ output.shadowPos = vec3(
37
+ posFromLight.xy * vec2(0.5, -0.5) + vec2(0.5),
38
+ posFromLight.z
39
+ );
40
+
41
+ output.Position = scene.cameraViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
42
+ output.fragPos = output.Position.xyz;
43
+ output.fragNorm = normal;
44
+ // nidza
45
+ output.uv = uv;
46
+
47
+ return output;
48
+ }
49
+ `
@@ -0,0 +1,20 @@
1
+ export let vertexShadowWGSL = `struct Scene {
2
+ lightViewProjMatrix: mat4x4f,
3
+ cameraViewProjMatrix: mat4x4f,
4
+ lightPos: vec3f,
5
+ }
6
+
7
+ struct Model {
8
+ modelMatrix: mat4x4f,
9
+ }
10
+
11
+ @group(0) @binding(0) var<uniform> scene : Scene;
12
+ @group(1) @binding(0) var<uniform> model : Model;
13
+
14
+ @vertex
15
+ fn main(
16
+ @location(0) position: vec3f
17
+ ) -> @builtin(position) vec4f {
18
+ return scene.lightViewProjMatrix * model.modelMatrix * vec4(position, 1.0);
19
+ }
20
+ `
package/src/world.js ADDED
@@ -0,0 +1,263 @@
1
+ import {vec3} from "wgpu-matrix";
2
+ import MEBall from "./engine/ball.js";
3
+ import MECube from './engine/cube.js';
4
+ import {ArcballCamera, WASDCamera} from "./engine/engine.js";
5
+ import MEMesh from "./engine/mesh.js";
6
+ import MEMeshObj from "./engine/mesh-obj.js";
7
+
8
+ export default class MatrixEngineWGPU {
9
+
10
+ mainRenderBundle = [];
11
+ rbContainer = [];
12
+ frame = () => {};
13
+
14
+ entityHolder = [];
15
+
16
+ entityArgPass = {
17
+ loadOp: 'clear',
18
+ storeOp: 'store',
19
+ depthLoadOp: 'clear',
20
+ depthStoreOp: 'store'
21
+ }
22
+
23
+ // The input handler
24
+ constructor(options, callback) {
25
+ // console.log('typeof options ', typeof options )
26
+ if(typeof options == 'undefined' || typeof options == "function") {
27
+ this.options = {
28
+ useSingleRenderPass: true,
29
+ canvasSize: 'fullscreen'
30
+ }
31
+ callback = options;
32
+ }
33
+
34
+ this.options = options;
35
+
36
+ var canvas = document.createElement('canvas')
37
+ if(this.options.canvasSize == 'fullscreen') {
38
+ canvas.width = window.innerWidth;
39
+ canvas.height = window.innerHeight;
40
+ } else {
41
+ canvas.width = this.options.canvasSize.w;
42
+ canvas.height = this.options.canvasSize.h;
43
+ }
44
+ document.body.append(canvas)
45
+
46
+ // The camera types
47
+ const initialCameraPosition = vec3.create(0, 0, 0);
48
+ this.mainCameraParams = {
49
+ type: 'WASD',
50
+ responseCoef: 2000
51
+ }
52
+
53
+ this.cameras = {
54
+ arcball: new ArcballCamera({position: initialCameraPosition}),
55
+ WASD: new WASDCamera({position: initialCameraPosition}),
56
+ };
57
+
58
+ this.init({canvas, callback})
59
+ }
60
+
61
+ init = async ({canvas, callback}) => {
62
+ this.canvas = canvas;
63
+ this.adapter = await navigator.gpu.requestAdapter();
64
+ this.device = await this.adapter.requestDevice();
65
+ this.context = canvas.getContext('webgpu');
66
+
67
+ const devicePixelRatio = window.devicePixelRatio;
68
+ canvas.width = canvas.clientWidth * devicePixelRatio;
69
+ canvas.height = canvas.clientHeight * devicePixelRatio;
70
+ const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
71
+
72
+ this.context.configure({
73
+ device: this.device,
74
+ format: presentationFormat,
75
+ alphaMode: 'premultiplied',
76
+ });
77
+
78
+ if(this.options.useSingleRenderPass == true) {
79
+ this.makeDefaultRenderPassDescriptor()
80
+ this.frame = this.frameSinglePass;
81
+ } else {
82
+ // must be
83
+ this.frame = this.framePassPerObject;
84
+ }
85
+
86
+ this.run(callback)
87
+ };
88
+
89
+ makeDefaultRenderPassDescriptor = () => {
90
+
91
+ this.depthTexture = this.device.createTexture({
92
+ size: [this.canvas.width, this.canvas.height],
93
+ format: 'depth24plus',
94
+ usage: GPUTextureUsage.RENDER_ATTACHMENT,
95
+ });
96
+
97
+ this.renderPassDescriptor = {
98
+ colorAttachments: [
99
+ {
100
+ view: undefined,
101
+ clearValue: {r: 0.0, g: 0.0, b: 0.0, a: 1.0},
102
+ loadOp: 'clear',
103
+ storeOp: 'store',
104
+ },
105
+ ],
106
+ depthStencilAttachment: {
107
+ view: this.depthTexture.createView(),
108
+ depthClearValue: 1.0,
109
+ depthLoadOp: 'clear',
110
+ depthStoreOp: 'store',
111
+ },
112
+ };
113
+ }
114
+
115
+ addCube = (o) => {
116
+ if(typeof o === 'undefined') {
117
+ var o = {
118
+ scale: 1,
119
+ position: {x: 0, y: 0, z: -4},
120
+ texturesPaths: ['./res/textures/default.png'],
121
+ rotation: {x: 0, y: 0, z: 0},
122
+ rotationSpeed: {x: 0, y: 0, z: 0},
123
+ entityArgPass: this.entityArgPass,
124
+ cameras: this.cameras,
125
+ mainCameraParams: this.mainCameraParams
126
+ }
127
+ } else {
128
+ if(typeof o.position === 'undefined') {o.position = {x: 0, y: 0, z: -4}}
129
+ if(typeof o.rotation === 'undefined') {o.rotation = {x: 0, y: 0, z: 0}}
130
+ if(typeof o.rotationSpeed === 'undefined') {o.rotationSpeed = {x: 0, y: 0, z: 0}}
131
+ if(typeof o.texturesPaths === 'undefined') {o.texturesPaths = ['./res/textures/default.png']}
132
+ if(typeof o.scale === 'undefined') {o.scale = 1;}
133
+ if(typeof o.mainCameraParams === 'undefined') {o.mainCameraParams = this.mainCameraParams}
134
+ o.entityArgPass = this.entityArgPass;
135
+ o.cameras = this.cameras;
136
+ }
137
+ let myCube1 = new MECube(this.canvas, this.device, this.context, o)
138
+ this.mainRenderBundle.push(myCube1);
139
+ }
140
+
141
+ addBall = (o) => {
142
+ if(typeof o === 'undefined') {
143
+ var o = {
144
+ scale: 1,
145
+ position: {x: 0, y: 0, z: -4},
146
+ texturesPaths: ['./res/textures/default.png'],
147
+ rotation: {x: 0, y: 0, z: 0},
148
+ rotationSpeed: {x: 0, y: 0, z: 0},
149
+ entityArgPass: this.entityArgPass,
150
+ cameras: this.cameras,
151
+ mainCameraParams: this.mainCameraParams
152
+ }
153
+ } else {
154
+ if(typeof o.position === 'undefined') {o.position = {x: 0, y: 0, z: -4}}
155
+ if(typeof o.rotation === 'undefined') {o.rotation = {x: 0, y: 0, z: 0}}
156
+ if(typeof o.rotationSpeed === 'undefined') {o.rotationSpeed = {x: 0, y: 0, z: 0}}
157
+ if(typeof o.texturesPaths === 'undefined') {o.texturesPaths = ['./res/textures/default.png']}
158
+ if(typeof o.mainCameraParams === 'undefined') {o.mainCameraParams = this.mainCameraParams}
159
+ if(typeof o.scale === 'undefined') {o.scale = 1;}
160
+ o.entityArgPass = this.entityArgPass;
161
+ o.cameras = this.cameras;
162
+ }
163
+ let myBall1 = new MEBall(this.canvas, this.device, this.context, o)
164
+ this.mainRenderBundle.push(myBall1);
165
+ }
166
+
167
+ addMesh = (o) => {
168
+ if(typeof o.position === 'undefined') {o.position = {x: 0, y: 0, z: -4}}
169
+ if(typeof o.rotation === 'undefined') {o.rotation = {x: 0, y: 0, z: 0}}
170
+ if(typeof o.rotationSpeed === 'undefined') {o.rotationSpeed = {x: 0, y: 0, z: 0}}
171
+ if(typeof o.texturesPaths === 'undefined') {o.texturesPaths = ['./res/textures/default.png']}
172
+ if(typeof o.mainCameraParams === 'undefined') {o.mainCameraParams = this.mainCameraParams}
173
+ if(typeof o.scale === 'undefined') {o.scale = 1;}
174
+ o.entityArgPass = this.entityArgPass;
175
+ o.cameras = this.cameras;
176
+ if(typeof o.name === 'undefined') {o.name = 'random' + Math.random();}
177
+ if(typeof o.mesh === 'undefined') {
178
+ throw console.error('arg mesh is empty...');
179
+ return;
180
+ }
181
+ console.log('Mesh procedure', o)
182
+
183
+ let myMesh1 = new MEMesh(this.canvas, this.device, this.context, o)
184
+ this.mainRenderBundle.push(myMesh1);
185
+
186
+
187
+ }
188
+
189
+ addMeshObj = (o) => {
190
+ if(typeof o.position === 'undefined') {o.position = {x: 0, y: 0, z: -4}}
191
+ if(typeof o.rotation === 'undefined') {o.rotation = {x: 0, y: 0, z: 0}}
192
+ if(typeof o.rotationSpeed === 'undefined') {o.rotationSpeed = {x: 0, y: 0, z: 0}}
193
+ if(typeof o.texturesPaths === 'undefined') {o.texturesPaths = ['./res/textures/default.png']}
194
+ if(typeof o.mainCameraParams === 'undefined') {o.mainCameraParams = this.mainCameraParams}
195
+ if(typeof o.scale === 'undefined') {o.scale = 1;}
196
+ o.entityArgPass = this.entityArgPass;
197
+ o.cameras = this.cameras;
198
+ if(typeof o.name === 'undefined') {o.name = 'random' + Math.random();}
199
+ if(typeof o.mesh === 'undefined') {
200
+ throw console.error('arg mesh is empty...');
201
+ return;
202
+ }
203
+ console.log('Mesh procedure', o)
204
+
205
+ let myMesh1 = new MEMeshObj(this.canvas, this.device, this.context, o)
206
+ this.mainRenderBundle.push(myMesh1);
207
+
208
+
209
+ }
210
+
211
+ run(callback) {
212
+ setTimeout(() => {requestAnimationFrame(this.frame)}, 500)
213
+ setTimeout(() => {callback()}, 20)
214
+ }
215
+
216
+ frameSinglePass = () => {
217
+
218
+ let passEncoder;
219
+ let commandEncoder = this.device.createCommandEncoder();
220
+ if(typeof this.mainRenderBundle != 'undefined') this.mainRenderBundle.forEach((meItem, index) => {
221
+ meItem.position.update();
222
+ meItem.draw(commandEncoder);
223
+
224
+ //
225
+ if(typeof meItem.done == 'undefined') {
226
+ this.rbContainer.push(meItem.renderBundle);
227
+ this.renderPassDescriptor.colorAttachments[0].view = this.context
228
+ .getCurrentTexture()
229
+ .createView();
230
+ // console.log('prolazi ')
231
+ passEncoder = commandEncoder.beginRenderPass(this.renderPassDescriptor);
232
+ passEncoder.executeBundles(this.rbContainer);
233
+ passEncoder.end();
234
+ // this.device.queue.submit([commandEncoder.finish()]);
235
+ }
236
+ })
237
+ this.device.queue.submit([commandEncoder.finish()]);
238
+
239
+ requestAnimationFrame(this.frame);
240
+ }
241
+
242
+ framePassPerObject = () => {
243
+ // console.log('framePassPerObject')
244
+ let commandEncoder = this.device.createCommandEncoder();
245
+ this.rbContainer = [];
246
+ let passEncoder;
247
+ this.mainRenderBundle.forEach((meItem, index) => {
248
+ meItem.draw(commandEncoder);
249
+
250
+ if(meItem.renderBundle) {
251
+ this.rbContainer.push(meItem.renderBundle)
252
+ passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
253
+ passEncoder.executeBundles(this.rbContainer);
254
+ passEncoder.end();
255
+ } else {
256
+ meItem.draw(commandEncoder)
257
+ }
258
+
259
+ })
260
+ this.device.queue.submit([commandEncoder.finish()]);
261
+ requestAnimationFrame(this.frame);
262
+ }
263
+ }
package/src/meWGPU.js DELETED
@@ -1,173 +0,0 @@
1
- import MEBall from "./engine/ball.js";
2
- import MECube from './engine/cube.js';
3
-
4
- export default class MatrixEngineWGPU {
5
-
6
- mainRenderBundle = [];
7
- rbContainer = [];
8
- frame = () => {};
9
-
10
- entityArgPass = {
11
- loadOp: 'clear',
12
- storeOp: 'store',
13
- depthLoadOp: 'clear',
14
- depthStoreOp: 'store'
15
- }
16
-
17
- constructor(options, callback) {
18
- console.log('typeof options ', typeof options )
19
- console.log('typeof options ', options )
20
- if (typeof options == 'undefined' || typeof options == "function") {
21
- this.options = {
22
- useSingleRenderPass: true
23
- }
24
- callback = options;
25
- }
26
-
27
- this.options = options;
28
-
29
- var canvas = document.createElement('canvas')
30
- canvas.width = window.innerWidth;
31
- canvas.height = window.innerHeight;
32
- document.body.append(canvas)
33
- this.init({canvas, callback})
34
- }
35
-
36
- init = async ({canvas, callback}) => {
37
- this.canvas = canvas;
38
- this.adapter = await navigator.gpu.requestAdapter();
39
- this.device = await this.adapter.requestDevice();
40
- this.context = canvas.getContext('webgpu');
41
-
42
- const devicePixelRatio = window.devicePixelRatio;
43
- canvas.width = canvas.clientWidth * devicePixelRatio;
44
- canvas.height = canvas.clientHeight * devicePixelRatio;
45
- const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
46
-
47
- this.context.configure({
48
- device: this.device,
49
- format: presentationFormat,
50
- alphaMode: 'premultiplied',
51
- });
52
-
53
- if(this.options.useSingleRenderPass == true) {
54
- this.makeDefaultRenderPassDescriptor()
55
- this.frame = this.frameSinglePass;
56
- } else {
57
- // must be
58
- this.frame = this.framePassPerObject;
59
- }
60
-
61
- this.run(callback)
62
- };
63
-
64
- makeDefaultRenderPassDescriptor = () => {
65
-
66
- this.depthTexture = this.device.createTexture({
67
- size: [this.canvas.width, this.canvas.height],
68
- format: 'depth24plus',
69
- usage: GPUTextureUsage.RENDER_ATTACHMENT,
70
- });
71
-
72
- this.renderPassDescriptor = {
73
- colorAttachments: [
74
- {
75
- view: undefined,
76
- clearValue: {r: 0.0, g: 0.0, b: 0.0, a: 1.0},
77
- loadOp: 'clear',
78
- storeOp: 'store',
79
- },
80
- ],
81
- depthStencilAttachment: {
82
- view: this.depthTexture.createView(),
83
- depthClearValue: 1.0,
84
- depthLoadOp: 'clear',
85
- depthStoreOp: 'store',
86
- },
87
- };
88
- }
89
-
90
- addCube = (o) => {
91
- if(typeof o === 'undefined') {
92
- var o = {
93
- position: {x: 0, y: 0, z: -4},
94
- texturesPaths: ['./res/textures/default.png'],
95
- rotation: {x: 0, y: 0, z: 0},
96
- rotationSpeed: {x: 0, y: 0, z: 0},
97
- entityArgPass: this.entityArgPass
98
- }
99
- } else {
100
- if(typeof o.position === 'undefined') {o.position = {x: 0, y: 0, z: -4}}
101
- if(typeof o.rotation === 'undefined') {o.rotation = {x: 0, y: 0, z: 0}}
102
- if(typeof o.rotationSpeed === 'undefined') {o.rotationSpeed = {x: 0, y: 0, z: 0}}
103
- if(typeof o.texturesPaths === 'undefined') {o.texturesPaths = ['./res/textures/default.png']}
104
- o.entityArgPass = this.entityArgPass;
105
- }
106
- let myCube1 = new MECube(this.canvas, this.device, this.context, o)
107
- this.mainRenderBundle.push(myCube1);
108
- }
109
-
110
- addBall = (o) => {
111
- if(typeof o === 'undefined') {
112
- var o = {
113
- position: {x: 0, y: 0, z: -4},
114
- texturesPaths: ['./res/textures/default.png'],
115
- rotation: {x: 0, y: 0, z: 0},
116
- rotationSpeed: {x: 0, y: 0, z: 0},
117
- entityArgPass: this.entityArgPass
118
- }
119
- } else {
120
- if(typeof o.position === 'undefined') {o.position = {x: 0, y: 0, z: -4}}
121
- if(typeof o.rotation === 'undefined') {o.rotation = {x: 0, y: 0, z: 0}}
122
- if(typeof o.rotationSpeed === 'undefined') {o.rotationSpeed = {x: 0, y: 0, z: 0}}
123
- if(typeof o.texturesPaths === 'undefined') {o.texturesPaths = ['./res/textures/default.png']}
124
- o.entityArgPass = this.entityArgPass;
125
- }
126
- let myBall1 = new MEBall(this.canvas, this.device, this.context, o)
127
- this.mainRenderBundle.push(myBall1);
128
- }
129
-
130
- run(callback) {
131
- setTimeout(() => {requestAnimationFrame(this.frame)}, 1000)
132
- setTimeout(() => {callback()}, 10)
133
- }
134
-
135
- frameSinglePass = () => {
136
- console.log('single')
137
- let commandEncoder = this.device.createCommandEncoder();
138
- this.rbContainer = [];
139
- let passEncoder;
140
-
141
- this.mainRenderBundle.forEach((meItem, index) => {
142
- meItem.draw();
143
- this.rbContainer.push(meItem.renderBundle)
144
- // if(index == 0) passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
145
- })
146
-
147
- this.renderPassDescriptor.colorAttachments[0].view = this.context
148
- .getCurrentTexture()
149
- .createView();
150
-
151
- passEncoder = commandEncoder.beginRenderPass(this.renderPassDescriptor);
152
- passEncoder.executeBundles(this.rbContainer);
153
- passEncoder.end();
154
- this.device.queue.submit([commandEncoder.finish()]);
155
- requestAnimationFrame(this.frame);
156
- }
157
-
158
- framePassPerObject = () => {
159
- console.log('framePassPerObject')
160
- let commandEncoder = this.device.createCommandEncoder();
161
- this.rbContainer = [];
162
- let passEncoder;
163
- this.mainRenderBundle.forEach((meItem, index) => {
164
- meItem.draw();
165
- this.rbContainer.push(meItem.renderBundle)
166
- passEncoder = commandEncoder.beginRenderPass(meItem.renderPassDescriptor);
167
- passEncoder.executeBundles(this.rbContainer);
168
- passEncoder.end();
169
- })
170
- this.device.queue.submit([commandEncoder.finish()]);
171
- requestAnimationFrame(this.frame);
172
- }
173
- }