p3nGu1nZz commited on
Commit
8e21624
·
1 Parent(s): 4313cb9

move vars to local scope

Browse files
Files changed (1) hide show
  1. index.html +93 -62
index.html CHANGED
@@ -14,84 +14,66 @@
14
  import { fetchShaderCode, generateGlyphTextureAtlas } from './utility.js';
15
  import { CONFIG } from './config.js';
16
  import { CANVAS, CTX, COLORS, RENDER_PASS_DESCRIPTOR } from './constants.js';
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  async function main() {
18
  const adapter = await navigator.gpu?.requestAdapter();
19
- const device = await adapter?.requestDevice();
20
  if (!device) {
21
  alert('need a browser that supports WebGPU');
22
  return;
23
  }
24
- const canvas = document.querySelector('canvas');
25
- const context = canvas.getContext('webgpu');
26
- const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
27
  context.configure({
28
  device,
29
  format: presentationFormat,
30
  });
 
31
  const shaderCode = await fetchShaderCode('shaders.wgsl');
32
  const module = device.createShaderModule({
33
  label: 'textured quad shaders',
34
  code: shaderCode,
35
  });
 
36
  const glyphCanvas = generateGlyphTextureAtlas(CANVAS, CTX, CONFIG);
37
  document.body.appendChild(glyphCanvas);
38
  glyphCanvas.style.backgroundColor = '#222';
 
39
  const vertexSize = CONFIG.floatsPerVertex * 4;
40
  const vertexBufferSize = CONFIG.maxGlyphs * CONFIG.vertsPerGlyph * vertexSize;
41
- const vertexBuffer = device.createBuffer({
42
  label: 'vertices',
43
  size: vertexBufferSize,
44
  usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
45
  });
46
- const indexBuffer = device.createBuffer({
 
47
  label: 'indices',
48
  size: CONFIG.maxGlyphs * CONFIG.vertsPerGlyph * 4,
49
  usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
50
  });
 
51
  const indices = Array.from({ length: CONFIG.maxGlyphs * 6 }, (_, i) => {
52
  const ndx = Math.floor(i / 6) * 4;
53
  return (i % 6 < 3 ? [ndx, ndx + 1, ndx + 2] : [ndx + 2, ndx + 1, ndx + 3])[i % 3];
54
  });
55
  device.queue.writeBuffer(indexBuffer, 0, new Uint32Array(indices));
56
- function generateGlyphVerticesForText(s, COLORS = [[1, 1, 1, 1]]) {
57
- const vertexData = new Float32Array(CONFIG.maxGlyphs * CONFIG.floatsPerVertex * CONFIG.vertsPerGlyph);
58
- const glyphUVWidth = CONFIG.glyphWidth / glyphCanvas.width;
59
- const glyphUVHeight = CONFIG.glyphHeight / glyphCanvas.height;
60
- let offset = 0, x0 = 0, y0 = 0, x1 = 1, y1 = 1, width = 0;
61
- let colorNdx = 0;
62
- const addVertex = (x, y, u, v, color) => {
63
- vertexData.set([x, y, u, v, ...color], offset);
64
- offset += 8;
65
- };
66
- for (let i = 0; i < s.length; ++i) {
67
- const c = s.charCodeAt(i);
68
- if (c >= 33) {
69
- const cIndex = c - 33;
70
- const glyphX = cIndex % CONFIG.glyphsAcrossTexture;
71
- const glyphY = Math.floor(cIndex / CONFIG.glyphsAcrossTexture);
72
- const u0 = glyphX * CONFIG.glyphWidth / glyphCanvas.width;
73
- const v1 = glyphY * CONFIG.glyphHeight / glyphCanvas.height;
74
- const u1 = u0 + glyphUVWidth;
75
- const v0 = v1 + glyphUVHeight;
76
- width = Math.max(x1, width);
77
- addVertex(x0, y0, u0, v0, COLORS[colorNdx]);
78
- addVertex(x1, y0, u1, v0, COLORS[colorNdx]);
79
- addVertex(x0, y1, u0, v1, COLORS[colorNdx]);
80
- addVertex(x1, y1, u1, v1, COLORS[colorNdx]);
81
- } else {
82
- colorNdx = (colorNdx + 1) % COLORS.length;
83
- if (c === 10) { // Newline
84
- x0 = 0; x1 = 1; y0--; y1 = y0 + 1;
85
- continue;
86
- }
87
- }
88
- x0 += 0.55; x1 = x0 + 1;
89
- }
90
- return { vertexData, numGlyphs: offset / CONFIG.floatsPerVertex, width, height: y1 };
91
- }
92
- const { vertexData, numGlyphs, width, height } = generateGlyphVerticesForText('Hello\nworld!\nText in\nWebGPU!', COLORS);
93
  device.queue.writeBuffer(vertexBuffer, 0, vertexData);
94
- const pipeline = device.createRenderPipeline({
 
95
  label: 'textured quad pipeline',
96
  layout: 'auto',
97
  vertex: {
@@ -120,32 +102,23 @@
120
  }],
121
  },
122
  });
123
- function createTextureFromSource(device, source, options = {}) {
124
- const texture = device.createTexture({
125
- format: 'rgba8unorm',
126
- size: [source.width, source.height],
127
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
128
- });
129
- device.queue.copyExternalImageToTexture(
130
- { source, flipY: options.flipY },
131
- { texture, premultipliedAlpha: true },
132
- { width: source.width, height: source.height }
133
- );
134
- return texture;
135
- }
136
- const texture = createTextureFromSource(device, glyphCanvas, { mips: true });
137
- const sampler = device.createSampler({
138
  minFilter: 'linear',
139
  magFilter: 'linear'
140
  });
141
- const uniformBuffer = device.createBuffer({
 
142
  label: 'uniforms for quad',
143
  size: CONFIG.uniformBufferSize,
144
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
145
  });
 
146
  const uniformValues = new Float32Array(CONFIG.uniformBufferSize / 4);
147
  const matrix = uniformValues.subarray(0, 16);
148
- const bindGroup = device.createBindGroup({
 
149
  layout: pipeline.getBindGroupLayout(0),
150
  entries: [
151
  { binding: 0, resource: sampler },
@@ -153,6 +126,7 @@
153
  { binding: 2, resource: { buffer: uniformBuffer } },
154
  ],
155
  });
 
156
  function render(time) {
157
  time *= CONFIG.time.phase;
158
  const fov = 60 * Math.PI / 180;
@@ -175,10 +149,67 @@
175
  device.queue.submit([encoder.finish()]);
176
  requestAnimationFrame(render);
177
  }
 
178
  requestAnimationFrame(render);
179
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  main();
181
  </script>
182
  </body>
183
 
184
- </html>
 
14
  import { fetchShaderCode, generateGlyphTextureAtlas } from './utility.js';
15
  import { CONFIG } from './config.js';
16
  import { CANVAS, CTX, COLORS, RENDER_PASS_DESCRIPTOR } from './constants.js';
17
+
18
+ const canvas = document.querySelector('canvas');
19
+ const context = canvas.getContext('webgpu');
20
+ const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
21
+ let device;
22
+ let pipeline;
23
+ let vertexBuffer;
24
+ let indexBuffer;
25
+ let uniformBuffer;
26
+ let texture;
27
+ let sampler;
28
+ let bindGroup;
29
+
30
  async function main() {
31
  const adapter = await navigator.gpu?.requestAdapter();
32
+ device = await adapter?.requestDevice();
33
  if (!device) {
34
  alert('need a browser that supports WebGPU');
35
  return;
36
  }
37
+
 
 
38
  context.configure({
39
  device,
40
  format: presentationFormat,
41
  });
42
+
43
  const shaderCode = await fetchShaderCode('shaders.wgsl');
44
  const module = device.createShaderModule({
45
  label: 'textured quad shaders',
46
  code: shaderCode,
47
  });
48
+
49
  const glyphCanvas = generateGlyphTextureAtlas(CANVAS, CTX, CONFIG);
50
  document.body.appendChild(glyphCanvas);
51
  glyphCanvas.style.backgroundColor = '#222';
52
+
53
  const vertexSize = CONFIG.floatsPerVertex * 4;
54
  const vertexBufferSize = CONFIG.maxGlyphs * CONFIG.vertsPerGlyph * vertexSize;
55
+ vertexBuffer = device.createBuffer({
56
  label: 'vertices',
57
  size: vertexBufferSize,
58
  usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
59
  });
60
+
61
+ indexBuffer = device.createBuffer({
62
  label: 'indices',
63
  size: CONFIG.maxGlyphs * CONFIG.vertsPerGlyph * 4,
64
  usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
65
  });
66
+
67
  const indices = Array.from({ length: CONFIG.maxGlyphs * 6 }, (_, i) => {
68
  const ndx = Math.floor(i / 6) * 4;
69
  return (i % 6 < 3 ? [ndx, ndx + 1, ndx + 2] : [ndx + 2, ndx + 1, ndx + 3])[i % 3];
70
  });
71
  device.queue.writeBuffer(indexBuffer, 0, new Uint32Array(indices));
72
+
73
+ const { vertexData, numGlyphs, width, height } = generateGlyphVerticesForText('Hello\nworld!\nText in\nWebGPU!', COLORS, glyphCanvas);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  device.queue.writeBuffer(vertexBuffer, 0, vertexData);
75
+
76
+ pipeline = device.createRenderPipeline({
77
  label: 'textured quad pipeline',
78
  layout: 'auto',
79
  vertex: {
 
102
  }],
103
  },
104
  });
105
+
106
+ texture = createTextureFromSource(device, glyphCanvas, { mips: true });
107
+ sampler = device.createSampler({
 
 
 
 
 
 
 
 
 
 
 
 
108
  minFilter: 'linear',
109
  magFilter: 'linear'
110
  });
111
+
112
+ uniformBuffer = device.createBuffer({
113
  label: 'uniforms for quad',
114
  size: CONFIG.uniformBufferSize,
115
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
116
  });
117
+
118
  const uniformValues = new Float32Array(CONFIG.uniformBufferSize / 4);
119
  const matrix = uniformValues.subarray(0, 16);
120
+
121
+ bindGroup = device.createBindGroup({
122
  layout: pipeline.getBindGroupLayout(0),
123
  entries: [
124
  { binding: 0, resource: sampler },
 
126
  { binding: 2, resource: { buffer: uniformBuffer } },
127
  ],
128
  });
129
+
130
  function render(time) {
131
  time *= CONFIG.time.phase;
132
  const fov = 60 * Math.PI / 180;
 
149
  device.queue.submit([encoder.finish()]);
150
  requestAnimationFrame(render);
151
  }
152
+
153
  requestAnimationFrame(render);
154
  }
155
+
156
+ function generateGlyphVerticesForText(s, COLORS, glyphCanvas) {
157
+ const vertexData = new Float32Array(CONFIG.maxGlyphs * CONFIG.floatsPerVertex * CONFIG.vertsPerGlyph);
158
+ const glyphUVWidth = CONFIG.glyphWidth / glyphCanvas.width;
159
+ const glyphUVHeight = CONFIG.glyphHeight / glyphCanvas.height;
160
+ let offset = 0, x0 = 0, y0 = 0, x1 = 1, y1 = 1, width = 0;
161
+ let colorNdx = 0;
162
+
163
+ const addVertex = (x, y, u, v, color) => {
164
+ vertexData.set([x, y, u, v, ...color], offset);
165
+ offset += 8;
166
+ };
167
+
168
+ for (let i = 0; i < s.length; ++i) {
169
+ const c = s.charCodeAt(i);
170
+ if (c >= 33) {
171
+ const cIndex = c - 33;
172
+ const glyphX = cIndex % CONFIG.glyphsAcrossTexture;
173
+ const glyphY = Math.floor(cIndex / CONFIG.glyphsAcrossTexture);
174
+ const u0 = glyphX * CONFIG.glyphWidth / glyphCanvas.width;
175
+ const v1 = glyphY * CONFIG.glyphHeight / glyphCanvas.height;
176
+ const u1 = u0 + glyphUVWidth;
177
+ const v0 = v1 + glyphUVHeight;
178
+ width = Math.max(x1, width);
179
+ addVertex(x0, y0, u0, v0, COLORS[colorNdx]);
180
+ addVertex(x1, y0, u1, v0, COLORS[colorNdx]);
181
+ addVertex(x0, y1, u0, v1, COLORS[colorNdx]);
182
+ addVertex(x1, y1, u1, v1, COLORS[colorNdx]);
183
+ } else {
184
+ colorNdx = (colorNdx + 1) % COLORS.length;
185
+ if (c === 10) { // Newline
186
+ x0 = 0; x1 = 1; y0--; y1 = y0 + 1;
187
+ continue;
188
+ }
189
+ }
190
+ x0 += 0.55; x1 = x0 + 1;
191
+ }
192
+ return { vertexData, numGlyphs: offset / CONFIG.floatsPerVertex, width, height: y1 };
193
+ }
194
+
195
+ function createTextureFromSource(device, source, options = {}) {
196
+ const texture = device.createTexture({
197
+ format: 'rgba8unorm',
198
+ size: [source.width, source.height],
199
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
200
+ });
201
+
202
+ device.queue.copyExternalImageToTexture(
203
+ { source, flipY: options.flipY },
204
+ { texture, premultipliedAlpha: true },
205
+ { width: source.width, height: source.height }
206
+ );
207
+
208
+ return texture;
209
+ }
210
+
211
  main();
212
  </script>
213
  </body>
214
 
215
+ </html>