[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