Skip to content

Instantly share code, notes, and snippets.

@sketchpunk
Last active February 1, 2024 23:10
Show Gist options
  • Save sketchpunk/b140dfcd2d381c4f3c7d4e7436af4334 to your computer and use it in GitHub Desktop.
Save sketchpunk/b140dfcd2d381c4f3c7d4e7436af4334 to your computer and use it in GitHub Desktop.
WebGL : Blender 4.0 GLSL Nodes
// #region CUSTOM - NON-BLENDER CODE
/*
USAGE
vec3 ramp_col[9] = vec3[](
rgb(0x0F2936),
rgb(0x123243),
rgb(0x24525D),
rgb(0x437274),
rgb(0x263F41),
rgb(0xFFCE8B),
rgb(0x769437),
rgb(0x576E29),
rgb(0x283313)
);
float ramp_wgt[9] = float[](
0.0,
0.134299,
0.26615,
0.333805,
0.40146,
0.474296,
0.504279,
0.596356,
0.743203
);
outColor.rgb = colorEaseRamp( ramp_col, ramp_wgt, n, 9 );
*/
vec3 rgb( int c ){
return vec3(
float( ( c >> 16 ) & 0xff ) * 0.00392156863,
float( ( c >> 8 ) & 0xff ) * 0.00392156863,
float( c & 0xff ) * 0.00392156863
);
}
vec3 colorLinearRamp( vec3[9] color, float[9] wgt, float t, int cnt ){
if( t >= wgt[ cnt-1 ] ) return color[ cnt-1 ];
if( t <= wgt[ 0 ] ) return color[ 0 ];
for( int i=1; i < cnt; i++ ){
if( t <= wgt[ i ] ){
float fac = ( t - wgt[ i-1 ] ) / ( wgt[ i ] - wgt[ i-1 ] );
return mix( color[ i-1 ], color[ i ], fac );
}
}
return color[ cnt-1 ];
}
vec3 colorEaseRamp( vec3[9] color, float[9] wgt, float t, int cnt ){
if( t >= wgt[ cnt-1 ] ) return color[ cnt-1 ];
if( t <= wgt[ 0 ] ) return color[ 0 ];
for( int i=1; i < cnt; i++ ){
if( t <= wgt[ i ] ){
float fac = ( t - wgt[ i-1 ] ) / ( wgt[ i ] - wgt[ i-1 ] );
fac = clamp( fac * fac * ( 3.0 - 2.0 * fac ), 0.0, 1.0 );
return mix( color[ i-1 ], color[ i ], fac );
}
}
return color[ cnt-1 ];
}
// #endregion
// #region MAP RANGE
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_map_range.glsl#L144
float map_range_stepped(
float value,
float fromMin,
float fromMax,
float toMin,
float toMax,
float steps )
{
if (fromMax != fromMin) {
float factor = (value - fromMin) / (fromMax - fromMin);
factor = (steps > 0.0) ? floor(factor * (steps + 1.0)) / steps : 0.0;
return toMin + factor * (toMax - toMin);
}
return 0.0;
}
// #endregion
// https://github.com/blender/blender/blob/23faaac68b52221b961d24647086daf95f670546/source/blender/gpu/shaders/common/gpu_shader_common_math_utils.glsl#L10C1-L14C1
float safe_divide(float a, float b){ return (b != 0.0) ? a / b : 0.0; }
vec3 safe_divide(vec3 a, vec3 b){ return vec3(safe_divide(a.x, b.x), safe_divide(a.y, b.y), safe_divide(a.z, b.z)); }
// https://github.com/blender/blender/blob/23faaac68b52221b961d24647086daf95f670546/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl#L81C1-L85C1
vec3 vector_math_snap(vec3 a, vec3 b ){
return floor(safe_divide(a, b)) * b;
}
// #region NOISE TEXTURE
/* USEAGE
float n = 0.0;
vec4 c = vec4( 0.0 );
node_noise_tex_fbm_3d( vec3( fragUV, 0.0 ),
0.6,
8.0,
0.486,
2.0,
0.0,
0.0, // Right Gain Default ?
0.25,
1.0 ,
n,
c
);
*/
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/common/gpu_shader_common_hash.glsl#L9C1-L9C55
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/common/gpu_shader_common_hash.glsl#L33C1-L49C4
#define final(a, b, c) \
{ \
c ^= b; \
c -= rot(b, 14); \
a ^= c; \
a -= rot(c, 11); \
b ^= a; \
b -= rot(a, 25); \
c ^= b; \
c -= rot(b, 16); \
a ^= c; \
a -= rot(c, 4); \
b ^= a; \
b -= rot(a, 14); \
c ^= b; \
c -= rot(b, 24); \
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/common/gpu_shader_common_hash.glsl#L74C1-L85C2
uint hash_uint3(uint kx, uint ky, uint kz){
uint a, b, c;
a = b = c = 0xdeadbeefu + (3u << 2u) + 13u;
c += kz;
b += ky;
a += kx;
final(a, b, c);
return c;
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/common/gpu_shader_common_hash.glsl#L117C1-L120C2
uint hash_int3(int kx, int ky, int kz){ return hash_uint3(uint(kx), uint(ky), uint(kz)); }
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl#L8C1-L8C112
#define FLOORFRAC(x, x_int, x_fract) { float x_floor = floor(x); x_int = int(x_floor); x_fract = x - x_floor; }
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl#L90C1-L93C2
float fade(float t){ return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); }
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl#L95C1-L98C2
float negate_if(float value, uint condition){ return (condition != 0u) ? -value : value; }
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/common/gpu_shader_common_hash.glsl#L62
uint hash_uint2(uint kx, uint ky){
uint a, b, c;
a = b = c = 0xdeadbeefu + (2u << 2u) + 13u;
b += ky;
a += kx;
final(a, b, c);
return c;
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/common/gpu_shader_common_hash.glsl#L134C1-L137C2
float hash_uint2_to_float(uint kx, uint ky){ return float(hash_uint2(kx, ky)) / float(0xFFFFFFFFu); }
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/common/gpu_shader_common_hash.glsl#L156C1-L159C2
float hash_vec2_to_float(vec2 k){ return hash_uint2_to_float(floatBitsToUint(k.x), floatBitsToUint(k.y)); }
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl#L45C1-L62C2
float tri_mix(float v0,
float v1,
float v2,
float v3,
float v4,
float v5,
float v6,
float v7,
float x,
float y,
float z)
{
float x1 = 1.0 - x;
float y1 = 1.0 - y;
float z1 = 1.0 - z;
return z1 * (y1 * (v0 * x1 + v1 * x) + y * (v2 * x1 + v3 * x)) +
z * (y1 * (v4 * x1 + v5 * x) + y * (v6 * x1 + v7 * x));
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl#L249C1-L252C2
float noise_scale3(float result){ return 0.9820 * result; }
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl#L115C1-L122C2
float noise_grad(uint hash, float x, float y, float z){
uint h = hash & 15u;
float u = h < 8u ? x : y;
float vt = ((h == 12u) || (h == 14u)) ? x : z;
float v = h < 4u ? y : vt;
return negate_if(u, h & 1u) + negate_if(v, h & 2u);
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl#L168
float noise_perlin(vec3 vec){
int X, Y, Z;
float fx, fy, fz;
FLOORFRAC(vec.x, X, fx);
FLOORFRAC(vec.y, Y, fy);
FLOORFRAC(vec.z, Z, fz);
float u = fade(fx);
float v = fade(fy);
float w = fade(fz);
float r = tri_mix(noise_grad(hash_int3(X, Y, Z), fx, fy, fz),
noise_grad(hash_int3(X + 1, Y, Z), fx - 1.0, fy, fz),
noise_grad(hash_int3(X, Y + 1, Z), fx, fy - 1.0, fz),
noise_grad(hash_int3(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz),
noise_grad(hash_int3(X, Y, Z + 1), fx, fy, fz - 1.0),
noise_grad(hash_int3(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0),
noise_grad(hash_int3(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0),
noise_grad(hash_int3(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0),
u,
v,
w);
return r;
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl#L126C1-L131C2
vec3 random_vec3_offset(float seed){
return vec3(100.0 + hash_vec2_to_float(vec2(seed, 0.0)) * 100.0,
100.0 + hash_vec2_to_float(vec2(seed, 1.0)) * 100.0,
100.0 + hash_vec2_to_float(vec2(seed, 2.0)) * 100.0);
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_noise.glsl#L283C1-L287C2
float snoise(vec3 p){
float r = noise_perlin(p);
return ( isinf(r) )? 0.0 : noise_scale3(r);
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl#L8
float noise_fbm( vec3 co, float detail, float roughness, float lacunarity, float offset, float gain, bool normalize ){
vec3 p = co;
float fscale = 1.0;
float amp = 1.0;
float maxamp = 0.0;
float sum = 0.0;
for(int i = 0; i <= int(detail); i++){
float t = snoise(fscale * p);
sum += t * amp;
maxamp += amp;
amp *= roughness;
fscale *= lacunarity;
}
float rmd = detail - floor(detail);
if( rmd != 0.0 ){
float t = snoise(fscale * p);
float sum2 = sum + t * amp;
return normalize
? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd)
: mix(sum, sum2, rmd);
}else{
return normalize ? 0.5 * sum / maxamp + 0.5 : sum;
}
}
// https://github.com/blender/blender/blob/main/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl#L185
void node_noise_tex_fbm_3d(vec3 co,
float scale,
float detail,
float roughness,
float lacunarity,
float offset,
float gain,
float distortion,
float normalize,
out float value,
out vec4 color )
{
detail = clamp(detail, 0.0, 15.0);
roughness = max(roughness, 0.0);
vec3 p = co * scale;
if (distortion != 0.0) {
p += vec3(snoise(p + random_vec3_offset(0.0)) * distortion,
snoise(p + random_vec3_offset(1.0)) * distortion,
snoise(p + random_vec3_offset(2.0)) * distortion);
}
value = noise_fbm( p, detail, roughness, lacunarity, offset, gain, normalize != 0.0 );
color = vec4(
value,
noise_fbm(p + random_vec3_offset(3.0), detail, roughness, lacunarity, offset, gain, normalize != 0.0 ),
noise_fbm(p + random_vec3_offset(4.0), detail, roughness, lacunarity, offset, gain, normalize != 0.0 ),
1.0
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment