Page 1 of 1

Sine ray distortion shader

Posted: Wed Apr 19, 2023 7:27 pm
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

Re: Sine ray distortion shader

Posted: Wed Apr 26, 2023 1:32 pm
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.