{
    "QEN": {
        "description": "This node contains noise / hash helper functions which other nodes can utilize.",
        "fragmentCode": [
            "#define HASH_BOX_SIZE 1920U",
            "#define PI 3.14159265359",
            "#define TAU 6.28318530718",
            "#define SQRT2 1.41421356237",
            "",
            "float hash21(vec2 n);",
            "vec3 hash23(vec2 n);",
            "float _hash11(uint n);",
            "float _hash21( uvec2 x );",
            "vec3 _hash13(uint n);",
            "",
            "// Hash from vec2 to float",
            "// Can be used directly with fragCoord",
            "float hash21(vec2 n)",
            "{",
            "    uvec2 uin = uvec2(n);",
            "    return _hash21(uin);",
            "}",
            "",
            "// Hash from vec2 to vec3",
            "// Can be used directly with fragCoord",
            "vec3 hash23(vec2 n)",
            "{",
            "    uvec2 uin = uvec2(n);",
            "    return _hash13(uin.x + HASH_BOX_SIZE * uin.y);",
            "}",
            "",
            "// Hash from uint to float",
            "float _hash11(uint n)",
            "{",
            "    n = (n << 13U) ^ n;",
            "    n = n * (n * n * 15731U + 789221U) + 1376312589U;",
            "    return float( n & uint(0x7fffffffU))/float(0x7fffffff);",
            "}",
            "",
            "// Hash from uvec2 to float",
            "float _hash21( uvec2 x )",
            "{",
            "    uvec2 q = 1103515245U * ( (x>>1U) ^ (x.yx   ) );",
            "    uint  n = 1103515245U * ( (q.x  ) ^ (q.y>>3U) );",
            "    return float(n) * (1.0/float(0xffffffffU));",
            "}",
            "",
            "// Hash from uint to vec3",
            "vec3 _hash13(uint n)",
            "{",
            "    n = (n << 13U) ^ n;",
            "    n = n * (n * n * 15731U + 789221U) + 1376312589U;",
            "    uvec3 k = n * uvec3(n,n*16807U,n*48271U);",
            "    return vec3( k & uvec3(0x7fffffffU))/float(0x7fffffff);",
            "}",
            "",
            "vec2 pseudo3dNoiseLevel(vec2 intPos, float t) {",
            "    float rand = hash21(intPos);",
            "    float angle = TAU * rand + t * rand;",
            "    return vec2(cos(angle), sin(angle));",
            "}",
            "",
            "// Generates noise which resembles 3D perlin-noise",
            "float pseudo3dNoise(vec3 pos) {",
            "    const vec2 i = floor(pos.xy);",
            "    const vec2 f = fract(pos.xy);",
            "    const vec2 blend = f * f * (3.0 - 2.0 * f);",
            "    float noiseVal = mix(",
            "        mix(",
            "            dot(pseudo3dNoiseLevel(i + vec2(0.0, 0.0), pos.z), f - vec2(0.0, 0.0)),",
            "            dot(pseudo3dNoiseLevel(i + vec2(1.0, 0.0), pos.z), f - vec2(1.0, 0.0)),",
            "            blend.x),",
            "        mix(",
            "            dot(pseudo3dNoiseLevel(i + vec2(0.0, 1.0), pos.z), f - vec2(0.0, 1.0)),",
            "            dot(pseudo3dNoiseLevel(i + vec2(1.0, 1.0), pos.z), f - vec2(1.0, 1.0)),",
            "            blend.x),",
            "        blend.y);",
            "    return noiseVal * SQRT2;",
            "}",
            "",
            "@main"
        ],
        "name": "NoiseHelper",
        "version": 1
    }
}
