Commit: 931da132330eb95d519aaf6708ae3d62acc5fafc Author: OmarSquircleArt Date: Thu Jun 27 15:10:36 2019 +0200 Branches: soc-2019-cycles-procedural https://developer.blender.org/rB931da132330eb95d519aaf6708ae3d62acc5fafc
Add 1D, 2D, and 4D noise to EEVEE =================================================================== M source/blender/editors/space_node/drawnode.c M source/blender/gpu/shaders/gpu_shader_material.glsl M source/blender/makesdna/DNA_node_types.h M source/blender/makesrna/intern/rna_nodetree.c M source/blender/nodes/shader/nodes/node_shader_tex_noise.c =================================================================== diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 3ab27a37857..8bac4317b09 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -915,6 +915,11 @@ static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), } } +static void node_shader_buts_tex_noise(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "dimensions", 0, "", ICON_NONE); +} + static void node_shader_buts_tex_pointdensity(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -1231,6 +1236,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_TEX_VORONOI: ntype->draw_buttons = node_shader_buts_tex_voronoi; break; + case SH_NODE_TEX_NOISE: + ntype->draw_buttons = node_shader_buts_tex_noise; + break; case SH_NODE_TEX_POINTDENSITY: ntype->draw_buttons = node_shader_buts_tex_pointdensity; break; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index de1eec6ffef..7b8ae3af201 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1389,6 +1389,26 @@ uint hash(uint kx, uint ky, uint kz, uint kw) #undef final #undef mix +uint hash(int kx) +{ + return hash(uint(kx)); +} + +uint hash(int kx, int ky) +{ + return hash(uint(kx), uint(ky)); +} + +uint hash(int kx, int ky, int kz) +{ + return hash(uint(kx), uint(ky), uint(kz)); +} + +uint hash(int kx, int ky, int kz, int kw) +{ + return hash(uint(kx), uint(ky), uint(kz), uint(kw)); +} + float bits_to_01(uint bits) { return (float(bits) / 4294967295.0); @@ -1472,29 +1492,6 @@ void white_noise_4D(vec3 vec, float w, out float fac) floatBitsToUint(vec.x), floatBitsToUint(vec.y), floatBitsToUint(vec.z), floatBitsToUint(w))); } -uint hash(int kx, int ky, int kz) -{ - return hash(uint(kx), uint(ky), uint(kz)); -} - -float cellnoise(vec3 p) -{ - int ix = quick_floor(p.x); - int iy = quick_floor(p.y); - int iz = quick_floor(p.z); - - return bits_to_01(hash(uint(ix), uint(iy), uint(iz))); -} - -vec3 cellnoise_color(vec3 p) -{ - float r = cellnoise(p.xyz); - float g = cellnoise(p.yxz); - float b = cellnoise(p.yzx); - - return vec3(r, g, b); -} - float floorfrac(float x, out int i) { float x_floor = floor(x); @@ -3116,19 +3113,118 @@ void node_tex_magic( fac = (color.x + color.y + color.z) / 3.0; } +/* **** Perlin Noise **** */ + +// The following functions compute 1D, 2D, 3D, and 4D perlin noise. +// The code is based on the OSL noise code for compatibility. +// See oslnoise.h + +// Bilinear Interpolation: +// +// v2 v3 +// @ + + + + @ y +// + + ^ +// + + | +// + + | +// @ + + + + @ @------> x +// v0 v1 + +float bi_mix(float v0, float v1, float v2, float v3, float x, float y) +{ + float x1 = 1.0 - x; + return (1.0 - y) * (v0 * x1 + v1 * x) + y * (v2 * x1 + v3 * x); +} + +// Trilinear Interpolation: +// +// v6 v7 +// @ + + + + + + @ +// +\ +\ +// + \ + \ +// + \ + \ +// + \ v4 + \ v5 +// + @ + + + +++ + @ z +// + + + + y ^ +// v2 @ + +++ + + + @ v3 + \ | +// \ + \ + \ | +// \ + \ + \| +// \ + \ + +---------> x +// \+ \+ +// @ + + + + + + @ +// v0 v1 + +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)); +} + +// An alternative to Hermite interpolation that have zero first and +// second derivatives at t = 0 and t = 1. +// Described in Ken Perlin's "Improving noise" [2002]. + float noise_fade(float t) { return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); } +// Remap the output of noise to a predictable range [-1, 1]. +// The values were computed experimentally by the OSL developers. + +float noise_scale1(float result) +{ + return 0.2500 * result; +} + +float noise_scale2(float result) +{ + return 0.6616 * result; +} + float noise_scale3(float result) { return 0.9820 * result; } -float noise_nerp(float t, float a, float b) +float noise_scale4(float result) +{ + return 0.8344 * result; +} + +float negate_if(float val, uint condition) +{ + return (condition != 0u) ? -val : val; +} + +// Compute the dot product with a randomly choose vector from a list of +// predetermined vectors based on a hash value. + +float noise_grad(uint hash, float x) +{ + uint h = hash & 15u; + float g = 1u + (h & 7u); + return negate_if(g, h & 8u) * x; +} + +float noise_grad(uint hash, float x, float y) { - return (1.0 - t) * a + t * b; + uint h = hash & 7u; + float u = h < 4u ? x : y; + float v = 2.0 * h < 4 ? y : x; + return negate_if(u, h & 1u) + negate_if(v, h & 2u); } float noise_grad(uint hash, float x, float y, float z) @@ -3137,59 +3233,249 @@ float noise_grad(uint hash, float x, float y, float z) float u = h < 8u ? x : y; float vt = ((h == 12u) || (h == 14u)) ? x : z; float v = h < 4u ? y : vt; - return (((h & 1u) != 0u) ? -u : u) + (((h & 2u) != 0u) ? -v : v); + return negate_if(u, h & 1u) + negate_if(v, h & 2u); } -float noise_perlin(float x, float y, float z) +float noise_grad(uint hash, float x, float y, float z, float w) +{ + uint h = hash & 31u; + float u = (h < 24u) ? x : y; + float v = (h < 16u) ? y : z; + float s = (h < 8u) ? z : w; + return negate_if(u, h & 1u) + negate_if(v, h & 2u) + negate_if(s, h & 4u); +} + +float noise_perlin(float x) { int X; float fx = floorfrac(x, X); + float u = noise_fade(fx); + + float r = mix(noise_grad(hash(X), fx), noise_grad(hash(X + 1), fx - 1.0), u); + + return (isinf(r)) ? 0.0 : noise_scale1(r); +} + +float noise_perlin(vec2 vec) +{ + int X; + int Y; + + float fx = floorfrac(vec.x, X); + float fy = floorfrac(vec.y, Y); + + float u = noise_fade(fx); + float v = noise_fade(fy); + + float r = bi_mix(noise_grad(hash(X, Y), fx, fy), + noise_grad(hash(X + 1, Y), fx - 1.0, fy), + noise_grad(hash(X, Y + 1), fx, fy - 1.0), + noise_grad(hash(X + 1, Y + 1), fx - 1.0, fy - 1.0), + u, + v); + + return (isinf(r)) ? 0.0 : noise_scale2(r); +} + +float noise_perlin(vec3 vec) +{ + int X; int Y; - float fy = floorfrac(y, Y); int Z; - float fz = floorfrac(z, Z); + + float fx = floorfrac(vec.x, X); + float fy = floorfrac(vec.y, Y); + float fz = floorfrac(vec.z, Z); float u = noise_fade(fx); float v = noise_fade(fy); float w = noise_fade(fz); - float noise_u[2], noise_v[2]; + float r = tri_mix(noise_grad(hash(X, Y, Z), fx, fy, fz), + noise_grad(hash(X + 1, Y, Z), fx - 1, fy, fz), + noise_grad(hash(X, Y + 1, Z), fx, fy - 1, fz), + noise_grad(hash(X + 1, Y + 1, Z), fx - 1, fy - 1, fz), + noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1), + noise_grad(hash(X + 1, Y, Z + 1), fx - 1, fy, fz - 1), + noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1, fz - 1), + noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1, fy - 1, fz - 1), + u, + v, + w); - noise_u[0] = noise_nerp( - u, noise_grad(hash(X, Y, Z), fx, fy, fz), noise_grad(hash(X + 1, Y, Z), fx - 1.0, fy, fz)); + return (isinf(r)) ? 0.0 : noise_scale3(r); +} - noise_u[1] = noise_nerp(u, - noise_grad(hash(X, Y + 1, Z), fx, fy - 1.0, fz), - noise_grad(hash(X + 1, Y + 1, Z), fx - 1.0, fy - 1.0, fz)); +float noise_perlin(vec4 vec) +{ + int X; + int Y; + int Z; + int W; - noise_v[0] = noise_nerp(v, noise_u[0], noise_u[1]); + float fx = floorfrac(vec.x, X); + float fy = floorfrac(vec.y, Y); + float fz = floorfrac(vec.z, Z); + float fw = floorfrac(vec.w, W); - noise_u[0] = noise_nerp(u, - noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1.0), - noise_grad(hash(X + 1, Y, Z + 1), fx - 1.0, fy, fz - 1.0)); + float u = noise_fade(fx); + float v = noise_fade(fy); + float t = noise_fade(fz); + float s = noise_fade(fw); - noise_u[1] = noise_nerp(u, - noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1.0, fz - 1.0), - noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1.0, fy - 1.0, fz - 1.0)); + float r = mix( + tri_mix(noise_grad(hash(X, Y, Z, W), fx, fy, fz, fw), + noise_grad(hash(X + 1, Y, Z, W), fx - 1.0, fy, fz, fw), + noise_grad(hash(X, Y + 1, Z, W), fx, fy - 1.0, fz, fw), + noise_grad(hash(X + 1, Y + 1, Z, W), fx - 1.0, fy - 1.0, fz, fw), + noise_grad(hash(X, Y, Z + 1, W), fx, fy, fz - 1.0, fw), + noise_grad(hash(X + 1, Y, Z + 1, W), fx - 1.0, fy, fz - 1.0, fw), + noise_grad(hash(X, Y + 1, Z + 1, W), fx, fy - 1.0, fz - 1.0, fw), + noise_grad(hash(X + 1, Y + 1, Z + 1, W), fx - 1.0, fy - 1.0, fz - 1.0, fw), + u, + v, + t), + tri_mix(noise_grad(hash(X, Y, Z, W + 1), fx, fy, fz, fw - 1.0), + noise_grad(hash(X + 1, Y, Z, W + 1), fx - 1.0, fy, fz, fw - 1.0), + noise_grad(hash(X, Y + 1, Z, W + 1), fx, fy - 1.0, fz, fw - 1.0), + noise_grad(hash(X + 1, Y + 1, Z, W + 1), fx - 1.0, fy - 1.0, fz, fw - 1.0), + noise_grad(hash(X, Y, Z + 1, W + 1), fx, fy, fz - 1.0, fw - 1.0), + @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs