Spaces:
Running
Running
π
Browse files- index.html +18 -61
index.html
CHANGED
@@ -126,38 +126,24 @@
|
|
126 |
function generateGlyphVerticesForText(s, colors = [[1, 1, 1, 1]]) {
|
127 |
const vertexData = new Float32Array(maxGlyphs * floatsPerVertex * vertsPerGlyph);
|
128 |
const glyphUVWidth = glyphWidth / glyphCanvas.width;
|
129 |
-
const
|
130 |
-
let offset = 0;
|
131 |
-
let
|
132 |
-
let x1 = 1;
|
133 |
-
let y0 = 0;
|
134 |
-
let y1 = 1;
|
135 |
-
let width = 0;
|
136 |
|
137 |
const addVertex = (x, y, u, v, r, g, b, a) => {
|
138 |
-
vertexData[
|
139 |
-
|
140 |
-
vertexData[offset++] = u;
|
141 |
-
vertexData[offset++] = v;
|
142 |
-
vertexData[offset++] = r;
|
143 |
-
vertexData[offset++] = g;
|
144 |
-
vertexData[offset++] = b;
|
145 |
-
vertexData[offset++] = a;
|
146 |
};
|
147 |
|
148 |
-
const spacing = 0.55;
|
149 |
-
let colorNdx = 0;
|
150 |
for (let i = 0; i < s.length; ++i) {
|
151 |
-
// convert char code to texcoords for glyph texture
|
152 |
const c = s.charCodeAt(i);
|
153 |
if (c >= 33) {
|
154 |
-
const
|
155 |
-
const
|
156 |
-
const glyphY = Math.floor(cNdx / glyphsAcrossTexture);
|
157 |
const u0 = (glyphX * glyphWidth) / glyphCanvas.width;
|
158 |
-
const
|
159 |
const u1 = u0 + glyphUVWidth;
|
160 |
-
const
|
161 |
width = Math.max(x1, width);
|
162 |
|
163 |
addVertex(x0, y0, u0, v0, ...colors[colorNdx]);
|
@@ -167,37 +153,24 @@
|
|
167 |
} else {
|
168 |
colorNdx = (colorNdx + 1) % colors.length;
|
169 |
if (c === 10) {
|
170 |
-
x0 = 0;
|
171 |
-
x1 = 1;
|
172 |
-
y0 = y0 - 1;
|
173 |
-
y1 = y0 + 1;
|
174 |
continue;
|
175 |
}
|
176 |
}
|
177 |
-
x0 = x0 +
|
178 |
-
x1 = x0 + 1;
|
179 |
}
|
180 |
|
181 |
-
return {
|
182 |
-
vertexData,
|
183 |
-
numGlyphs: offset / floatsPerVertex,
|
184 |
-
width,
|
185 |
-
height: y1,
|
186 |
-
};
|
187 |
}
|
188 |
|
189 |
const { vertexData, numGlyphs, width, height } = generateGlyphVerticesForText(
|
190 |
'Hello\nworld!\nText in\nWebGPU!', [
|
191 |
-
[1, 1, 0, 1],
|
192 |
-
[0, 1, 1, 1],
|
193 |
-
[1, 0, 1, 1],
|
194 |
-
[1, 0, 0, 1],
|
195 |
-
[0, .5, 1, 1],
|
196 |
]);
|
197 |
device.queue.writeBuffer(vertexBuffer, 0, vertexData);
|
198 |
|
199 |
const pipeline = device.createRenderPipeline({
|
200 |
-
label: '
|
201 |
layout: 'auto',
|
202 |
vertex: {
|
203 |
module,
|
@@ -206,9 +179,9 @@
|
|
206 |
{
|
207 |
arrayStride: vertexSize,
|
208 |
attributes: [
|
209 |
-
{ shaderLocation: 0, offset: 0, format: 'float32x2' },
|
210 |
-
{ shaderLocation: 1, offset: 8, format: 'float32x2' },
|
211 |
-
{ shaderLocation: 2, offset: 16, format: 'float32x4' }
|
212 |
],
|
213 |
},
|
214 |
],
|
@@ -216,23 +189,7 @@
|
|
216 |
fragment: {
|
217 |
module,
|
218 |
entryPoint: 'fs',
|
219 |
-
targets: [
|
220 |
-
{
|
221 |
-
format: presentationFormat,
|
222 |
-
blend: {
|
223 |
-
color: {
|
224 |
-
srcFactor: 'one',
|
225 |
-
dstFactor: 'one-minus-src-alpha',
|
226 |
-
operation: 'add',
|
227 |
-
},
|
228 |
-
alpha: {
|
229 |
-
srcFactor: 'one',
|
230 |
-
dstFactor: 'one-minus-src-alpha',
|
231 |
-
operation: 'add',
|
232 |
-
},
|
233 |
-
},
|
234 |
-
},
|
235 |
-
],
|
236 |
},
|
237 |
});
|
238 |
|
|
|
126 |
function generateGlyphVerticesForText(s, colors = [[1, 1, 1, 1]]) {
|
127 |
const vertexData = new Float32Array(maxGlyphs * floatsPerVertex * vertsPerGlyph);
|
128 |
const glyphUVWidth = glyphWidth / glyphCanvas.width;
|
129 |
+
const glyphUVHeight = glyphHeight / glyphCanvas.height;
|
130 |
+
let offset = 0, x0 = 0, y0 = 0, x1 = 1, y1 = 1, width = 0;
|
131 |
+
let colorNdx = 0;
|
|
|
|
|
|
|
|
|
132 |
|
133 |
const addVertex = (x, y, u, v, r, g, b, a) => {
|
134 |
+
vertexData.set([x, y, u, v, r, g, b, a], offset);
|
135 |
+
offset += 8;
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
};
|
137 |
|
|
|
|
|
138 |
for (let i = 0; i < s.length; ++i) {
|
|
|
139 |
const c = s.charCodeAt(i);
|
140 |
if (c >= 33) {
|
141 |
+
const glyphX = (c - 33) % glyphsAcrossTexture;
|
142 |
+
const glyphY = Math.floor((c - 33) / glyphsAcrossTexture);
|
|
|
143 |
const u0 = (glyphX * glyphWidth) / glyphCanvas.width;
|
144 |
+
const v0 = ((glyphY + 1) * glyphHeight) / glyphCanvas.height;
|
145 |
const u1 = u0 + glyphUVWidth;
|
146 |
+
const v1 = v0 - glyphUVHeight;
|
147 |
width = Math.max(x1, width);
|
148 |
|
149 |
addVertex(x0, y0, u0, v0, ...colors[colorNdx]);
|
|
|
153 |
} else {
|
154 |
colorNdx = (colorNdx + 1) % colors.length;
|
155 |
if (c === 10) {
|
156 |
+
x0 = 0; x1 = 1; y0--; y1 = y0 + 1;
|
|
|
|
|
|
|
157 |
continue;
|
158 |
}
|
159 |
}
|
160 |
+
x0 += 0.55; x1 = x0 + 1;
|
|
|
161 |
}
|
162 |
|
163 |
+
return { vertexData, numGlyphs: offset / floatsPerVertex, width, height: y1 };
|
|
|
|
|
|
|
|
|
|
|
164 |
}
|
165 |
|
166 |
const { vertexData, numGlyphs, width, height } = generateGlyphVerticesForText(
|
167 |
'Hello\nworld!\nText in\nWebGPU!', [
|
168 |
+
[1, 1, 0, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 0, 0, 1], [0, .5, 1, 1],
|
|
|
|
|
|
|
|
|
169 |
]);
|
170 |
device.queue.writeBuffer(vertexBuffer, 0, vertexData);
|
171 |
|
172 |
const pipeline = device.createRenderPipeline({
|
173 |
+
label: 'textured quad pipeline',
|
174 |
layout: 'auto',
|
175 |
vertex: {
|
176 |
module,
|
|
|
179 |
{
|
180 |
arrayStride: vertexSize,
|
181 |
attributes: [
|
182 |
+
{ shaderLocation: 0, offset: 0, format: 'float32x2' }, // position
|
183 |
+
{ shaderLocation: 1, offset: 8, format: 'float32x2' }, // texcoord
|
184 |
+
{ shaderLocation: 2, offset: 16, format: 'float32x4' } // color
|
185 |
],
|
186 |
},
|
187 |
],
|
|
|
189 |
fragment: {
|
190 |
module,
|
191 |
entryPoint: 'fs',
|
192 |
+
targets: [{ format: presentationFormat }],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
},
|
194 |
});
|
195 |
|