Created
November 23, 2025 00:25
-
-
Save theMackabu/4bf475f6e642249f524290fee80abda2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| float ease(float x) { | |
| return pow(1.0 - x, 10.0); | |
| } | |
| float sdBox(in vec2 p, in vec2 xy, in vec2 b) | |
| { | |
| vec2 d = abs(p - xy) - b; | |
| return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); | |
| } | |
| float getSdfRectangle(in vec2 p, in vec2 xy, in vec2 b) | |
| { | |
| vec2 d = abs(p - xy) - b; | |
| return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); | |
| } | |
| float seg(in vec2 p, in vec2 a, in vec2 b, inout float s, float d) { | |
| vec2 e = b - a; | |
| vec2 w = p - a; | |
| vec2 proj = a + e * clamp(dot(w, e) / dot(e, e), 0.0, 1.0); | |
| float segd = dot(p - proj, p - proj); | |
| d = min(d, segd); | |
| float c0 = step(0.0, p.y - a.y); | |
| float c1 = 1.0 - step(0.0, p.y - b.y); | |
| float c2 = 1.0 - step(0.0, e.x * w.y - e.y * w.x); | |
| float allCond = c0 * c1 * c2; | |
| float noneCond = (1.0 - c0) * (1.0 - c1) * (1.0 - c2); | |
| float flip = mix(1.0, -1.0, step(0.5, allCond + noneCond)); | |
| s *= flip; | |
| return d; | |
| } | |
| float getSdfParallelogram(in vec2 p, in vec2 v0, in vec2 v1, in vec2 v2, in vec2 v3) { | |
| float s = 1.0; | |
| float d = dot(p - v0, p - v0); | |
| d = seg(p, v0, v3, s, d); | |
| d = seg(p, v1, v0, s, d); | |
| d = seg(p, v2, v1, s, d); | |
| d = seg(p, v3, v2, s, d); | |
| return s * sqrt(d); | |
| } | |
| vec2 normalize(vec2 value, float isPosition) { | |
| return (value * 2.0 - (iResolution.xy * isPosition)) / iResolution.y; | |
| } | |
| float blend(float t) | |
| { | |
| float sqr = t * t; | |
| return sqr / (2.0 * (sqr - t) + 1.0); | |
| } | |
| float antialising(float distance) { | |
| return 1. - smoothstep(0., normalize(vec2(2., 2.), 0.).x, distance); | |
| } | |
| float determineStartVertexFactor(vec2 a, vec2 b) { | |
| float condition1 = step(b.x, a.x) * step(a.y, b.y); | |
| float condition2 = step(a.x, b.x) * step(b.y, a.y); | |
| return 1.0 - max(condition1, condition2); | |
| } | |
| vec2 getRectangleCenter(vec4 rectangle) { | |
| return vec2(rectangle.x + (rectangle.z / 2.), rectangle.y - (rectangle.w / 2.)); | |
| } | |
| const vec4 TRAIL_COLOR = vec4(1.0, 0.725, 0.161, 1.0); // yellow | |
| const vec4 CURRENT_CURSOR_COLOR = TRAIL_COLOR; | |
| const vec4 PREVIOUS_CURSOR_COLOR = TRAIL_COLOR; | |
| const vec4 TRAIL_COLOR_ACCENT = vec4(1.0, 0., 0., 1.0); // red-orange | |
| const float DURATION = .5; | |
| const float OPACITY = .2; | |
| void mainImage(out vec4 fragColor, in vec2 fragCoord) | |
| { | |
| #if !defined(WEB) | |
| fragColor = texture(iChannel0, fragCoord.xy / iResolution.xy); | |
| #endif | |
| vec2 vu = normalize(fragCoord, 1.); | |
| vec2 offsetFactor = vec2(-.5, 0.5); | |
| vec4 currentCursor = vec4(normalize(iCurrentCursor.xy, 1.), normalize(iCurrentCursor.zw, 0.)); | |
| vec4 previousCursor = vec4(normalize(iPreviousCursor.xy, 1.), normalize(iPreviousCursor.zw, 0.)); | |
| float vertexFactor = determineStartVertexFactor(currentCursor.xy, previousCursor.xy); | |
| float invertedVertexFactor = 1.0 - vertexFactor; | |
| vec2 v0 = vec2(currentCursor.x + currentCursor.z * vertexFactor, currentCursor.y - currentCursor.w); | |
| vec2 v1 = vec2(currentCursor.x + currentCursor.z * invertedVertexFactor, currentCursor.y); | |
| vec2 v2 = vec2(previousCursor.x + currentCursor.z * invertedVertexFactor, previousCursor.y); | |
| vec2 v3 = vec2(previousCursor.x + currentCursor.z * vertexFactor, previousCursor.y - previousCursor.w); | |
| vec4 newColor = vec4(fragColor); | |
| float progress = blend(clamp((iTime - iTimeCursorChange) / DURATION, 0.0, 1)); | |
| float easedProgress = ease(progress); | |
| vec2 centerCC = getRectangleCenter(currentCursor); | |
| vec2 centerCP = getRectangleCenter(previousCursor); | |
| float lineLength = distance(centerCC, centerCP); | |
| float distanceToEnd = distance(vu.xy, centerCC); | |
| float alphaModifier = distanceToEnd / (lineLength * (easedProgress)); | |
| if (alphaModifier > 1.0) { | |
| alphaModifier = 1.0; | |
| } | |
| float sdfCursor = getSdfRectangle(vu, currentCursor.xy - (currentCursor.zw * offsetFactor), currentCursor.zw * 0.5); | |
| float sdfTrail = getSdfParallelogram(vu, v0, v1, v2, v3); | |
| newColor = mix(newColor, TRAIL_COLOR_ACCENT, 1.0 - smoothstep(sdfTrail, -0.01, 0.001)); | |
| newColor = mix(newColor, TRAIL_COLOR, antialising(sdfTrail)); | |
| newColor = mix(fragColor, newColor, 1.0 - alphaModifier); | |
| fragColor = mix(newColor, fragColor, step(sdfCursor, 0)); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment