q5 2.12.12 → 2.13.2
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/package.json +1 -1
- package/q5.js +250 -247
- package/q5.min.js +2 -2
- package/src/q5-2d-canvas.js +1 -0
- package/src/q5-core.js +1 -1
- package/src/q5-webgpu-canvas.js +100 -107
- package/src/q5-webgpu-drawing.js +27 -35
- package/src/q5-webgpu-image.js +86 -65
- package/src/q5-webgpu-text.js +35 -39
package/q5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* q5.js
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.13
|
|
4
4
|
* @author quinton-ashley, Tezumie, and LingDong-
|
|
5
5
|
* @license LGPL-3.0
|
|
6
6
|
* @class Q5
|
|
@@ -843,6 +843,7 @@ Q5.renderers.q2d.canvas = ($, q) => {
|
|
|
843
843
|
if ($.ctx) {
|
|
844
844
|
$.ctx.resetTransform();
|
|
845
845
|
$.scale($._pixelDensity);
|
|
846
|
+
if ($._webgpuFallback) $.translate($.canvas.hw, $.canvas.hh);
|
|
846
847
|
}
|
|
847
848
|
};
|
|
848
849
|
|
|
@@ -3594,11 +3595,13 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3594
3595
|
c.width = $.width = 500;
|
|
3595
3596
|
c.height = $.height = 500;
|
|
3596
3597
|
|
|
3598
|
+
// q2d graphics context
|
|
3599
|
+
$._g = $.createGraphics(1, 1);
|
|
3600
|
+
|
|
3597
3601
|
if ($.colorMode) $.colorMode('rgb', 1);
|
|
3598
3602
|
|
|
3599
3603
|
let pass,
|
|
3600
3604
|
mainView,
|
|
3601
|
-
colorsLayout,
|
|
3602
3605
|
colorIndex = 1,
|
|
3603
3606
|
colorStackIndex = 8;
|
|
3604
3607
|
|
|
@@ -3610,7 +3613,6 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3610
3613
|
let drawStack = ($.drawStack = []);
|
|
3611
3614
|
|
|
3612
3615
|
// colors used for each draw call
|
|
3613
|
-
|
|
3614
3616
|
let colorStack = ($.colorStack = new Float32Array(1e6));
|
|
3615
3617
|
|
|
3616
3618
|
// prettier-ignore
|
|
@@ -3619,43 +3621,28 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3619
3621
|
1, 1, 1, 1 // white
|
|
3620
3622
|
]);
|
|
3621
3623
|
|
|
3622
|
-
|
|
3623
|
-
label: '
|
|
3624
|
+
let mainLayout = Q5.device.createBindGroupLayout({
|
|
3625
|
+
label: 'mainLayout',
|
|
3624
3626
|
entries: [
|
|
3625
3627
|
{
|
|
3626
3628
|
binding: 0,
|
|
3627
3629
|
visibility: GPUShaderStage.VERTEX,
|
|
3628
|
-
buffer: {
|
|
3629
|
-
type: 'uniform',
|
|
3630
|
-
hasDynamicOffset: false
|
|
3631
|
-
}
|
|
3630
|
+
buffer: { type: 'uniform' }
|
|
3632
3631
|
},
|
|
3633
3632
|
{
|
|
3634
3633
|
binding: 1,
|
|
3635
3634
|
visibility: GPUShaderStage.VERTEX,
|
|
3636
|
-
buffer: {
|
|
3637
|
-
|
|
3638
|
-
hasDynamicOffset: false
|
|
3639
|
-
}
|
|
3640
|
-
}
|
|
3641
|
-
]
|
|
3642
|
-
});
|
|
3643
|
-
|
|
3644
|
-
colorsLayout = Q5.device.createBindGroupLayout({
|
|
3645
|
-
label: 'colorsLayout',
|
|
3646
|
-
entries: [
|
|
3635
|
+
buffer: { type: 'read-only-storage' }
|
|
3636
|
+
},
|
|
3647
3637
|
{
|
|
3648
|
-
binding:
|
|
3638
|
+
binding: 2,
|
|
3649
3639
|
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
3650
|
-
buffer: {
|
|
3651
|
-
type: 'read-only-storage',
|
|
3652
|
-
hasDynamicOffset: false
|
|
3653
|
-
}
|
|
3640
|
+
buffer: { type: 'read-only-storage' }
|
|
3654
3641
|
}
|
|
3655
3642
|
]
|
|
3656
3643
|
});
|
|
3657
3644
|
|
|
3658
|
-
$.bindGroupLayouts = [
|
|
3645
|
+
$.bindGroupLayouts = [mainLayout];
|
|
3659
3646
|
|
|
3660
3647
|
let uniformBuffer = Q5.device.createBuffer({
|
|
3661
3648
|
size: 8, // Size of two floats
|
|
@@ -3685,7 +3672,6 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3685
3672
|
Q5.device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([$.canvas.hw, $.canvas.hh]));
|
|
3686
3673
|
|
|
3687
3674
|
createMainView();
|
|
3688
|
-
|
|
3689
3675
|
return c;
|
|
3690
3676
|
};
|
|
3691
3677
|
|
|
@@ -3729,7 +3715,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3729
3715
|
};
|
|
3730
3716
|
|
|
3731
3717
|
$._stroke = 0;
|
|
3732
|
-
$._fill = 1;
|
|
3718
|
+
$._fill = $._tint = $._globalAlpha = 1;
|
|
3733
3719
|
$._doFill = $._doStroke = true;
|
|
3734
3720
|
|
|
3735
3721
|
$.fill = (r, g, b, a) => {
|
|
@@ -3742,42 +3728,53 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3742
3728
|
$._doStroke = $._strokeSet = true;
|
|
3743
3729
|
$._stroke = colorIndex;
|
|
3744
3730
|
};
|
|
3731
|
+
$.tint = (r, g, b, a) => {
|
|
3732
|
+
addColor(r, g, b, a);
|
|
3733
|
+
$._tint = colorIndex;
|
|
3734
|
+
};
|
|
3735
|
+
$.opacity = (a) => ($._globalAlpha = a);
|
|
3745
3736
|
|
|
3746
3737
|
$.noFill = () => ($._doFill = false);
|
|
3747
3738
|
$.noStroke = () => ($._doStroke = false);
|
|
3739
|
+
$.noTint = () => ($._tint = 1);
|
|
3748
3740
|
|
|
3749
3741
|
$._strokeWeight = 1;
|
|
3750
3742
|
$.strokeWeight = (v) => ($._strokeWeight = Math.abs(v));
|
|
3751
3743
|
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
0, 0, 1, 0,
|
|
3760
|
-
0, 0, 0, 1
|
|
3761
|
-
];
|
|
3762
|
-
$._transformIndex = 0;
|
|
3763
|
-
};
|
|
3764
|
-
$.resetMatrix();
|
|
3744
|
+
const MAX_TRANSFORMS = 1e7, // or whatever maximum you need
|
|
3745
|
+
MATRIX_SIZE = 16, // 4x4 matrix
|
|
3746
|
+
transforms = new Float32Array(MAX_TRANSFORMS * MATRIX_SIZE),
|
|
3747
|
+
matrices = [],
|
|
3748
|
+
matricesIndexStack = [];
|
|
3749
|
+
|
|
3750
|
+
let matrix;
|
|
3765
3751
|
|
|
3766
3752
|
// tracks if the matrix has been modified
|
|
3767
3753
|
$._matrixDirty = false;
|
|
3768
3754
|
|
|
3769
|
-
//
|
|
3770
|
-
|
|
3755
|
+
// initialize with a 4x4 identity matrix
|
|
3756
|
+
// prettier-ignore
|
|
3757
|
+
matrices.push([
|
|
3758
|
+
1, 0, 0, 0,
|
|
3759
|
+
0, 1, 0, 0,
|
|
3760
|
+
0, 0, 1, 0,
|
|
3761
|
+
0, 0, 0, 1
|
|
3762
|
+
]);
|
|
3771
3763
|
|
|
3772
|
-
|
|
3773
|
-
|
|
3764
|
+
transforms.set(matrices[0]);
|
|
3765
|
+
|
|
3766
|
+
$.resetMatrix = () => {
|
|
3767
|
+
matrix = matrices[0].slice();
|
|
3768
|
+
$._matrixIndex = 0;
|
|
3769
|
+
};
|
|
3770
|
+
$.resetMatrix();
|
|
3774
3771
|
|
|
3775
3772
|
$.translate = (x, y, z) => {
|
|
3776
3773
|
if (!x && !y && !z) return;
|
|
3777
3774
|
// update the translation values
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3775
|
+
matrix[12] += x;
|
|
3776
|
+
matrix[13] -= y;
|
|
3777
|
+
matrix[14] += z || 0;
|
|
3781
3778
|
$._matrixDirty = true;
|
|
3782
3779
|
};
|
|
3783
3780
|
|
|
@@ -3785,12 +3782,10 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3785
3782
|
if (!a) return;
|
|
3786
3783
|
if ($._angleMode) a *= $._DEGTORAD;
|
|
3787
3784
|
|
|
3788
|
-
let cosR = Math.cos(a)
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
let m0 = m[0],
|
|
3785
|
+
let cosR = Math.cos(a),
|
|
3786
|
+
sinR = Math.sin(a),
|
|
3787
|
+
m = matrix,
|
|
3788
|
+
m0 = m[0],
|
|
3794
3789
|
m1 = m[1],
|
|
3795
3790
|
m4 = m[4],
|
|
3796
3791
|
m5 = m[5];
|
|
@@ -3815,7 +3810,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3815
3810
|
$.scale = (x = 1, y, z = 1) => {
|
|
3816
3811
|
y ??= x;
|
|
3817
3812
|
|
|
3818
|
-
let m =
|
|
3813
|
+
let m = matrix;
|
|
3819
3814
|
|
|
3820
3815
|
m[0] *= x;
|
|
3821
3816
|
m[1] *= x;
|
|
@@ -3837,15 +3832,15 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3837
3832
|
if (!ang) return;
|
|
3838
3833
|
if ($._angleMode) ang *= $._DEGTORAD;
|
|
3839
3834
|
|
|
3840
|
-
let tanAng = Math.tan(ang)
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
m1 =
|
|
3844
|
-
m4 =
|
|
3845
|
-
m5 =
|
|
3835
|
+
let tanAng = Math.tan(ang),
|
|
3836
|
+
m = matrix,
|
|
3837
|
+
m0 = m[0],
|
|
3838
|
+
m1 = m[1],
|
|
3839
|
+
m4 = m[4],
|
|
3840
|
+
m5 = m[5];
|
|
3846
3841
|
|
|
3847
|
-
|
|
3848
|
-
|
|
3842
|
+
m[0] = m0 + m4 * tanAng;
|
|
3843
|
+
m[1] = m1 + m5 * tanAng;
|
|
3849
3844
|
|
|
3850
3845
|
$._matrixDirty = true;
|
|
3851
3846
|
};
|
|
@@ -3854,15 +3849,15 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3854
3849
|
if (!ang) return;
|
|
3855
3850
|
if ($._angleMode) ang *= $._DEGTORAD;
|
|
3856
3851
|
|
|
3857
|
-
let tanAng = Math.tan(ang)
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
m1 =
|
|
3861
|
-
m4 =
|
|
3862
|
-
m5 =
|
|
3852
|
+
let tanAng = Math.tan(ang),
|
|
3853
|
+
m = matrix,
|
|
3854
|
+
m0 = m[0],
|
|
3855
|
+
m1 = m[1],
|
|
3856
|
+
m4 = m[4],
|
|
3857
|
+
m5 = m[5];
|
|
3863
3858
|
|
|
3864
|
-
|
|
3865
|
-
|
|
3859
|
+
m[4] = m4 + m0 * tanAng;
|
|
3860
|
+
m[5] = m5 + m1 * tanAng;
|
|
3866
3861
|
|
|
3867
3862
|
$._matrixDirty = true;
|
|
3868
3863
|
};
|
|
@@ -3880,31 +3875,32 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3880
3875
|
}
|
|
3881
3876
|
|
|
3882
3877
|
// overwrite the current transformation matrix
|
|
3883
|
-
|
|
3878
|
+
matrix = m.slice();
|
|
3884
3879
|
$._matrixDirty = true;
|
|
3885
3880
|
};
|
|
3886
3881
|
|
|
3887
3882
|
// function to save the current matrix state if dirty
|
|
3888
3883
|
$._saveMatrix = () => {
|
|
3889
|
-
|
|
3890
|
-
$.
|
|
3884
|
+
transforms.set(matrix, matrices.length * MATRIX_SIZE);
|
|
3885
|
+
$._matrixIndex = matrices.length;
|
|
3886
|
+
matrices.push(matrix.slice());
|
|
3891
3887
|
$._matrixDirty = false;
|
|
3892
3888
|
};
|
|
3893
3889
|
|
|
3894
3890
|
// push the current matrix index onto the stack
|
|
3895
3891
|
$.pushMatrix = () => {
|
|
3896
3892
|
if ($._matrixDirty) $._saveMatrix();
|
|
3897
|
-
|
|
3893
|
+
matricesIndexStack.push($._matrixIndex);
|
|
3898
3894
|
};
|
|
3899
3895
|
|
|
3900
3896
|
$.popMatrix = () => {
|
|
3901
|
-
if (
|
|
3897
|
+
if (!matricesIndexStack.length) {
|
|
3902
3898
|
return console.warn('Matrix index stack is empty!');
|
|
3903
3899
|
}
|
|
3904
3900
|
// pop the last matrix index and set it as the current matrix index
|
|
3905
|
-
let idx =
|
|
3906
|
-
|
|
3907
|
-
$.
|
|
3901
|
+
let idx = matricesIndexStack.pop();
|
|
3902
|
+
matrix = matrices[idx].slice();
|
|
3903
|
+
$._matrixIndex = idx;
|
|
3908
3904
|
$._matrixDirty = false;
|
|
3909
3905
|
};
|
|
3910
3906
|
|
|
@@ -4029,26 +4025,14 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4029
4025
|
};
|
|
4030
4026
|
|
|
4031
4027
|
$._render = () => {
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
});
|
|
4038
|
-
|
|
4039
|
-
new Float32Array(transformBuffer.getMappedRange()).set(transformStates.flat());
|
|
4040
|
-
transformBuffer.unmap();
|
|
4041
|
-
|
|
4042
|
-
$._transformBindGroup = Q5.device.createBindGroup({
|
|
4043
|
-
layout: $._transformLayout,
|
|
4044
|
-
entries: [
|
|
4045
|
-
{ binding: 0, resource: { buffer: uniformBuffer } },
|
|
4046
|
-
{ binding: 1, resource: { buffer: transformBuffer } }
|
|
4047
|
-
]
|
|
4048
|
-
});
|
|
4049
|
-
}
|
|
4028
|
+
let transformBuffer = Q5.device.createBuffer({
|
|
4029
|
+
size: matrices.length * MATRIX_SIZE * 4, // 4 bytes per float
|
|
4030
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
4031
|
+
mappedAtCreation: true
|
|
4032
|
+
});
|
|
4050
4033
|
|
|
4051
|
-
|
|
4034
|
+
new Float32Array(transformBuffer.getMappedRange()).set(transforms.slice(0, matrices.length * MATRIX_SIZE));
|
|
4035
|
+
transformBuffer.unmap();
|
|
4052
4036
|
|
|
4053
4037
|
let colorsBuffer = Q5.device.createBuffer({
|
|
4054
4038
|
size: colorStackIndex * 4,
|
|
@@ -4059,12 +4043,16 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4059
4043
|
new Float32Array(colorsBuffer.getMappedRange()).set(colorStack.slice(0, colorStackIndex));
|
|
4060
4044
|
colorsBuffer.unmap();
|
|
4061
4045
|
|
|
4062
|
-
|
|
4063
|
-
layout:
|
|
4064
|
-
entries: [
|
|
4046
|
+
mainBindGroup = Q5.device.createBindGroup({
|
|
4047
|
+
layout: mainLayout,
|
|
4048
|
+
entries: [
|
|
4049
|
+
{ binding: 0, resource: { buffer: uniformBuffer } },
|
|
4050
|
+
{ binding: 1, resource: { buffer: transformBuffer } },
|
|
4051
|
+
{ binding: 2, resource: { buffer: colorsBuffer } }
|
|
4052
|
+
]
|
|
4065
4053
|
});
|
|
4066
4054
|
|
|
4067
|
-
|
|
4055
|
+
pass.setBindGroup(0, mainBindGroup);
|
|
4068
4056
|
|
|
4069
4057
|
for (let m of $._hooks.preRender) m();
|
|
4070
4058
|
|
|
@@ -4088,18 +4076,20 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4088
4076
|
pass.draw(v, 1, drawVertOffset);
|
|
4089
4077
|
drawVertOffset += v;
|
|
4090
4078
|
} else if (curPipelineIndex == 1) {
|
|
4079
|
+
// let instanceCount = drawStack[i + 2];
|
|
4091
4080
|
// draw images
|
|
4092
4081
|
if (curTextureIndex != v) {
|
|
4093
4082
|
// v is the texture index
|
|
4094
|
-
pass.setBindGroup(
|
|
4083
|
+
pass.setBindGroup(1, $._textureBindGroups[v]);
|
|
4095
4084
|
}
|
|
4096
4085
|
pass.draw(4, 1, imageVertOffset);
|
|
4097
4086
|
imageVertOffset += 4;
|
|
4087
|
+
// i++;
|
|
4098
4088
|
} else if (curPipelineIndex == 2) {
|
|
4099
4089
|
// draw text
|
|
4100
4090
|
let o = drawStack[i + 2];
|
|
4101
|
-
pass.setBindGroup(
|
|
4102
|
-
pass.setBindGroup(
|
|
4091
|
+
pass.setBindGroup(1, $._fonts[o].bindGroup);
|
|
4092
|
+
pass.setBindGroup(2, $._textBindGroup);
|
|
4103
4093
|
|
|
4104
4094
|
// v is the number of characters in the text
|
|
4105
4095
|
pass.draw(4, v, 0, textCharOffset);
|
|
@@ -4123,8 +4113,9 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
4123
4113
|
colorIndex = 1;
|
|
4124
4114
|
colorStackIndex = 8;
|
|
4125
4115
|
rotation = 0;
|
|
4126
|
-
|
|
4127
|
-
|
|
4116
|
+
transforms.length = MATRIX_SIZE;
|
|
4117
|
+
matrices.length = 1;
|
|
4118
|
+
matricesIndexStack.length = 0;
|
|
4128
4119
|
};
|
|
4129
4120
|
};
|
|
4130
4121
|
|
|
@@ -4135,7 +4126,10 @@ Q5.initWebGPU = async () => {
|
|
|
4135
4126
|
}
|
|
4136
4127
|
if (!Q5.device) {
|
|
4137
4128
|
let adapter = await navigator.gpu.requestAdapter();
|
|
4138
|
-
if (!adapter)
|
|
4129
|
+
if (!adapter) {
|
|
4130
|
+
console.warn('q5 WebGPU could not start! No appropriate GPUAdapter found, vulkan may need to be enabled.');
|
|
4131
|
+
return false;
|
|
4132
|
+
}
|
|
4139
4133
|
Q5.device = await adapter.requestDevice();
|
|
4140
4134
|
}
|
|
4141
4135
|
return true;
|
|
@@ -4154,46 +4148,40 @@ Q5.renderers.webgpu.drawing = ($, q) => {
|
|
|
4154
4148
|
vertexStack = new Float32Array(1e7),
|
|
4155
4149
|
vertIndex = 0;
|
|
4156
4150
|
|
|
4157
|
-
let
|
|
4158
|
-
label: '
|
|
4151
|
+
let drawingShader = Q5.device.createShaderModule({
|
|
4152
|
+
label: 'drawingShader',
|
|
4159
4153
|
code: `
|
|
4160
|
-
struct
|
|
4154
|
+
struct Uniforms {
|
|
4155
|
+
halfWidth: f32,
|
|
4156
|
+
halfHeight: f32
|
|
4157
|
+
}
|
|
4158
|
+
struct VertexParams {
|
|
4161
4159
|
@location(0) pos: vec2f,
|
|
4162
4160
|
@location(1) colorIndex: f32,
|
|
4163
|
-
@location(2)
|
|
4161
|
+
@location(2) matrixIndex: f32
|
|
4164
4162
|
}
|
|
4165
|
-
struct
|
|
4163
|
+
struct FragmentParams {
|
|
4166
4164
|
@builtin(position) position: vec4f,
|
|
4167
4165
|
@location(0) color: vec4f
|
|
4168
4166
|
}
|
|
4169
|
-
struct Uniforms {
|
|
4170
|
-
halfWidth: f32,
|
|
4171
|
-
halfHeight: f32
|
|
4172
|
-
}
|
|
4173
4167
|
|
|
4174
4168
|
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
4175
4169
|
@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
|
|
4176
|
-
|
|
4177
|
-
@group(1) @binding(0) var<storage> colors : array<vec4f>;
|
|
4170
|
+
@group(0) @binding(2) var<storage> colors : array<vec4f>;
|
|
4178
4171
|
|
|
4179
4172
|
@vertex
|
|
4180
|
-
fn vertexMain(
|
|
4181
|
-
var vert = vec4f(
|
|
4182
|
-
vert = transforms[i32(
|
|
4173
|
+
fn vertexMain(v: VertexParams) -> FragmentParams {
|
|
4174
|
+
var vert = vec4f(v.pos, 0.0, 1.0);
|
|
4175
|
+
vert = transforms[i32(v.matrixIndex)] * vert;
|
|
4183
4176
|
vert.x /= uniforms.halfWidth;
|
|
4184
4177
|
vert.y /= uniforms.halfHeight;
|
|
4185
4178
|
|
|
4186
|
-
var
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
return
|
|
4179
|
+
var f: FragmentParams;
|
|
4180
|
+
f.position = vert;
|
|
4181
|
+
f.color = colors[i32(v.colorIndex)];
|
|
4182
|
+
return f;
|
|
4190
4183
|
}
|
|
4191
|
-
`
|
|
4192
|
-
});
|
|
4193
4184
|
|
|
4194
|
-
let fragmentShader = Q5.device.createShaderModule({
|
|
4195
|
-
label: 'drawingFragmentShader',
|
|
4196
|
-
code: `
|
|
4197
4185
|
@fragment
|
|
4198
4186
|
fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
4199
4187
|
return color;
|
|
@@ -4206,7 +4194,7 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4206
4194
|
attributes: [
|
|
4207
4195
|
{ format: 'float32x2', offset: 0, shaderLocation: 0 }, // position
|
|
4208
4196
|
{ format: 'float32', offset: 8, shaderLocation: 1 }, // colorIndex
|
|
4209
|
-
{ format: 'float32', offset: 12, shaderLocation: 2 } //
|
|
4197
|
+
{ format: 'float32', offset: 12, shaderLocation: 2 } // matrixIndex
|
|
4210
4198
|
]
|
|
4211
4199
|
};
|
|
4212
4200
|
|
|
@@ -4219,19 +4207,17 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4219
4207
|
label: 'drawingPipeline',
|
|
4220
4208
|
layout: pipelineLayout,
|
|
4221
4209
|
vertex: {
|
|
4222
|
-
module:
|
|
4210
|
+
module: drawingShader,
|
|
4223
4211
|
entryPoint: 'vertexMain',
|
|
4224
4212
|
buffers: [vertexBufferLayout]
|
|
4225
4213
|
},
|
|
4226
4214
|
fragment: {
|
|
4227
|
-
module:
|
|
4215
|
+
module: drawingShader,
|
|
4228
4216
|
entryPoint: 'fragmentMain',
|
|
4229
4217
|
targets: [{ format: 'bgra8unorm', blend: $.blendConfigs.normal }]
|
|
4230
4218
|
},
|
|
4231
4219
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
4232
|
-
multisample: {
|
|
4233
|
-
count: 4
|
|
4234
|
-
}
|
|
4220
|
+
multisample: { count: 4 }
|
|
4235
4221
|
};
|
|
4236
4222
|
|
|
4237
4223
|
$._pipelines[0] = Q5.device.createRenderPipeline($._pipelineConfigs[0]);
|
|
@@ -4360,7 +4346,7 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4360
4346
|
let [l, r, t, b] = $._calcBox(x, y, w, h, $._rectMode);
|
|
4361
4347
|
let ci, ti;
|
|
4362
4348
|
if ($._matrixDirty) $._saveMatrix();
|
|
4363
|
-
ti = $.
|
|
4349
|
+
ti = $._matrixIndex;
|
|
4364
4350
|
|
|
4365
4351
|
if ($._doFill) {
|
|
4366
4352
|
ci = $._fill;
|
|
@@ -4434,7 +4420,7 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4434
4420
|
let b = w == h ? a : Math.max(h, 1) / 2;
|
|
4435
4421
|
|
|
4436
4422
|
if ($._matrixDirty) $._saveMatrix();
|
|
4437
|
-
let ti = $.
|
|
4423
|
+
let ti = $._matrixIndex;
|
|
4438
4424
|
|
|
4439
4425
|
if ($._doFill) {
|
|
4440
4426
|
addEllipse(x, y, a, b, n, $._fill, ti);
|
|
@@ -4450,7 +4436,7 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4450
4436
|
|
|
4451
4437
|
$.point = (x, y) => {
|
|
4452
4438
|
if ($._matrixDirty) $._saveMatrix();
|
|
4453
|
-
let ti = $.
|
|
4439
|
+
let ti = $._matrixIndex,
|
|
4454
4440
|
ci = $._stroke,
|
|
4455
4441
|
sw = $._strokeWeight;
|
|
4456
4442
|
|
|
@@ -4470,7 +4456,7 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4470
4456
|
|
|
4471
4457
|
$.line = (x1, y1, x2, y2) => {
|
|
4472
4458
|
if ($._matrixDirty) $._saveMatrix();
|
|
4473
|
-
let ti = $.
|
|
4459
|
+
let ti = $._matrixIndex,
|
|
4474
4460
|
ci = $._stroke,
|
|
4475
4461
|
sw = $._strokeWeight,
|
|
4476
4462
|
hsw = sw / 2;
|
|
@@ -4505,7 +4491,7 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4505
4491
|
|
|
4506
4492
|
$.vertex = (x, y) => {
|
|
4507
4493
|
if ($._matrixDirty) $._saveMatrix();
|
|
4508
|
-
sv.push(x, -y, $._fill, $.
|
|
4494
|
+
sv.push(x, -y, $._fill, $._matrixIndex);
|
|
4509
4495
|
shapeVertCount++;
|
|
4510
4496
|
};
|
|
4511
4497
|
|
|
@@ -4550,7 +4536,7 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4550
4536
|
(2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y) * t2 +
|
|
4551
4537
|
(-p0.y + 3 * p1.y - 3 * p2.y + p3.y) * t3);
|
|
4552
4538
|
|
|
4553
|
-
sv.push(x, y, $._fill, $.
|
|
4539
|
+
sv.push(x, y, $._fill, $._matrixIndex);
|
|
4554
4540
|
shapeVertCount++;
|
|
4555
4541
|
}
|
|
4556
4542
|
}
|
|
@@ -4667,53 +4653,66 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4667
4653
|
});
|
|
4668
4654
|
};
|
|
4669
4655
|
Q5.renderers.webgpu.image = ($, q) => {
|
|
4670
|
-
|
|
4671
|
-
|
|
4656
|
+
let vertexStack = new Float32Array(1e7),
|
|
4657
|
+
vertIndex = 0;
|
|
4672
4658
|
|
|
4673
|
-
let
|
|
4674
|
-
label: '
|
|
4659
|
+
let imageShader = Q5.device.createShaderModule({
|
|
4660
|
+
label: 'imageShader',
|
|
4675
4661
|
code: `
|
|
4676
|
-
struct VertexOutput {
|
|
4677
|
-
@builtin(position) position: vec4f,
|
|
4678
|
-
@location(0) texCoord: vec2f
|
|
4679
|
-
}
|
|
4680
4662
|
struct Uniforms {
|
|
4681
4663
|
halfWidth: f32,
|
|
4682
4664
|
halfHeight: f32
|
|
4683
4665
|
}
|
|
4666
|
+
struct VertexParams {
|
|
4667
|
+
@location(0) pos: vec2f,
|
|
4668
|
+
@location(1) texCoord: vec2f,
|
|
4669
|
+
@location(2) tintIndex: f32,
|
|
4670
|
+
@location(3) matrixIndex: f32,
|
|
4671
|
+
@location(4) globalAlpha: f32
|
|
4672
|
+
}
|
|
4673
|
+
struct FragmentParams {
|
|
4674
|
+
@builtin(position) position: vec4f,
|
|
4675
|
+
@location(0) texCoord: vec2f,
|
|
4676
|
+
@location(1) tintIndex: f32,
|
|
4677
|
+
@location(2) globalAlpha: f32
|
|
4678
|
+
}
|
|
4684
4679
|
|
|
4685
4680
|
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
4686
4681
|
@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
|
|
4682
|
+
@group(0) @binding(2) var<storage> colors : array<vec4f>;
|
|
4683
|
+
|
|
4684
|
+
@group(1) @binding(0) var samp: sampler;
|
|
4685
|
+
@group(1) @binding(1) var texture: texture_2d<f32>;
|
|
4687
4686
|
|
|
4688
4687
|
@vertex
|
|
4689
|
-
fn vertexMain(
|
|
4690
|
-
var vert = vec4f(pos, 0.0, 1.0);
|
|
4691
|
-
vert = transforms[i32(
|
|
4688
|
+
fn vertexMain(v: VertexParams) -> FragmentParams {
|
|
4689
|
+
var vert = vec4f(v.pos, 0.0, 1.0);
|
|
4690
|
+
vert = transforms[i32(v.matrixIndex)] * vert;
|
|
4692
4691
|
vert.x /= uniforms.halfWidth;
|
|
4693
4692
|
vert.y /= uniforms.halfHeight;
|
|
4694
4693
|
|
|
4695
|
-
var
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4694
|
+
var f: FragmentParams;
|
|
4695
|
+
f.position = vert;
|
|
4696
|
+
f.texCoord = v.texCoord;
|
|
4697
|
+
f.tintIndex = v.tintIndex;
|
|
4698
|
+
f.globalAlpha = v.globalAlpha;
|
|
4699
|
+
return f;
|
|
4699
4700
|
}
|
|
4700
|
-
`
|
|
4701
|
-
});
|
|
4702
|
-
|
|
4703
|
-
let fragmentShader = Q5.device.createShaderModule({
|
|
4704
|
-
label: 'imageFragmentShader',
|
|
4705
|
-
code: `
|
|
4706
|
-
@group(2) @binding(0) var samp: sampler;
|
|
4707
|
-
@group(2) @binding(1) var texture: texture_2d<f32>;
|
|
4708
4701
|
|
|
4709
4702
|
@fragment
|
|
4710
|
-
fn fragmentMain(
|
|
4711
|
-
|
|
4712
|
-
|
|
4703
|
+
fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
|
|
4704
|
+
let texColor = textureSample(texture, samp, f.texCoord);
|
|
4705
|
+
let tintColor = colors[i32(f.tintIndex)];
|
|
4706
|
+
|
|
4707
|
+
// Mix original and tinted colors using tint alpha as blend factor
|
|
4708
|
+
let tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a * f.globalAlpha);
|
|
4709
|
+
return mix(texColor, tinted, tintColor.a);
|
|
4713
4710
|
}
|
|
4714
4711
|
`
|
|
4715
4712
|
});
|
|
4716
4713
|
|
|
4714
|
+
$._textureBindGroups = [];
|
|
4715
|
+
|
|
4717
4716
|
let textureLayout = Q5.device.createBindGroupLayout({
|
|
4718
4717
|
label: 'textureLayout',
|
|
4719
4718
|
entries: [
|
|
@@ -4731,11 +4730,13 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4731
4730
|
});
|
|
4732
4731
|
|
|
4733
4732
|
const vertexBufferLayout = {
|
|
4734
|
-
arrayStride:
|
|
4733
|
+
arrayStride: 28,
|
|
4735
4734
|
attributes: [
|
|
4736
4735
|
{ shaderLocation: 0, offset: 0, format: 'float32x2' },
|
|
4737
4736
|
{ shaderLocation: 1, offset: 8, format: 'float32x2' },
|
|
4738
|
-
{ shaderLocation: 2, offset: 16, format: 'float32' } //
|
|
4737
|
+
{ shaderLocation: 2, offset: 16, format: 'float32' }, // tintIndex
|
|
4738
|
+
{ shaderLocation: 3, offset: 20, format: 'float32' }, // matrixIndex
|
|
4739
|
+
{ shaderLocation: 4, offset: 24, format: 'float32' } // globalAlpha
|
|
4739
4740
|
]
|
|
4740
4741
|
};
|
|
4741
4742
|
|
|
@@ -4748,12 +4749,12 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4748
4749
|
label: 'imagePipeline',
|
|
4749
4750
|
layout: pipelineLayout,
|
|
4750
4751
|
vertex: {
|
|
4751
|
-
module:
|
|
4752
|
+
module: imageShader,
|
|
4752
4753
|
entryPoint: 'vertexMain',
|
|
4753
4754
|
buffers: [{ arrayStride: 0, attributes: [] }, vertexBufferLayout]
|
|
4754
4755
|
},
|
|
4755
4756
|
fragment: {
|
|
4756
|
-
module:
|
|
4757
|
+
module: imageShader,
|
|
4757
4758
|
entryPoint: 'fragmentMain',
|
|
4758
4759
|
targets: [{ format: 'bgra8unorm', blend: $.blendConfigs.normal }]
|
|
4759
4760
|
},
|
|
@@ -4829,58 +4830,64 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4829
4830
|
|
|
4830
4831
|
$.loadImage = (src, cb) => {
|
|
4831
4832
|
q._preloadCount++;
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
// calculate the default width and height that the image
|
|
4836
|
-
// should be drawn at if the user doesn't specify a display size
|
|
4837
|
-
img.defaultWidth = img.width * $._defaultImageScale;
|
|
4838
|
-
img.defaultHeight = img.height * $._defaultImageScale;
|
|
4839
|
-
img.pixelDensity = 1;
|
|
4840
|
-
|
|
4833
|
+
let g = $._g.loadImage(src, (img) => {
|
|
4834
|
+
g.defaultWidth = img.width * $._defaultImageScale;
|
|
4835
|
+
g.defaultHeight = img.height * $._defaultImageScale;
|
|
4841
4836
|
$._createTexture(img);
|
|
4842
4837
|
q._preloadCount--;
|
|
4843
4838
|
if (cb) cb(img);
|
|
4844
|
-
};
|
|
4845
|
-
|
|
4846
|
-
return img;
|
|
4839
|
+
});
|
|
4840
|
+
return g;
|
|
4847
4841
|
};
|
|
4848
4842
|
|
|
4849
4843
|
$.imageMode = (x) => ($._imageMode = x);
|
|
4850
4844
|
|
|
4851
|
-
|
|
4845
|
+
const addVert = (x, y, u, v, ci, ti, ga) => {
|
|
4846
|
+
let s = vertexStack,
|
|
4847
|
+
i = vertIndex;
|
|
4848
|
+
s[i++] = x;
|
|
4849
|
+
s[i++] = y;
|
|
4850
|
+
s[i++] = u;
|
|
4851
|
+
s[i++] = v;
|
|
4852
|
+
s[i++] = ci;
|
|
4853
|
+
s[i++] = ti;
|
|
4854
|
+
s[i++] = ga;
|
|
4855
|
+
vertIndex = i;
|
|
4856
|
+
};
|
|
4857
|
+
|
|
4858
|
+
$.image = (img, dx = 0, dy = 0, dw, dh, sx = 0, sy = 0, sw, sh) => {
|
|
4859
|
+
let g = img;
|
|
4852
4860
|
if (img.canvas) img = img.canvas;
|
|
4853
4861
|
if (img.textureIndex == undefined) return;
|
|
4854
4862
|
|
|
4855
4863
|
if ($._matrixDirty) $._saveMatrix();
|
|
4856
|
-
let ti = $._transformIndex;
|
|
4857
4864
|
|
|
4858
|
-
let w = img.width
|
|
4859
|
-
|
|
4865
|
+
let w = img.width,
|
|
4866
|
+
h = img.height,
|
|
4867
|
+
pd = g._pixelDensity || 1;
|
|
4860
4868
|
|
|
4861
|
-
dw ??=
|
|
4862
|
-
dh ??=
|
|
4869
|
+
dw ??= g.defaultWidth;
|
|
4870
|
+
dh ??= g.defaultHeight;
|
|
4863
4871
|
sw ??= w;
|
|
4864
4872
|
sh ??= h;
|
|
4865
4873
|
|
|
4866
|
-
let pd = img.pixelDensity || 1;
|
|
4867
4874
|
dw *= pd;
|
|
4868
4875
|
dh *= pd;
|
|
4869
4876
|
|
|
4870
4877
|
let [l, r, t, b] = $._calcBox(dx, dy, dw, dh, $._imageMode);
|
|
4871
4878
|
|
|
4872
|
-
let u0 = sx / w
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
);
|
|
4879
|
+
let u0 = sx / w,
|
|
4880
|
+
v0 = sy / h,
|
|
4881
|
+
u1 = (sx + sw) / w,
|
|
4882
|
+
v1 = (sy + sh) / h,
|
|
4883
|
+
ti = $._matrixIndex,
|
|
4884
|
+
ci = $._tint,
|
|
4885
|
+
ga = $._globalAlpha;
|
|
4886
|
+
|
|
4887
|
+
addVert(l, t, u0, v0, ci, ti, ga);
|
|
4888
|
+
addVert(r, t, u1, v0, ci, ti, ga);
|
|
4889
|
+
addVert(l, b, u0, v1, ci, ti, ga);
|
|
4890
|
+
addVert(r, b, u1, v1, ci, ti, ga);
|
|
4884
4891
|
|
|
4885
4892
|
$.drawStack.push(1, img.textureIndex);
|
|
4886
4893
|
};
|
|
@@ -4891,20 +4898,20 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4891
4898
|
// Switch to image pipeline
|
|
4892
4899
|
$.pass.setPipeline($._pipelines[1]);
|
|
4893
4900
|
|
|
4894
|
-
|
|
4895
|
-
size:
|
|
4901
|
+
let vertexBuffer = Q5.device.createBuffer({
|
|
4902
|
+
size: vertIndex * 5,
|
|
4896
4903
|
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
|
4897
4904
|
mappedAtCreation: true
|
|
4898
4905
|
});
|
|
4899
4906
|
|
|
4900
|
-
new Float32Array(vertexBuffer.getMappedRange()).set(vertexStack);
|
|
4907
|
+
new Float32Array(vertexBuffer.getMappedRange()).set(vertexStack.slice(0, vertIndex));
|
|
4901
4908
|
vertexBuffer.unmap();
|
|
4902
4909
|
|
|
4903
4910
|
$.pass.setVertexBuffer(1, vertexBuffer);
|
|
4904
4911
|
});
|
|
4905
4912
|
|
|
4906
4913
|
$._hooks.postRender.push(() => {
|
|
4907
|
-
|
|
4914
|
+
vertIndex = 0;
|
|
4908
4915
|
});
|
|
4909
4916
|
};
|
|
4910
4917
|
|
|
@@ -4920,14 +4927,15 @@ Q5.renderers.webgpu.text = ($, q) => {
|
|
|
4920
4927
|
let textShader = Q5.device.createShaderModule({
|
|
4921
4928
|
label: 'MSDF text shader',
|
|
4922
4929
|
code: `
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4930
|
+
struct Uniforms {
|
|
4931
|
+
halfWidth: f32,
|
|
4932
|
+
halfHeight: f32
|
|
4933
|
+
}
|
|
4934
|
+
struct VertexParams {
|
|
4927
4935
|
@builtin(vertex_index) vertex : u32,
|
|
4928
4936
|
@builtin(instance_index) instance : u32
|
|
4929
4937
|
}
|
|
4930
|
-
struct
|
|
4938
|
+
struct FragmentParams {
|
|
4931
4939
|
@builtin(position) position : vec4f,
|
|
4932
4940
|
@location(0) texCoord : vec2f,
|
|
4933
4941
|
@location(1) fillColor : vec4f
|
|
@@ -4941,47 +4949,44 @@ struct Char {
|
|
|
4941
4949
|
struct Text {
|
|
4942
4950
|
pos: vec2f,
|
|
4943
4951
|
scale: f32,
|
|
4944
|
-
|
|
4952
|
+
matrixIndex: f32,
|
|
4945
4953
|
fillIndex: f32,
|
|
4946
4954
|
strokeIndex: f32
|
|
4947
4955
|
}
|
|
4948
|
-
struct Uniforms {
|
|
4949
|
-
halfWidth: f32,
|
|
4950
|
-
halfHeight: f32
|
|
4951
|
-
}
|
|
4952
4956
|
|
|
4953
4957
|
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
4954
4958
|
@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
|
|
4959
|
+
@group(0) @binding(2) var<storage> colors : array<vec4f>;
|
|
4955
4960
|
|
|
4956
|
-
@group(1) @binding(0) var
|
|
4961
|
+
@group(1) @binding(0) var fontTexture: texture_2d<f32>;
|
|
4962
|
+
@group(1) @binding(1) var fontSampler: sampler;
|
|
4963
|
+
@group(1) @binding(2) var<storage> fontChars: array<Char>;
|
|
4957
4964
|
|
|
4958
|
-
@group(2) @binding(0) var
|
|
4959
|
-
@group(2) @binding(1) var
|
|
4960
|
-
@group(2) @binding(2) var<storage> fontChars: array<Char>;
|
|
4965
|
+
@group(2) @binding(0) var<storage> textChars: array<vec4f>;
|
|
4966
|
+
@group(2) @binding(1) var<storage> textMetadata: array<Text>;
|
|
4961
4967
|
|
|
4962
|
-
|
|
4963
|
-
@group(3) @binding(1) var<storage> textMetadata: array<Text>;
|
|
4968
|
+
const quad = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));
|
|
4964
4969
|
|
|
4965
4970
|
@vertex
|
|
4966
|
-
fn vertexMain(
|
|
4967
|
-
let char = textChars[
|
|
4971
|
+
fn vertexMain(v : VertexParams) -> FragmentParams {
|
|
4972
|
+
let char = textChars[v.instance];
|
|
4968
4973
|
|
|
4969
4974
|
let text = textMetadata[i32(char.w)];
|
|
4970
4975
|
|
|
4971
4976
|
let fontChar = fontChars[i32(char.z)];
|
|
4972
4977
|
|
|
4973
|
-
let charPos = ((
|
|
4978
|
+
let charPos = ((quad[v.vertex] * fontChar.size + char.xy + fontChar.offset) * text.scale) + text.pos;
|
|
4974
4979
|
|
|
4975
4980
|
var vert = vec4f(charPos, 0.0, 1.0);
|
|
4976
|
-
vert = transforms[i32(text.
|
|
4981
|
+
vert = transforms[i32(text.matrixIndex)] * vert;
|
|
4977
4982
|
vert.x /= uniforms.halfWidth;
|
|
4978
4983
|
vert.y /= uniforms.halfHeight;
|
|
4979
4984
|
|
|
4980
|
-
var
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
return
|
|
4985
|
+
var f : FragmentParams;
|
|
4986
|
+
f.position = vert;
|
|
4987
|
+
f.texCoord = (quad[v.vertex] * vec2f(1, -1)) * fontChar.texExtent + fontChar.texOffset;
|
|
4988
|
+
f.fillColor = colors[i32(text.fillIndex)];
|
|
4989
|
+
return f;
|
|
4985
4990
|
}
|
|
4986
4991
|
|
|
4987
4992
|
fn sampleMsdf(texCoord: vec2f) -> f32 {
|
|
@@ -4990,22 +4995,22 @@ fn sampleMsdf(texCoord: vec2f) -> f32 {
|
|
|
4990
4995
|
}
|
|
4991
4996
|
|
|
4992
4997
|
@fragment
|
|
4993
|
-
fn fragmentMain(
|
|
4998
|
+
fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
|
|
4994
4999
|
// pxRange (AKA distanceRange) comes from the msdfgen tool,
|
|
4995
5000
|
// uses the default which is 4.
|
|
4996
5001
|
let pxRange = 4.0;
|
|
4997
5002
|
let sz = vec2f(textureDimensions(fontTexture, 0));
|
|
4998
|
-
let dx = sz.x*length(vec2f(dpdxFine(
|
|
4999
|
-
let dy = sz.y*length(vec2f(dpdxFine(
|
|
5003
|
+
let dx = sz.x*length(vec2f(dpdxFine(f.texCoord.x), dpdyFine(f.texCoord.x)));
|
|
5004
|
+
let dy = sz.y*length(vec2f(dpdxFine(f.texCoord.y), dpdyFine(f.texCoord.y)));
|
|
5000
5005
|
let toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);
|
|
5001
|
-
let sigDist = sampleMsdf(
|
|
5006
|
+
let sigDist = sampleMsdf(f.texCoord) - 0.5;
|
|
5002
5007
|
let pxDist = sigDist * toPixels;
|
|
5003
5008
|
let edgeWidth = 0.5;
|
|
5004
5009
|
let alpha = smoothstep(-edgeWidth, edgeWidth, pxDist);
|
|
5005
5010
|
if (alpha < 0.001) {
|
|
5006
5011
|
discard;
|
|
5007
5012
|
}
|
|
5008
|
-
return vec4f(
|
|
5013
|
+
return vec4f(f.fillColor.rgb, f.fillColor.a * alpha);
|
|
5009
5014
|
}
|
|
5010
5015
|
`
|
|
5011
5016
|
});
|
|
@@ -5197,13 +5202,11 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
|
|
|
5197
5202
|
if (cb) cb(fontName);
|
|
5198
5203
|
};
|
|
5199
5204
|
|
|
5200
|
-
|
|
5201
|
-
let g = $.createGraphics(1, 1);
|
|
5202
|
-
g.colorMode($.RGB, 1);
|
|
5205
|
+
$._g.colorMode($.RGB, 1);
|
|
5203
5206
|
|
|
5204
5207
|
$.loadFont = (url, cb) => {
|
|
5205
5208
|
let ext = url.slice(url.lastIndexOf('.') + 1);
|
|
5206
|
-
if (ext != 'json') return
|
|
5209
|
+
if (ext != 'json') return $._g.loadFont(url, cb);
|
|
5207
5210
|
let fontName = url.slice(url.lastIndexOf('/') + 1, url.lastIndexOf('-'));
|
|
5208
5211
|
createFont(url, fontName, cb);
|
|
5209
5212
|
return fontName;
|
|
@@ -5388,7 +5391,7 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
|
|
|
5388
5391
|
text[0] = x;
|
|
5389
5392
|
text[1] = -y;
|
|
5390
5393
|
text[2] = $._textSize / 44;
|
|
5391
|
-
text[3] = $.
|
|
5394
|
+
text[3] = $._matrixIndex;
|
|
5392
5395
|
text[4] = $._fillSet ? $._fill : 0;
|
|
5393
5396
|
text[5] = $._stroke;
|
|
5394
5397
|
|
|
@@ -5402,18 +5405,18 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
|
|
|
5402
5405
|
};
|
|
5403
5406
|
|
|
5404
5407
|
$.createTextImage = (str, w, h) => {
|
|
5405
|
-
|
|
5408
|
+
$._g.textSize($._textSize);
|
|
5406
5409
|
|
|
5407
5410
|
if ($._doFill) {
|
|
5408
5411
|
let fi = $._fill * 4;
|
|
5409
|
-
|
|
5412
|
+
$._g.fill(colorStack.slice(fi, fi + 4));
|
|
5410
5413
|
}
|
|
5411
5414
|
if ($._doStroke) {
|
|
5412
5415
|
let si = $._stroke * 4;
|
|
5413
|
-
|
|
5416
|
+
$._g.stroke(colorStack.slice(si, si + 4));
|
|
5414
5417
|
}
|
|
5415
5418
|
|
|
5416
|
-
let img =
|
|
5419
|
+
let img = $._g.createTextImage(str, w, h);
|
|
5417
5420
|
|
|
5418
5421
|
if (img.canvas.textureIndex == undefined) {
|
|
5419
5422
|
$._createTexture(img);
|