Back to shaders

Shader test bench

LaserShader 02.fs

misc-isf-shaders utility glsl runnable fragment MIT
Source
runnable fragment

Complete GLSL fragment shader. Stronghold runs it directly when the browser can compile it.

Code

uniform float amplitude;
uniform float wavelength;
uniform float randomSeed;
uniform vec2 position;
uniform float rotation;
uniform float moveSpeed;
uniform int reverseWave;
uniform float moveAmount;
uniform float rotationSpeed;
uniform int reverseRotation;
uniform vec4 color1;
uniform vec4 color2;
uniform vec4 color3;
uniform vec4 color4;
uniform vec4 color5;
uniform vec4 color6;
precision mediump float;
/*{
    "DESCRIPTION": "Animated wave with customizable shape, colors, movement, and rotation.",
    "CREDIT": "Cornelius // ProjectileObjects",
    "ISFVSN": "2.0",
    "CATEGORIES": [ "Generator" ],
    "INPUTS": [
        { "NAME": "amplitude", "TYPE": "float", "DEFAULT": 0.2, "MIN": 0.05, "MAX": 0.5 },
        { "NAME": "wavelength", "TYPE": "float", "DEFAULT": 4.0, "MIN": 1.0, "MAX": 20.0 },
        { "NAME": "randomSeed", "TYPE": "float", "DEFAULT": 0.0, "MIN": 0.0, "MAX": 10.0 },
        { "NAME": "position", "TYPE": "point2D", "DEFAULT": [0.0, 0.0], "MIN": [-1.0, -1.0], "MAX": [1.0, 1.0] },
        { "NAME": "rotation", "TYPE": "float", "DEFAULT": 0.0, "MIN": 0.0, "MAX": 360.0 },
        { "NAME": "moveSpeed", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 5.0 },
        { "NAME": "reverseWave", "TYPE": "bool", "DEFAULT": false },
        { "NAME": "moveAmount", "TYPE": "float", "DEFAULT": 0.05, "MIN": 0.0, "MAX": 0.3 },
        { "NAME": "rotationSpeed", "TYPE": "float", "DEFAULT": 30.0, "MIN": 0.0, "MAX": 180.0 },
        { "NAME": "reverseRotation", "TYPE": "bool", "DEFAULT": false },
        { "NAME": "color1", "TYPE": "color", "DEFAULT": [1.0, 0.0, 0.0, 1.0] },
        { "NAME": "color2", "TYPE": "color", "DEFAULT": [1.0, 0.5, 0.0, 1.0] },
        { "NAME": "color3", "TYPE": "color", "DEFAULT": [1.0, 1.0, 0.0, 1.0] },
        { "NAME": "color4", "TYPE": "color", "DEFAULT": [0.0, 1.0, 0.0, 1.0] },
        { "NAME": "color5", "TYPE": "color", "DEFAULT": [0.0, 0.0, 1.0, 1.0] },
        { "NAME": "color6", "TYPE": "color", "DEFAULT": [0.5, 0.0, 1.0, 1.0] }
    ]
}*/

float random(vec2 st) {
    return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
}

void main() {
    vec2 uv = gl_FragCoord.xy / u_resolution.xy;
    
    // Normalize position so (0,0) is center, (-1,-1) bottom-left, (1,1) top-right
    vec2 normPos = position * 0.5 + 0.5;
    
    // Adjust UV coordinates based on position
    vec2 centeredUV = (uv - normPos) * vec2(u_resolution.x / u_resolution.y, 1.0);

    // Define PI explicitly
    const float PI = 3.14159265359;

    // Reverse wave movement if toggle is enabled
    float directionMultiplier = reverseWave ? -1.0 : 1.0;
    float animatedX = centeredUV.x * wavelength + u_time * moveSpeed * directionMultiplier;

    // Apply randomization to the wave shape based on `randomSeed`
    float randomFactor = random(vec2(floor(animatedX * randomSeed), randomSeed)) * 0.5;
    float wave = sin(animatedX + randomFactor) * amplitude;

    // Define the thickness of the wave line
    float waveMask = smoothstep(0.01, 0.0, abs(centeredUV.y - wave));

    // Use wave position to determine color blend
    float rotatedAngle = mod(centeredUV.x + radians(rotation + u_time * rotationSpeed * (reverseRotation ? -1.0 : 1.0)), 2.0 * PI) / (2.0 * PI);
    float segment = rotatedAngle * 6.0; // Divide into 6 segments
    float index = floor(segment);
    float mixFactor = fract(segment);

    // Store colors in an array
    vec3 colors[6];
    colors[0] = color1.rgb;
    colors[1] = color2.rgb;
    colors[2] = color3.rgb;
    colors[3] = color4.rgb;
    colors[4] = color5.rgb;
    colors[5] = color6.rgb;

    // Smooth transition between colors
    vec3 finalColor = mix(colors[int(mod(index, 6.0))], colors[int(mod(index + 1.0, 6.0))], mixFactor);

    // Blend wave with a solid black background
    vec3 outputColor = mix(vec3(0.0), finalColor, waveMask);
    gl_FragColor = vec4(outputColor, 1.0);
}