cuneus 0.5.0

A WGPU-based shader development tool
Documentation
struct TimeUniform {
    time: f32,
    delta: f32,
    frame: u32,
    _padding: u32,
};

@group(0) @binding(0) var<uniform> u_time: TimeUniform;
@group(1) @binding(0) var output: texture_storage_2d<rgba16float, write>;
@group(1) @binding(1) var<uniform> params: Params;
struct Params {
    lambda: f32,
    theta: f32,
    alpha: f32,
    sigma: f32,
    gamma: f32,
    blue: f32,
    a: f32,
    b: f32,
    base_color_r: f32,
    base_color_g: f32,
    base_color_b: f32,
    accent_color_r: f32,
    accent_color_g: f32,
    accent_color_b: f32,
    background_r: f32,
    background_g: f32,
    background_b: f32,
    gamma_correction: f32,
    aces_tonemapping: f32,
    _padding: f32,
};

const PI: f32 = 3.14159265358979323846;
const LIGHT_INTENSITY: f32 = 2.2;
const RIM_POWER: f32 = 2.0;
const AO_STRENGTH: f32 = 0.05;
const ENV_LIGHT_STRENGTH: f32 = 0.4;
const IRIDESCENCE_POWER: f32 = 0.15;
const FALLOFF_DISTANCE: f32 = 2.5;
const VIGNETTE_STRENGTH: f32 = 0.25;

fn rotate(angle: f32) -> mat2x2<f32> {
    let c = cos(angle);
    let s = sin(angle);
    return mat2x2<f32>(
        vec2<f32>(c, -s),
        vec2<f32>(s, c)
    );
}

fn oscillate(minn: f32, maxxi: f32, interval: f32, now: f32) -> f32 {
    return minn + (maxxi - minn) * 0.5 * (sin(2.0 * PI * now / interval) + 1.0);
}

fn getpentpo(angle: f32, radius: f32) -> vec2<f32> {
    return vec2<f32>(cos(angle), sin(angle)) * radius;
}

fn sdPentagon(p: vec2<f32>, r: f32, angle: f32) -> f32 {
    var rotatedP = rotate(-angle) * p;
    let vertices = params.lambda;
    let angleStep = params.theta * PI / vertices;

    var d = length(rotatedP) - r;

    var i: f32 = 0.0;
    while(i < vertices) {
        let a1 = angleStep * i;
        let a2 = angleStep * (i + 1.0);

        let p1 = getpentpo(a1, r);
        let p2 = getpentpo(a2, r);

        let edge = p2 - p1;
        let normal = normalize(vec2<f32>(edge.y, -edge.x));
        let dist = dot(rotatedP - p1, normal);

        d = max(d, dist);
        i = i + 1.0;
    }

    return max(d, 0.1);
}

fn getpent(uv: vec2<f32>, size: f32, angle: f32) -> array<vec2<f32>, 5> {
    var vertices: array<vec2<f32>, 5>;
    let r = size * 0.8;

    for(var i: i32 = 0; i < 5; i = i + 1) {
        let a = (f32(i) / 5.0) * 2.0 * PI;
        vertices[i] = getpentpo(a, r);
    }

    let rot = rotate(angle);
    for(var i: i32 = 0; i < 5; i = i + 1) {
        vertices[i] = rot * vertices[i] + uv;
    }

    return vertices;
}
//get light
fn gl(uv: vec2<f32>, pentagon: f32, layer: f32, time: f32, angle: f32) -> f32 {
    let vertices = getpent(uv, layer, angle);

    let phaseShift1 = sin(layer * 13.37 + time * 0.3);
    let phaseShift2 = cos(layer * 7.54 - time * 0.4);
    let phaseShift3 = sin(layer * 9.21 + time * 0.5);
    let phaseShift4 = cos(layer * 11.13 + time * 0.6);
    let phaseShift5 = sin(layer * 8.45 + time * 0.7);

    var lp: array<vec2<f32>, 5>;
    lp[0] = vertices[0] + vec2<f32>(cos(time * 0.5 + phaseShift1), sin(time * 0.7 + phaseShift2)) * 0.3;
    lp[1] = vertices[1] + vec2<f32>(sin(time * 0.3 + phaseShift2), cos(time * 0.4 + phaseShift3)) * 0.3;
    lp[2] = vertices[2] + vec2<f32>(cos(time * 0.6 + phaseShift3), sin(time * 0.5 + phaseShift4)) * 0.3;
    lp[3] = vertices[3] + vec2<f32>(sin(time * 0.4 + phaseShift4), cos(time * 0.6 + phaseShift5)) * 0.3;
    lp[4] = vertices[4] + vec2<f32>(cos(time * 0.5 + phaseShift5), sin(time * 0.3 + phaseShift1)) * 0.3;

    var distances: array<f32, 5>;
    var falloffs: array<f32, 5>;
    var weights: array<f32, 5>;
    var totalWeight: f32 = 0.0;

    for(var i: i32 = 0; i < 5; i = i + 1) {
        distances[i] = length(uv - lp[i]) *
            (1.0 + 0.2 * sin(layer * (15.0 + f32(i)) + time * (0.7 + f32(i) * 0.1)));

        falloffs[i] = 2.0 / (4.0 + distances[i] * FALLOFF_DISTANCE);
        weights[i] = 0.2 + 0.1 * sin(layer * (11.0 + f32(i) * 2.0) + time * (0.5 + f32(i) * 0.1));
        totalWeight = totalWeight + weights[i];
    }

    for(var i: i32 = 0; i < 5; i = i + 1) {
        weights[i] = weights[i] / totalWeight;
    }

    let ao = 0.4 - (layer * AO_STRENGTH) * (1.0 + 0.2 * sin(layer * 20.0 + time));

    let normal = normalize(vec2<f32>(cos(angle + layer), sin(angle + layer)));
    var rim = 2.1 - abs(dot(normalize(uv), normal));
    rim = pow(rim, RIM_POWER);

    var vertexLights: f32 = 0.0;
    for(var i: i32 = 0; i < 5; i = i + 1) {
        vertexLights = vertexLights + falloffs[i] * weights[i];
    }

    let shimmer = sin(layer * 10.0 + time) * cos(layer * 7.0 - time);
    vertexLights = vertexLights * (1.0 + 0.15 * shimmer);

    return vertexLights * ao * LIGHT_INTENSITY + rim * 0.4;
}
//env light get
fn geeee(uv: vec2<f32>, angle: f32, layer: f32, time: f32) -> f32 {
    let lightDir = normalize(vec2<f32>(cos(time), sin(time)));
    let normal = normalize(vec2<f32>(cos(angle), sin(angle)));
    var envLight = dot(normal, lightDir);
    envLight = envLight * 0.5 + 0.5;

    let depth = 1.0 - (layer / 1.5);
    let layerEffect = sin(layer * 4.0 + time) * 0.5 + 0.5;

    return mix(envLight, layerEffect, 0.5) * depth * ENV_LIGHT_STRENGTH;
}

fn gamma(color: vec3<f32>, gamma: f32) -> vec3<f32> {
    return pow(color, vec3<f32>(1.0 / gamma));
}

fn aces_tonemap(color: vec3<f32>) -> vec3<f32> {
    let a = 2.51;
    let b = 0.03;
    let c = 2.43;
    let d = 0.59;
    let e = 0.14;
    return clamp((color * (a * color + b)) / (color * (c * color + d) + e), vec3<f32>(0.0), vec3<f32>(1.0));
}

@compute @workgroup_size(16, 16, 1)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
    let R = vec2<f32>(textureDimensions(output));
    let coords = vec2<u32>(global_id.xy);
    
    if (coords.x >= u32(R.x) || coords.y >= u32(R.y)) {
        return;
    }
    
    let FragCoord = vec2<f32>(f32(coords.x), R.y - f32(coords.y));
    
    let bg_color = vec3<f32>(params.background_r, params.background_g, params.background_b);
    let bg = oscillate(0.6, 0.6, 8.0, u_time.time);
    var fragColor = vec4<f32>(bg_color * bg, 1.0);
    let screen_size = R;
    let t = u_time.time * 0.5;
    var angle: f32 = 0.25;
    let foldPattern = cos(t * 0.5) * PI * 0.25;
    let globalLight = oscillate(0.4, 1.5, 8.0, u_time.time);
    let asd = oscillate(params.alpha, params.sigma, 25.0, u_time.time);

    var i = params.gamma;
    while(i > 0.003) {
        let layer = i * 1.0;

        let fold = sin(t + layer * 0.2) * cos(t * 0.5 + layer * 0.1);
        let wave = cos(t * 0.7 + layer * 0.15) * sin(t * 0.3 + i);

        let temp_angle = foldPattern;
        angle = angle - sin(angle - sin(temp_angle)) * (0.5 + 1.5 * sin(layer));

        let alternatingFold = sign(sin(layer * params.b)) * sin(t + i * 2.0);

        var uv = 4.7 * (FragCoord.xy - screen_size) / screen_size.y;
        uv.y = uv.y + 2.3;
        uv.x = uv.x + 3.0;
        uv = rotate(i + (angle + alternatingFold) + foldPattern) * uv;

        let pentagon = sdPentagon(uv, i, angle + t * (1.0 + 0.2 * sin(layer)));
        let alpha = smoothstep(0.0, 0.2, (pentagon - 0.1) * screen_size.y * 0.15);

        let lightIntensity = gl(uv, pentagon, i, t, angle);
        let envLight = geeee(uv, angle, i, t);

        let des = oscillate(0.5, 1.0, 5.0, u_time.time);
        let des2 = oscillate(0.1, 1.0, 5.0, u_time.time);

        let colorIntensity = 0.8 +
            0.2 * sin(layer * 24.37 + t) *
            cos(layer * 12.54 - t * 0.4) *
            sin(angle * 3.0 + t * 0.7);

        let colorShift = 0.2 +
            0.1 * cos(layer * 9.21 + t * 0.5) *
            sin(angle * 5.0 - t * 0.3);

        let base_color = vec3<f32>(params.base_color_r, params.base_color_g, params.base_color_b);
        let accent_color = vec3<f32>(params.accent_color_r, params.accent_color_g, params.accent_color_b);
        let original_hue = sin(i / des2 + angle / des + vec4<f32>(params.blue, 2.0, 3.0, 1.0) + fold * 0.5) * colorShift + colorIntensity;
        let color_influence = (base_color + accent_color) * 0.5;
        let enhanced_hue = original_hue * vec4<f32>(color_influence, 1.0);
        let hue = enhanced_hue;

        let litColor = hue * (lightIntensity * globalLight + envLight);

        let depthFactor = params.a - (i - 0.003) / (1.5 - 0.003);
        let iridescence = sin(dot(uv, uv) * 4.0 + t) * IRIDESCENCE_POWER * depthFactor + 0.95;
        let litColorIrid = litColor * vec4<f32>(iridescence, iridescence * 0.98, iridescence * 1.02, 1.0);

        let des4 = oscillate(0.4, 0.2, 10.0, u_time.time);
        let des12 = oscillate(0.1, 0.1, 10.0, u_time.time);

        let mixFactor = des4 / (pentagon + 0.01) * (0.6 - depthFactor * 0.25);
        fragColor = mix(litColorIrid, fragColor, alpha) *
                   mix(vec4<f32>(1.0), hue + 1.5 * alpha * des12 * (uv.x / pentagon + lightIntensity), mixFactor);

        i = i - asd;
    }

    let des2_final = oscillate(0.7, 0.7, 5.0, u_time.time);
    fragColor = vec4<f32>(fragColor.rgb * (des2_final + globalLight * 0.1), 1.0);

    let vignetteUV = (FragCoord.xy - 0.5 * screen_size) / screen_size.y;
    let vignette = 1.0 - dot(vignetteUV, vignetteUV) * VIGNETTE_STRENGTH;

    var final_color = fragColor.rgb;
    if (params.aces_tonemapping > 0.0) {
        final_color = mix(final_color, aces_tonemap(final_color), params.aces_tonemapping);
    }
    let cor = gamma(final_color, params.gamma_correction);
    let result = vec4<f32>(cor, fragColor.a);
    
    textureStore(output, vec2<i32>(i32(coords.x), i32(coords.y)), result);
}