[Bf-blender-cvs] [6c87aa858bf] soc-2019-cycles-procedural: Remove magic numbers and swizzling from Noise code.

OmarSquircleArt noreply at git.blender.org
Thu Aug 8 14:32:40 CEST 2019


Commit: 6c87aa858bf0f756560949b25c1afc9c6a887996
Author: OmarSquircleArt
Date:   Thu Aug 8 14:33:35 2019 +0200
Branches: soc-2019-cycles-procedural
https://developer.blender.org/rB6c87aa858bf0f756560949b25c1afc9c6a887996

Remove magic numbers and swizzling from Noise code.

Previously, we used a random swizzling pattern as a sort of seed for noise, this proved bad in a lot of cases, including the cases where some of the components are constants. Additionally, we also added some offsets from a set of "magic numbers" as a form of seed. Those magic numbers are bad practice, so we introduced some new functions to generate random offsets based on the hash functions we already have, this happens at compile time, so this has no effect on performance.

===================================================================

M	intern/cycles/kernel/shaders/node_noise_texture.osl
M	intern/cycles/kernel/svm/svm_noisetex.h
M	source/blender/gpu/shaders/gpu_shader_material.glsl

===================================================================

diff --git a/intern/cycles/kernel/shaders/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl
index 4b100dc21ad..2113d162137 100644
--- a/intern/cycles/kernel/shaders/node_noise_texture.osl
+++ b/intern/cycles/kernel/shaders/node_noise_texture.osl
@@ -21,68 +21,95 @@
 
 #define vector3 point
 
-/* To compute the color output of the noise, we either swizzle the
- * components, add a random offset {75, 125, 150}, or do both.
+/* The following offset functions generate random offsets to be added to texture
+ * coordinates to act as a seed since the noise functions don't have seed values.
+ * A seed value is needed for generating distortion textures and color outputs.
+ * The offset's components are in the range [100, 200], not too high to cause
+ * bad precision and not to small to be noticeable. We use float seed because
+ * OSL only support float hashes.
  */
+
+float random_float_offset(float seed)
+{
+  return 100.0 + noise("hash", seed) * 100.0;
+}
+
+vector2 random_vector2_offset(float seed)
+{
+  return vector2(100.0 + noise("hash", seed, 0.0) * 100.0,
+                 100.0 + noise("hash", seed, 1.0) * 100.0);
+}
+
+vector3 random_vector3_offset(float seed)
+{
+  return vector3(100.0 + noise("hash", seed, 0.0) * 100.0,
+                 100.0 + noise("hash", seed, 1.0) * 100.0,
+                 100.0 + noise("hash", seed, 2.0) * 100.0);
+}
+
+vector4 random_vector4_offset(float seed)
+{
+  return vector4(100.0 + noise("hash", seed, 0.0) * 100.0,
+                 100.0 + noise("hash", seed, 1.0) * 100.0,
+                 100.0 + noise("hash", seed, 2.0) * 100.0,
+                 100.0 + noise("hash", seed, 3.0) * 100.0);
+}
+
 float noise(float p, float detail, float distortion, output color Color)
 {
   if (distortion != 0.0) {
-    p += safe_noise(p + 13.5) * distortion;
+    p += safe_noise(p + random_float_offset(0.0)) * distortion;
   }
 
   float value = noise_turbulence(p, detail);
-  Color = color(value, noise_turbulence(p + 75.0, detail), noise_turbulence(p + 125.0, detail));
+  Color = color(value,
+                noise_turbulence(p + random_float_offset(1.0), detail),
+                noise_turbulence(p + random_float_offset(2.0), detail));
   return value;
 }
 
 float noise(vector2 p, float detail, float distortion, output color Color)
 {
   if (distortion != 0.0) {
-    vector2 r;
-    r.x = safe_noise(p + vector2(13.5, 13.5)) * distortion;
-    r.y = safe_noise(p) * distortion;
-    p += r;
+    p += vector2(safe_noise(p + random_vector2_offset(0.0)) * distortion,
+                 safe_noise(p + random_vector2_offset(1.0)) * distortion);
   }
 
   float value = noise_turbulence(p, detail);
   Color = color(value,
-                noise_turbulence(p + vector2(150.0, 125.0), detail),
-                noise_turbulence(p + vector2(75.0, 125.0), detail));
+                noise_turbulence(p + random_vector2_offset(2.0), detail),
+                noise_turbulence(p + random_vector2_offset(3.0), detail));
   return value;
 }
 
 float noise(vector3 p, float detail, float distortion, output color Color)
 {
   if (distortion != 0.0) {
-    vector3 r, offset = vector3(13.5);
-    r[0] = safe_noise(p + offset) * distortion;
-    r[1] = safe_noise(p) * distortion;
-    r[2] = safe_noise(p - offset) * distortion;
-    p += r;
+    p += vector3(safe_noise(p + random_vector3_offset(0.0)) * distortion,
+                 safe_noise(p + random_vector3_offset(1.0)) * distortion,
+                 safe_noise(p + random_vector3_offset(2.0)) * distortion);
   }
 
   float value = noise_turbulence(p, detail);
   Color = color(value,
-                noise_turbulence(vector3(p[1], p[0], p[2]), detail),
-                noise_turbulence(vector3(p[1], p[2], p[0]), detail));
+                noise_turbulence(p + random_vector3_offset(3.0), detail),
+                noise_turbulence(p + random_vector3_offset(4.0), detail));
   return value;
 }
 
 float noise(vector4 p, float detail, float distortion, output color Color)
 {
   if (distortion != 0.0) {
-    vector4 r, offset = vector4(13.5, 13.5, 13.5, 13.5);
-    r.x = safe_noise(p + offset) * distortion;
-    r.y = safe_noise(p) * distortion;
-    r.z = safe_noise(p - offset) * distortion;
-    r.w = safe_noise(vector4(p.w, p.y, p.z, p.x) + offset) * distortion;
-    p += r;
+    p += vector4(safe_noise(p + random_vector4_offset(0.0)) * distortion,
+                 safe_noise(p + random_vector4_offset(1.0)) * distortion,
+                 safe_noise(p + random_vector4_offset(2.0)) * distortion,
+                 safe_noise(p + random_vector4_offset(3.0)) * distortion);
   }
 
   float value = noise_turbulence(p, detail);
   Color = color(value,
-                noise_turbulence(vector4(p.y, p.w, p.z, p.x), detail),
-                noise_turbulence(vector4(p.y, p.z, p.w, p.x), detail));
+                noise_turbulence(p + random_vector4_offset(4.0), detail),
+                noise_turbulence(p + random_vector4_offset(5.0), detail));
   return value;
 }
 
diff --git a/intern/cycles/kernel/svm/svm_noisetex.h b/intern/cycles/kernel/svm/svm_noisetex.h
index 3173ff73fbc..03f489efcad 100644
--- a/intern/cycles/kernel/svm/svm_noisetex.h
+++ b/intern/cycles/kernel/svm/svm_noisetex.h
@@ -16,20 +16,52 @@
 
 CCL_NAMESPACE_BEGIN
 
-/* To compute the color output of the noise, we either swizzle the
- * components, add a random offset {75, 125, 150}, or do both.
+/* The following offset functions generate random offsets to be added to texture
+ * coordinates to act as a seed since the noise functions don't have seed values.
+ * A seed value is needed for generating distortion textures and color outputs.
+ * The offset's components are in the range [100, 200], not too high to cause
+ * bad precision and not to small to be noticeable. We use float seed because
+ * OSL only support float hashes.
  */
+
+ccl_device_inline float random_float_offset(float seed)
+{
+  return 100.0f + hash_float_to_float(seed) * 100.0f;
+}
+
+ccl_device_inline float2 random_float2_offset(float seed)
+{
+  return make_float2(100.0f + hash_float2_to_float(make_float2(seed, 0.0f)) * 100.0f,
+                     100.0f + hash_float2_to_float(make_float2(seed, 1.0f)) * 100.0f);
+}
+
+ccl_device_inline float3 random_float3_offset(float seed)
+{
+  return make_float3(100.0f + hash_float2_to_float(make_float2(seed, 0.0f)) * 100.0f,
+                     100.0f + hash_float2_to_float(make_float2(seed, 1.0f)) * 100.0f,
+                     100.0f + hash_float2_to_float(make_float2(seed, 2.0f)) * 100.0f);
+}
+
+ccl_device_inline float4 random_float4_offset(float seed)
+{
+  return make_float4(100.0f + hash_float2_to_float(make_float2(seed, 0.0f)) * 100.0f,
+                     100.0f + hash_float2_to_float(make_float2(seed, 1.0f)) * 100.0f,
+                     100.0f + hash_float2_to_float(make_float2(seed, 2.0f)) * 100.0f,
+                     100.0f + hash_float2_to_float(make_float2(seed, 3.0f)) * 100.0f);
+}
+
 ccl_device void tex_noise_1d(
     float p, float detail, float distortion, bool color_is_needed, float *value, float3 *color)
 {
   if (distortion != 0.0f) {
-    p += noise_1d(p + 13.5f) * distortion;
+    p += noise_1d(p + random_float_offset(0.0f)) * distortion;
   }
 
   *value = noise_turbulence_1d(p, detail);
   if (color_is_needed) {
-    *color = make_float3(
-        *value, noise_turbulence_1d(p + 75.0f, detail), noise_turbulence_1d(p + 125.0f, detail));
+    *color = make_float3(*value,
+                         noise_turbulence_1d(p + random_float_offset(1.0f), detail),
+                         noise_turbulence_1d(p + random_float_offset(2.0f), detail));
   }
 }
 
@@ -37,17 +69,15 @@ ccl_device void tex_noise_2d(
     float2 p, float detail, float distortion, bool color_is_needed, float *value, float3 *color)
 {
   if (distortion != 0.0f) {
-    float2 r;
-    r.x = noise_2d(p + make_float2(13.5f, 13.5f)) * distortion;
-    r.y = noise_2d(p) * distortion;
-    p += r;
+    p += make_float2(noise_2d(p + random_float2_offset(0.0f)) * distortion,
+                     noise_2d(p + random_float2_offset(1.0f)) * distortion);
   }
 
   *value = noise_turbulence_2d(p, detail);
   if (color_is_needed) {
     *color = make_float3(*value,
-                         noise_turbulence_2d(p + make_float2(150.0f, 125.0f), detail),
-                         noise_turbulence_2d(p + make_float2(75.0f, 125.0f), detail));
+                         noise_turbulence_2d(p + random_float2_offset(2.0f), detail),
+                         noise_turbulence_2d(p + random_float2_offset(3.0f), detail));
   }
 }
 
@@ -55,18 +85,16 @@ ccl_device void tex_noise_3d(
     float3 p, float detail, float distortion, bool color_is_needed, float *value, float3 *color)
 {
   if (distortion != 0.0f) {
-    float3 r, offset = make_float3(13.5f, 13.5f, 13.5f);
-    r.x = noise_3d(p + offset) * distortion;
-    r.y = noise_3d(p) * distortion;
-    r.z = noise_3d(p - offset) * distortion;
-    p += r;
+    p += make_float3(noise_3d(p + random_float3_offset(0.0f)) * distortion,
+                     noise_3d(p + random_float3_offset(1.0f)) * distortion,
+                     noise_3d(p + random_float3_offset(2.0f)) * distortion);
   }
 
   *value = noise_turbulence_3d(p, detail);
   if (color_is_needed) {
     *color = make_float3(*value,
-                         noise_turbulence_3d(make_float3(p.y, p.x, p.z), detail),
-                         noise_turbulence_3d(make_float3(p.y, p.z, p.x), detail));
+                         noise_turbulence_3d(p + random_float3_offset(3.0f), detail),
+                         noise_turbulence_3d(p + random_float3_offset(4.0f), detail));
   }
 }
 
@@ -74,19 +102,17 @@ ccl_device void tex_noise_4d(
     float4 p, float detail, float distortion, bool color_is_needed, float *value, float3 *color)
 {
   if (distortion != 0.0f) {
-    float4 r, offset = make_float4(13.5, 13.5, 13.5, 13.5);
-    r.x = noise_4d(p + offset) * distortion;
-    r.y = noise_4d(p) * distortion;
-    r.z = noise_4d(p - offset) * distortion;
-    r.w = noise_4d(make_float4(p.w, p.y, p.z, p.x) + offset) * distortion;
-    p += r;
+    p += make_float4(noise_4d(p + random_float4_offset(0.0f)) * distortion,
+                     nois

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list