[Bf-blender-cvs] [931da132330] soc-2019-cycles-procedural: Add 1D, 2D, and 4D noise to EEVEE

OmarSquircleArt noreply at git.blender.org
Thu Jun 27 15:09:57 CEST 2019


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. @@



More information about the Bf-blender-cvs mailing list