* overhaul of perlin noise

* batch processing moved to fore-front
* speed attribute for noise
* noise offset changed to vec2 for 2d noise
* batch attribute moved to bottom of noises
This commit is contained in:
Alexander G. Morano
2025-06-17 18:11:30 -04:00
parent 5a363a6ad9
commit 00af94cab6
8 changed files with 151 additions and 420 deletions
+7
View File
@@ -44,6 +44,13 @@ Please consider sponsoring me if you enjoy the results of my work, code or docum
## UPDATES
**2025/06/16** @1.1.37:
* overhaul of perlin noise
* batch processing moved to fore-front
* speed attribute for noise
* noise offset changed to vec2 for 2d noise
* batch attribute moved to bottom of noises
**2025/05/16** @1.1.36:
* updated to comfy_cozy 0.0.25
+8 -8
View File
@@ -126,7 +126,7 @@ class GLSLNodeDynamic(CozyImageNode):
CONTROL = []
PARAM = []
# res, frame. framerate, time, batch, matte, edge, batch, seed
# res, frame. framerate, time, matte, edge, seed, batch
@classmethod
def INPUT_TYPES(cls) -> dict:
@@ -157,12 +157,6 @@ class GLSLNodeDynamic(CozyImageNode):
"tooltip": "Value to use directly; if > -1 will override iFrame/iFrameRate calculation."
})
if 'BATCH' in cls.CONTROL:
optional["batch"] = ("INT", {
"default": 1, "min": 1, "max": sys.maxsize,
"tooltip": "Number of frames to generate. 0 (continuous mode) means continue from the last queue generating the next single frame based on iFrameRate. In the shader this will be the index of the batch iteration or 0."
})
if 'MATTE' in cls.CONTROL:
optional["matte"] = ("VEC4", {
"default": (0, 0, 0, 255),
@@ -197,6 +191,12 @@ class GLSLNodeDynamic(CozyImageNode):
"tooltip": "Number of frames to generate. 0 (continuous mode) means continue from the last queue generating the next single frame based on iFrameRate."
})
if 'BATCH' in cls.CONTROL:
optional["batch"] = ("INT", {
"default": 1, "min": 1, "max": sys.maxsize,
"tooltip": "Number of frames to generate. 0 (continuous mode) means continue from the last queue generating the next single frame based on iFrameRate. In the shader this will be the index of the batch iteration or 0."
})
"""
'MODE': (EnumScaleMode._member_names_, {"default": EnumScaleMode.MATTE.name})
'SAMPLE': (EnumInterpolation._member_names_, {"default": EnumInterpolation.LANCZOS4.name})
@@ -277,7 +277,7 @@ class GLSLNodeDynamic(CozyImageNode):
self.__glsl = None
def run(self, ident, **kw) -> RGBAMaskType:
# IRES, MATTE, EDGE, IFRAME, IFRAMERATE, ITIME, BATCH, SEED
# IRES, MATTE, EDGE, IFRAME, IFRAMERATE, ITIME, SEED, BATCH
iResolution = parse_param(kw, 'iRes', EnumConvertType.VEC2INT,
[(IMAGE_SIZE_DEFAULT, IMAGE_SIZE_DEFAULT)],
IMAGE_SIZE_MIN, IMAGE_SIZE_MAX)
+3 -3
View File
@@ -8,11 +8,11 @@
//------------------------------------------------------------------------------
// Generate high-quality blue noise
float noise_blue(vec2 uv int seed) {
float noise_blue(vec2 uv uint seed) {
vec3 p = vec3(uv, 0.0);
float t = fract(0.0);
vec3 n1 = noise_hash3(floor(p), seed);
vec3 n2 = noise_hash3(ceil(p), seed);
vec3 n1 = noise_hash(floor(p), seed);
vec3 n2 = noise_hash(ceil(p), seed);
return mix(n1.x, n2.x, smoothstep(0.0, 1.0, t));
}
+35 -1
View File
@@ -2,7 +2,7 @@
#define LIB_NOISE_GRAD
//------------------------------------------------------------------------------
// GRADIENT COMPUTATION
// GRADIENT (GENERIC)
// Core gradient calculation functions used by noise algorithms
//------------------------------------------------------------------------------
@@ -15,4 +15,38 @@ GRAD(vec2)
GRAD(vec3)
GRAD(vec4)
//------------------------------------------------------------------------------
// GRADIENT
// Core gradient calculation functions used by noise algorithms
//------------------------------------------------------------------------------
vec2 gradient2D(vec2 h) {
// Convert [0,1] -> angle in radians
float angle = 6.2831853 * fract(h.x + h.y);
return vec2(cos(angle), sin(angle));
}
vec3 gradient3D(vec3 h) {
float theta = 6.2831853 * h.x;
float phi = acos(2.0 * h.y - 1.0);
return vec3(
sin(phi) * cos(theta),
sin(phi) * sin(theta),
cos(phi)
);
}
vec4 gradient4D(vec4 h) {
float theta1 = 6.2831853 * h.x;
float theta2 = 6.2831853 * h.y;
float r1 = sqrt(1.0 - h.z);
float r2 = sqrt(h.z);
return vec4(
r1 * cos(theta1),
r1 * sin(theta1),
r2 * cos(theta2),
r2 * sin(theta2)
);
}
#endif
+33 -319
View File
@@ -1,337 +1,51 @@
#ifndef LIB_NOISE_HASH
#define LIB_NOISE_HASH
//------------------------------------------------------------------------------
// SUPPORT
//------------------------------------------------------------------------------
uvec2 floatToBits(vec2 v) {
return uvec2(floatBitsToUint(v.x), floatBitsToUint(v.y));
}
uvec3 floatToBits(vec3 v) {
return uvec3(floatBitsToUint(v.x), floatBitsToUint(v.y), floatBitsToUint(v.z));
}
uvec4 floatToBits(vec4 v) {
return uvec4(floatBitsToUint(v.x), floatBitsToUint(v.y), floatBitsToUint(v.z), floatBitsToUint(v.w));
}
//------------------------------------------------------------------------------
// HASH NOISE
//------------------------------------------------------------------------------
uint hashMurmur_11(uint src, uint seed) {
const uint M = 0x5bd1e995u;
uint h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
vec2 noise_hash(vec2 p, uint seed) {
// Base fract transform on position only
vec3 p3 = fract(vec3(p.xyx) * 0.1031);
// 1 output, 1 input
float hash11(float src, uint seed) {
uint h = hashMurmur_11(floatBitsToUint(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
// Mix in seed parts scaled down to small floats for precision-safe entropy injection
float seedA = float((seed & 0xFFu)) * 0.0001;
float seedB = float(((seed >> 8) & 0xFFu)) * 0.0007;
float seedC = float(((seed >> 16) & 0xFFu)) * 0.0003;
//------------------------------------------------------------------------------
uint hashMurmur_12(uvec2 src, uint seed) {
const uint M = 0x5bd1e995u;
uint h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 1 output, 2 inputs
float hash12(vec2 src, uint seed) {
uint h = hashMurmur_12(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uint hashMurmur_13(uvec3 src, uint seed) {
const uint M = 0x5bd1e995u;
uint h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 1 output, 3 inputs
float hash13(vec3 src, uint seed) {
uint h = hashMurmur_13(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uint hashMurmur_14(uvec4 src, uint seed) {
const uint M = 0x5bd1e995u;
uint h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z; h *= M; h ^= src.w;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 1 output, 4 inputs
float hash14(vec4 src, uint seed) {
uint h = hashMurmur_14(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec2 hashMurmur_21(uint src, uvec2 seed) {
const uint M = 0x5bd1e995u;
uvec2 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 2 outputs, 1 input
vec2 hash21(float src, uvec2 seed) {
uvec2 h = hashMurmur_21(floatBitsToUint(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec2 hashMurmur_22(uvec2 src, uvec2 seed) {
const uint M = 0x5bd1e995u;
uvec2 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 2 outputs, 2 inputs
vec2 hash22(vec2 src, uvec2 seed) {
uvec2 h = hashMurmur_22(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec2 hashMurmur_23(uvec3 src, uvec2 seed) {
const uint M = 0x5bd1e995u;
uvec2 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 2 outputs, 3 inputs
vec2 hash23(vec3 src, uvec2 seed) {
uvec2 h = hashMurmur_23(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec2 hashMurmur_24(uvec4 src, uvec2 seed) {
const uint M = 0x5bd1e995u;
uvec2 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z; h *= M; h ^= src.w;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 2 outputs, 4 inputs
vec2 hash24(vec4 src, uvec2 seed) {
uvec2 h = hashMurmur_24(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec3 hashMurmur_31(uint src, uvec3 seed) {
const uint M = 0x5bd1e995u;
uvec3 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 3 outputs, 1 input
vec3 hash31(float src, uvec3 seed) {
uvec3 h = hashMurmur_31(floatBitsToUint(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec3 hashMurmur_32(uvec2 src, uvec3 seed) {
const uint M = 0x5bd1e995u;
uvec3 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 3 outputs, 2 inputs
vec3 hash32(vec2 src, uvec3 seed) {
uvec3 h = hashMurmur_32(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec3 hashMurmur_33(uvec3 src, uvec3 seed) {
const uint M = 0x5bd1e995u;
uvec3 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 3 outputs, 3 inputs
vec3 hash33(vec3 src, uvec3 seed) {
uvec3 h = hashMurmur_33(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec3 hashMurmur_34(uvec4 src, uvec3 seed) {
const uint M = 0x5bd1e995u;
uvec3 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z; h *= M; h ^= src.w;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 3 outputs, 4 inputs
vec3 hash34(vec4 src, uvec3 seed) {
uvec3 h = hashMurmur_34(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec4 hashMurmur_41(uint src, uvec4 seed) {
const uint M = 0x5bd1e995u;
uvec4 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 4 outputs, 1 input
vec4 hash41(float src, uvec4 seed) {
uvec4 h = hashMurmur_41(floatBitsToUint(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec4 hashMurmur_42(uvec2 src, uvec4 seed) {
const uint M = 0x5bd1e995u;
uvec4 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 4 outputs, 2 inputs
vec4 hash42(vec2 src, uvec4 seed) {
uvec4 h = hashMurmur_42(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec4 hashMurmur_43(uvec3 src, uvec4 seed) {
const uint M = 0x5bd1e995u;
uvec4 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 4 outputs, 3 inputs
vec4 hash43(vec3 src, uvec4 seed) {
uvec4 h = hashMurmur_43(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
uvec4 hashMurmur_44(uvec4 src, uvec4 seed) {
const uint M = 0x5bd1e995u;
uvec4 h = seed;
src *= M; src ^= src>>24u; src *= M;
h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z; h *= M; h ^= src.w;
h ^= h>>13u; h *= M; h ^= h>>15u;
return h;
}
// 4 outputs, 4 inputs
vec4 hash44(vec4 src, uvec4 seed) {
uvec4 h = hashMurmur_44(floatToBits(src), seed);
return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
}
//------------------------------------------------------------------------------
// STANDARD HASH NOISE
//------------------------------------------------------------------------------
float noise_hash(int n) {
n = (n << 13) ^ n;
return float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 0x7fffffff;
}
// Basic 1D hash - maps float to float [0,1]
float noise_hash11(float p) {
p = fract(p * .1031);
p *= p + 33.33;
return fract(p * p);
}
// 2D to 1D hash - maps vec2 to float [0,1]
float noise_hash21(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * .1031);
p3 += seedA + seedB + seedC;
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.x + p3.y) * p3.z);
return fract(vec2(p3.x + p3.y, p3.y + p3.z));
}
// 3D to 3D hash - maps vec3 to vec3 [0,1]
vec3 noise_hash33(vec3 p) {
p = fract(p * vec3(443.8975, 397.2973, 491.1871));
p += dot(p.zxy, p.yxz + 19.19);
return fract(vec3(p.x * p.y, p.y * p.z, p.z * p.x));
vec3 noise_hash(vec3 p, uint seed) {
p = fract(p * 0.1031);
float seedA = float((seed & 0xFFu)) * 0.0001;
float seedB = float(((seed >> 8) & 0xFFu)) * 0.0007;
float seedC = float(((seed >> 16) & 0xFFu)) * 0.0003;
p += seedA + seedB + seedC;
p += dot(p, p.yzx + 33.33);
return fract((p.xxy + p.yzz) * p.zyx);
}
vec3 noise_hash33_2(vec3 p) {
p = vec3( dot(p,vec3(127.1,311.7, 74.7)),
dot(p,vec3(269.5,183.3,246.1)),
dot(p,vec3(113.5,271.9,124.6)));
return fract(sin(p)*43758.5453123);
vec4 noise_hash(vec4 p, uint seed) {
p = fract(p * 0.1031);
float seedA = float((seed & 0xFFu)) * 0.0001;
float seedB = float(((seed >> 8) & 0xFFu)) * 0.0007;
float seedC = float(((seed >> 16) & 0xFFu)) * 0.0003;
float seedD = float(((seed >> 24) & 0xFFu)) * 0.0005;
p += seedA + seedB + seedC + seedD;
p += dot(p, p.wzxy + 33.33);
return fract((p.xxyz + p.yzzw) * p.wzyx);
}
vec3 noise_hash33_3(vec3 p3) {
p3 = fract(p3 * vec3(10.31, 10.3, 9.73));
p3 += dot(p3, p3.yxz+33.33);
return fract((p3.xxy + p3.yxx)*p3.zyx);
}
#endif
+61 -85
View File
@@ -2,118 +2,94 @@
#define LIB_NOISE_PERLIN
#include .lib/noise/noise_hash.lib
#include .lib/noise/noise_grad.lib
#include .lib/noise/noise_param.lib
//------------------------------------------------------------------------------
// NOISE PERLIN
//------------------------------------------------------------------------------
vec2 gradient2D(uint hash) {
switch (int(hash) & 7) {
case 0: return vec2(1, 0);
case 1: return vec2(-1, 0);
case 2: return vec2(0, 1);
case 3: return vec2(0, -1);
case 4: return normalize(vec2(1, 1));
case 5: return normalize(vec2(-1, 1));
case 6: return normalize(vec2(1, -1));
case 7: return normalize(vec2(-1, -1));
default: return vec2(0);
}
}
vec3 gradient3D(uint hash) {
// look at the last four bits to pick a gradient direction
switch (int(hash) & 15) {
case 0: return vec3(1, 1, 0);
case 1: return vec3(-1, 1, 0);
case 2: return vec3(1, -1, 0);
case 3: return vec3(-1, -1, 0);
case 4: return vec3(1, 0, 1);
case 5: return vec3(-1, 0, 1);
case 6: return vec3(1, 0, -1);
case 7: return vec3(-1, 0, -1);
case 8: return vec3(0, 1, 1);
case 9: return vec3(0, -1, 1);
case 10: return vec3(0, 1, -1);
case 11: return vec3(0, -1, -1);
case 12: return vec3(1, 1, 0);
case 13: return vec3(-1, 1, 0);
case 14: return vec3(0, -1, 1);
case 15: return vec3(0, -1, -1);
default: return vec2(0);
}
}
vec4 gradient4D(uint hash) {
int h = int(hash) & 31;
return normalize(vec4(
((h & 1) == 0) ? 1.0 : -1.0,
((h & 2) == 0) ? 1.0 : -1.0,
((h & 4) == 0) ? 1.0 : -1.0,
((h & 8) == 0) ? 1.0 : -1.0
));
}
// Generate 2D Perlin noise
float noise_perlin(vec2 p, uint seed) {
vec2 i = floor(p);
vec2 f = p - i;
uvec2 cellSeed = uvec2(seed);
float a = dot(gradient2D(hash22(i, cellSeed)), f);
float b = dot(gradient2D(hash22((i + vec2(1., 0.)), cellSeed)), f - vec2(1., 0.));
float c = dot(gradient2D(hash22((i + vec2(0., 1.)), cellSeed)), f - vec2(0., 1.));
float d = dot(gradient2D(hash22((i + vec2(1., 1.)), cellSeed)), f - vec2(1., 1.));
float a = dot(gradient2D(noise_hash(i, seed)), f);
float b = dot(gradient2D(noise_hash((i + vec2(1., 0.)), seed)), f - vec2(1., 0.));
float c = dot(gradient2D(noise_hash((i + vec2(0., 1.)), seed)), f - vec2(0., 1.));
float d = dot(gradient2D(noise_hash((i + vec2(1., 1.)), seed)), f - vec2(1., 1.));
vec2 u = smoothstep(0., 1., f);
//vec2 u = smoothstep(0., 1., f);
vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
}
// 3D Perlin Noise function
float noise_perlin(vec3 p, uint seed) {
vec3 i = floor(p);
vec3 f = p - i;
uvec3 cellSeed = uvec3(seed);
float a = dot(gradient3D(hash33(i, cellSeed)), f);
float b = dot(gradient3D(hash33((i + vec3(1., 0., 0.)), cellSeed)), f - vec3(1., 0., 0.));
float c = dot(gradient3D(hash33((i + vec3(0., 1., 0.)), cellSeed)), f - vec3(0., 1., 0.));
float d = dot(gradient3D(hash33((i + vec3(1., 1., 0.)), cellSeed)), f - vec3(1., 1., 0.));
float e = dot(gradient3D(hash33((i + vec3(0., 0., 1.)), cellSeed)), f - vec3(0., 0., 1.));
float f0 = dot(gradient3D(hash33((i + vec3(1., 0., 1.)), cellSeed)), f - vec3(1., 0., 1.));
float g0 = dot(gradient3D(hash33((i + vec3(0., 1., 1.)), cellSeed)), f - vec3(0., 1., 1.));
float h0 = dot(gradient3D(hash33((i + vec3(1., 1., 1.)), cellSeed)), f - vec3(1., 1., 1.));
float n000 = dot(gradient3D(noise_hash(i + vec3(0, 0, 0), seed)), f - vec3(0, 0, 0));
float n100 = dot(gradient3D(noise_hash(i + vec3(1, 0, 0), seed)), f - vec3(1, 0, 0));
float n010 = dot(gradient3D(noise_hash(i + vec3(0, 1, 0), seed)), f - vec3(0, 1, 0));
float n110 = dot(gradient3D(noise_hash(i + vec3(1, 1, 0), seed)), f - vec3(1, 1, 0));
float n001 = dot(gradient3D(noise_hash(i + vec3(0, 0, 1), seed)), f - vec3(0, 0, 1));
float n101 = dot(gradient3D(noise_hash(i + vec3(1, 0, 1), seed)), f - vec3(1, 0, 1));
float n011 = dot(gradient3D(noise_hash(i + vec3(0, 1, 1), seed)), f - vec3(0, 1, 1));
float n111 = dot(gradient3D(noise_hash(i + vec3(1, 1, 1), seed)), f - vec3(1, 1, 1));
vec3 u = smoothstep(0., 1., f);
return mix(mix(mix(a, b, u.x), mix(c, d, u.x), u.y), mix(mix(e, f0, u.x), mix(g0, h0, u.x), u.y), u.z);
vec3 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
return mix(
mix(mix(n000, n100, u.x), mix(n010, n110, u.x), u.y),
mix(mix(n001, n101, u.x), mix(n011, n111, u.x), u.y),
u.z
);
}
// 4D Perlin Noise function
float noise_perlin(vec4 p, uint seed) {
vec4 i = floor(p);
vec4 f = p - i;
uvec4 cellSeed = uvec4(seed);
float a = dot(gradient4D(hash44(i, cellSeed)), f);
float b = dot(gradient4D(hash44((i + vec4(1, 0, 0, 0)), cellSeed)), f - vec4(1., 0., 0., 0.));
float c = dot(gradient4D(hash44((i + vec4(0, 1, 0, 0)), cellSeed)), f - vec4(0., 1., 0., 0.));
float d = dot(gradient4D(hash44((i + vec4(1, 1, 0, 0)), cellSeed)), f - vec4(1., 1., 0., 0.));
float e = dot(gradient4D(hash44((i + vec4(0, 0, 1, 0)), cellSeed)), f - vec4(0., 0., 1., 0.));
float f0 = dot(gradient4D(hash44((i + vec4(1, 0, 1, 0)), cellSeed)), f - vec4(1., 0., 1., 0.));
float g0 = dot(gradient4D(hash44((i + vec4(0, 1, 1, 0)), cellSeed)), f - vec4(0., 1., 1., 0.));
float h0 = dot(gradient4D(hash44((i + vec4(1, 1, 1, 0)), cellSeed)), f - vec4(1., 1., 1., 0.));
float i1 = dot(gradient4D(hash44((i + vec4(0, 0, 0, 1)), cellSeed)), f - vec4(0., 0., 0., 1.));
float j1 = dot(gradient4D(hash44((i + vec4(1, 0, 0, 1)), cellSeed)), f - vec4(1., 0., 0., 1.));
float k1 = dot(gradient4D(hash44((i + vec4(0, 1, 0, 1)), cellSeed)), f - vec4(0., 1., 0., 1.));
float l1 = dot(gradient4D(hash44((i + vec4(1, 1, 0, 1)), cellSeed)), f - vec4(1., 1., 0., 1.));
float m1 = dot(gradient4D(hash44((i + vec4(0, 0, 1, 1)), cellSeed)), f - vec4(0., 0., 1., 1.));
float n1 = dot(gradient4D(hash44((i + vec4(1, 0, 1, 1)), cellSeed)), f - vec4(1., 0., 1., 1.));
float o1 = dot(gradient4D(hash44((i + vec4(0, 1, 1, 1)), cellSeed)), f - vec4(0., 1., 1., 1.));
float p1 = dot(gradient4D(hash44((i + vec4(1, 1, 1, 1)), cellSeed)), f - vec4(1., 1., 1., 1.));
#define DOT(off) dot(gradient4D(noise_hash(i + off, seed)), f - off)
vec3 u = smoothstep(0., 1., f);
return mix(mix(mix(a, b, u.x), mix(c, d, u.x), u.y), mix(mix(e, f0, u.x), mix(g0, h0, u.x), u.y), u.z);
float n0000 = DOT(vec4(0, 0, 0, 0));
float n1000 = DOT(vec4(1, 0, 0, 0));
float n0100 = DOT(vec4(0, 1, 0, 0));
float n1100 = DOT(vec4(1, 1, 0, 0));
float n0010 = DOT(vec4(0, 0, 1, 0));
float n1010 = DOT(vec4(1, 0, 1, 0));
float n0110 = DOT(vec4(0, 1, 1, 0));
float n1110 = DOT(vec4(1, 1, 1, 0));
float n0001 = DOT(vec4(0, 0, 0, 1));
float n1001 = DOT(vec4(1, 0, 0, 1));
float n0101 = DOT(vec4(0, 1, 0, 1));
float n1101 = DOT(vec4(1, 1, 0, 1));
float n0011 = DOT(vec4(0, 0, 1, 1));
float n1011 = DOT(vec4(1, 0, 1, 1));
float n0111 = DOT(vec4(0, 1, 1, 1));
float n1111 = DOT(vec4(1, 1, 1, 1));
vec4 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
float x00 = mix(n0000, n1000, u.x);
float x10 = mix(n0100, n1100, u.x);
float x01 = mix(n0010, n1010, u.x);
float x11 = mix(n0110, n1110, u.x);
float x00_1 = mix(n0001, n1001, u.x);
float x10_1 = mix(n0101, n1101, u.x);
float x01_1 = mix(n0011, n1011, u.x);
float x11_1 = mix(n0111, n1111, u.x);
float y0 = mix(x00, x10, u.y);
float y1 = mix(x01, x11, u.y);
float y0_1 = mix(x00_1, x10_1, u.y);
float y1_1 = mix(x01_1, x11_1, u.y);
float z0 = mix(y0, y1, u.z);
float z1 = mix(y0_1, y1_1, u.z);
return mix(z0, z1, u.w);
}
//------------------------------------------------------------------------------
+1 -1
View File
@@ -16,7 +16,7 @@ float noise_cosmicWeb(vec2 p, float scale) {
for(int y = -1; y <= 1; y++) {
for(int x = -1; x <= 1; x++) {
vec2 offset = vec2(x, y);
vec2 pos = offset + noise_hash33(vec3(id + offset, 0.0)).xy;
vec2 pos = offset + noise_hash(vec3(id + offset, 0.0)).xy;
min_dist = min(min_dist, length(f - pos));
}
}
+3 -3
View File
@@ -12,9 +12,9 @@
"INVERT (JOV_GL)": "Invert the channels of an image along a scalar [0",
"LINEAR GRADIENT (JOV_GL)": "Generate a two color linear gradient",
"MIN MAX (JOV_GL)": "Gets the minimum and maximum of an image",
"NOISE PERLIN (JOV_GL)": "Classic Perlin noise",
"NOISE SIMPLEX (JOV_GL)": "Simplex noise, simply",
"NOISE WORLEY (JOV_GL)": "Worley noise with the best",
"NOISE PERLIN (JOV_GL)": "Classic Perlin noise with batch output",
"NOISE SIMPLEX (JOV_GL)": "Simplex noise with batch output",
"NOISE WORLEY (JOV_GL)": "Worley (cellular) noise with batch output",
"NORMAL (JOV_GL)": "Convert input into a Normal map",
"NORMAL BLEND (JOV_GL)": "Blend two Normal maps",
"PIXELATE (JOV_GL)": "Pixelate input image",