1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
#ifndef ALLOW_INCLUDES
#define ALLOW_INCLUDES
#extension GL_ARB_shading_language_include : enable
#endif
#include "cm_helpers.glsl"
#if USE_ROUNDING
#include "rounding.glsl"
#endif
vec4 okLabAToSrgb(vec4 lab) {
float l = pow(lab[0] + lab[1] * 0.3963377774 + lab[2] * 0.2158037573, 3.0);
float m = pow(lab[0] + lab[1] * (-0.1055613458) + lab[2] * (-0.0638541728), 3.0);
float s = pow(lab[0] + lab[1] * (-0.0894841775) + lab[2] * (-1.2914855480), 3.0);
return vec4(fromLinearRGB(vec3(l * 4.0767416621 + m * -3.3077115913 + s * 0.2309699292, l * (-1.2684380046) + m * 2.6097574011 + s * (-0.3413193965),
l * (-0.0041960863) + m * (-0.7034186147) + s * 1.7076147010),
CM_TRANSFER_FUNCTION_GAMMA22),
lab[3]);
}
vec4 getOkColorForCoordArray1(vec2 normalizedCoord, int gradientLength, vec4 gradient[10], float angle) {
if (gradientLength < 2)
return gradient[0];
float finalAng = 0.0;
if (angle > 4.71 /* 270 deg */) {
normalizedCoord[1] = 1.0 - normalizedCoord[1];
finalAng = 6.28 - angle;
} else if (angle > 3.14 /* 180 deg */) {
normalizedCoord[0] = 1.0 - normalizedCoord[0];
normalizedCoord[1] = 1.0 - normalizedCoord[1];
finalAng = angle - 3.14;
} else if (angle > 1.57 /* 90 deg */) {
normalizedCoord[0] = 1.0 - normalizedCoord[0];
finalAng = 3.14 - angle;
} else {
finalAng = angle;
}
float sine = sin(finalAng);
float progress = (normalizedCoord[1] * sine + normalizedCoord[0] * (1.0 - sine)) * float(gradientLength - 1);
int bottom = int(floor(progress));
int top = bottom + 1;
return gradient[top] * (progress - float(bottom)) + gradient[bottom] * (float(top) - progress);
}
vec4 getOkColorForCoordArray2(vec2 normalizedCoord, float angle, int gradient2Length, vec4 gradient2[10], float angle2) {
if (gradient2Length < 2)
return gradient2[0];
float finalAng = 0.0;
if (angle2 > 4.71 /* 270 deg */) {
normalizedCoord[1] = 1.0 - normalizedCoord[1];
finalAng = 6.28 - angle;
} else if (angle2 > 3.14 /* 180 deg */) {
normalizedCoord[0] = 1.0 - normalizedCoord[0];
normalizedCoord[1] = 1.0 - normalizedCoord[1];
finalAng = angle - 3.14;
} else if (angle2 > 1.57 /* 90 deg */) {
normalizedCoord[0] = 1.0 - normalizedCoord[0];
finalAng = 3.14 - angle2;
} else {
finalAng = angle2;
}
float sine = sin(finalAng);
float progress = (normalizedCoord[1] * sine + normalizedCoord[0] * (1.0 - sine)) * float(gradient2Length - 1);
int bottom = int(floor(progress));
int top = bottom + 1;
return gradient2[top] * (progress - float(bottom)) + gradient2[bottom] * (float(top) - progress);
}
vec4 getColorForCoord(vec2 normalizedCoord, int gradientLength, vec4 gradient[10], float angle, int gradient2Length, vec4 gradient2[10], float angle2, float gradientLerp) {
vec4 result1 = getOkColorForCoordArray1(normalizedCoord, gradientLength, gradient, angle);
if (gradient2Length <= 0)
return okLabAToSrgb(result1);
vec4 result2 = getOkColorForCoordArray2(normalizedCoord, angle, gradient2Length, gradient2, angle2);
return okLabAToSrgb(mix(result1, result2, gradientLerp));
}
#if USE_MIRROR
vec4[2]
#else
vec4
#endif
getBorder(vec2 v_texcoord, float alpha, vec2 fullSizeUntransformed, float radiusOuter, float thick, float radius, float roundingPower, vec2 topLeft, vec2 fullSize,
int gradientLength, vec4 gradient[10], float angle, int gradient2Length, vec4 gradient2[10], float angle2, float gradientLerp
#if USE_CM
,
int sourceTF, int targetTF, mat3 convertMatrix, vec2 srcTFRange, vec2 dstTFRange
#if USE_ICC
,
highp sampler3D iccLut3D, float iccLutSize
#else
#if USE_TONEMAP || USE_SDR_MOD
,
mat3 targetPrimariesXYZ
#endif
#if USE_TONEMAP
,
float maxLuminance, float dstMaxLuminance, float dstRefLuminance, float srcRefLuminance
#endif
#if USE_SDR_MOD
,
float sdrSaturation, float sdrBrightnessMultiplier
#endif
#endif
#endif
) {
vec2 pixCoord = vec2(gl_FragCoord);
vec2 pixCoordOuter = pixCoord;
vec2 originalPixCoord = v_texcoord;
originalPixCoord *= fullSizeUntransformed;
float additionalAlpha = 1.0;
vec4 pixColor = vec4(1.0, 1.0, 1.0, 1.0);
bool done = false;
pixCoord -= topLeft + fullSize * 0.5;
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
pixCoordOuter = pixCoord;
pixCoord -= fullSize * 0.5 - radius;
pixCoordOuter -= fullSize * 0.5 - radiusOuter;
// center the pixes don't make it top-left
pixCoord += vec2(1.0, 1.0) / fullSize;
pixCoordOuter += vec2(1.0, 1.0) / fullSize;
#if USE_ROUNDING
if (min(pixCoord.x, pixCoord.y) > 0.0 && radius > 0.0) {
float dist = pow(pow(pixCoord.x, roundingPower) + pow(pixCoord.y, roundingPower), 1.0 / roundingPower);
float distOuter = pow(pow(pixCoordOuter.x, roundingPower) + pow(pixCoordOuter.y, roundingPower), 1.0 / roundingPower);
float h = (thick / 2.0);
if (dist < radius - h) {
// lower
float normalized = smoothstep(0.0, 1.0, (dist - radius + thick + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
additionalAlpha *= normalized;
done = true;
} else if (min(pixCoordOuter.x, pixCoordOuter.y) > 0.0) {
// higher
float normalized = 1.0 - smoothstep(0.0, 1.0, (distOuter - radiusOuter + SMOOTHING_CONSTANT) / (SMOOTHING_CONSTANT * 2.0));
additionalAlpha *= normalized;
done = true;
} else if (distOuter < radiusOuter - h) {
additionalAlpha = 1.0;
done = true;
}
}
#endif
// now check for other shit
if (!done) {
// distance to all straight bb borders
float distanceT = originalPixCoord[1];
float distanceB = fullSizeUntransformed[1] - originalPixCoord[1];
float distanceL = originalPixCoord[0];
float distanceR = fullSizeUntransformed[0] - originalPixCoord[0];
// get the smallest
float smallest = min(min(distanceT, distanceB), min(distanceL, distanceR));
if (smallest > thick)
discard;
}
if (additionalAlpha == 0.0)
discard;
pixColor = getColorForCoord(v_texcoord, gradientLength, gradient, angle, gradient2Length, gradient2, angle2, gradientLerp);
pixColor.rgb *= pixColor[3];
#if USE_CM
#if USE_MIRROR
vec4[2] pixColors =
#else
pixColor =
#endif
doColorManagement(pixColor, sourceTF, targetTF, convertMatrix, srcTFRange, dstTFRange
#if USE_ICC
,
iccLut3D, iccLutSize
#else
#if USE_TONEMAP || USE_SDR_MOD
,
targetPrimariesXYZ
#endif
#if USE_TONEMAP
,
maxLuminance, dstMaxLuminance, dstRefLuminance, srcRefLuminance
#endif
#if USE_SDR_MOD
,
sdrSaturation, sdrBrightnessMultiplier
#endif
#endif
);
#endif
#if USE_MIRROR
pixColors[0] *= alpha * additionalAlpha;
pixColors[1] *= alpha * additionalAlpha;
return pixColors;
#else
pixColor *= alpha * additionalAlpha;
return pixColor;
#endif
}
|