Add hot reload
This commit is contained in:
parent
9349a57781
commit
9cf8f73e18
17 changed files with 20009 additions and 2656 deletions
1
.eslintignore
Normal file
1
.eslintignore
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
**/*.js
|
||||||
29
.eslintrc.json
Normal file
29
.eslintrc.json
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es2020": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/eslint-recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"prettier"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 11,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"plugins": ["unused-imports", "@typescript-eslint", "prettier"],
|
||||||
|
"rules": {
|
||||||
|
"prettier/prettier": "error",
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"unused-imports/no-unused-imports-ts": "error",
|
||||||
|
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
|
"@typescript-eslint/ban-ts-comment": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -41,5 +41,3 @@ temp
|
||||||
*.js
|
*.js
|
||||||
*.map
|
*.map
|
||||||
!webpack.*
|
!webpack.*
|
||||||
|
|
||||||
dist
|
|
||||||
|
|
|
||||||
14
.prettierrc
14
.prettierrc
|
|
@ -1,6 +1,10 @@
|
||||||
{
|
{
|
||||||
"trailingComma": "none",
|
"trailingComma": "es5",
|
||||||
"tabWidth": 4,
|
"printWidth": 90,
|
||||||
"semi": true,
|
"tabWidth": 2,
|
||||||
"singleQuote": true
|
"singleQuote": true,
|
||||||
}
|
"endOfLine": "lf",
|
||||||
|
"importOrder": ["^[./]", ".*", ".scss$"],
|
||||||
|
"importOrderSeparation": true,
|
||||||
|
"importOrderSortSpecifiers": true
|
||||||
|
}
|
||||||
|
|
|
||||||
37
README.md
37
README.md
|
|
@ -10,46 +10,9 @@ A WebGPU repo you can use to get started with your own renderer.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
First install:
|
|
||||||
|
|
||||||
- [Git](https://git-scm.com/)
|
|
||||||
|
|
||||||
- [Node.js](https://nodejs.org/en/)
|
|
||||||
|
|
||||||
- A Text Editor such as [Visual Studio Code](https://code.visualstudio.com/).
|
|
||||||
|
|
||||||
Then type the following in any terminal your such as [VS Code's Integrated Terminal](https://code.visualstudio.com/docs/editor/integrated-terminal).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 🐑 Clone the repo
|
|
||||||
git clone https://github.com/alaingalvan/webgpu-seed
|
|
||||||
|
|
||||||
# 💿 go inside the folder
|
|
||||||
cd webgpu-seed
|
|
||||||
|
|
||||||
# 🔨 Start installing dependencies, building, and running at localhost:8080
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
> Refer to [this blog post on designing web libraries and apps](https://alain.xyz/blog/designing-a-web-app) for more details on Node.js, packages, etc.
|
> Refer to [this blog post on designing web libraries and apps](https://alain.xyz/blog/designing-a-web-app) for more details on Node.js, packages, etc.
|
||||||
|
|
||||||
## Project Layout
|
|
||||||
|
|
||||||
As your project becomes more complex, you'll want to separate files and organize your application to something more akin to a game or renderer, check out this post on [game engine architecture](https://alain.xyz/blog/game-engine-architecture) and this one on [real time renderer architecture](https://alain.xyz/blog/realtime-renderer-architectures) for more details.
|
As your project becomes more complex, you'll want to separate files and organize your application to something more akin to a game or renderer, check out this post on [game engine architecture](https://alain.xyz/blog/game-engine-architecture) and this one on [real time renderer architecture](https://alain.xyz/blog/realtime-renderer-architectures) for more details.
|
||||||
|
|
||||||
```bash
|
|
||||||
├─ 📂 node_modules/ # 👶 Dependencies
|
|
||||||
│ ├─ 📁 gl-matrix # ➕ Linear Algebra
|
|
||||||
│ └─ 📁 ... # 🕚 Other Dependencies (TypeScript, Webpack, etc.)
|
|
||||||
├─ 📂 src/ # 🌟 Source Files
|
|
||||||
│ ├─ 📄 index.html # 📇 Main HTML file
|
|
||||||
│ └─ 📄 renderer.ts # 🔺 Triangle Renderer
|
|
||||||
├─ 📄 .gitignore # 👁️ Ignore certain files in git repo
|
|
||||||
├─ 📄 package.json # 📦 Node Package File
|
|
||||||
├─ 📄 license.md # ⚖️ Your License (Unlicense)
|
|
||||||
└─ 📃readme.md # 📖 Read Me!
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
[license-img]: https://img.shields.io/:license-unlicense-blue.svg?style=flat-square
|
[license-img]: https://img.shields.io/:license-unlicense-blue.svg?style=flat-square
|
||||||
[license-url]: https://unlicense.org/
|
[license-url]: https://unlicense.org/
|
||||||
|
|
|
||||||
15
definitions.d.ts
vendored
15
definitions.d.ts
vendored
|
|
@ -1 +1,14 @@
|
||||||
declare module '*.wgsl';
|
declare module '*.wgsl' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.svg' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '*.html' {
|
||||||
|
const content: string;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
|
||||||
2
dist/index.html
vendored
Normal file
2
dist/index.html
vendored
Normal file
File diff suppressed because one or more lines are too long
28
index.html
28
index.html
|
|
@ -1,28 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en-US">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>WebGPU Hello Triangle</title>
|
|
||||||
<style>
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
font-size: 100%;
|
|
||||||
font: inherit;
|
|
||||||
vertical-align: baseline;
|
|
||||||
background: #000;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<canvas id="gfx"></canvas>
|
|
||||||
<script type="text/javascript" src="dist/main.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
18815
package-lock.json
generated
18815
package-lock.json
generated
File diff suppressed because it is too large
Load diff
42
package.json
42
package.json
|
|
@ -4,9 +4,10 @@
|
||||||
"description": "🔺 A simple hello triangle example introducing WebGPU.",
|
"description": "🔺 A simple hello triangle example introducing WebGPU.",
|
||||||
"main": "dist/main.js",
|
"main": "dist/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npm i && npm run build && npm run dev",
|
"start": "webpack serve --open --mode development",
|
||||||
"dev": "http-server",
|
"lint": "eslint --fix \"src/**/*.ts\" && prettier --write \"src/**/*.(ts|scss|json|html)\"",
|
||||||
"build": "cross-env NODE_ENV=production ts-node webpack.ts"
|
"build": "webpack --mode production",
|
||||||
|
"update": "ncu"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
@ -27,15 +28,32 @@
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/alaingalvan/webgpu-seed#readme",
|
"homepage": "https://github.com/alaingalvan/webgpu-seed#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.11.x",
|
"@webgpu/types": "^0.1.30",
|
||||||
"@webgpu/types": "^0.1.26",
|
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
|
||||||
"clean-webpack-plugin": "^4.0.x",
|
"@typescript-eslint/eslint-plugin": "^5.38.0",
|
||||||
"cross-env": "^7.0.x",
|
"css-loader": "^6.7.1",
|
||||||
"http-server": "^14.1.x",
|
"eslint": "^8.23.1",
|
||||||
"ts-loader": "^9.4.x",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"ts-node": "^10.9.x",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"typescript": "^4.9.x",
|
"eslint-plugin-unused-imports": "^2.0.0",
|
||||||
"webpack": "^5.75.x"
|
"html-webpack-plugin": "^5.5.0",
|
||||||
|
"inline-source-webpack-plugin": "^2.0.1",
|
||||||
|
"mini-css-extract-plugin": "^2.6.1",
|
||||||
|
"npm-check-updates": "^16.3.2",
|
||||||
|
"prettier": "^2.7.1",
|
||||||
|
"resolve-url-loader": "^5.0.0",
|
||||||
|
"responsive-loader": "^3.1.1",
|
||||||
|
"sass": "^1.55.0",
|
||||||
|
"sass-loader": "^13.0.2",
|
||||||
|
"sharp": "^0.31.0",
|
||||||
|
"string-replace-loader": "^3.1.0",
|
||||||
|
"svg-inline-loader": "^0.8.2",
|
||||||
|
"terser-webpack-plugin": "^5.3.6",
|
||||||
|
"ts-loader": "^9.4.1",
|
||||||
|
"typescript": "^4.8.3",
|
||||||
|
"webpack": "^5.74.0",
|
||||||
|
"webpack-cli": "^4.10.0",
|
||||||
|
"webpack-dev-server": "^4.11.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"gl-matrix": "^3.4.3"
|
"gl-matrix": "^3.4.3"
|
||||||
|
|
|
||||||
38
src/index.html
Normal file
38
src/index.html
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
|
<meta property="og:title" content="WebGPU | Andras Schmelczer" />
|
||||||
|
<meta property="og:description" content="Discover my projects." />
|
||||||
|
<meta property="og:url" content="https://schmelczer.dev" />
|
||||||
|
|
||||||
|
<meta property="og:image:width" content="1920" />
|
||||||
|
<meta property="og:image:height" content="1920" />
|
||||||
|
<meta property="og:image" content="https://schmelczer.dev/og-image.jpg" />
|
||||||
|
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
|
<link rel="icon" href="favicon.ico" type="image/x-icon" />
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||||
|
<link rel="manifest" href="/site.webmanifest" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="I'm Andras Schmelczer, and this is my portfolio. Discover some of my projects. I'm passionate about solving challenging problems and designing large-scale systems, especially in the context of machine learning."
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width,initial-scale=1,viewport-fit=cover"
|
||||||
|
/>
|
||||||
|
<meta name="theme-color" content="#b7455e" />
|
||||||
|
|
||||||
|
<title>WebGPU | Andras Schmelczer</title>
|
||||||
|
|
||||||
|
<link inline inline-asset="index.css" inline-asset-delete />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>JavaScript is required for this website.</noscript>
|
||||||
|
<canvas></canvas>
|
||||||
|
<script inline inline-asset="index.js" inline-asset-delete></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
15
src/index.scss
Normal file
15
src/index.scss
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
font: inherit;
|
||||||
|
vertical-align: baseline;
|
||||||
|
background: #000;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
import './index.scss';
|
||||||
import Renderer from './renderer';
|
import Renderer from './renderer';
|
||||||
|
|
||||||
const canvas = document.getElementById('gfx') as HTMLCanvasElement;
|
const canvas = document.querySelector('canvas') as HTMLCanvasElement;
|
||||||
canvas.width = canvas.height = 640;
|
canvas.width = canvas.height = 640;
|
||||||
const renderer = new Renderer(canvas);
|
const renderer = new Renderer(canvas);
|
||||||
renderer.start();
|
renderer.start();
|
||||||
|
|
@ -1,20 +1,8 @@
|
||||||
import vertShaderCode from './shaders/triangle.vert.wgsl';
|
|
||||||
import fragShaderCode from './shaders/triangle.frag.wgsl';
|
import fragShaderCode from './shaders/triangle.frag.wgsl';
|
||||||
|
import vertShaderCode from './shaders/triangle.vert.wgsl';
|
||||||
|
|
||||||
const positions = new Float32Array([
|
const positions = new Float32Array([1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0]);
|
||||||
1.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0
|
const colors = new Float32Array([1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0]);
|
||||||
]);
|
|
||||||
const colors = new Float32Array([
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0
|
|
||||||
]);
|
|
||||||
|
|
||||||
const indices = new Uint16Array([0, 1, 2]);
|
const indices = new Uint16Array([0, 1, 2]);
|
||||||
|
|
||||||
|
|
@ -72,17 +60,14 @@ export default class Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
async initializeResources() {
|
async initializeResources() {
|
||||||
const createBuffer = (
|
const createBuffer = (arr: Float32Array | Uint16Array, usage: number) => {
|
||||||
arr: Float32Array | Uint16Array,
|
|
||||||
usage: number
|
|
||||||
) => {
|
|
||||||
// 📏 Align to 4 bytes (thanks @chrimsonite)
|
// 📏 Align to 4 bytes (thanks @chrimsonite)
|
||||||
let desc = {
|
const desc = {
|
||||||
size: (arr.byteLength + 3) & ~3,
|
size: (arr.byteLength + 3) & ~3,
|
||||||
usage,
|
usage,
|
||||||
mappedAtCreation: true
|
mappedAtCreation: true,
|
||||||
};
|
};
|
||||||
let buffer = this.device.createBuffer(desc);
|
const buffer = this.device.createBuffer(desc);
|
||||||
const writeArray =
|
const writeArray =
|
||||||
arr instanceof Uint16Array
|
arr instanceof Uint16Array
|
||||||
? new Uint16Array(buffer.getMappedRange())
|
? new Uint16Array(buffer.getMappedRange())
|
||||||
|
|
@ -97,40 +82,40 @@ export default class Renderer {
|
||||||
this.indexBuffer = createBuffer(indices, GPUBufferUsage.INDEX);
|
this.indexBuffer = createBuffer(indices, GPUBufferUsage.INDEX);
|
||||||
|
|
||||||
const vsmDesc = {
|
const vsmDesc = {
|
||||||
code: vertShaderCode
|
code: vertShaderCode,
|
||||||
};
|
};
|
||||||
this.vertModule = this.device.createShaderModule(vsmDesc);
|
this.vertModule = this.device.createShaderModule(vsmDesc);
|
||||||
|
|
||||||
const fsmDesc = {
|
const fsmDesc = {
|
||||||
code: fragShaderCode
|
code: fragShaderCode,
|
||||||
};
|
};
|
||||||
this.fragModule = this.device.createShaderModule(fsmDesc);
|
this.fragModule = this.device.createShaderModule(fsmDesc);
|
||||||
|
|
||||||
const positionAttribDesc: GPUVertexAttribute = {
|
const positionAttribDesc: GPUVertexAttribute = {
|
||||||
shaderLocation: 0, // [[location(0)]]
|
shaderLocation: 0, // [[location(0)]]
|
||||||
offset: 0,
|
offset: 0,
|
||||||
format: 'float32x3'
|
format: 'float32x3',
|
||||||
};
|
};
|
||||||
const colorAttribDesc: GPUVertexAttribute = {
|
const colorAttribDesc: GPUVertexAttribute = {
|
||||||
shaderLocation: 1, // [[location(1)]]
|
shaderLocation: 1, // [[location(1)]]
|
||||||
offset: 0,
|
offset: 0,
|
||||||
format: 'float32x3'
|
format: 'float32x3',
|
||||||
};
|
};
|
||||||
const positionBufferDesc: GPUVertexBufferLayout = {
|
const positionBufferDesc: GPUVertexBufferLayout = {
|
||||||
attributes: [positionAttribDesc],
|
attributes: [positionAttribDesc],
|
||||||
arrayStride: 4 * 3, // sizeof(float) * 3
|
arrayStride: 4 * 3, // sizeof(float) * 3
|
||||||
stepMode: 'vertex'
|
stepMode: 'vertex',
|
||||||
};
|
};
|
||||||
const colorBufferDesc: GPUVertexBufferLayout = {
|
const colorBufferDesc: GPUVertexBufferLayout = {
|
||||||
attributes: [colorAttribDesc],
|
attributes: [colorAttribDesc],
|
||||||
arrayStride: 4 * 3, // sizeof(float) * 3
|
arrayStride: 4 * 3, // sizeof(float) * 3
|
||||||
stepMode: 'vertex'
|
stepMode: 'vertex',
|
||||||
};
|
};
|
||||||
|
|
||||||
const depthStencil: GPUDepthStencilState = {
|
const depthStencil: GPUDepthStencilState = {
|
||||||
depthWriteEnabled: true,
|
depthWriteEnabled: true,
|
||||||
depthCompare: 'less',
|
depthCompare: 'less',
|
||||||
format: 'depth24plus-stencil8'
|
format: 'depth24plus-stencil8',
|
||||||
};
|
};
|
||||||
|
|
||||||
const pipelineLayoutDesc = { bindGroupLayouts: [] };
|
const pipelineLayoutDesc = { bindGroupLayouts: [] };
|
||||||
|
|
@ -139,23 +124,23 @@ export default class Renderer {
|
||||||
const vertex: GPUVertexState = {
|
const vertex: GPUVertexState = {
|
||||||
module: this.vertModule,
|
module: this.vertModule,
|
||||||
entryPoint: 'main',
|
entryPoint: 'main',
|
||||||
buffers: [positionBufferDesc, colorBufferDesc]
|
buffers: [positionBufferDesc, colorBufferDesc],
|
||||||
};
|
};
|
||||||
|
|
||||||
const colorState: GPUColorTargetState = {
|
const colorState: GPUColorTargetState = {
|
||||||
format: 'bgra8unorm'
|
format: 'bgra8unorm',
|
||||||
};
|
};
|
||||||
|
|
||||||
const fragment: GPUFragmentState = {
|
const fragment: GPUFragmentState = {
|
||||||
module: this.fragModule,
|
module: this.fragModule,
|
||||||
entryPoint: 'main',
|
entryPoint: 'main',
|
||||||
targets: [colorState]
|
targets: [colorState],
|
||||||
};
|
};
|
||||||
|
|
||||||
const primitive: GPUPrimitiveState = {
|
const primitive: GPUPrimitiveState = {
|
||||||
frontFace: 'cw',
|
frontFace: 'cw',
|
||||||
cullMode: 'none',
|
cullMode: 'none',
|
||||||
topology: 'triangle-list'
|
topology: 'triangle-list',
|
||||||
};
|
};
|
||||||
|
|
||||||
const pipelineDesc: GPURenderPipelineDescriptor = {
|
const pipelineDesc: GPURenderPipelineDescriptor = {
|
||||||
|
|
@ -165,21 +150,19 @@ export default class Renderer {
|
||||||
fragment,
|
fragment,
|
||||||
|
|
||||||
primitive,
|
primitive,
|
||||||
depthStencil
|
depthStencil,
|
||||||
};
|
};
|
||||||
this.pipeline = this.device.createRenderPipeline(pipelineDesc);
|
this.pipeline = this.device.createRenderPipeline(pipelineDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
resizeBackings() {
|
resizeBackings() {
|
||||||
if (!this.context) {
|
if (!this.context) {
|
||||||
this.context = this.canvas.getContext('webgpu');
|
this.context = this.canvas.getContext('webgpu') as any;
|
||||||
const canvasConfig: GPUCanvasConfiguration = {
|
const canvasConfig: GPUCanvasConfiguration = {
|
||||||
device: this.device,
|
device: this.device,
|
||||||
format: 'bgra8unorm',
|
format: 'bgra8unorm',
|
||||||
usage:
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
|
||||||
GPUTextureUsage.RENDER_ATTACHMENT |
|
alphaMode: 'opaque',
|
||||||
GPUTextureUsage.COPY_SRC,
|
|
||||||
alphaMode: 'opaque'
|
|
||||||
};
|
};
|
||||||
this.context.configure(canvasConfig);
|
this.context.configure(canvasConfig);
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +171,7 @@ export default class Renderer {
|
||||||
size: [this.canvas.width, this.canvas.height, 1],
|
size: [this.canvas.width, this.canvas.height, 1],
|
||||||
dimension: '2d',
|
dimension: '2d',
|
||||||
format: 'depth24plus-stencil8',
|
format: 'depth24plus-stencil8',
|
||||||
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
|
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.depthTexture = this.device.createTexture(depthTextureDesc);
|
this.depthTexture = this.device.createTexture(depthTextureDesc);
|
||||||
|
|
@ -196,11 +179,11 @@ export default class Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeCommands() {
|
encodeCommands() {
|
||||||
let colorAttachment: GPURenderPassColorAttachment = {
|
const colorAttachment: GPURenderPassColorAttachment = {
|
||||||
view: this.colorTextureView,
|
view: this.colorTextureView,
|
||||||
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
clearValue: { r: 0, g: 0, b: 0, a: 1 },
|
||||||
loadOp: 'clear',
|
loadOp: 'clear',
|
||||||
storeOp: 'store'
|
storeOp: 'store',
|
||||||
};
|
};
|
||||||
|
|
||||||
const depthAttachment: GPURenderPassDepthStencilAttachment = {
|
const depthAttachment: GPURenderPassDepthStencilAttachment = {
|
||||||
|
|
@ -210,33 +193,20 @@ export default class Renderer {
|
||||||
depthStoreOp: 'store',
|
depthStoreOp: 'store',
|
||||||
stencilClearValue: 0,
|
stencilClearValue: 0,
|
||||||
stencilLoadOp: 'clear',
|
stencilLoadOp: 'clear',
|
||||||
stencilStoreOp: 'store'
|
stencilStoreOp: 'store',
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderPassDesc: GPURenderPassDescriptor = {
|
const renderPassDesc: GPURenderPassDescriptor = {
|
||||||
colorAttachments: [colorAttachment],
|
colorAttachments: [colorAttachment],
|
||||||
depthStencilAttachment: depthAttachment
|
depthStencilAttachment: depthAttachment,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.commandEncoder = this.device.createCommandEncoder();
|
this.commandEncoder = this.device.createCommandEncoder();
|
||||||
|
|
||||||
// 🖌️ Encode drawing commands
|
|
||||||
this.passEncoder = this.commandEncoder.beginRenderPass(renderPassDesc);
|
this.passEncoder = this.commandEncoder.beginRenderPass(renderPassDesc);
|
||||||
this.passEncoder.setPipeline(this.pipeline);
|
this.passEncoder.setPipeline(this.pipeline);
|
||||||
this.passEncoder.setViewport(
|
this.passEncoder.setViewport(0, 0, this.canvas.width, this.canvas.height, 0, 1);
|
||||||
0,
|
this.passEncoder.setScissorRect(0, 0, this.canvas.width, this.canvas.height);
|
||||||
0,
|
|
||||||
this.canvas.width,
|
|
||||||
this.canvas.height,
|
|
||||||
0,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
this.passEncoder.setScissorRect(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
this.canvas.width,
|
|
||||||
this.canvas.height
|
|
||||||
);
|
|
||||||
this.passEncoder.setVertexBuffer(0, this.positionBuffer);
|
this.passEncoder.setVertexBuffer(0, this.positionBuffer);
|
||||||
this.passEncoder.setVertexBuffer(1, this.colorBuffer);
|
this.passEncoder.setVertexBuffer(1, this.colorBuffer);
|
||||||
this.passEncoder.setIndexBuffer(this.indexBuffer, 'uint16');
|
this.passEncoder.setIndexBuffer(this.indexBuffer, 'uint16');
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,13 @@
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"noEmitHelpers": false,
|
"noEmitHelpers": false,
|
||||||
"sourceMap": false,
|
"sourceMap": true,
|
||||||
"strictNullChecks": false,
|
"strictNullChecks": false,
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true
|
"allowSyntheticDefaultImports": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["definitions.d.ts", "src/**/*", "node_modules/@webgpu/types/**/*"],
|
||||||
"definitions.d.ts",
|
|
||||||
"src/**/*",
|
|
||||||
"node_modules/@webgpu/types/**/*"
|
|
||||||
],
|
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"buildOnSave": false
|
"buildOnSave": false
|
||||||
}
|
}
|
||||||
90
webpack.config.js
Normal file
90
webpack.config.js
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
const path = require('path');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
|
const InlineSourceWebpackPlugin = require('inline-source-webpack-plugin');
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
|
||||||
|
module.exports = (env, argv) => ({
|
||||||
|
devtool: argv.mode === 'development' ? 'inline-source-map' : false,
|
||||||
|
entry: {
|
||||||
|
index: './src/index.ts',
|
||||||
|
},
|
||||||
|
watchOptions: {
|
||||||
|
ignored: '**/node_modules',
|
||||||
|
},
|
||||||
|
optimization: {
|
||||||
|
minimizer: [
|
||||||
|
new TerserPlugin({
|
||||||
|
terserOptions: {
|
||||||
|
module: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: './src/index.html',
|
||||||
|
}),
|
||||||
|
new MiniCssExtractPlugin(),
|
||||||
|
argv.mode === 'production'
|
||||||
|
? new InlineSourceWebpackPlugin({
|
||||||
|
compress: true,
|
||||||
|
})
|
||||||
|
: null,
|
||||||
|
new (require('webpack').DefinePlugin)({
|
||||||
|
__CURRENT_DATE__: Date.now(),
|
||||||
|
}),
|
||||||
|
].filter(Boolean),
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.svg$/i,
|
||||||
|
use: 'svg-inline-loader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.wgsl/,
|
||||||
|
type: 'asset/source',
|
||||||
|
generator: {
|
||||||
|
filename: '[name][ext]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\/no-change\//i,
|
||||||
|
type: 'asset/resource',
|
||||||
|
generator: {
|
||||||
|
filename: '[name][ext]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/i,
|
||||||
|
use: [
|
||||||
|
MiniCssExtractPlugin.loader,
|
||||||
|
'css-loader',
|
||||||
|
'resolve-url-loader',
|
||||||
|
{
|
||||||
|
loader: 'sass-loader',
|
||||||
|
options: {
|
||||||
|
sourceMap: true, // required by resolve-url-loader
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.ts$/,
|
||||||
|
use: 'ts-loader',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: [
|
||||||
|
'.ts',
|
||||||
|
'.js', // required for development
|
||||||
|
],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
clean: true,
|
||||||
|
filename: '[name].js',
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
publicPath: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
112
webpack.ts
112
webpack.ts
|
|
@ -1,112 +0,0 @@
|
||||||
import webpack from 'webpack';
|
|
||||||
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
|
||||||
import path from 'path';
|
|
||||||
import { argv } from 'process';
|
|
||||||
|
|
||||||
let env = process.env['NODE_ENV'];
|
|
||||||
let isProduction =
|
|
||||||
(env && env.match(/production/)) ||
|
|
||||||
argv.reduce((prev, cur) => prev || cur === '--production', false);
|
|
||||||
|
|
||||||
let config: webpack.Configuration = {
|
|
||||||
context: path.join(__dirname, 'src'),
|
|
||||||
entry: {
|
|
||||||
app: './main.ts'
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
filename: 'main.js',
|
|
||||||
path: path.resolve(__dirname, 'dist')
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
extensions: ['.ts', '.tsx', 'js'],
|
|
||||||
modules: [path.resolve(__dirname, 'src'), 'node_modules']
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.ts/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
loader: 'ts-loader',
|
|
||||||
options: {
|
|
||||||
transpileOnly: true,
|
|
||||||
compilerOptions: {
|
|
||||||
isolatedModules: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.wgsl/,
|
|
||||||
type: 'asset/source'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
node: false,
|
|
||||||
plugins: [
|
|
||||||
new CleanWebpackPlugin(),
|
|
||||||
new webpack.DefinePlugin({
|
|
||||||
'process.env': {
|
|
||||||
NODE_ENV: JSON.stringify(
|
|
||||||
isProduction ? 'production' : 'development'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
],
|
|
||||||
optimization: {
|
|
||||||
minimize: isProduction ? true : false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start Build
|
|
||||||
*/
|
|
||||||
const compiler: webpack.Compiler = webpack(config);
|
|
||||||
|
|
||||||
if (!argv.reduce((prev, cur) => prev || cur === '--watch', false)) {
|
|
||||||
compiler.run((err, stats) => {
|
|
||||||
if (err) return console.error(err);
|
|
||||||
|
|
||||||
if (stats.hasErrors()) {
|
|
||||||
let statsJson = stats.toJson();
|
|
||||||
console.log(
|
|
||||||
'❌' + ' · Error · ' + 'webgpu-seed failed to compile:'
|
|
||||||
);
|
|
||||||
for (let error of statsJson.errors) {
|
|
||||||
console.log(error.message);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(
|
|
||||||
'✔️️' +
|
|
||||||
' · Success · ' +
|
|
||||||
'webgpu-seed' +
|
|
||||||
(isProduction ? ' (production) ' : ' (development) ') +
|
|
||||||
'built in ' +
|
|
||||||
(+stats.endTime - +stats.startTime + ' ms.')
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
compiler.watch({}, (err, stats) => {
|
|
||||||
if (err) return console.error(err);
|
|
||||||
|
|
||||||
if (stats.hasErrors()) {
|
|
||||||
let statsJson = stats.toJson();
|
|
||||||
console.log(
|
|
||||||
'❌' + ' · Error · ' + 'webgpu-seed failed to compile:'
|
|
||||||
);
|
|
||||||
for (let error of statsJson.errors) {
|
|
||||||
console.log(error.message);
|
|
||||||
}
|
|
||||||
console.log('\n👀 · Watching for changes... · \n');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(
|
|
||||||
'✔️️' +
|
|
||||||
' · Success · ' +
|
|
||||||
'webgpu-seed' +
|
|
||||||
(isProduction ? ' (production) ' : ' (development) ') +
|
|
||||||
'built in ' +
|
|
||||||
(+stats.endTime - +stats.startTime + ' ms.') +
|
|
||||||
'\n👀 · Watching for changes... · \n'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue