q5 2.20.10 → 2.21.0
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/README.md +4 -4
- package/deno.json +1 -1
- package/package.json +3 -3
- package/q5.d.ts +1141 -920
- package/q5.js +261 -136
- package/q5.min.js +2 -2
package/q5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* q5.js
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.21
|
|
4
4
|
* @author quinton-ashley, Tezumie, and LingDong-
|
|
5
5
|
* @license LGPL-3.0
|
|
6
6
|
* @class Q5
|
|
@@ -314,7 +314,7 @@ function createCanvas(w, h, opt) {
|
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
Q5.version = Q5.VERSION = '2.
|
|
317
|
+
Q5.version = Q5.VERSION = '2.21';
|
|
318
318
|
|
|
319
319
|
if (typeof document == 'object') {
|
|
320
320
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -837,7 +837,7 @@ Q5.renderers.c2d.canvas = ($, q) => {
|
|
|
837
837
|
_popStyles();
|
|
838
838
|
};
|
|
839
839
|
};
|
|
840
|
-
Q5.renderers.c2d.
|
|
840
|
+
Q5.renderers.c2d.shapes = ($) => {
|
|
841
841
|
$._doStroke = true;
|
|
842
842
|
$._doFill = true;
|
|
843
843
|
$._strokeSet = false;
|
|
@@ -1580,7 +1580,7 @@ Q5.renderers.c2d.image = ($, q) => {
|
|
|
1580
1580
|
|
|
1581
1581
|
$._saveCanvas = async (data, ext) => {
|
|
1582
1582
|
data = data.canvas || data;
|
|
1583
|
-
if (data instanceof
|
|
1583
|
+
if (data instanceof OffscreenCanvas) {
|
|
1584
1584
|
const blob = await data.convertToBlob({ type: 'image/' + ext });
|
|
1585
1585
|
|
|
1586
1586
|
return await new Promise((resolve) => {
|
|
@@ -1786,7 +1786,7 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
1786
1786
|
};
|
|
1787
1787
|
|
|
1788
1788
|
$.textFont = (x) => {
|
|
1789
|
-
if (typeof x != 'string') x = x.family;
|
|
1789
|
+
if (x && typeof x != 'string') x = x.family;
|
|
1790
1790
|
if (!x || x == font) return font;
|
|
1791
1791
|
font = x;
|
|
1792
1792
|
fontMod = true;
|
|
@@ -4494,6 +4494,23 @@ for (let k of ['fromAngle', 'fromAngles', 'random2D', 'random3D']) {
|
|
|
4494
4494
|
Q5.renderers.webgpu = {};
|
|
4495
4495
|
|
|
4496
4496
|
Q5.renderers.webgpu.canvas = ($, q) => {
|
|
4497
|
+
$._baseShaderCode = /* wgsl */ `
|
|
4498
|
+
struct Q5 {
|
|
4499
|
+
width: f32,
|
|
4500
|
+
height: f32,
|
|
4501
|
+
halfWidth: f32,
|
|
4502
|
+
halfHeight: f32,
|
|
4503
|
+
pixelDensity: f32,
|
|
4504
|
+
frameCount: f32,
|
|
4505
|
+
time: f32,
|
|
4506
|
+
deltaTime: f32,
|
|
4507
|
+
mouseX: f32,
|
|
4508
|
+
mouseY: f32,
|
|
4509
|
+
mouseIsPressed: f32,
|
|
4510
|
+
keyCode: f32,
|
|
4511
|
+
keyIsPressed: f32
|
|
4512
|
+
}`;
|
|
4513
|
+
|
|
4497
4514
|
let c = $.canvas;
|
|
4498
4515
|
|
|
4499
4516
|
c.width = $.width = 500;
|
|
@@ -4535,7 +4552,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4535
4552
|
entries: [
|
|
4536
4553
|
{
|
|
4537
4554
|
binding: 0,
|
|
4538
|
-
visibility: GPUShaderStage.VERTEX,
|
|
4555
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
4539
4556
|
buffer: { type: 'uniform' }
|
|
4540
4557
|
},
|
|
4541
4558
|
{
|
|
@@ -4554,7 +4571,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4554
4571
|
$.bindGroupLayouts = [mainLayout];
|
|
4555
4572
|
|
|
4556
4573
|
let uniformBuffer = Q5.device.createBuffer({
|
|
4557
|
-
size:
|
|
4574
|
+
size: 64, // Size of four floats
|
|
4558
4575
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
4559
4576
|
});
|
|
4560
4577
|
|
|
@@ -4624,8 +4641,6 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4624
4641
|
|
|
4625
4642
|
$.ctx.configure(opt);
|
|
4626
4643
|
|
|
4627
|
-
Q5.device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([$.canvas.hw, $.canvas.hh]));
|
|
4628
|
-
|
|
4629
4644
|
createMainView();
|
|
4630
4645
|
return c;
|
|
4631
4646
|
};
|
|
@@ -4888,9 +4903,6 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4888
4903
|
};
|
|
4889
4904
|
|
|
4890
4905
|
$._calcBox = (x, y, w, h, mode) => {
|
|
4891
|
-
let hw = w / 2;
|
|
4892
|
-
let hh = h / 2;
|
|
4893
|
-
|
|
4894
4906
|
// left, right, top, bottom
|
|
4895
4907
|
let l, r, t, b;
|
|
4896
4908
|
if (!mode || mode == 'corner') {
|
|
@@ -4899,6 +4911,8 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4899
4911
|
t = -y;
|
|
4900
4912
|
b = -(y + h);
|
|
4901
4913
|
} else if (mode == 'center') {
|
|
4914
|
+
let hw = w / 2,
|
|
4915
|
+
hh = h / 2;
|
|
4902
4916
|
l = x - hw;
|
|
4903
4917
|
r = x + hw;
|
|
4904
4918
|
t = -(y - hh);
|
|
@@ -5028,7 +5042,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
5028
5042
|
$._render = () => {
|
|
5029
5043
|
let transformBuffer = Q5.device.createBuffer({
|
|
5030
5044
|
size: matrices.length * MATRIX_SIZE * 4, // 4 bytes per float
|
|
5031
|
-
usage: GPUBufferUsage.STORAGE
|
|
5045
|
+
usage: GPUBufferUsage.STORAGE,
|
|
5032
5046
|
mappedAtCreation: true
|
|
5033
5047
|
});
|
|
5034
5048
|
|
|
@@ -5037,13 +5051,31 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
5037
5051
|
|
|
5038
5052
|
let colorsBuffer = Q5.device.createBuffer({
|
|
5039
5053
|
size: colorStackIndex * 4,
|
|
5040
|
-
usage: GPUBufferUsage.STORAGE
|
|
5054
|
+
usage: GPUBufferUsage.STORAGE,
|
|
5041
5055
|
mappedAtCreation: true
|
|
5042
5056
|
});
|
|
5043
5057
|
|
|
5044
5058
|
new Float32Array(colorsBuffer.getMappedRange()).set(colorStack.slice(0, colorStackIndex));
|
|
5045
5059
|
colorsBuffer.unmap();
|
|
5046
5060
|
|
|
5061
|
+
$._uniforms = [
|
|
5062
|
+
$.width,
|
|
5063
|
+
$.height,
|
|
5064
|
+
$.halfWidth,
|
|
5065
|
+
$.halfHeight,
|
|
5066
|
+
$._pixelDensity,
|
|
5067
|
+
$.frameCount,
|
|
5068
|
+
performance.now(),
|
|
5069
|
+
$.deltaTime,
|
|
5070
|
+
$.mouseX,
|
|
5071
|
+
$.mouseY,
|
|
5072
|
+
$.mouseIsPressed ? 1 : 0,
|
|
5073
|
+
$.keyCode,
|
|
5074
|
+
$.keyIsPressed ? 1 : 0
|
|
5075
|
+
];
|
|
5076
|
+
|
|
5077
|
+
Q5.device.queue.writeBuffer(uniformBuffer, 0, new Float32Array($._uniforms));
|
|
5078
|
+
|
|
5047
5079
|
let mainBindGroup = Q5.device.createBindGroup({
|
|
5048
5080
|
layout: mainLayout,
|
|
5049
5081
|
entries: [
|
|
@@ -5070,18 +5102,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
5070
5102
|
pass.setPipeline($._pipelines[curPipelineIndex]);
|
|
5071
5103
|
}
|
|
5072
5104
|
|
|
5073
|
-
if (curPipelineIndex ==
|
|
5074
|
-
// draw a shape
|
|
5075
|
-
// v is the number of vertices
|
|
5076
|
-
pass.draw(v, 1, drawVertOffset);
|
|
5077
|
-
drawVertOffset += v;
|
|
5078
|
-
} else if (curPipelineIndex <= 2) {
|
|
5079
|
-
// draw an image or video frame
|
|
5080
|
-
// v is the texture index
|
|
5081
|
-
pass.setBindGroup(1, $._textureBindGroups[v]);
|
|
5082
|
-
pass.draw(4, 1, imageVertOffset);
|
|
5083
|
-
imageVertOffset += 4;
|
|
5084
|
-
} else if (curPipelineIndex == 3) {
|
|
5105
|
+
if (curPipelineIndex == 3 || curPipelineIndex >= 400) {
|
|
5085
5106
|
// draw text
|
|
5086
5107
|
let o = drawStack[i + 2];
|
|
5087
5108
|
pass.setBindGroup(1, $._fonts[o].bindGroup);
|
|
@@ -5091,6 +5112,17 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
5091
5112
|
pass.draw(4, v, 0, textCharOffset);
|
|
5092
5113
|
textCharOffset += v;
|
|
5093
5114
|
i++;
|
|
5115
|
+
} else if (curPipelineIndex == 1 || curPipelineIndex == 2 || curPipelineIndex >= 200) {
|
|
5116
|
+
// draw an image or video frame
|
|
5117
|
+
// v is the texture index
|
|
5118
|
+
pass.setBindGroup(1, $._textureBindGroups[v]);
|
|
5119
|
+
pass.draw(4, 1, imageVertOffset);
|
|
5120
|
+
imageVertOffset += 4;
|
|
5121
|
+
} else if (curPipelineIndex == 0 || curPipelineIndex >= 100) {
|
|
5122
|
+
// draw a shape
|
|
5123
|
+
// v is the number of vertices
|
|
5124
|
+
pass.draw(v, 1, drawVertOffset);
|
|
5125
|
+
drawVertOffset += v;
|
|
5094
5126
|
}
|
|
5095
5127
|
}
|
|
5096
5128
|
};
|
|
@@ -5134,7 +5166,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
5134
5166
|
q.pass = $.encoder = null;
|
|
5135
5167
|
|
|
5136
5168
|
// clear the stacks for the next frame
|
|
5137
|
-
|
|
5169
|
+
drawStack.splice(0, drawStack.length);
|
|
5138
5170
|
colorIndex = 1;
|
|
5139
5171
|
colorStackIndex = 8;
|
|
5140
5172
|
matrices = [matrices[0]];
|
|
@@ -5149,7 +5181,7 @@ Q5.initWebGPU = async () => {
|
|
|
5149
5181
|
console.warn('q5 WebGPU not supported on this browser! Use Google Chrome or Edge.');
|
|
5150
5182
|
return false;
|
|
5151
5183
|
}
|
|
5152
|
-
if (!Q5.
|
|
5184
|
+
if (!Q5.requestedGPU) {
|
|
5153
5185
|
let adapter = await navigator.gpu.requestAdapter();
|
|
5154
5186
|
if (!adapter) {
|
|
5155
5187
|
console.warn('q5 WebGPU could not start! No appropriate GPUAdapter found, vulkan may need to be enabled.');
|
|
@@ -5172,62 +5204,63 @@ Q5.webgpu = async function (scope, parent) {
|
|
|
5172
5204
|
}
|
|
5173
5205
|
return new Q5(scope, parent, 'webgpu');
|
|
5174
5206
|
};
|
|
5175
|
-
Q5.renderers.webgpu.
|
|
5176
|
-
|
|
5177
|
-
drawStack = $.drawStack,
|
|
5178
|
-
vertexStack = new Float32Array($._graphics ? 1000 : 1e7),
|
|
5179
|
-
vertIndex = 0;
|
|
5180
|
-
const TAU = Math.PI * 2;
|
|
5181
|
-
const HALF_PI = Math.PI / 2;
|
|
5207
|
+
Q5.renderers.webgpu.shapes = ($) => {
|
|
5208
|
+
$._shapesPL = 0;
|
|
5182
5209
|
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
halfHeight: f32
|
|
5187
|
-
}
|
|
5210
|
+
$._shapesShaderCode =
|
|
5211
|
+
$._baseShaderCode +
|
|
5212
|
+
/* wgsl */ `
|
|
5188
5213
|
struct VertexParams {
|
|
5214
|
+
@builtin(vertex_index) vertexIndex : u32,
|
|
5189
5215
|
@location(0) pos: vec2f,
|
|
5190
5216
|
@location(1) colorIndex: f32,
|
|
5191
5217
|
@location(2) matrixIndex: f32
|
|
5192
5218
|
}
|
|
5193
|
-
struct
|
|
5219
|
+
struct FragParams {
|
|
5194
5220
|
@builtin(position) position: vec4f,
|
|
5195
5221
|
@location(0) color: vec4f
|
|
5196
5222
|
}
|
|
5197
5223
|
|
|
5198
|
-
@group(0) @binding(0) var<uniform>
|
|
5224
|
+
@group(0) @binding(0) var<uniform> q: Q5;
|
|
5199
5225
|
@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
|
|
5200
5226
|
@group(0) @binding(2) var<storage> colors : array<vec4f>;
|
|
5201
5227
|
|
|
5202
5228
|
fn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {
|
|
5203
5229
|
var vert = vec4f(pos, 0.0, 1.0);
|
|
5204
5230
|
vert = transforms[i32(matrixIndex)] * vert;
|
|
5205
|
-
vert.x /=
|
|
5206
|
-
vert.y /=
|
|
5231
|
+
vert.x /= q.halfWidth;
|
|
5232
|
+
vert.y /= q.halfHeight;
|
|
5207
5233
|
return vert;
|
|
5208
5234
|
}
|
|
5209
5235
|
|
|
5210
5236
|
@vertex
|
|
5211
|
-
fn vertexMain(v: VertexParams) ->
|
|
5237
|
+
fn vertexMain(v: VertexParams) -> FragParams {
|
|
5212
5238
|
var vert = transformVertex(v.pos, v.matrixIndex);
|
|
5213
5239
|
|
|
5214
|
-
var f:
|
|
5240
|
+
var f: FragParams;
|
|
5215
5241
|
f.position = vert;
|
|
5216
5242
|
f.color = colors[i32(v.colorIndex)];
|
|
5217
5243
|
return f;
|
|
5218
5244
|
}
|
|
5219
5245
|
|
|
5220
5246
|
@fragment
|
|
5221
|
-
fn
|
|
5247
|
+
fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
5222
5248
|
return f.color;
|
|
5223
5249
|
}
|
|
5224
5250
|
`;
|
|
5225
5251
|
|
|
5226
|
-
let
|
|
5227
|
-
label: '
|
|
5228
|
-
code:
|
|
5252
|
+
let shapesShader = Q5.device.createShaderModule({
|
|
5253
|
+
label: 'shapesShader',
|
|
5254
|
+
code: $._shapesShaderCode
|
|
5229
5255
|
});
|
|
5230
5256
|
|
|
5257
|
+
let c = $.canvas,
|
|
5258
|
+
drawStack = $.drawStack,
|
|
5259
|
+
vertexStack = new Float32Array($._graphics ? 1000 : 1e7),
|
|
5260
|
+
vertIndex = 0;
|
|
5261
|
+
const TAU = Math.PI * 2;
|
|
5262
|
+
const HALF_PI = Math.PI / 2;
|
|
5263
|
+
|
|
5231
5264
|
let vertexBufferLayout = {
|
|
5232
5265
|
arrayStride: 16, // 4 floats * 4 bytes
|
|
5233
5266
|
attributes: [
|
|
@@ -5238,21 +5271,21 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5238
5271
|
};
|
|
5239
5272
|
|
|
5240
5273
|
let pipelineLayout = Q5.device.createPipelineLayout({
|
|
5241
|
-
label: '
|
|
5274
|
+
label: 'shapesPipelineLayout',
|
|
5242
5275
|
bindGroupLayouts: $.bindGroupLayouts
|
|
5243
5276
|
});
|
|
5244
5277
|
|
|
5245
5278
|
$._pipelineConfigs[0] = {
|
|
5246
|
-
label: '
|
|
5279
|
+
label: 'shapesPipeline',
|
|
5247
5280
|
layout: pipelineLayout,
|
|
5248
5281
|
vertex: {
|
|
5249
|
-
module:
|
|
5282
|
+
module: shapesShader,
|
|
5250
5283
|
entryPoint: 'vertexMain',
|
|
5251
5284
|
buffers: [vertexBufferLayout]
|
|
5252
5285
|
},
|
|
5253
5286
|
fragment: {
|
|
5254
|
-
module:
|
|
5255
|
-
entryPoint: '
|
|
5287
|
+
module: shapesShader,
|
|
5288
|
+
entryPoint: 'fragMain',
|
|
5256
5289
|
targets: [{ format: 'bgra8unorm', blend: $.blendConfigs.normal }]
|
|
5257
5290
|
},
|
|
5258
5291
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
@@ -5296,7 +5329,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5296
5329
|
v[i++] = ti;
|
|
5297
5330
|
|
|
5298
5331
|
vertIndex = i;
|
|
5299
|
-
drawStack.push(
|
|
5332
|
+
drawStack.push($._shapesPL, 4);
|
|
5300
5333
|
};
|
|
5301
5334
|
|
|
5302
5335
|
const addArc = (x, y, a, b, startAngle, endAngle, n, ci, ti) => {
|
|
@@ -5328,7 +5361,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5328
5361
|
}
|
|
5329
5362
|
|
|
5330
5363
|
vertIndex = i;
|
|
5331
|
-
drawStack.push(
|
|
5364
|
+
drawStack.push($._shapesPL, (n + 1) * 2);
|
|
5332
5365
|
};
|
|
5333
5366
|
|
|
5334
5367
|
const addArcStroke = (x, y, outerA, outerB, innerA, innerB, startAngle, endAngle, n, ci, ti) => {
|
|
@@ -5363,7 +5396,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5363
5396
|
}
|
|
5364
5397
|
|
|
5365
5398
|
vertIndex = i;
|
|
5366
|
-
drawStack.push(
|
|
5399
|
+
drawStack.push($._shapesPL, (n + 1) * 2);
|
|
5367
5400
|
};
|
|
5368
5401
|
|
|
5369
5402
|
$.rectMode = (x) => ($._rectMode = x);
|
|
@@ -5468,6 +5501,13 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5468
5501
|
|
|
5469
5502
|
$.square = (x, y, s) => $.rect(x, y, s, s);
|
|
5470
5503
|
|
|
5504
|
+
$.plane = (x, y, w, h) => {
|
|
5505
|
+
h ??= w;
|
|
5506
|
+
let [l, r, t, b] = $._calcBox(x, y, w, h, 'center');
|
|
5507
|
+
if ($._matrixDirty) $._saveMatrix();
|
|
5508
|
+
addRect(l, t, r, t, r, b, l, b, $._fill, $._matrixIndex);
|
|
5509
|
+
};
|
|
5510
|
+
|
|
5471
5511
|
// prettier-ignore
|
|
5472
5512
|
const getArcSegments = (d) =>
|
|
5473
5513
|
d < 4 ? 6 :
|
|
@@ -5713,7 +5753,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5713
5753
|
addVert(sv[4], sv[5], sv[6], sv[7]); // v1
|
|
5714
5754
|
addVert(sv[12], sv[13], sv[14], sv[15]); // v3
|
|
5715
5755
|
addVert(sv[8], sv[9], sv[10], sv[11]); // v2
|
|
5716
|
-
drawStack.push(
|
|
5756
|
+
drawStack.push($._shapesPL, 4);
|
|
5717
5757
|
} else {
|
|
5718
5758
|
// triangulate the shape
|
|
5719
5759
|
for (let i = 1; i < shapeVertCount - 1; i++) {
|
|
@@ -5725,7 +5765,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5725
5765
|
addVert(sv[v1], sv[v1 + 1], sv[v1 + 2], sv[v1 + 3]);
|
|
5726
5766
|
addVert(sv[v2], sv[v2 + 1], sv[v2 + 2], sv[v2 + 3]);
|
|
5727
5767
|
}
|
|
5728
|
-
drawStack.push(
|
|
5768
|
+
drawStack.push($._shapesPL, (shapeVertCount - 2) * 3);
|
|
5729
5769
|
}
|
|
5730
5770
|
}
|
|
5731
5771
|
|
|
@@ -5795,7 +5835,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5795
5835
|
|
|
5796
5836
|
let vertexBuffer = Q5.device.createBuffer({
|
|
5797
5837
|
size: vertIndex * 4,
|
|
5798
|
-
usage: GPUBufferUsage.VERTEX
|
|
5838
|
+
usage: GPUBufferUsage.VERTEX,
|
|
5799
5839
|
mappedAtCreation: true
|
|
5800
5840
|
});
|
|
5801
5841
|
|
|
@@ -5808,53 +5848,58 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5808
5848
|
});
|
|
5809
5849
|
|
|
5810
5850
|
$._hooks.postRender.push(() => {
|
|
5811
|
-
drawStack = $.drawStack;
|
|
5812
5851
|
vertIndex = 0;
|
|
5813
5852
|
});
|
|
5814
5853
|
};
|
|
5815
5854
|
Q5.renderers.webgpu.image = ($, q) => {
|
|
5816
|
-
|
|
5817
|
-
|
|
5855
|
+
$._imagePL = 1;
|
|
5856
|
+
$._videoPL = 2;
|
|
5818
5857
|
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
halfHeight: f32
|
|
5823
|
-
}
|
|
5858
|
+
$._imageShaderCode =
|
|
5859
|
+
$._baseShaderCode +
|
|
5860
|
+
/* wgsl */ `
|
|
5824
5861
|
struct VertexParams {
|
|
5862
|
+
@builtin(vertex_index) vertexIndex : u32,
|
|
5825
5863
|
@location(0) pos: vec2f,
|
|
5826
5864
|
@location(1) texCoord: vec2f,
|
|
5827
5865
|
@location(2) tintIndex: f32,
|
|
5828
5866
|
@location(3) matrixIndex: f32,
|
|
5829
5867
|
@location(4) imageAlpha: f32
|
|
5830
5868
|
}
|
|
5831
|
-
struct
|
|
5869
|
+
struct FragParams {
|
|
5832
5870
|
@builtin(position) position: vec4f,
|
|
5833
5871
|
@location(0) texCoord: vec2f,
|
|
5834
5872
|
@location(1) tintColor: vec4f,
|
|
5835
5873
|
@location(2) imageAlpha: f32
|
|
5836
5874
|
}
|
|
5837
5875
|
|
|
5838
|
-
@group(0) @binding(0) var<uniform>
|
|
5876
|
+
@group(0) @binding(0) var<uniform> q: Q5;
|
|
5839
5877
|
@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
|
|
5840
5878
|
@group(0) @binding(2) var<storage> colors : array<vec4f>;
|
|
5841
5879
|
|
|
5842
5880
|
@group(1) @binding(0) var samp: sampler;
|
|
5843
|
-
@group(1) @binding(1) var
|
|
5881
|
+
@group(1) @binding(1) var tex: texture_2d<f32>;
|
|
5844
5882
|
|
|
5845
5883
|
fn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {
|
|
5846
5884
|
var vert = vec4f(pos, 0.0, 1.0);
|
|
5847
5885
|
vert = transforms[i32(matrixIndex)] * vert;
|
|
5848
|
-
vert.x /=
|
|
5849
|
-
vert.y /=
|
|
5886
|
+
vert.x /= q.halfWidth;
|
|
5887
|
+
vert.y /= q.halfHeight;
|
|
5850
5888
|
return vert;
|
|
5851
5889
|
}
|
|
5852
5890
|
|
|
5891
|
+
fn applyTint(texColor: vec4f, tintColor: vec4f, imageAlpha: f32) -> vec4f {
|
|
5892
|
+
// apply the tint color to the sampled texture color at full strength
|
|
5893
|
+
let tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a * imageAlpha);
|
|
5894
|
+
// mix in the tint using the tint alpha as the blend strength
|
|
5895
|
+
return mix(texColor, tinted, tintColor.a);
|
|
5896
|
+
}
|
|
5897
|
+
|
|
5853
5898
|
@vertex
|
|
5854
|
-
fn vertexMain(v: VertexParams) ->
|
|
5899
|
+
fn vertexMain(v: VertexParams) -> FragParams {
|
|
5855
5900
|
var vert = transformVertex(v.pos, v.matrixIndex);
|
|
5856
5901
|
|
|
5857
|
-
var f:
|
|
5902
|
+
var f: FragParams;
|
|
5858
5903
|
f.position = vert;
|
|
5859
5904
|
f.texCoord = v.texCoord;
|
|
5860
5905
|
f.tintColor = colors[i32(v.tintIndex)];
|
|
@@ -5863,29 +5908,30 @@ fn vertexMain(v: VertexParams) -> FragmentParams {
|
|
|
5863
5908
|
}
|
|
5864
5909
|
|
|
5865
5910
|
@fragment
|
|
5866
|
-
fn
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
let tinted = vec4f(texColor.rgb * f.tintColor.rgb, texColor.a * f.imageAlpha);
|
|
5871
|
-
return mix(texColor, tinted, f.tintColor.a);
|
|
5911
|
+
fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
5912
|
+
var texColor = textureSample(tex, samp, f.texCoord);
|
|
5913
|
+
|
|
5914
|
+
return applyTint(texColor, f.tintColor, f.imageAlpha);
|
|
5872
5915
|
}
|
|
5873
5916
|
`;
|
|
5874
5917
|
|
|
5875
5918
|
let imageShader = Q5.device.createShaderModule({
|
|
5876
5919
|
label: 'imageShader',
|
|
5877
|
-
code:
|
|
5920
|
+
code: $._imageShaderCode
|
|
5878
5921
|
});
|
|
5879
5922
|
|
|
5880
|
-
|
|
5923
|
+
$._videoShaderCode = $._imageShaderCode
|
|
5881
5924
|
.replace('texture_2d<f32>', 'texture_external')
|
|
5882
5925
|
.replace('textureSample', 'textureSampleBaseClampToEdge');
|
|
5883
5926
|
|
|
5884
5927
|
let videoShader = Q5.device.createShaderModule({
|
|
5885
5928
|
label: 'videoShader',
|
|
5886
|
-
code:
|
|
5929
|
+
code: $._videoShaderCode
|
|
5887
5930
|
});
|
|
5888
5931
|
|
|
5932
|
+
let vertexStack = new Float32Array($._graphics ? 1000 : 1e7),
|
|
5933
|
+
vertIndex = 0;
|
|
5934
|
+
|
|
5889
5935
|
let vertexBufferLayout = {
|
|
5890
5936
|
arrayStride: 28,
|
|
5891
5937
|
attributes: [
|
|
@@ -5949,7 +5995,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5949
5995
|
},
|
|
5950
5996
|
fragment: {
|
|
5951
5997
|
module: imageShader,
|
|
5952
|
-
entryPoint: '
|
|
5998
|
+
entryPoint: 'fragMain',
|
|
5953
5999
|
targets: [{ format: 'bgra8unorm', blend: $.blendConfigs.normal }]
|
|
5954
6000
|
},
|
|
5955
6001
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
@@ -5968,7 +6014,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
5968
6014
|
},
|
|
5969
6015
|
fragment: {
|
|
5970
6016
|
module: videoShader,
|
|
5971
|
-
entryPoint: '
|
|
6017
|
+
entryPoint: 'fragMain',
|
|
5972
6018
|
targets: [{ format: 'bgra8unorm', blend: $.blendConfigs.normal }]
|
|
5973
6019
|
},
|
|
5974
6020
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
@@ -6081,7 +6127,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
6081
6127
|
let isVideo;
|
|
6082
6128
|
if (img.textureIndex == undefined) {
|
|
6083
6129
|
isVideo = img.tagName == 'VIDEO';
|
|
6084
|
-
if (!isVideo || !img.width) return;
|
|
6130
|
+
if (!isVideo || !img.width || !img.currentTime) return;
|
|
6085
6131
|
if (img.flipped) $.scale(-1, 1);
|
|
6086
6132
|
}
|
|
6087
6133
|
|
|
@@ -6129,7 +6175,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
6129
6175
|
v1 = (sy + sh) / h,
|
|
6130
6176
|
ti = $._matrixIndex,
|
|
6131
6177
|
ci = $._tint,
|
|
6132
|
-
ia = $.
|
|
6178
|
+
ia = $._globalAlpha;
|
|
6133
6179
|
|
|
6134
6180
|
addVert(l, t, u0, v0, ci, ti, ia);
|
|
6135
6181
|
addVert(r, t, u1, v0, ci, ti, ia);
|
|
@@ -6137,7 +6183,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
6137
6183
|
addVert(r, b, u1, v1, ci, ti, ia);
|
|
6138
6184
|
|
|
6139
6185
|
if (!isVideo) {
|
|
6140
|
-
$.drawStack.push(
|
|
6186
|
+
$.drawStack.push($._imagePL, img.textureIndex);
|
|
6141
6187
|
} else {
|
|
6142
6188
|
// render video
|
|
6143
6189
|
let externalTexture = Q5.device.importExternalTexture({ source: img });
|
|
@@ -6154,7 +6200,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
6154
6200
|
})
|
|
6155
6201
|
);
|
|
6156
6202
|
|
|
6157
|
-
$.drawStack.push(
|
|
6203
|
+
$.drawStack.push($._videoPL, $._textureBindGroups.length - 1);
|
|
6158
6204
|
|
|
6159
6205
|
if (img.flipped) $.scale(-1, 1);
|
|
6160
6206
|
}
|
|
@@ -6224,7 +6270,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
|
6224
6270
|
|
|
6225
6271
|
let vertexBuffer = Q5.device.createBuffer({
|
|
6226
6272
|
size: vertIndex * 5,
|
|
6227
|
-
usage: GPUBufferUsage.VERTEX
|
|
6273
|
+
usage: GPUBufferUsage.VERTEX,
|
|
6228
6274
|
mappedAtCreation: true
|
|
6229
6275
|
});
|
|
6230
6276
|
|
|
@@ -6258,16 +6304,16 @@ Q5.DILATE = 6;
|
|
|
6258
6304
|
Q5.ERODE = 7;
|
|
6259
6305
|
Q5.BLUR = 8;
|
|
6260
6306
|
Q5.renderers.webgpu.text = ($, q) => {
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6307
|
+
$._textPL = 3;
|
|
6308
|
+
|
|
6309
|
+
$._textShaderCode =
|
|
6310
|
+
$._baseShaderCode +
|
|
6311
|
+
/* wgsl */ `
|
|
6266
6312
|
struct VertexParams {
|
|
6267
|
-
@builtin(vertex_index)
|
|
6268
|
-
@builtin(instance_index)
|
|
6313
|
+
@builtin(vertex_index) vertexIndex : u32,
|
|
6314
|
+
@builtin(instance_index) instanceIndex : u32
|
|
6269
6315
|
}
|
|
6270
|
-
struct
|
|
6316
|
+
struct FragParams {
|
|
6271
6317
|
@builtin(position) position : vec4f,
|
|
6272
6318
|
@location(0) texCoord : vec2f,
|
|
6273
6319
|
@location(1) fillColor : vec4f,
|
|
@@ -6289,7 +6335,7 @@ struct Text {
|
|
|
6289
6335
|
strokeWeight: f32
|
|
6290
6336
|
}
|
|
6291
6337
|
|
|
6292
|
-
@group(0) @binding(0) var<uniform>
|
|
6338
|
+
@group(0) @binding(0) var<uniform> q: Q5;
|
|
6293
6339
|
@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
|
|
6294
6340
|
@group(0) @binding(2) var<storage> colors : array<vec4f>;
|
|
6295
6341
|
|
|
@@ -6302,32 +6348,48 @@ struct Text {
|
|
|
6302
6348
|
|
|
6303
6349
|
const quad = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));
|
|
6304
6350
|
|
|
6305
|
-
fn
|
|
6306
|
-
|
|
6307
|
-
|
|
6351
|
+
fn calcPos(i: u32, char: vec4f, fontChar: Char, text: Text) -> vec2f {
|
|
6352
|
+
return ((quad[i] * fontChar.size + char.xy + fontChar.offset) *
|
|
6353
|
+
text.scale) + text.pos;
|
|
6354
|
+
}
|
|
6355
|
+
|
|
6356
|
+
fn calcUV(i: u32, fontChar: Char) -> vec2f {
|
|
6357
|
+
return (quad[i] * vec2f(1, -1)) *
|
|
6358
|
+
fontChar.texExtent + fontChar.texOffset;
|
|
6308
6359
|
}
|
|
6309
6360
|
|
|
6310
6361
|
fn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {
|
|
6311
6362
|
var vert = vec4f(pos, 0.0, 1.0);
|
|
6312
6363
|
vert = transforms[i32(matrixIndex)] * vert;
|
|
6313
|
-
vert.x /=
|
|
6314
|
-
vert.y /=
|
|
6364
|
+
vert.x /= q.halfWidth;
|
|
6365
|
+
vert.y /= q.halfHeight;
|
|
6315
6366
|
return vert;
|
|
6316
6367
|
}
|
|
6317
6368
|
|
|
6369
|
+
fn calcDist(texCoord: vec2f, edgeWidth: f32) -> f32 {
|
|
6370
|
+
let c = textureSample(fontTexture, fontSampler, texCoord);
|
|
6371
|
+
let sigDist = max(min(c.r, c.g), min(max(c.r, c.g), c.b)) - edgeWidth;
|
|
6372
|
+
|
|
6373
|
+
let pxRange = 4.0;
|
|
6374
|
+
let sz = vec2f(textureDimensions(fontTexture, 0));
|
|
6375
|
+
let dx = sz.x * length(vec2f(dpdxFine(texCoord.x), dpdyFine(texCoord.x)));
|
|
6376
|
+
let dy = sz.y * length(vec2f(dpdxFine(texCoord.y), dpdyFine(texCoord.y)));
|
|
6377
|
+
let toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);
|
|
6378
|
+
return sigDist * toPixels;
|
|
6379
|
+
}
|
|
6380
|
+
|
|
6318
6381
|
@vertex
|
|
6319
|
-
fn vertexMain(v : VertexParams) ->
|
|
6320
|
-
let char = textChars[v.
|
|
6382
|
+
fn vertexMain(v : VertexParams) -> FragParams {
|
|
6383
|
+
let char = textChars[v.instanceIndex];
|
|
6321
6384
|
let text = textMetadata[i32(char.w)];
|
|
6322
6385
|
let fontChar = fontChars[i32(char.z)];
|
|
6386
|
+
let pos = calcPos(v.vertexIndex, char, fontChar, text);
|
|
6323
6387
|
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
var vert = transformVertex(charPos, text.matrixIndex);
|
|
6388
|
+
var vert = transformVertex(pos, text.matrixIndex);
|
|
6327
6389
|
|
|
6328
|
-
var f :
|
|
6390
|
+
var f : FragParams;
|
|
6329
6391
|
f.position = vert;
|
|
6330
|
-
f.texCoord = (
|
|
6392
|
+
f.texCoord = calcUV(v.vertexIndex, fontChar);
|
|
6331
6393
|
f.fillColor = colors[i32(text.fillIndex)];
|
|
6332
6394
|
f.strokeColor = colors[i32(text.strokeIndex)];
|
|
6333
6395
|
f.strokeWeight = text.strokeWeight;
|
|
@@ -6335,19 +6397,13 @@ fn vertexMain(v : VertexParams) -> FragmentParams {
|
|
|
6335
6397
|
}
|
|
6336
6398
|
|
|
6337
6399
|
@fragment
|
|
6338
|
-
fn
|
|
6339
|
-
let
|
|
6340
|
-
let
|
|
6341
|
-
let dx = sz.x * length(vec2f(dpdxFine(f.texCoord.x), dpdyFine(f.texCoord.x)));
|
|
6342
|
-
let dy = sz.y * length(vec2f(dpdxFine(f.texCoord.y), dpdyFine(f.texCoord.y)));
|
|
6343
|
-
let toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);
|
|
6344
|
-
let sigDist = sampleMsdf(f.texCoord) - 0.5;
|
|
6345
|
-
let pxDist = sigDist * toPixels;
|
|
6346
|
-
let edgeWidth = 0.5;
|
|
6400
|
+
fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
6401
|
+
let edge = 0.5;
|
|
6402
|
+
let dist = calcDist(f.texCoord, edge);
|
|
6347
6403
|
|
|
6348
6404
|
if (f.strokeWeight == 0.0) {
|
|
6349
|
-
let fillAlpha = smoothstep(-
|
|
6350
|
-
|
|
6405
|
+
let fillAlpha = smoothstep(-edge, edge, dist);
|
|
6406
|
+
let color = vec4f(f.fillColor.rgb, f.fillColor.a * fillAlpha);
|
|
6351
6407
|
if (color.a < 0.01) {
|
|
6352
6408
|
discard;
|
|
6353
6409
|
}
|
|
@@ -6355,8 +6411,8 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6355
6411
|
}
|
|
6356
6412
|
|
|
6357
6413
|
let halfStroke = f.strokeWeight / 2.0;
|
|
6358
|
-
let fillAlpha = smoothstep(-
|
|
6359
|
-
let strokeAlpha = smoothstep(-
|
|
6414
|
+
let fillAlpha = smoothstep(-edge, edge, dist - halfStroke);
|
|
6415
|
+
let strokeAlpha = smoothstep(-edge, edge, dist + halfStroke);
|
|
6360
6416
|
var color = mix(f.strokeColor, f.fillColor, fillAlpha);
|
|
6361
6417
|
color = vec4f(color.rgb, color.a * strokeAlpha);
|
|
6362
6418
|
if (color.a < 0.01) {
|
|
@@ -6368,11 +6424,11 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6368
6424
|
|
|
6369
6425
|
let textShader = Q5.device.createShaderModule({
|
|
6370
6426
|
label: 'textShader',
|
|
6371
|
-
code:
|
|
6427
|
+
code: $._textShaderCode
|
|
6372
6428
|
});
|
|
6373
6429
|
|
|
6374
6430
|
let textBindGroupLayout = Q5.device.createBindGroupLayout({
|
|
6375
|
-
label: '
|
|
6431
|
+
label: 'textBindGroupLayout',
|
|
6376
6432
|
entries: [
|
|
6377
6433
|
{
|
|
6378
6434
|
binding: 0,
|
|
@@ -6395,7 +6451,7 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6395
6451
|
});
|
|
6396
6452
|
|
|
6397
6453
|
let fontBindGroupLayout = Q5.device.createBindGroupLayout({
|
|
6398
|
-
label: '
|
|
6454
|
+
label: 'fontBindGroupLayout',
|
|
6399
6455
|
entries: [
|
|
6400
6456
|
{
|
|
6401
6457
|
binding: 0,
|
|
@@ -6420,12 +6476,12 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6420
6476
|
});
|
|
6421
6477
|
|
|
6422
6478
|
$._pipelineConfigs[3] = {
|
|
6423
|
-
label: '
|
|
6479
|
+
label: 'textPipeline',
|
|
6424
6480
|
layout: fontPipelineLayout,
|
|
6425
6481
|
vertex: { module: textShader, entryPoint: 'vertexMain' },
|
|
6426
6482
|
fragment: {
|
|
6427
6483
|
module: textShader,
|
|
6428
|
-
entryPoint: '
|
|
6484
|
+
entryPoint: 'fragMain',
|
|
6429
6485
|
targets: [{ format: 'bgra8unorm', blend: $.blendConfigs.normal }]
|
|
6430
6486
|
},
|
|
6431
6487
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
@@ -6526,7 +6582,7 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6526
6582
|
charsBuffer.unmap();
|
|
6527
6583
|
|
|
6528
6584
|
let fontBindGroup = Q5.device.createBindGroup({
|
|
6529
|
-
label: '
|
|
6585
|
+
label: 'fontBindGroup',
|
|
6530
6586
|
layout: fontBindGroupLayout,
|
|
6531
6587
|
entries: [
|
|
6532
6588
|
{ binding: 0, resource: texture.createView() },
|
|
@@ -6771,7 +6827,7 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6771
6827
|
txt[7] = 0; // padding
|
|
6772
6828
|
|
|
6773
6829
|
textStack.push(txt);
|
|
6774
|
-
$.drawStack.push(
|
|
6830
|
+
$.drawStack.push($._textPL, measurements.printedCharCount, $._font.index);
|
|
6775
6831
|
};
|
|
6776
6832
|
|
|
6777
6833
|
$.textWidth = (str) => {
|
|
@@ -6836,7 +6892,7 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6836
6892
|
// create a single buffer for all the char data
|
|
6837
6893
|
let charBuffer = Q5.device.createBuffer({
|
|
6838
6894
|
size: totalTextSize,
|
|
6839
|
-
usage: GPUBufferUsage.STORAGE
|
|
6895
|
+
usage: GPUBufferUsage.STORAGE,
|
|
6840
6896
|
mappedAtCreation: true
|
|
6841
6897
|
});
|
|
6842
6898
|
|
|
@@ -6851,7 +6907,7 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6851
6907
|
let textBuffer = Q5.device.createBuffer({
|
|
6852
6908
|
label: 'textBuffer',
|
|
6853
6909
|
size: totalMetadataSize,
|
|
6854
|
-
usage: GPUBufferUsage.STORAGE
|
|
6910
|
+
usage: GPUBufferUsage.STORAGE,
|
|
6855
6911
|
mappedAtCreation: true
|
|
6856
6912
|
});
|
|
6857
6913
|
|
|
@@ -6863,7 +6919,7 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6863
6919
|
|
|
6864
6920
|
// create a single bind group for the text buffer and metadata buffer
|
|
6865
6921
|
$._textBindGroup = Q5.device.createBindGroup({
|
|
6866
|
-
label: '
|
|
6922
|
+
label: 'textBindGroup',
|
|
6867
6923
|
layout: textBindGroupLayout,
|
|
6868
6924
|
entries: [
|
|
6869
6925
|
{ binding: 0, resource: { buffer: charBuffer } },
|
|
@@ -6877,3 +6933,72 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
|
6877
6933
|
textStack = [];
|
|
6878
6934
|
});
|
|
6879
6935
|
};
|
|
6936
|
+
Q5.renderers.webgpu.shaders = ($) => {
|
|
6937
|
+
let pipelineTypes = ['shapes', 'image', 'video', 'text'];
|
|
6938
|
+
|
|
6939
|
+
let plCounters = {
|
|
6940
|
+
shapes: 100,
|
|
6941
|
+
image: 200,
|
|
6942
|
+
video: 300,
|
|
6943
|
+
text: 400
|
|
6944
|
+
};
|
|
6945
|
+
|
|
6946
|
+
$._createShader = (code, type = 'shapes') => {
|
|
6947
|
+
code = code.trim();
|
|
6948
|
+
|
|
6949
|
+
// default shader code
|
|
6950
|
+
let def = $['_' + type + 'ShaderCode'];
|
|
6951
|
+
|
|
6952
|
+
let defVertIdx = def.indexOf('@vertex');
|
|
6953
|
+
let defFragIdx = def.indexOf('@fragment');
|
|
6954
|
+
|
|
6955
|
+
if (!code.includes('@fragment')) {
|
|
6956
|
+
// replace @vertex section
|
|
6957
|
+
code = def.slice(0, defVertIdx) + code + '\n\n' + def.slice(defFragIdx);
|
|
6958
|
+
} else if (!code.includes('@vertex')) {
|
|
6959
|
+
// replace @fragment section
|
|
6960
|
+
code = def.slice(0, defFragIdx) + code;
|
|
6961
|
+
} else {
|
|
6962
|
+
// replace @vertex and @fragment sections
|
|
6963
|
+
code = def.slice(0, defVertIdx) + code;
|
|
6964
|
+
}
|
|
6965
|
+
|
|
6966
|
+
let shader = Q5.device.createShaderModule({
|
|
6967
|
+
label: type + 'Shader',
|
|
6968
|
+
code: code
|
|
6969
|
+
});
|
|
6970
|
+
shader.type = type;
|
|
6971
|
+
|
|
6972
|
+
let pipelineIndex = pipelineTypes.indexOf(type);
|
|
6973
|
+
let config = Object.assign({}, $._pipelineConfigs[pipelineIndex]);
|
|
6974
|
+
config.vertex.module = config.fragment.module = shader;
|
|
6975
|
+
|
|
6976
|
+
let pl = plCounters[type];
|
|
6977
|
+
$._pipelines[pl] = Q5.device.createRenderPipeline(config);
|
|
6978
|
+
shader.pipelineIndex = pl;
|
|
6979
|
+
plCounters[type]++;
|
|
6980
|
+
|
|
6981
|
+
return shader;
|
|
6982
|
+
};
|
|
6983
|
+
|
|
6984
|
+
$.createShader = $.createShapesShader = $._createShader;
|
|
6985
|
+
$.createImageShader = (code) => $._createShader(code, 'image');
|
|
6986
|
+
$.createVideoShader = (code) => $._createShader(code, 'video');
|
|
6987
|
+
$.createTextShader = (code) => $._createShader(code, 'text');
|
|
6988
|
+
|
|
6989
|
+
$.shader = (shader) => {
|
|
6990
|
+
$['_' + shader.type + 'PL'] = shader.pipelineIndex;
|
|
6991
|
+
};
|
|
6992
|
+
|
|
6993
|
+
$.resetShader = (type = 'shapes') => {
|
|
6994
|
+
$['_' + type + 'PL'] = pipelineTypes.indexOf(type);
|
|
6995
|
+
};
|
|
6996
|
+
|
|
6997
|
+
$.resetShaders = () => {
|
|
6998
|
+
$._shapesPL = 0;
|
|
6999
|
+
$._imagePL = 1;
|
|
7000
|
+
$._videoPL = 2;
|
|
7001
|
+
$._textPL = 3;
|
|
7002
|
+
$._planePL = 4;
|
|
7003
|
+
};
|
|
7004
|
+
};
|