kas-wgpu 0.17.1

KAS GUI / wgpu front-end
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License in the LICENSE-APACHE file or at:
//     https://www.apache.org/licenses/LICENSE-2.0

#version 450
#extension GL_ARB_separate_shader_objects : enable

precision mediump float;

layout(location = 0) in vec4 fragColor;
layout(location = 1) in vec2 dir;
layout(location = 2) in vec2 adjust;
layout(location = 3) in vec2 off;

layout(location = 0) out vec4 outColor;

layout(set = 0, binding = 1) uniform FragCommon {
    vec3 lightNorm;
    // Note: since WGPU v0.12 this type is interpreted as 16 bytes.
    // For compatibility, we explicitly pad to 16 bytes.
    float _padding;
};

float sample_a(vec2 dir) {
    vec2 dir2 = dir * dir;
    float ss = dir2.x + dir2.y;
    return (ss <= 1.0) ? 0.25 : 0.0;
}

void main() {
    // Multi-sample alpha to avoid ugly aliasing. A single colour sample is adequate.
    vec2 off1 = vec2(off.x, 0.0);
    vec2 off2 = vec2(0.0, off.y);
    float alpha = sample_a(dir + off1)
        + sample_a(dir - off1)
        + sample_a(dir + off2)
        + sample_a(dir - off2);
    if (alpha == 0.0) discard;

    vec2 dir2 = dir * dir;
    float ss = dir2.x + dir2.y;

    // With multi-sampling we can hit ss>1. Clamp to avoid imaginary roots:
    float z = sqrt(max(1.0 - ss, 0));
    float h = sqrt(ss);
    float t = adjust.x + adjust.y * atan(h, z);
    vec2 normh = vec2(0.0);
    if (h > 0.0) {
        normh = dir * (sin(t) / h);
        z = cos(t);
    }
    vec3 norm = vec3(normh, z);

    // Simplified version with only scale adjustment; looks okay with convex
    // curvature but not with concave:
    // float z = sqrt(1.0 - adjust.y * ss);
    // vec3 norm = vec3(dir * sqrt(adjust.y), z);

    vec3 c = fragColor.rgb * dot(norm, lightNorm);
    outColor = vec4(c, fragColor.a * alpha);
}