feat: distance field approach

This commit is contained in:
2025-09-05 11:34:02 +02:00
parent 2aca6c5b1f
commit dc9de39aa5
12 changed files with 298 additions and 146 deletions

View File

@@ -1,50 +0,0 @@
#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
uniform vec2 resolution;
uniform vec2 mouse_pos;
uniform float ball_radius;
uniform vec2 polygon_points[6];
uniform float polygon_influence;
out vec4 finalColor;
float distanceToPolygon(vec2 point, vec2 polyPoints[6]) {
float minDist = 100000.0;
for (int i = 0; i < 6; i++) {
int j = (i + 1) % 6;
vec2 a = polyPoints[i];
vec2 b = polyPoints[j];
vec2 pa = point - a;
vec2 ba = b - a;
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
float dist = length(pa - ba * h);
minDist = min(minDist, dist);
}
return minDist;
}
void main()
{
vec2 pixel_pos = fragTexCoord * resolution;
vec2 ball_pixel_pos = mouse_pos;
float ball_dist = distance(pixel_pos, ball_pixel_pos);
float ball_value = (ball_radius * ball_radius) / (ball_dist * ball_dist + 1.0);
float poly_dist = distanceToPolygon(pixel_pos, polygon_points);
float poly_value = polygon_influence / (poly_dist * poly_dist + 1.0);
float total_value = ball_value + poly_value;
if (total_value > 0.7) {
finalColor = vec4(1.0, 1.0, 1.0, 1.0); // White
} else {
finalColor = vec4(0.0, 0.0, 0.0, 1.0); // Black
}
}

View File

@@ -0,0 +1,60 @@
#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
uniform sampler2D texture0;
uniform sampler2D distanceFieldTex;
uniform vec2 resolution;
uniform vec2 mousePos;
uniform float ballRadius;
uniform float shapeInfluence;
out vec4 finalColor;
float getBallInfluence(vec2 pos, vec2 center, float radius) {
vec2 diff = pos - center;
float distSq = dot(diff, diff);
float radiusSq = radius * radius;
if (distSq > radiusSq) return 0.0;
float dist = sqrt(distSq);
return 1.0 - (dist / radius);
}
float getShapeInfluence(vec2 pos) {
vec2 uv = pos / resolution;
uv.y = 1 - uv.y + 0.045; // invert y and offset to match with wallpaper texture
if (any(lessThan(uv, vec2(0.0))) || any(greaterThan(uv, vec2(1.0)))) {
return 0.0;
}
float signedDistance = texture(distanceFieldTex, uv).r * 255.0 - 128.0;
float isInside = step(signedDistance, 0.0);
float isOutside = 1.0 - isInside;
// inside calculation
float normalizedDist = abs(signedDistance) * 0.015625; // 1/64
float insideInfluence = shapeInfluence * exp(-normalizedDist * 0.5) * 3.0;
// outside calculation
float adjustedDistance = signedDistance * 0.5;
float shapeInfluenceSq = shapeInfluence * shapeInfluence;
float outsideInfluence = shapeInfluenceSq / (adjustedDistance * adjustedDistance + shapeInfluence) +
shapeInfluence * 0.8 * exp(-signedDistance * 0.025); // 1/40
return isInside * insideInfluence + isOutside * outsideInfluence;
}
void main()
{
vec2 pixelPos = fragTexCoord * resolution;
float ballValue = getBallInfluence(pixelPos, mousePos, ballRadius);
float shapeValue = getShapeInfluence(pixelPos);
float totalValue = ballValue + shapeValue * 0.01;
float mask = step(0.75, totalValue);
finalColor = vec4(mask, mask, mask, 1.0);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 MiB