#ifdef perlin4x
    #define perlinChannel a
#else
    #define perlinChannel b
#endif

float perlin2D(in vec2 coord, in float size, in vec2 offset) {
    coord      *= size;
    coord      += offset;
    coord      /= 1024;
    return texture(noisetex, coord).perlinChannel*2.0-1.0;
}
float perlin2D(in vec2 coord, in float size) {
    coord      *= size;
    coord      /= 1024;
    return texture(noisetex, coord).perlinChannel*2.0-1.0;
}
float perlin2D(in vec2 coord) {
    coord      /= 1024;
    return texture(noisetex, coord).perlinChannel*2.0-1.0;
}
float perlin3D(in vec3 pos, in float size, in vec3 offset) {
    pos.z          /= 8.0;
    pos            *= size*4;
    pos            += offset;
    vec3 i          = floor(pos);
    vec3 f          = fract(pos);

    vec2 p1         = (i.xy+i.z*vec2(17.0)+f.xy);
    vec2 p2         = (i.xy+(i.z+1.f)*vec2(17.0))+f.xy;
    vec2 c1         = (p1+0.5)/1024;
    vec2 c2         = (p2+0.5)/1024;
    float r1        = texture(noisetex, c1).perlinChannel;
    float r2        = texture(noisetex, c2).perlinChannel;
    return mix(r1, r2, f.z)*2-1;
}
float perlin3D(in vec3 pos) {
    return perlin3D(pos, 1.0, vec3(0.0));
}