vxdraw 0.1.0

Simple 2D rendering library
Documentation
#version 450

layout (location = 0) in vec2 texpos;
layout (location = 0) out vec4 Color;

layout(push_constant) uniform PushConstant {
    layout (offset = 0) vec4 rand_seed;
} push;

// Hash function: http://amindforeverprogramming.blogspot.com/2013/07/random-floats-in-glsl-330.html
uint hash( uint x ) {
    x += ( x << 10u );
    x ^= ( x >>  6u );
    x += ( x <<  3u );
    x ^= ( x >> 11u );
    x += ( x << 15u );
    return x;
}
uint hash(uvec3 v) {
    return hash( v.x ^ hash(v.y) ^ hash(v.z) );
}
float random(uvec3 pos) {
    const uint mantissaMask = 0x007FFFFFu;
    const uint one          = 0x3F800000u;
   
    uint h = hash( pos );
    h &= mantissaMask;
    h |= one;
    
    float  r2 = uintBitsToFloat( h );
    return r2 - 1.0;
}
float random(vec3 pos) {
    return random(floatBitsToUint(pos));
}
// returns fraction part
float separate(float n, out float i) {
    float frac = modf(n, i);
    if (n < 0.f) {
        frac = 1 + frac; // make fraction non-negative and invert (1 - frac)
        i --;
    }
    return frac;
}

// Perlin: http://www.iquilezles.org/www/articles/morenoise/morenoise.htm
float perlin(vec3 pos, out float dnx, out float dny, out float dnz) {
    float i, j, k;
    float u, v, w;

    // Separate integer and fractional part of coordinates
    u = separate( pos.x, i);
    v = separate( pos.y, j);
    w = separate( pos.z, k);


    float du = 30.0f*u*u*(u*(u-2.0f)+1.0f);
    float dv = 30.0f*v*v*(v*(v-2.0f)+1.0f);
    float dw = 30.0f*w*w*(w*(w-2.0f)+1.0f);

    u = u*u*u*(u*(u*6.0f-15.0f)+10.0f);
    v = v*v*v*(v*(v*6.0f-15.0f)+10.0f);
    w = w*w*w*(w*(w*6.0f-15.0f)+10.0f);

    float a = random( vec3(i+0, j+0, k+0) );
    float b = random( vec3(i+1, j+0, k+0) );
    float c = random( vec3(i+0, j+1, k+0) );
    float d = random( vec3(i+1, j+1, k+0) );
    float e = random( vec3(i+0, j+0, k+1) );
    float f = random( vec3(i+1, j+0, k+1) );
    float g = random( vec3(i+0, j+1, k+1) );
    float h = random( vec3(i+1, j+1, k+1) );

    float k0 =   a;
    float k1 =   b - a;
    float k2 =   c - a;
    float k3 =   e - a;
    float k4 =   a - b - c + d;
    float k5 =   a - c - e + g;
    float k6 =   a - b - e + f;
    float k7 = - a + b + c - d + e - f - g + h;

    /* dnx = du * (k1 + k4*v + k6*w + k7*v*w); */
    /* dny = dv * (k2 + k5*w + k4*u + k7*w*u); */
    /* dnz = dw * (k3 + k6*u + k5*v + k7*u*v); */
    return k0 + k1*u + k2*v + k3*w + k4*u*v + k5*v*w + k6*w*u + k7*u*v*w;
}

// Note: It starts (octave 1) with the highest frequency, `width`
float FBM(vec3 pos, int octaves) {
    float a, b, c;
    float result = 0;
    float p;

    pos *= push.rand_seed.x; // Frequency = pixel
    /* pos *= 1000; */

    const float power = 3;  // Higher -> lower frequencies dominate. Normally 2.
    float pos_factor = 1.f;
    float strength_factor = 1.f / pow(power, octaves);
    for (int i = 0; i < octaves; i ++)
    {
        p = perlin(pos * pos_factor, a, b, c );
        result += (power - 1) * strength_factor * p;

        pos_factor *= 0.5f;
        strength_factor *= power;
    }

    return result;
}

void main()
{
    int octaves = 8;
    float r;
    r = FBM(vec3(texpos,0) + push.rand_seed.yzw, octaves);
    r = step(0.5, r);
    Color = vec4(vec3(r), 1);
}