Sine ray distortion shader

Show off your games, demos and other (playable) creations.
Post Reply
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Sine ray distortion shader

Post by Bigfoot71 »

Hello everyone :D

Just a little thing that I had to do myself because I couldn't find anything similar elsewhere, so maybe it can help someone.

I made a prototype game where a cannon levitates balls and has to throw them at targets and I wanted to find a cool effect, so I had the idea of ​​some kind of warping ray that would simulate magnetism or I do not know what.

In short, here is a demo that I made apart for the image:
Image

The shader (surely optimizable):

Code: Select all

uniform float thickness; // Thickness (amplitude) of the ray
uniform float time;

uniform vec2 p1; // First point of the seg
uniform vec2 p2; // Second point of the seg

float attenuation(float distance, float thickness) {
    return 1.0 - distance / thickness;
}

vec4 effect(vec4 c, Image tex, vec2 tc, vec2 sc) {

    /* Calculation of the distance of the line p1->p2 */

    vec2 v = p2 - p1;
    vec2 w = sc - p1;
    float c1 = dot(w, v);
    float c2 = dot(v, v);
    float distanceToPoint;

    if (c1 <= 0.0) {
        distanceToPoint = distance(sc, p1);
    } else if (c2 <= c1) {
        distanceToPoint = distance(sc, p2);
    } else {
        vec2 pb = p1 + v * (c1 / c2);
        distanceToPoint = distance(sc, pb);
    }

    /* Ripple of line p1->p2 */

    if (distanceToPoint < thickness) {

        vec2 dir = normalize(p2 - p1);          // direction vector between p1 and p2
        vec2 parallel = vec2(dir.y, -dir.x);    // line parallel vector
        vec2 offset = sc - p1;                  // offset vector with respect to p1
        float distance = dot(offset, dir);      // distance along the line between p1 and p2
        float angle = distance * 0.1 + time;    // angle as a function of time and distance (0.1 = ripple factor)

        float amplitude = thickness * 0.001;                    // 0.001 = deformation factor
        amplitude *= attenuation(distanceToPoint, thickness);   // attenuation so that it stays in line with the edges of the ray

        vec2 wave = vec2(
            cos(angle) * amplitude * parallel.x,
            sin(angle) * amplitude * parallel.y
        );
        
        return Texel(tex, tc + wave);

    }

    return Texel(tex, tc);

}
And the demo in attachment.

If you want to use it you are free, it's done for, totally free of rights :D

Background source: https://opengameart.org/content/background-2
Attachments
SineRayShader.love
(126.96 KiB) Downloaded 156 times
My avatar code for the curious :D V1, V2, V3.
User avatar
knorke
Party member
Posts: 274
Joined: Wed Jul 14, 2010 7:06 pm
Contact:

Re: Sine ray distortion shader

Post by knorke »

Neat. Reminds me of hot exhaust gases. Or waves in water.
The background image is maybe not the best example, too many flat colored areas where no wobble is visible.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Amazon [Bot] and 8 guests