lgimgui 0.1.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 +111 -0
- package/demo/public/materials.json +809 -0
- package/package.json +39 -0
- package/src/core/curve.js +71 -0
- package/src/core/frame.js +272 -0
- package/src/core/geometry.js +61 -0
- package/src/core/ids.js +31 -0
- package/src/core/input.js +294 -0
- package/src/core/layout.js +220 -0
- package/src/core/spring.js +113 -0
- package/src/core/state.js +54 -0
- package/src/core/theme.js +77 -0
- package/src/index.js +221 -0
- package/src/material/adapt.js +72 -0
- package/src/material/material.js +131 -0
- package/src/material/optics.js +49 -0
- package/src/material/params.js +83 -0
- package/src/material/presets.js +291 -0
- package/src/render/batch.js +236 -0
- package/src/render/context.js +138 -0
- package/src/render/glyphs.js +177 -0
- package/src/render/probe.js +64 -0
- package/src/render/pyramid.js +48 -0
- package/src/render/renderer.js +296 -0
- package/src/render/shaders/color.js +58 -0
- package/src/render/shaders/glass.js +241 -0
- package/src/render/shaders/ui.js +194 -0
- package/src/widgets/composite.js +355 -0
- package/src/widgets/controls.js +545 -0
- package/src/widgets/desktop.js +144 -0
- package/src/widgets/glass.js +326 -0
- package/src/widgets/primitives.js +355 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { colorLib } from './color.js'
|
|
2
|
+
|
|
3
|
+
export const MAX_SHAPES = 8
|
|
4
|
+
|
|
5
|
+
export const glassVertex = /* glsl */ `#version 300 es
|
|
6
|
+
precision highp float;
|
|
7
|
+
uniform vec2 u_viewport;
|
|
8
|
+
uniform vec4 u_quad;
|
|
9
|
+
void main() {
|
|
10
|
+
vec2 corner = vec2(float(gl_VertexID & 1), float((gl_VertexID >> 1) & 1));
|
|
11
|
+
vec2 p = u_quad.xy + corner * u_quad.zw;
|
|
12
|
+
gl_Position = vec4(p.x / u_viewport.x * 2.0 - 1.0, 1.0 - p.y / u_viewport.y * 2.0, 0.0, 1.0);
|
|
13
|
+
}
|
|
14
|
+
`
|
|
15
|
+
|
|
16
|
+
export const glassFragment = /* glsl */ `#version 300 es
|
|
17
|
+
precision highp float;
|
|
18
|
+
|
|
19
|
+
#define PI 3.14159265359
|
|
20
|
+
#define MAX_SHAPES ${MAX_SHAPES}
|
|
21
|
+
|
|
22
|
+
const float N_R = 1.0 - 0.02;
|
|
23
|
+
const float N_G = 1.0;
|
|
24
|
+
const float N_B = 1.0 + 0.02;
|
|
25
|
+
|
|
26
|
+
uniform sampler2D u_scene;
|
|
27
|
+
uniform vec2 u_resolution;
|
|
28
|
+
uniform float u_dpr;
|
|
29
|
+
uniform int u_pass;
|
|
30
|
+
uniform int u_shapeCount;
|
|
31
|
+
uniform vec4 u_shapes[MAX_SHAPES];
|
|
32
|
+
uniform vec2 u_corners[MAX_SHAPES];
|
|
33
|
+
uniform float u_shapeFade[MAX_SHAPES];
|
|
34
|
+
uniform float u_mergeRate;
|
|
35
|
+
uniform int u_hardFirst;
|
|
36
|
+
|
|
37
|
+
uniform vec4 u_tint;
|
|
38
|
+
uniform float u_refThickness;
|
|
39
|
+
uniform float u_refFactor;
|
|
40
|
+
uniform float u_refDispersion;
|
|
41
|
+
uniform float u_refFresnelRange;
|
|
42
|
+
uniform float u_refFresnelFactor;
|
|
43
|
+
uniform float u_refFresnelHardness;
|
|
44
|
+
uniform float u_glareRange;
|
|
45
|
+
uniform float u_glareConvergence;
|
|
46
|
+
uniform float u_glareOppositeFactor;
|
|
47
|
+
uniform float u_glareFactor;
|
|
48
|
+
uniform float u_glareHardness;
|
|
49
|
+
uniform float u_glareAngle;
|
|
50
|
+
uniform int u_blurEdge;
|
|
51
|
+
uniform float u_blurLod;
|
|
52
|
+
|
|
53
|
+
uniform float u_shadowExpand;
|
|
54
|
+
uniform float u_shadowFactor;
|
|
55
|
+
uniform vec2 u_shadowOffset;
|
|
56
|
+
uniform int u_shadowClipOn;
|
|
57
|
+
uniform vec4 u_shadowClipRect;
|
|
58
|
+
uniform vec2 u_shadowClipCorner;
|
|
59
|
+
|
|
60
|
+
uniform float u_dimming;
|
|
61
|
+
uniform vec4 u_glow;
|
|
62
|
+
uniform float u_coverageScale;
|
|
63
|
+
uniform float u_border;
|
|
64
|
+
uniform vec4 u_borderColor;
|
|
65
|
+
|
|
66
|
+
out vec4 fragColor;
|
|
67
|
+
|
|
68
|
+
${colorLib}
|
|
69
|
+
|
|
70
|
+
float safeAsin(float x) {
|
|
71
|
+
return asin(clamp(x, -1.0, 1.0));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
float superellipseCornerSDF(vec2 p, float r, float n) {
|
|
75
|
+
p = abs(p);
|
|
76
|
+
return pow(pow(p.x, n) + pow(p.y, n), 1.0 / n) - r;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
float roundedRectSDF(vec2 p, vec4 shape, vec2 corner) {
|
|
80
|
+
vec2 half_size = shape.zw * 0.5;
|
|
81
|
+
vec2 q = p - (shape.xy + half_size);
|
|
82
|
+
float cr = max(0.5, min(corner.x, min(half_size.x, half_size.y)));
|
|
83
|
+
float n = cr >= min(half_size.x, half_size.y) - 0.5 ? 2.0 : corner.y;
|
|
84
|
+
vec2 d = abs(q) - half_size;
|
|
85
|
+
if (d.x > -cr && d.y > -cr) {
|
|
86
|
+
vec2 cornerCenter = sign(q) * (half_size - vec2(cr));
|
|
87
|
+
return superellipseCornerSDF(q - cornerCenter, cr, n);
|
|
88
|
+
}
|
|
89
|
+
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
float smin(float a, float b, float k) {
|
|
93
|
+
if (k <= 0.0) return min(a, b);
|
|
94
|
+
float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);
|
|
95
|
+
return mix(b, a, h) - k * h * (1.0 - h);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
float shapeSDF(vec2 p, int i) {
|
|
99
|
+
return roundedRectSDF(p, u_shapes[i], u_corners[i]) + u_mergeRate * (1.0 - u_shapeFade[i]);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
float mainSDF(vec2 p) {
|
|
103
|
+
int first = u_hardFirst > 0 ? 1 : 0;
|
|
104
|
+
float d = first < u_shapeCount ? shapeSDF(p, first) : 1e5;
|
|
105
|
+
for (int i = 1; i < MAX_SHAPES; i++) {
|
|
106
|
+
if (i <= first) continue;
|
|
107
|
+
if (i >= u_shapeCount) break;
|
|
108
|
+
d = smin(d, shapeSDF(p, i), u_mergeRate);
|
|
109
|
+
}
|
|
110
|
+
if (u_hardFirst > 0) d = min(d, shapeSDF(p, 0));
|
|
111
|
+
return d;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
vec2 getNormal(vec2 p) {
|
|
115
|
+
float h = 1.0 / u_dpr;
|
|
116
|
+
return vec2(
|
|
117
|
+
mainSDF(p + vec2(h, 0.0)) - mainSDF(p - vec2(h, 0.0)),
|
|
118
|
+
mainSDF(p + vec2(0.0, h)) - mainSDF(p - vec2(0.0, h))
|
|
119
|
+
) / (2.0 * h);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
float vec2ToAngle(vec2 v) {
|
|
123
|
+
float angle = atan(v.y, v.x);
|
|
124
|
+
if (angle < 0.0) angle += 2.0 * PI;
|
|
125
|
+
return angle;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
vec2 toUv(vec2 cssOffset) {
|
|
129
|
+
return vec2(cssOffset.x, -cssOffset.y) * u_dpr / u_resolution;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
vec4 getTextureDispersion(vec2 uv, float mixRate, vec2 offset, float factor) {
|
|
133
|
+
vec2 offR = toUv(offset * (1.0 - (N_R - 1.0) * factor));
|
|
134
|
+
vec2 offG = toUv(offset * (1.0 - (N_G - 1.0) * factor));
|
|
135
|
+
vec2 offB = toUv(offset * (1.0 - (N_B - 1.0) * factor));
|
|
136
|
+
float bgR = textureLod(u_scene, uv + offR, 0.0).r;
|
|
137
|
+
float bgG = textureLod(u_scene, uv + offG, 0.0).g;
|
|
138
|
+
float bgB = textureLod(u_scene, uv + offB, 0.0).b;
|
|
139
|
+
float blurR = textureLod(u_scene, uv + offR, u_blurLod).r;
|
|
140
|
+
float blurG = textureLod(u_scene, uv + offG, u_blurLod).g;
|
|
141
|
+
float blurB = textureLod(u_scene, uv + offB, u_blurLod).b;
|
|
142
|
+
return vec4(mix(bgR, blurR, mixRate), mix(bgG, blurG, mixRate), mix(bgB, blurB, mixRate), 1.0);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
float edgeProfile(float sdf, float range, float hardness) {
|
|
146
|
+
float safeRange = max(range, 0.001);
|
|
147
|
+
return clamp(pow(max(1.0 + sdf / 1500.0 * pow(500.0 / safeRange, 2.0) + hardness, 0.0), 5.0), 0.0, 1.0);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
void main() {
|
|
151
|
+
vec2 uv = gl_FragCoord.xy / u_resolution;
|
|
152
|
+
vec2 p = vec2(gl_FragCoord.x, u_resolution.y - gl_FragCoord.y) / u_dpr;
|
|
153
|
+
|
|
154
|
+
if (u_pass == 0) {
|
|
155
|
+
float sdf = mainSDF(p - u_shadowOffset);
|
|
156
|
+
float shadow = exp(-1.0 / u_shadowExpand * max(sdf, 0.0)) * 0.6 * u_shadowFactor;
|
|
157
|
+
if (u_shadowClipOn > 0) {
|
|
158
|
+
float clipSdf = roundedRectSDF(p, u_shadowClipRect, u_shadowClipCorner);
|
|
159
|
+
float aa = 0.75 / u_dpr;
|
|
160
|
+
shadow *= 1.0 - smoothstep(-aa, aa, clipSdf);
|
|
161
|
+
}
|
|
162
|
+
fragColor = vec4(vec3(shadow), 0.0);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
float merged = mainSDF(p);
|
|
167
|
+
float aa = 0.75 / u_dpr;
|
|
168
|
+
float coverage = (1.0 - smoothstep(-aa, aa, merged)) * u_coverageScale;
|
|
169
|
+
if (coverage <= 0.0 && u_border <= 0.0) {
|
|
170
|
+
fragColor = vec4(0.0);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
float nmerged = -merged;
|
|
175
|
+
float x_R_ratio = 1.0 - nmerged / u_refThickness;
|
|
176
|
+
float thetaI = safeAsin(pow(x_R_ratio, 2.0));
|
|
177
|
+
float thetaT = safeAsin(1.0 / u_refFactor * sin(thetaI));
|
|
178
|
+
float edgeFactor = -1.0 * tan(thetaT - thetaI);
|
|
179
|
+
if (nmerged >= u_refThickness) edgeFactor = 0.0;
|
|
180
|
+
|
|
181
|
+
vec2 normal = vec2(0.0);
|
|
182
|
+
float normalLength = 0.0;
|
|
183
|
+
vec3 blurredPixel;
|
|
184
|
+
if (edgeFactor <= 0.0) {
|
|
185
|
+
blurredPixel = textureLod(u_scene, uv, u_blurLod).rgb;
|
|
186
|
+
} else {
|
|
187
|
+
float edgeH = nmerged / u_refThickness;
|
|
188
|
+
normal = getNormal(p);
|
|
189
|
+
normalLength = length(normal);
|
|
190
|
+
blurredPixel = getTextureDispersion(
|
|
191
|
+
uv,
|
|
192
|
+
u_blurEdge > 0 ? 1.0 : edgeH,
|
|
193
|
+
-normal * edgeFactor * 70.710678,
|
|
194
|
+
u_refDispersion
|
|
195
|
+
).rgb;
|
|
196
|
+
}
|
|
197
|
+
blurredPixel *= 1.0 - u_dimming;
|
|
198
|
+
vec3 outColor = mix(blurredPixel, u_tint.rgb, u_tint.a);
|
|
199
|
+
|
|
200
|
+
if (edgeFactor > 0.0) {
|
|
201
|
+
float rimFade = smoothstep(0.0, -1.5 / u_dpr, merged);
|
|
202
|
+
float fresnelFactor = edgeProfile(merged, u_refFresnelRange, u_refFresnelHardness) * rimFade;
|
|
203
|
+
vec3 fresnelTintLCH = SRGB_TO_LCH(mix(vec3(1.0), u_tint.rgb, u_tint.a * 0.5));
|
|
204
|
+
fresnelTintLCH.x += 20.0 * fresnelFactor * u_refFresnelFactor;
|
|
205
|
+
fresnelTintLCH.x = clamp(fresnelTintLCH.x, 0.0, 100.0);
|
|
206
|
+
outColor = mix(outColor, LCH_TO_SRGB(fresnelTintLCH), fresnelFactor * u_refFresnelFactor * 0.7 * normalLength);
|
|
207
|
+
|
|
208
|
+
float glareGeoFactor = edgeProfile(merged, u_glareRange, u_glareHardness) * rimFade;
|
|
209
|
+
float glareAngle = (vec2ToAngle(normalize(normal)) - PI / 4.0 + u_glareAngle) * 2.0;
|
|
210
|
+
bool glareFarside = (glareAngle > PI * 1.5 && glareAngle < PI * 3.5) || glareAngle < -PI * 0.5;
|
|
211
|
+
float glareAngleFactor = (0.5 + sin(glareAngle) * 0.5) * (glareFarside ? 1.2 * u_glareOppositeFactor : 1.2) * u_glareFactor;
|
|
212
|
+
glareAngleFactor = clamp(pow(max(glareAngleFactor, 0.0), 0.1 + u_glareConvergence * 2.0), 0.0, 1.0);
|
|
213
|
+
|
|
214
|
+
vec3 glareTintLCH = SRGB_TO_LCH(mix(blurredPixel, u_tint.rgb, u_tint.a * 0.5));
|
|
215
|
+
glareTintLCH.x += 150.0 * glareAngleFactor * glareGeoFactor;
|
|
216
|
+
glareTintLCH.y += 30.0 * glareAngleFactor * glareGeoFactor;
|
|
217
|
+
glareTintLCH.x = clamp(glareTintLCH.x, 0.0, 120.0);
|
|
218
|
+
outColor = mix(outColor, LCH_TO_SRGB(glareTintLCH), glareAngleFactor * glareGeoFactor * normalLength);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (u_glow.w > 0.0) {
|
|
222
|
+
float glowDistance = length(p - u_glow.xy);
|
|
223
|
+
float glow = u_glow.w * (1.0 - smoothstep(0.0, max(u_glow.z, 1.0), glowDistance));
|
|
224
|
+
if (glow > 0.001) {
|
|
225
|
+
vec3 glowLCH = SRGB_TO_LCH(outColor);
|
|
226
|
+
glowLCH.x = clamp(glowLCH.x + 22.0 * glow, 0.0, 100.0);
|
|
227
|
+
outColor = LCH_TO_SRGB(glowLCH);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
vec4 result = vec4(outColor * coverage, coverage);
|
|
232
|
+
|
|
233
|
+
if (u_border > 0.0) {
|
|
234
|
+
float ring = 1.0 - smoothstep(u_border * 0.5 - aa, u_border * 0.5 + aa, abs(merged + u_border * 0.5));
|
|
235
|
+
vec4 border = vec4(u_borderColor.rgb, 1.0) * u_borderColor.a * ring * coverage;
|
|
236
|
+
result = border + result * (1.0 - border.a);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
fragColor = result;
|
|
240
|
+
}
|
|
241
|
+
`
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
export const MODE_FILL = 0
|
|
2
|
+
export const MODE_IMAGE = 1
|
|
3
|
+
export const MODE_GLYPH = 2
|
|
4
|
+
export const MODE_STROKE = 3
|
|
5
|
+
export const MODE_VIBRANT_GLYPH = 6
|
|
6
|
+
export const MODE_GRADIENT = 7
|
|
7
|
+
export const MODE_TINTED_FILL = 8
|
|
8
|
+
|
|
9
|
+
export const uiVertex = /* glsl */ `#version 300 es
|
|
10
|
+
precision highp float;
|
|
11
|
+
|
|
12
|
+
layout(location = 0) in vec4 a_rect;
|
|
13
|
+
layout(location = 1) in vec4 a_corner;
|
|
14
|
+
layout(location = 2) in vec4 a_color;
|
|
15
|
+
layout(location = 3) in vec4 a_uv;
|
|
16
|
+
layout(location = 4) in vec4 a_clip;
|
|
17
|
+
layout(location = 5) in vec4 a_extra;
|
|
18
|
+
layout(location = 6) in vec4 a_color2;
|
|
19
|
+
layout(location = 7) in vec4 a_fade;
|
|
20
|
+
|
|
21
|
+
uniform vec2 u_viewport;
|
|
22
|
+
|
|
23
|
+
out vec4 v_rect;
|
|
24
|
+
out vec4 v_corner;
|
|
25
|
+
out vec4 v_color;
|
|
26
|
+
out vec4 v_color2;
|
|
27
|
+
out vec2 v_uv;
|
|
28
|
+
out vec4 v_clip;
|
|
29
|
+
out vec4 v_extra;
|
|
30
|
+
out vec2 v_pos;
|
|
31
|
+
out vec4 v_fade;
|
|
32
|
+
|
|
33
|
+
void main() {
|
|
34
|
+
vec2 unit = vec2(float(gl_VertexID & 1), float((gl_VertexID >> 1) & 1));
|
|
35
|
+
float expand = a_extra.w;
|
|
36
|
+
vec2 origin = a_rect.xy - vec2(expand);
|
|
37
|
+
vec2 size = a_rect.zw + vec2(expand * 2.0);
|
|
38
|
+
vec2 p = origin + unit * size;
|
|
39
|
+
v_pos = p;
|
|
40
|
+
v_rect = a_rect;
|
|
41
|
+
v_corner = a_corner;
|
|
42
|
+
v_color = a_color;
|
|
43
|
+
v_color2 = a_color2;
|
|
44
|
+
v_uv = mix(a_uv.xy, a_uv.zw, (p - a_rect.xy) / max(a_rect.zw, vec2(0.0001)));
|
|
45
|
+
v_clip = a_clip;
|
|
46
|
+
v_extra = a_extra;
|
|
47
|
+
v_fade = a_fade;
|
|
48
|
+
gl_Position = vec4(p.x / u_viewport.x * 2.0 - 1.0, 1.0 - p.y / u_viewport.y * 2.0, 0.0, 1.0);
|
|
49
|
+
}
|
|
50
|
+
`
|
|
51
|
+
|
|
52
|
+
export const uiFragment = /* glsl */ `#version 300 es
|
|
53
|
+
precision highp float;
|
|
54
|
+
|
|
55
|
+
in vec4 v_rect;
|
|
56
|
+
in vec4 v_corner;
|
|
57
|
+
in vec4 v_color;
|
|
58
|
+
in vec4 v_color2;
|
|
59
|
+
in vec2 v_uv;
|
|
60
|
+
in vec4 v_clip;
|
|
61
|
+
in vec4 v_extra;
|
|
62
|
+
in vec2 v_pos;
|
|
63
|
+
in vec4 v_fade;
|
|
64
|
+
|
|
65
|
+
uniform sampler2D u_texture;
|
|
66
|
+
uniform sampler2D u_scene;
|
|
67
|
+
uniform vec2 u_resolution;
|
|
68
|
+
uniform float u_dpr;
|
|
69
|
+
uniform int u_mode;
|
|
70
|
+
|
|
71
|
+
out vec4 fragColor;
|
|
72
|
+
|
|
73
|
+
float superellipseCornerSDF(vec2 p, float r, float n) {
|
|
74
|
+
p = abs(p);
|
|
75
|
+
return pow(pow(p.x, n) + pow(p.y, n), 1.0 / n) - r;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
float roundedRectSDF(vec2 p, vec4 rect, float radius, float roundness) {
|
|
79
|
+
vec2 half_size = rect.zw * 0.5;
|
|
80
|
+
vec2 q = p - (rect.xy + half_size);
|
|
81
|
+
float cr = min(radius, min(half_size.x, half_size.y));
|
|
82
|
+
float n = cr >= min(half_size.x, half_size.y) - 0.5 ? 2.0 : roundness;
|
|
83
|
+
vec2 d = abs(q) - half_size;
|
|
84
|
+
if (cr > 0.0 && d.x > -cr && d.y > -cr) {
|
|
85
|
+
vec2 cornerCenter = sign(q) * (half_size - vec2(cr));
|
|
86
|
+
return superellipseCornerSDF(q - cornerCenter, cr, n);
|
|
87
|
+
}
|
|
88
|
+
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
float clipCoverage(vec2 p) {
|
|
92
|
+
if (v_clip.z <= 0.0) return 1.0;
|
|
93
|
+
vec2 d = max(v_clip.xy - p, p - (v_clip.xy + v_clip.zw));
|
|
94
|
+
float outside = max(d.x, d.y);
|
|
95
|
+
return 1.0 - smoothstep(-0.5, 0.5, outside);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
void main() {
|
|
99
|
+
float aa = 0.6 / u_dpr;
|
|
100
|
+
vec2 pos = v_pos;
|
|
101
|
+
if (v_extra.z != 0.0) {
|
|
102
|
+
vec2 center = v_rect.xy + v_rect.zw * 0.5;
|
|
103
|
+
float s = sin(-v_extra.z);
|
|
104
|
+
float c = cos(-v_extra.z);
|
|
105
|
+
vec2 d = pos - center;
|
|
106
|
+
pos = center + vec2(c * d.x - s * d.y, s * d.x + c * d.y);
|
|
107
|
+
}
|
|
108
|
+
float sdf = roundedRectSDF(pos, v_rect, v_corner.x, max(v_corner.y, 2.0));
|
|
109
|
+
float shape = 1.0 - smoothstep(-aa, aa, sdf);
|
|
110
|
+
float clip = clipCoverage(v_pos);
|
|
111
|
+
vec4 color = v_color;
|
|
112
|
+
vec4 result;
|
|
113
|
+
|
|
114
|
+
if (u_mode == ${MODE_FILL}) {
|
|
115
|
+
result = vec4(color.rgb, 1.0) * color.a * shape;
|
|
116
|
+
} else if (u_mode == ${MODE_IMAGE}) {
|
|
117
|
+
vec4 texel = texture(u_texture, v_uv);
|
|
118
|
+
result = vec4(texel.rgb * color.rgb, 1.0) * texel.a * color.a * shape;
|
|
119
|
+
} else if (u_mode == ${MODE_GLYPH}) {
|
|
120
|
+
float alpha = texture(u_texture, v_uv).a;
|
|
121
|
+
result = vec4(color.rgb, 1.0) * color.a * alpha;
|
|
122
|
+
} else if (u_mode == ${MODE_VIBRANT_GLYPH}) {
|
|
123
|
+
float alpha = texture(u_texture, v_uv).a;
|
|
124
|
+
vec2 uv = gl_FragCoord.xy / u_resolution;
|
|
125
|
+
vec3 behind = textureLod(u_scene, uv, 4.0).rgb;
|
|
126
|
+
float target = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
|
|
127
|
+
vec3 vibrant = target > 0.5 ? mix(behind, vec3(1.0), 0.82) : mix(behind, vec3(0.0), 0.78);
|
|
128
|
+
vec3 rgb = mix(color.rgb, vibrant, v_extra.x);
|
|
129
|
+
result = vec4(rgb, 1.0) * color.a * alpha;
|
|
130
|
+
} else if (u_mode == ${MODE_STROKE}) {
|
|
131
|
+
float width = v_extra.x;
|
|
132
|
+
float ring = 1.0 - smoothstep(width * 0.5 - aa, width * 0.5 + aa, abs(sdf + width * 0.5));
|
|
133
|
+
result = vec4(color.rgb, 1.0) * color.a * ring;
|
|
134
|
+
} else if (u_mode == ${MODE_TINTED_FILL}) {
|
|
135
|
+
vec2 uv = gl_FragCoord.xy / u_resolution;
|
|
136
|
+
vec3 behind = textureLod(u_scene, uv, 4.5).rgb;
|
|
137
|
+
float luma = dot(behind, vec3(0.2126, 0.7152, 0.0722));
|
|
138
|
+
float lift = (0.52 - luma) * v_extra.x;
|
|
139
|
+
vec3 rgb = clamp(color.rgb * (1.0 + lift) + lift * 0.25, 0.0, 1.0);
|
|
140
|
+
result = vec4(rgb, 1.0) * color.a * shape;
|
|
141
|
+
} else if (u_mode == ${MODE_GRADIENT}) {
|
|
142
|
+
float t = v_extra.y > 0.5 ? v_uv.x : v_uv.y;
|
|
143
|
+
vec4 mixed = mix(color, v_color2, clamp(t, 0.0, 1.0));
|
|
144
|
+
result = vec4(mixed.rgb, 1.0) * mixed.a * shape;
|
|
145
|
+
} else {
|
|
146
|
+
result = vec4(1.0, 0.0, 1.0, 1.0);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
float fade = 1.0;
|
|
150
|
+
if (v_fade.y > v_fade.x) fade *= smoothstep(v_fade.x, v_fade.y, v_pos.y);
|
|
151
|
+
if (v_fade.w > v_fade.z) fade *= 1.0 - smoothstep(v_fade.z, v_fade.w, v_pos.y);
|
|
152
|
+
fragColor = result * clip * fade;
|
|
153
|
+
}
|
|
154
|
+
`
|
|
155
|
+
|
|
156
|
+
export const blitVertex = /* glsl */ `#version 300 es
|
|
157
|
+
precision highp float;
|
|
158
|
+
out vec2 v_uv;
|
|
159
|
+
void main() {
|
|
160
|
+
vec2 unit = vec2(float(gl_VertexID & 1), float((gl_VertexID >> 1) & 1));
|
|
161
|
+
v_uv = unit;
|
|
162
|
+
gl_Position = vec4(unit * 2.0 - 1.0, 0.0, 1.0);
|
|
163
|
+
}
|
|
164
|
+
`
|
|
165
|
+
|
|
166
|
+
export const blitFragment = /* glsl */ `#version 300 es
|
|
167
|
+
precision highp float;
|
|
168
|
+
in vec2 v_uv;
|
|
169
|
+
uniform sampler2D u_texture;
|
|
170
|
+
uniform float u_lod;
|
|
171
|
+
out vec4 fragColor;
|
|
172
|
+
void main() {
|
|
173
|
+
fragColor = textureLod(u_texture, v_uv, u_lod);
|
|
174
|
+
}
|
|
175
|
+
`
|
|
176
|
+
|
|
177
|
+
export const downsampleFragment = /* glsl */ `#version 300 es
|
|
178
|
+
precision highp float;
|
|
179
|
+
in vec2 v_uv;
|
|
180
|
+
uniform sampler2D u_texture;
|
|
181
|
+
uniform vec2 u_texel;
|
|
182
|
+
uniform vec2 u_direction;
|
|
183
|
+
uniform float u_lod;
|
|
184
|
+
out vec4 fragColor;
|
|
185
|
+
void main() {
|
|
186
|
+
vec2 step = u_direction * u_texel;
|
|
187
|
+
vec4 color = textureLod(u_texture, v_uv, u_lod) * 0.38292;
|
|
188
|
+
color += textureLod(u_texture, v_uv + step, u_lod) * 0.24173;
|
|
189
|
+
color += textureLod(u_texture, v_uv - step, u_lod) * 0.24173;
|
|
190
|
+
color += textureLod(u_texture, v_uv + step * 2.0, u_lod) * 0.06681;
|
|
191
|
+
color += textureLod(u_texture, v_uv - step * 2.0, u_lod) * 0.06681;
|
|
192
|
+
fragColor = color;
|
|
193
|
+
}
|
|
194
|
+
`
|