improve shader

pull/35357/head
deanlee 2 weeks ago
parent 756c4617b2
commit 992247617a
  1. 137
      system/ui/lib/shader_polygon.py

@ -23,110 +23,93 @@ uniform float gradientStops[8];
uniform int gradientColorCount;
vec4 getGradientColor(vec2 pos) {
vec2 gradientDir = gradientEnd - gradientStart;
float gradientLength = length(gradientDir);
vec2 dir = gradientEnd - gradientStart;
float len = length(dir);
if (len < 0.001) return gradientColors[0];
if (gradientLength < 0.001) return gradientColors[0];
float t = clamp(dot(pos - gradientStart, dir) / (len * len), 0.0, 1.0);
vec2 normalizedDir = gradientDir / gradientLength;
vec2 pointVec = pos - gradientStart;
float projection = dot(pointVec, normalizedDir);
float t = clamp(projection / gradientLength, 0.0, 1.0);
if (gradientColorCount == 2) {
return mix(gradientColors[0], gradientColors[1], t);
}
for (int i = 0; i < gradientColorCount - 1; i++) {
if (t >= gradientStops[i] && t <= gradientStops[i+1]) {
float segmentT = (t - gradientStops[i]) / (gradientStops[i+1] - gradientStops[i]);
return mix(gradientColors[i], gradientColors[i+1], segmentT);
int low = 0;
int high = gradientColorCount - 1;
while (low < high) {
int mid = (low + high) / 2;
if (t > gradientStops[mid]) low = mid + 1;
else high = mid;
}
}
return gradientColors[gradientColorCount-1];
if (low == 0) return gradientColors[0];
if (low == gradientColorCount) return gradientColors[gradientColorCount - 1];
float segmentT = (t - gradientStops[low - 1]) / (gradientStops[low] - gradientStops[low - 1]);
return mix(gradientColors[low - 1], gradientColors[low], segmentT);
}
float distanceToEdge(vec2 p) {
float minDist = 1000.0;
for (int i = 0, j = pointCount - 1; i < pointCount; j = i++) {
vec2 edge0 = points[j];
vec2 edge1 = points[i];
float minDist = resolution.x;
if (edge0 == edge1) continue;
for (int i = 0, j = pointCount - 1; i < pointCount; j = i++) {
vec2 edge0 = points[j];
vec2 edge1 = points[i];
vec2 v1 = p - edge0;
vec2 v2 = edge1 - edge0;
float l2 = dot(v2, v2);
vec2 v2 = edge1 - edge0;
float l2 = dot(v2, v2);
if (l2 < 0.0001) continue;
if (l2 < 0.0001) {
float dist = length(v1);
minDist = min(minDist, dist);
continue;
vec2 v1 = p - edge0;
float t = clamp(dot(v1, v2) / l2, 0.0, 1.0);
minDist = min(minDist, length(v1 - t * v2));
}
float t = max(0.0, min(1.0, dot(v1, v2) / l2));
vec2 projection = edge0 + t * v2;
float dist = length(p - projection);
minDist = min(minDist, dist);
}
return minDist;
return minDist;
}
bool isPointInsidePolygon(vec2 p) {
if (pointCount < 3) return false;
if (pointCount == 3) {
vec2 v0 = points[0];
vec2 v1 = points[1];
vec2 v2 = points[2];
if (pointCount < 3) return false;
float d = (v1.y - v2.y) * (v0.x - v2.x) + (v2.x - v1.x) * (v0.y - v2.y);
if (abs(d) < 0.0001) return false;
if (pointCount == 3) {
vec2 v0 = points[0], v1 = points[1], v2 = points[2];
float d = (v1.y - v2.y) * (v0.x - v2.x) + (v2.x - v1.x) * (v0.y - v2.y);
if (abs(d) < 0.0001) return false;
float a = ((v1.y - v2.y) * (p.x - v2.x) + (v2.x - v1.x) * (p.y - v2.y)) / d;
float b = ((v2.y - v0.y) * (p.x - v2.x) + (v0.x - v2.x) * (p.y - v2.y)) / d;
float c = 1.0 - a - b;
return (a >= 0.0 && b >= 0.0 && c >= 0.0);
}
bool inside = false;
for (int i = 0, j = pointCount - 1; i < pointCount; j = i++) {
if (points[i] == points[j]) continue;
float a = ((v1.y - v2.y) * (p.x - v2.x) + (v2.x - v1.x) * (p.y - v2.y)) / d;
float b = ((v2.y - v0.y) * (p.x - v2.x) + (v0.x - v2.x) * (p.y - v2.y)) / d;
float c = 1.0 - a - b;
return a >= 0.0 && b >= 0.0 && c >= 0.0;
}
float dy = points[j].y - points[i].y;
if (abs(dy) < 0.0001) continue;
bool inside = false;
for (int i = 0, j = pointCount - 1; i < pointCount; j = i++) {
vec2 pi = points[i], pj = points[j];
float dy = pj.y - pi.y;
if (abs(dy) < 1e-4 || pi == pj) continue;
if (((points[i].y > p.y) != (points[j].y > p.y))) {
float x_intersect = points[i].x + (points[j].x - points[i].x) * (p.y - points[i].y) / dy;
if (p.x < x_intersect) {
inside = !inside;
}
if ((pi.y > p.y) != (pj.y > p.y)) {
float x_intersect = pi.x + (pj.x - pi.x) * (p.y - pi.y) / dy;
if (p.x < x_intersect) inside = !inside;
}
}
}
return inside;
return inside;
}
void main() {
vec2 pixel = fragTexCoord * resolution;
bool inside = isPointInsidePolygon(pixel);
float dist = distanceToEdge(pixel);
float aaWidth = 1.0;
float alpha = inside ?
min(1.0, dist / aaWidth) :
max(0.0, 1.0 - dist / aaWidth);
if (alpha > 0.0) {
vec4 color;
if (useGradient) {
color = getGradientColor(fragTexCoord);
} else {
color = fillColor;
vec2 pixel = fragTexCoord * resolution;
bool inside = isPointInsidePolygon(pixel);
float dist = distanceToEdge(pixel);
float aaWidth = 2.0 / min(resolution.x, resolution.y);
float alpha = inside ? min(1.0, dist / aaWidth) : max(0.0, 1.0 - dist / aaWidth);
if (alpha == 0.0) {
discard;
}
vec4 color = useGradient ? getGradientColor(pixel) : fillColor;
finalColor = vec4(color.rgb, color.a * alpha);
} else {
finalColor = vec4(0.0, 0.0, 0.0, 0.0);
}
}
"""
# Default vertex shader

Loading…
Cancel
Save