Shading: add Roughness input to Noise and Wave texture nodes
authorBartosz Moniewski <monio>
Thu, 26 Mar 2020 13:43:53 +0000 (14:43 +0100)
committerBrecht Van Lommel <brecht@blender.org>
Thu, 9 Apr 2020 19:48:03 +0000 (21:48 +0200)
Currently in fractal_noise functions, each subsequent octave doubles the
frequency and reduces the amplitude by half. This patch introduces Roughness
input to Noise and Wave nodes. This multiplier determines how quickly the
amplitudes of the subsequent octaves decrease.

Value of 0.5 will be the default, generating identical noise we had before.
Values above 0.5 will increase influence of each octave resulting in more
"rough" noise, most interesting pattern changes happen there. Values below
0.5 will result in more "smooth" noise.

Differential Revision: https://developer.blender.org/D7065

13 files changed:
intern/cycles/kernel/shaders/node_noise.h
intern/cycles/kernel/shaders/node_noise_texture.osl
intern/cycles/kernel/shaders/node_wave_texture.osl
intern/cycles/kernel/svm/svm_fractal_noise.h
intern/cycles/kernel/svm/svm_noisetex.h
intern/cycles/kernel/svm/svm_wave.h
intern/cycles/render/nodes.cpp
intern/cycles/render/nodes.h
source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl
source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl
source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl
source/blender/nodes/shader/nodes/node_shader_tex_noise.c
source/blender/nodes/shader/nodes/node_shader_tex_wave.c

index 23d1987a00e49ac7adeb602059bce7e15a9ba114..ab4cd7792ccf4b870f83eb97b3f3c4086b22b7b4 100644 (file)
@@ -84,114 +84,118 @@ float safe_snoise(vector4 p)
 }
 
 /* The fractal_noise functions are all exactly the same except for the input type. */
-float fractal_noise(float p, float details)
+float fractal_noise(float p, float details, float roughness)
 {
   float fscale = 1.0;
   float amp = 1.0;
+  float maxamp = 0.0;
   float sum = 0.0;
   float octaves = clamp(details, 0.0, 16.0);
   int n = (int)octaves;
   for (int i = 0; i <= n; i++) {
     float t = safe_noise(fscale * p);
     sum += t * amp;
-    amp *= 0.5;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0, 1.0);
     fscale *= 2.0;
   }
   float rmd = octaves - floor(octaves);
   if (rmd != 0.0) {
     float t = safe_noise(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0 - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise functions are all exactly the same except for the input type. */
-float fractal_noise(vector2 p, float details)
+float fractal_noise(vector2 p, float details, float roughness)
 {
   float fscale = 1.0;
   float amp = 1.0;
+  float maxamp = 0.0;
   float sum = 0.0;
   float octaves = clamp(details, 0.0, 16.0);
   int n = (int)octaves;
   for (int i = 0; i <= n; i++) {
     float t = safe_noise(fscale * p);
     sum += t * amp;
-    amp *= 0.5;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0, 1.0);
     fscale *= 2.0;
   }
   float rmd = octaves - floor(octaves);
   if (rmd != 0.0) {
     float t = safe_noise(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0 - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise functions are all exactly the same except for the input type. */
-float fractal_noise(vector3 p, float details)
+float fractal_noise(vector3 p, float details, float roughness)
 {
   float fscale = 1.0;
   float amp = 1.0;
+  float maxamp = 0.0;
   float sum = 0.0;
   float octaves = clamp(details, 0.0, 16.0);
   int n = (int)octaves;
   for (int i = 0; i <= n; i++) {
     float t = safe_noise(fscale * p);
     sum += t * amp;
-    amp *= 0.5;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0, 1.0);
     fscale *= 2.0;
   }
   float rmd = octaves - floor(octaves);
   if (rmd != 0.0) {
     float t = safe_noise(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0 - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise functions are all exactly the same except for the input type. */
-float fractal_noise(vector4 p, float details)
+float fractal_noise(vector4 p, float details, float roughness)
 {
   float fscale = 1.0;
   float amp = 1.0;
+  float maxamp = 0.0;
   float sum = 0.0;
   float octaves = clamp(details, 0.0, 16.0);
   int n = (int)octaves;
   for (int i = 0; i <= n; i++) {
     float t = safe_noise(fscale * p);
     sum += t * amp;
-    amp *= 0.5;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0, 1.0);
     fscale *= 2.0;
   }
   float rmd = octaves - floor(octaves);
   if (rmd != 0.0) {
     float t = safe_noise(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0 - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
index 4121b4156731d09090677fb6cf1e2cc813f032c3..61c0216910b0c323d7cba7326537b709f9ad7870 100644 (file)
@@ -55,21 +55,22 @@ vector4 random_vector4_offset(float seed)
                  100.0 + noise("hash", seed, 3.0) * 100.0);
 }
 
-float noise_texture(float co, float detail, float distortion, output color Color)
+float noise_texture(float co, float detail, float roughness, float distortion, output color Color)
 {
   float p = co;
   if (distortion != 0.0) {
     p += safe_snoise(p + random_float_offset(0.0)) * distortion;
   }
 
-  float value = fractal_noise(p, detail);
+  float value = fractal_noise(p, detail, roughness);
   Color = color(value,
-                fractal_noise(p + random_float_offset(1.0), detail),
-                fractal_noise(p + random_float_offset(2.0), detail));
+                fractal_noise(p + random_float_offset(1.0), detail, roughness),
+                fractal_noise(p + random_float_offset(2.0), detail, roughness));
   return value;
 }
 
-float noise_texture(vector2 co, float detail, float distortion, output color Color)
+float noise_texture(
+    vector2 co, float detail, float roughness, float distortion, output color Color)
 {
   vector2 p = co;
   if (distortion != 0.0) {
@@ -77,14 +78,15 @@ float noise_texture(vector2 co, float detail, float distortion, output color Col
                  safe_snoise(p + random_vector2_offset(1.0)) * distortion);
   }
 
-  float value = fractal_noise(p, detail);
+  float value = fractal_noise(p, detail, roughness);
   Color = color(value,
-                fractal_noise(p + random_vector2_offset(2.0), detail),
-                fractal_noise(p + random_vector2_offset(3.0), detail));
+                fractal_noise(p + random_vector2_offset(2.0), detail, roughness),
+                fractal_noise(p + random_vector2_offset(3.0), detail, roughness));
   return value;
 }
 
-float noise_texture(vector3 co, float detail, float distortion, output color Color)
+float noise_texture(
+    vector3 co, float detail, float roughness, float distortion, output color Color)
 {
   vector3 p = co;
   if (distortion != 0.0) {
@@ -93,14 +95,15 @@ float noise_texture(vector3 co, float detail, float distortion, output color Col
                  safe_snoise(p + random_vector3_offset(2.0)) * distortion);
   }
 
-  float value = fractal_noise(p, detail);
+  float value = fractal_noise(p, detail, roughness);
   Color = color(value,
-                fractal_noise(p + random_vector3_offset(3.0), detail),
-                fractal_noise(p + random_vector3_offset(4.0), detail));
+                fractal_noise(p + random_vector3_offset(3.0), detail, roughness),
+                fractal_noise(p + random_vector3_offset(4.0), detail, roughness));
   return value;
 }
 
-float noise_texture(vector4 co, float detail, float distortion, output color Color)
+float noise_texture(
+    vector4 co, float detail, float roughness, float distortion, output color Color)
 {
   vector4 p = co;
   if (distortion != 0.0) {
@@ -110,10 +113,10 @@ float noise_texture(vector4 co, float detail, float distortion, output color Col
                  safe_snoise(p + random_vector4_offset(3.0)) * distortion);
   }
 
-  float value = fractal_noise(p, detail);
+  float value = fractal_noise(p, detail, roughness);
   Color = color(value,
-                fractal_noise(p + random_vector4_offset(4.0), detail),
-                fractal_noise(p + random_vector4_offset(5.0), detail));
+                fractal_noise(p + random_vector4_offset(4.0), detail, roughness),
+                fractal_noise(p + random_vector4_offset(5.0), detail, roughness));
   return value;
 }
 
@@ -124,6 +127,7 @@ shader node_noise_texture(int use_mapping = 0,
                           float W = 0.0,
                           float Scale = 5.0,
                           float Detail = 2.0,
+                          float Roughness = 0.5,
                           float Distortion = 0.0,
                           output float Fac = 0.0,
                           output color Color = 0.0)
@@ -136,13 +140,13 @@ shader node_noise_texture(int use_mapping = 0,
   float w = W * Scale;
 
   if (dimensions == "1D")
-    Fac = noise_texture(w, Detail, Distortion, Color);
+    Fac = noise_texture(w, Detail, Roughness, Distortion, Color);
   else if (dimensions == "2D")
-    Fac = noise_texture(vector2(p[0], p[1]), Detail, Distortion, Color);
+    Fac = noise_texture(vector2(p[0], p[1]), Detail, Roughness, Distortion, Color);
   else if (dimensions == "3D")
-    Fac = noise_texture(p, Detail, Distortion, Color);
+    Fac = noise_texture(p, Detail, Roughness, Distortion, Color);
   else if (dimensions == "4D")
-    Fac = noise_texture(vector4(p[0], p[1], p[2], w), Detail, Distortion, Color);
+    Fac = noise_texture(vector4(p[0], p[1], p[2], w), Detail, Roughness, Distortion, Color);
   else
     error("Unknown dimension!");
 }
index f17397be24378cfa110464545d10f4e699bcf3dc..874bfb8d3af0cb6ccd2cbee8cb922eeea85b6e9c 100644 (file)
@@ -24,9 +24,10 @@ float wave(point p_input,
            string bands_direction,
            string rings_direction,
            string profile,
-           float detail,
            float distortion,
+           float detail,
            float dscale,
+           float droughness,
            float phase)
 {
   /* Prevent precision issues on unit coordinates. */
@@ -67,7 +68,7 @@ float wave(point p_input,
   n += phase;
 
   if (distortion != 0.0) {
-    n = n + (distortion * (fractal_noise(p * dscale, detail) * 2.0 - 1.0));
+    n = n + (distortion * (fractal_noise(p * dscale, detail, droughness) * 2.0 - 1.0));
   }
 
   if (profile == "sine") {
@@ -93,6 +94,7 @@ shader node_wave_texture(int use_mapping = 0,
                          float Distortion = 0.0,
                          float Detail = 2.0,
                          float DetailScale = 1.0,
+                         float DetailRoughness = 0.5,
                          float PhaseOffset = 0.0,
                          point Vector = P,
                          output float Fac = 0.0,
@@ -108,9 +110,10 @@ shader node_wave_texture(int use_mapping = 0,
              bands_direction,
              rings_direction,
              profile,
-             Detail,
              Distortion,
+             Detail,
              DetailScale,
+             DetailRoughness,
              PhaseOffset);
   Color = Fac;
 }
index 5b2e4a28fce8608d2b1c369fb0f67548333c4045..57fa8c690ac5df4bef9dec3b2b9797718ab61532 100644 (file)
 CCL_NAMESPACE_BEGIN
 
 /* The fractal_noise_[1-4] functions are all exactly the same except for the input type. */
-ccl_device_noinline float fractal_noise_1d(float p, float octaves)
+ccl_device_noinline float fractal_noise_1d(float p, float octaves, float roughness)
 {
   float fscale = 1.0f;
   float amp = 1.0f;
+  float maxamp = 0.0f;
   float sum = 0.0f;
   octaves = clamp(octaves, 0.0f, 16.0f);
   int n = float_to_int(octaves);
   for (int i = 0; i <= n; i++) {
     float t = noise_1d(fscale * p);
     sum += t * amp;
-    amp *= 0.5f;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0f, 1.0f);
     fscale *= 2.0f;
   }
   float rmd = octaves - floorf(octaves);
   if (rmd != 0.0f) {
     float t = noise_1d(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0f - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise_[1-4] functions are all exactly the same except for the input type. */
-ccl_device_noinline float fractal_noise_2d(float2 p, float octaves)
+ccl_device_noinline float fractal_noise_2d(float2 p, float octaves, float roughness)
 {
   float fscale = 1.0f;
   float amp = 1.0f;
+  float maxamp = 0.0f;
   float sum = 0.0f;
   octaves = clamp(octaves, 0.0f, 16.0f);
   int n = float_to_int(octaves);
   for (int i = 0; i <= n; i++) {
     float t = noise_2d(fscale * p);
     sum += t * amp;
-    amp *= 0.5f;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0f, 1.0f);
     fscale *= 2.0f;
   }
   float rmd = octaves - floorf(octaves);
   if (rmd != 0.0f) {
     float t = noise_2d(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0f - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise_[1-4] functions are all exactly the same except for the input type. */
-ccl_device_noinline float fractal_noise_3d(float3 p, float octaves)
+ccl_device_noinline float fractal_noise_3d(float3 p, float octaves, float roughness)
 {
   float fscale = 1.0f;
   float amp = 1.0f;
+  float maxamp = 0.0f;
   float sum = 0.0f;
   octaves = clamp(octaves, 0.0f, 16.0f);
   int n = float_to_int(octaves);
   for (int i = 0; i <= n; i++) {
     float t = noise_3d(fscale * p);
     sum += t * amp;
-    amp *= 0.5f;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0f, 1.0f);
     fscale *= 2.0f;
   }
   float rmd = octaves - floorf(octaves);
   if (rmd != 0.0f) {
     float t = noise_3d(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0f - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise_[1-4] functions are all exactly the same except for the input type. */
-ccl_device_noinline float fractal_noise_4d(float4 p, float octaves)
+ccl_device_noinline float fractal_noise_4d(float4 p, float octaves, float roughness)
 {
   float fscale = 1.0f;
   float amp = 1.0f;
+  float maxamp = 0.0f;
   float sum = 0.0f;
   octaves = clamp(octaves, 0.0f, 16.0f);
   int n = float_to_int(octaves);
   for (int i = 0; i <= n; i++) {
     float t = noise_4d(fscale * p);
     sum += t * amp;
-    amp *= 0.5f;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0f, 1.0f);
     fscale *= 2.0f;
   }
   float rmd = octaves - floorf(octaves);
   if (rmd != 0.0f) {
     float t = noise_4d(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    sum2 *= ((float)(1 << (n + 1)) / (float)((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0f - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
index 12884c6cb25178e25c60441f356a983c3b184695..920dd7d9d0288b13bb215aea5fa716e6c46615fa 100644 (file)
@@ -50,24 +50,34 @@ ccl_device_inline float4 random_float4_offset(float seed)
                      100.0f + hash_float2_to_float(make_float2(seed, 3.0f)) * 100.0f);
 }
 
-ccl_device void noise_texture_1d(
-    float co, float detail, float distortion, bool color_is_needed, float *value, float3 *color)
+ccl_device void noise_texture_1d(float co,
+                                 float detail,
+                                 float roughness,
+                                 float distortion,
+                                 bool color_is_needed,
+                                 float *value,
+                                 float3 *color)
 {
   float p = co;
   if (distortion != 0.0f) {
     p += snoise_1d(p + random_float_offset(0.0f)) * distortion;
   }
 
-  *value = fractal_noise_1d(p, detail);
+  *value = fractal_noise_1d(p, detail, roughness);
   if (color_is_needed) {
     *color = make_float3(*value,
-                         fractal_noise_1d(p + random_float_offset(1.0f), detail),
-                         fractal_noise_1d(p + random_float_offset(2.0f), detail));
+                         fractal_noise_1d(p + random_float_offset(1.0f), detail, roughness),
+                         fractal_noise_1d(p + random_float_offset(2.0f), detail, roughness));
   }
 }
 
-ccl_device void noise_texture_2d(
-    float2 co, float detail, float distortion, bool color_is_needed, float *value, float3 *color)
+ccl_device void noise_texture_2d(float2 co,
+                                 float detail,
+                                 float roughness,
+                                 float distortion,
+                                 bool color_is_needed,
+                                 float *value,
+                                 float3 *color)
 {
   float2 p = co;
   if (distortion != 0.0f) {
@@ -75,16 +85,21 @@ ccl_device void noise_texture_2d(
                      snoise_2d(p + random_float2_offset(1.0f)) * distortion);
   }
 
-  *value = fractal_noise_2d(p, detail);
+  *value = fractal_noise_2d(p, detail, roughness);
   if (color_is_needed) {
     *color = make_float3(*value,
-                         fractal_noise_2d(p + random_float2_offset(2.0f), detail),
-                         fractal_noise_2d(p + random_float2_offset(3.0f), detail));
+                         fractal_noise_2d(p + random_float2_offset(2.0f), detail, roughness),
+                         fractal_noise_2d(p + random_float2_offset(3.0f), detail, roughness));
   }
 }
 
-ccl_device void noise_texture_3d(
-    float3 co, float detail, float distortion, bool color_is_needed, float *value, float3 *color)
+ccl_device void noise_texture_3d(float3 co,
+                                 float detail,
+                                 float roughness,
+                                 float distortion,
+                                 bool color_is_needed,
+                                 float *value,
+                                 float3 *color)
 {
   float3 p = co;
   if (distortion != 0.0f) {
@@ -93,16 +108,21 @@ ccl_device void noise_texture_3d(
                      snoise_3d(p + random_float3_offset(2.0f)) * distortion);
   }
 
-  *value = fractal_noise_3d(p, detail);
+  *value = fractal_noise_3d(p, detail, roughness);
   if (color_is_needed) {
     *color = make_float3(*value,
-                         fractal_noise_3d(p + random_float3_offset(3.0f), detail),
-                         fractal_noise_3d(p + random_float3_offset(4.0f), detail));
+                         fractal_noise_3d(p + random_float3_offset(3.0f), detail, roughness),
+                         fractal_noise_3d(p + random_float3_offset(4.0f), detail, roughness));
   }
 }
 
-ccl_device void noise_texture_4d(
-    float4 co, float detail, float distortion, bool color_is_needed, float *value, float3 *color)
+ccl_device void noise_texture_4d(float4 co,
+                                 float detail,
+                                 float roughness,
+                                 float distortion,
+                                 bool color_is_needed,
+                                 float *value,
+                                 float3 *color)
 {
   float4 p = co;
   if (distortion != 0.0f) {
@@ -112,11 +132,11 @@ ccl_device void noise_texture_4d(
                      snoise_4d(p + random_float4_offset(3.0f)) * distortion);
   }
 
-  *value = fractal_noise_4d(p, detail);
+  *value = fractal_noise_4d(p, detail, roughness);
   if (color_is_needed) {
     *color = make_float3(*value,
-                         fractal_noise_4d(p + random_float4_offset(4.0f), detail),
-                         fractal_noise_4d(p + random_float4_offset(5.0f), detail));
+                         fractal_noise_4d(p + random_float4_offset(4.0f), detail, roughness),
+                         fractal_noise_4d(p + random_float4_offset(5.0f), detail, roughness));
   }
 }
 
@@ -128,21 +148,27 @@ ccl_device void svm_node_tex_noise(KernelGlobals *kg,
                                    uint offsets2,
                                    int *offset)
 {
-  uint vector_stack_offset, w_stack_offset, scale_stack_offset, detail_stack_offset;
-  uint distortion_stack_offset, value_stack_offset, color_stack_offset;
+  uint vector_stack_offset, w_stack_offset, scale_stack_offset;
+  uint detail_stack_offset, roughness_stack_offset, distortion_stack_offset;
+  uint value_stack_offset, color_stack_offset;
 
   svm_unpack_node_uchar4(
       offsets1, &vector_stack_offset, &w_stack_offset, &scale_stack_offset, &detail_stack_offset);
-  svm_unpack_node_uchar3(
-      offsets2, &distortion_stack_offset, &value_stack_offset, &color_stack_offset);
+  svm_unpack_node_uchar4(offsets2,
+                         &roughness_stack_offset,
+                         &distortion_stack_offset,
+                         &value_stack_offset,
+                         &color_stack_offset);
 
-  uint4 defaults = read_node(kg, offset);
+  uint4 defaults1 = read_node(kg, offset);
+  uint4 defaults2 = read_node(kg, offset);
 
   float3 vector = stack_load_float3(stack, vector_stack_offset);
-  float w = stack_load_float_default(stack, w_stack_offset, defaults.x);
-  float scale = stack_load_float_default(stack, scale_stack_offset, defaults.y);
-  float detail = stack_load_float_default(stack, detail_stack_offset, defaults.z);
-  float distortion = stack_load_float_default(stack, distortion_stack_offset, defaults.w);
+  float w = stack_load_float_default(stack, w_stack_offset, defaults1.x);
+  float scale = stack_load_float_default(stack, scale_stack_offset, defaults1.y);
+  float detail = stack_load_float_default(stack, detail_stack_offset, defaults1.z);
+  float roughness = stack_load_float_default(stack, roughness_stack_offset, defaults1.w);
+  float distortion = stack_load_float_default(stack, distortion_stack_offset, defaults2.x);
 
   vector *= scale;
   w *= scale;
@@ -151,11 +177,13 @@ ccl_device void svm_node_tex_noise(KernelGlobals *kg,
   float3 color;
   switch (dimensions) {
     case 1:
-      noise_texture_1d(w, detail, distortion, stack_valid(color_stack_offset), &value, &color);
+      noise_texture_1d(
+          w, detail, roughness, distortion, stack_valid(color_stack_offset), &value, &color);
       break;
     case 2:
       noise_texture_2d(make_float2(vector.x, vector.y),
                        detail,
+                       roughness,
                        distortion,
                        stack_valid(color_stack_offset),
                        &value,
@@ -163,11 +191,12 @@ ccl_device void svm_node_tex_noise(KernelGlobals *kg,
       break;
     case 3:
       noise_texture_3d(
-          vector, detail, distortion, stack_valid(color_stack_offset), &value, &color);
+          vector, detail, roughness, distortion, stack_valid(color_stack_offset), &value, &color);
       break;
     case 4:
       noise_texture_4d(make_float4(vector.x, vector.y, vector.z, w),
                        detail,
+                       roughness,
                        distortion,
                        stack_valid(color_stack_offset),
                        &value,
index 64102535f7dbf55a97b5ff4d6d6e758c5070e311..c4763475b47296a49931d0084c79c6cbd04b860e 100644 (file)
@@ -23,9 +23,10 @@ ccl_device_noinline_cpu float svm_wave(NodeWaveType type,
                                        NodeWaveRingsDirection rings_dir,
                                        NodeWaveProfile profile,
                                        float3 p,
-                                       float detail,
                                        float distortion,
+                                       float detail,
                                        float dscale,
+                                       float droughness,
                                        float phase)
 {
   /* Prevent precision issues on unit coordinates. */
@@ -66,7 +67,7 @@ ccl_device_noinline_cpu float svm_wave(NodeWaveType type,
   n += phase;
 
   if (distortion != 0.0f)
-    n += distortion * (fractal_noise_3d(p * dscale, detail) * 2.0f - 1.0f);
+    n += distortion * (fractal_noise_3d(p * dscale, detail, droughness) * 2.0f - 1.0f);
 
   if (profile == NODE_WAVE_PROFILE_SIN) {
     return 0.5f + 0.5f * sinf(n - M_PI_2_F);
@@ -84,35 +85,40 @@ ccl_device_noinline_cpu float svm_wave(NodeWaveType type,
 ccl_device void svm_node_tex_wave(
     KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
 {
-  uint4 defaults1 = read_node(kg, offset);
-  uint4 defaults2 = read_node(kg, offset);
+  uint4 node2 = read_node(kg, offset);
+  uint4 node3 = read_node(kg, offset);
 
   /* RNA properties */
   uint type_offset, bands_dir_offset, rings_dir_offset, profile_offset;
   /* Inputs, Outputs */
-  uint co_offset, scale_offset, distortion_offset, detail_offset, dscale_offset, phase_offset;
+  uint co_offset, scale_offset, distortion_offset, detail_offset, dscale_offset, droughness_offset,
+      phase_offset;
   uint color_offset, fac_offset;
 
   svm_unpack_node_uchar4(
       node.y, &type_offset, &bands_dir_offset, &rings_dir_offset, &profile_offset);
-  svm_unpack_node_uchar4(node.z, &co_offset, &scale_offset, &distortion_offset, &detail_offset);
-  svm_unpack_node_uchar4(node.w, &dscale_offset, &phase_offset, &color_offset, &fac_offset);
+  svm_unpack_node_uchar3(node.z, &co_offset, &scale_offset, &distortion_offset);
+  svm_unpack_node_uchar4(
+      node.w, &detail_offset, &dscale_offset, &droughness_offset, &phase_offset);
+  svm_unpack_node_uchar2(node2.x, &color_offset, &fac_offset);
 
   float3 co = stack_load_float3(stack, co_offset);
-  float scale = stack_load_float_default(stack, scale_offset, defaults1.x);
-  float detail = stack_load_float_default(stack, detail_offset, defaults1.y);
-  float distortion = stack_load_float_default(stack, distortion_offset, defaults1.z);
-  float dscale = stack_load_float_default(stack, dscale_offset, defaults1.w);
-  float phase = stack_load_float_default(stack, phase_offset, defaults2.x);
+  float scale = stack_load_float_default(stack, scale_offset, node2.y);
+  float distortion = stack_load_float_default(stack, distortion_offset, node2.z);
+  float detail = stack_load_float_default(stack, detail_offset, node2.w);
+  float dscale = stack_load_float_default(stack, dscale_offset, node3.x);
+  float droughness = stack_load_float_default(stack, droughness_offset, node3.y);
+  float phase = stack_load_float_default(stack, phase_offset, node3.z);
 
   float f = svm_wave((NodeWaveType)type_offset,
                      (NodeWaveBandsDirection)bands_dir_offset,
                      (NodeWaveRingsDirection)rings_dir_offset,
                      (NodeWaveProfile)profile_offset,
                      co * scale,
-                     detail,
                      distortion,
+                     detail,
                      dscale,
+                     droughness,
                      phase);
 
   if (stack_valid(fac_offset))
index ac07d91c4cab0182cf8e3cc7e7e2f5d7080de071..4b4958fe3dacd847e5d0dfb6199918a215eb28f7 100644 (file)
@@ -922,6 +922,7 @@ NODE_DEFINE(NoiseTextureNode)
   SOCKET_IN_FLOAT(w, "W", 0.0f);
   SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
   SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
+  SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
   SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
 
   SOCKET_OUT_FLOAT(fac, "Fac");
@@ -940,6 +941,7 @@ void NoiseTextureNode::compile(SVMCompiler &compiler)
   ShaderInput *w_in = input("W");
   ShaderInput *scale_in = input("Scale");
   ShaderInput *detail_in = input("Detail");
+  ShaderInput *roughness_in = input("Roughness");
   ShaderInput *distortion_in = input("Distortion");
   ShaderOutput *fac_out = output("Fac");
   ShaderOutput *color_out = output("Color");
@@ -948,6 +950,7 @@ void NoiseTextureNode::compile(SVMCompiler &compiler)
   int w_stack_offset = compiler.stack_assign_if_linked(w_in);
   int scale_stack_offset = compiler.stack_assign_if_linked(scale_in);
   int detail_stack_offset = compiler.stack_assign_if_linked(detail_in);
+  int roughness_stack_offset = compiler.stack_assign_if_linked(roughness_in);
   int distortion_stack_offset = compiler.stack_assign_if_linked(distortion_in);
   int fac_stack_offset = compiler.stack_assign_if_linked(fac_out);
   int color_stack_offset = compiler.stack_assign_if_linked(color_out);
@@ -957,11 +960,13 @@ void NoiseTextureNode::compile(SVMCompiler &compiler)
       dimensions,
       compiler.encode_uchar4(
           vector_stack_offset, w_stack_offset, scale_stack_offset, detail_stack_offset),
-      compiler.encode_uchar4(distortion_stack_offset, fac_stack_offset, color_stack_offset));
-  compiler.add_node(__float_as_int(w),
-                    __float_as_int(scale),
-                    __float_as_int(detail),
-                    __float_as_int(distortion));
+      compiler.encode_uchar4(
+          roughness_stack_offset, distortion_stack_offset, fac_stack_offset, color_stack_offset));
+  compiler.add_node(
+      __float_as_int(w), __float_as_int(scale), __float_as_int(detail), __float_as_int(roughness));
+
+  compiler.add_node(
+      __float_as_int(distortion), SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID);
 
   tex_mapping.compile_end(compiler, vector_in, vector_stack_offset);
 }
@@ -1343,14 +1348,14 @@ NODE_DEFINE(WaveTextureNode)
   profile_enum.insert("tri", NODE_WAVE_PROFILE_TRI);
   SOCKET_ENUM(profile, "Profile", profile_enum, NODE_WAVE_PROFILE_SIN);
 
+  SOCKET_IN_POINT(
+      vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
   SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
   SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
   SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
   SOCKET_IN_FLOAT(detail_scale, "Detail Scale", 0.0f);
+  SOCKET_IN_FLOAT(detail_roughness, "Detail Roughness", 0.5f);
   SOCKET_IN_FLOAT(phase, "Phase Offset", 0.0f);
-  SOCKET_IN_POINT(
-      vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED);
-
   SOCKET_OUT_COLOR(color, "Color");
   SOCKET_OUT_FLOAT(fac, "Fac");
 
@@ -1368,6 +1373,7 @@ void WaveTextureNode::compile(SVMCompiler &compiler)
   ShaderInput *distortion_in = input("Distortion");
   ShaderInput *detail_in = input("Detail");
   ShaderInput *dscale_in = input("Detail Scale");
+  ShaderInput *droughness_in = input("Detail Roughness");
   ShaderInput *phase_in = input("Phase Offset");
   ShaderOutput *color_out = output("Color");
   ShaderOutput *fac_out = output("Fac");
@@ -1378,20 +1384,22 @@ void WaveTextureNode::compile(SVMCompiler &compiler)
                     compiler.encode_uchar4(type, bands_direction, rings_direction, profile),
                     compiler.encode_uchar4(vector_offset,
                                            compiler.stack_assign_if_linked(scale_in),
-                                           compiler.stack_assign_if_linked(distortion_in),
-                                           compiler.stack_assign_if_linked(detail_in)),
-                    compiler.encode_uchar4(compiler.stack_assign_if_linked(dscale_in),
-                                           compiler.stack_assign_if_linked(phase_in),
-                                           compiler.stack_assign_if_linked(color_out),
-                                           compiler.stack_assign_if_linked(fac_out)));
+                                           compiler.stack_assign_if_linked(distortion_in)),
+                    compiler.encode_uchar4(compiler.stack_assign_if_linked(detail_in),
+                                           compiler.stack_assign_if_linked(dscale_in),
+                                           compiler.stack_assign_if_linked(droughness_in),
+                                           compiler.stack_assign_if_linked(phase_in)));
 
-  compiler.add_node(__float_as_int(scale),
-                    __float_as_int(detail),
+  compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(color_out),
+                                           compiler.stack_assign_if_linked(fac_out)),
+                    __float_as_int(scale),
                     __float_as_int(distortion),
-                    __float_as_int(detail_scale));
+                    __float_as_int(detail));
 
-  compiler.add_node(
-      __float_as_int(phase), SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID);
+  compiler.add_node(__float_as_int(detail_scale),
+                    __float_as_int(detail_roughness),
+                    __float_as_int(phase),
+                    SVM_STACK_INVALID);
 
   tex_mapping.compile_end(compiler, vector_in, vector_offset);
 }
index e201118574b11231cf72ccb56ed5ca49da6e1e56..8316fa3cf9b37ad616da5e5e3830a2b496cfe0fe 100644 (file)
@@ -230,7 +230,7 @@ class NoiseTextureNode : public TextureNode {
   SHADER_NODE_CLASS(NoiseTextureNode)
 
   int dimensions;
-  float w, scale, detail, distortion;
+  float w, scale, detail, roughness, distortion;
   float3 vector;
 };
 
@@ -291,7 +291,7 @@ class WaveTextureNode : public TextureNode {
   NodeWaveRingsDirection rings_direction;
   NodeWaveProfile profile;
 
-  float scale, distortion, detail, detail_scale, phase;
+  float scale, distortion, detail, detail_scale, detail_roughness, phase;
   float3 vector;
 };
 
index 701b07b4aae30d3df979cd3a2f322c2adfa821f1..f25691c1a835238e40e1a24c43f4f8d998893cfc 100644 (file)
 /* The fractal_noise functions are all exactly the same except for the input type. */
-float fractal_noise(float p, float octaves)
+float fractal_noise(float p, float octaves, float roughness)
 {
   float fscale = 1.0;
   float amp = 1.0;
+  float maxamp = 0.0;
   float sum = 0.0;
   octaves = clamp(octaves, 0.0, 16.0);
   int n = int(octaves);
   for (int i = 0; i <= n; i++) {
     float t = noise(fscale * p);
     sum += t * amp;
-    amp *= 0.5;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0, 1.0);
     fscale *= 2.0;
   }
   float rmd = octaves - floor(octaves);
   if (rmd != 0.0) {
     float t = noise(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
-    sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0 - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise functions are all exactly the same except for the input type. */
-float fractal_noise(vec2 p, float octaves)
+float fractal_noise(vec2 p, float octaves, float roughness)
 {
   float fscale = 1.0;
   float amp = 1.0;
+  float maxamp = 0.0;
   float sum = 0.0;
   octaves = clamp(octaves, 0.0, 16.0);
   int n = int(octaves);
   for (int i = 0; i <= n; i++) {
     float t = noise(fscale * p);
     sum += t * amp;
-    amp *= 0.5;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0, 1.0);
     fscale *= 2.0;
   }
   float rmd = octaves - floor(octaves);
   if (rmd != 0.0) {
     float t = noise(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
-    sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0 - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise functions are all exactly the same except for the input type. */
-float fractal_noise(vec3 p, float octaves)
+float fractal_noise(vec3 p, float octaves, float roughness)
 {
   float fscale = 1.0;
   float amp = 1.0;
+  float maxamp = 0.0;
   float sum = 0.0;
   octaves = clamp(octaves, 0.0, 16.0);
   int n = int(octaves);
   for (int i = 0; i <= n; i++) {
     float t = noise(fscale * p);
     sum += t * amp;
-    amp *= 0.5;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0, 1.0);
     fscale *= 2.0;
   }
   float rmd = octaves - floor(octaves);
   if (rmd != 0.0) {
     float t = noise(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
-    sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0 - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
 
 /* The fractal_noise functions are all exactly the same except for the input type. */
-float fractal_noise(vec4 p, float octaves)
+float fractal_noise(vec4 p, float octaves, float roughness)
 {
   float fscale = 1.0;
   float amp = 1.0;
+  float maxamp = 0.0;
   float sum = 0.0;
   octaves = clamp(octaves, 0.0, 16.0);
   int n = int(octaves);
   for (int i = 0; i <= n; i++) {
     float t = noise(fscale * p);
     sum += t * amp;
-    amp *= 0.5;
+    maxamp += amp;
+    amp *= clamp(roughness, 0.0, 1.0);
     fscale *= 2.0;
   }
   float rmd = octaves - floor(octaves);
   if (rmd != 0.0) {
     float t = noise(fscale * p);
     float sum2 = sum + t * amp;
-    sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
-    sum2 *= (float(1 << (n + 1)) / float((1 << (n + 2)) - 1));
+    sum /= maxamp;
+    sum2 /= maxamp + amp;
     return (1.0 - rmd) * sum + rmd * sum2;
   }
   else {
-    sum *= (float(1 << n) / float((1 << (n + 1)) - 1));
-    return sum;
+    return sum / maxamp;
   }
 }
index 6aeb23b1f991b4f546c174f4d315c1b8bd66ae1f..d8d9ecdf287d083c48a16d98de2717519efb4dec 100644 (file)
@@ -32,23 +32,35 @@ vec4 random_vec4_offset(float seed)
               100.0 + hash_vec2_to_float(vec2(seed, 3.0)) * 100.0);
 }
 
-void node_noise_texture_1d(
-    vec3 co, float w, float scale, float detail, float distortion, out float value, out vec4 color)
+void node_noise_texture_1d(vec3 co,
+                           float w,
+                           float scale,
+                           float detail,
+                           float roughness,
+                           float distortion,
+                           out float value,
+                           out vec4 color)
 {
   float p = w * scale;
   if (distortion != 0.0) {
     p += snoise(p + random_float_offset(0.0)) * distortion;
   }
 
-  value = fractal_noise(p, detail);
+  value = fractal_noise(p, detail, roughness);
   color = vec4(value,
-               fractal_noise(p + random_float_offset(1.0), detail),
-               fractal_noise(p + random_float_offset(2.0), detail),
+               fractal_noise(p + random_float_offset(1.0), detail, roughness),
+               fractal_noise(p + random_float_offset(2.0), detail, roughness),
                1.0);
 }
 
-void node_noise_texture_2d(
-    vec3 co, float w, float scale, float detail, float distortion, out float value, out vec4 color)
+void node_noise_texture_2d(vec3 co,
+                           float w,
+                           float scale,
+                           float detail,
+                           float roughness,
+                           float distortion,
+                           out float value,
+                           out vec4 color)
 {
   vec2 p = co.xy * scale;
   if (distortion != 0.0) {
@@ -56,15 +68,21 @@ void node_noise_texture_2d(
               snoise(p + random_vec2_offset(1.0)) * distortion);
   }
 
-  value = fractal_noise(p, detail);
+  value = fractal_noise(p, detail, roughness);
   color = vec4(value,
-               fractal_noise(p + random_vec2_offset(2.0), detail),
-               fractal_noise(p + random_vec2_offset(3.0), detail),
+               fractal_noise(p + random_vec2_offset(2.0), detail, roughness),
+               fractal_noise(p + random_vec2_offset(3.0), detail, roughness),
                1.0);
 }
 
-void node_noise_texture_3d(
-    vec3 co, float w, float scale, float detail, float distortion, out float value, out vec4 color)
+void node_noise_texture_3d(vec3 co,
+                           float w,
+                           float scale,
+                           float detail,
+                           float roughness,
+                           float distortion,
+                           out float value,
+                           out vec4 color)
 {
   vec3 p = co * scale;
   if (distortion != 0.0) {
@@ -73,15 +91,21 @@ void node_noise_texture_3d(
               snoise(p + random_vec3_offset(2.0)) * distortion);
   }
 
-  value = fractal_noise(p, detail);
+  value = fractal_noise(p, detail, roughness);
   color = vec4(value,
-               fractal_noise(p + random_vec3_offset(3.0), detail),
-               fractal_noise(p + random_vec3_offset(4.0), detail),
+               fractal_noise(p + random_vec3_offset(3.0), detail, roughness),
+               fractal_noise(p + random_vec3_offset(4.0), detail, roughness),
                1.0);
 }
 
-void node_noise_texture_4d(
-    vec3 co, float w, float scale, float detail, float distortion, out float value, out vec4 color)
+void node_noise_texture_4d(vec3 co,
+                           float w,
+                           float scale,
+                           float detail,
+                           float roughness,
+                           float distortion,
+                           out float value,
+                           out vec4 color)
 {
   vec4 p = vec4(co, w) * scale;
   if (distortion != 0.0) {
@@ -91,9 +115,9 @@ void node_noise_texture_4d(
               snoise(p + random_vec4_offset(3.0)) * distortion);
   }
 
-  value = fractal_noise(p, detail);
+  value = fractal_noise(p, detail, roughness);
   color = vec4(value,
-               fractal_noise(p + random_vec4_offset(4.0), detail),
-               fractal_noise(p + random_vec4_offset(5.0), detail),
+               fractal_noise(p + random_vec4_offset(4.0), detail, roughness),
+               fractal_noise(p + random_vec4_offset(5.0), detail, roughness),
                1.0);
 }
index c72f9717af35eecad66899221800e57f1b963fc4..070f42a5e30ee5cd3290d05ab4d3f35405614670 100644 (file)
@@ -2,6 +2,7 @@ float calc_wave(vec3 p,
                 float distortion,
                 float detail,
                 float detail_scale,
+                float detail_roughness,
                 float phase,
                 int wave_type,
                 int bands_dir,
@@ -46,7 +47,7 @@ float calc_wave(vec3 p,
   n += phase;
 
   if (distortion != 0.0) {
-    n += distortion * (fractal_noise(p * detail_scale, detail) * 2.0 - 1.0);
+    n += distortion * (fractal_noise(p * detail_scale, detail, detail_roughness) * 2.0 - 1.0);
   }
 
   if (wave_profile == 0) { /* profile sin */
@@ -67,6 +68,7 @@ void node_tex_wave(vec3 co,
                    float distortion,
                    float detail,
                    float detail_scale,
+                   float detail_roughness,
                    float phase,
                    float wave_type,
                    float bands_dir,
@@ -80,6 +82,7 @@ void node_tex_wave(vec3 co,
                 distortion,
                 detail,
                 detail_scale,
+                detail_roughness,
                 phase,
                 int(wave_type),
                 int(bands_dir),
index 2205a1a86a3f27e6b73677c85f33d53f21aa1667..7b67c2d1f2ef63c89bcf95c6d59a25b3f2c075e8 100644 (file)
@@ -26,6 +26,7 @@ static bNodeSocketTemplate sh_node_tex_noise_in[] = {
     {SOCK_FLOAT, N_("W"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
     {SOCK_FLOAT, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
     {SOCK_FLOAT, N_("Detail"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 16.0f},
+    {SOCK_FLOAT, N_("Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
     {SOCK_FLOAT, N_("Distortion"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
     {-1, ""},
 };
index 0b6cd7ee4db75eca45fd7bfcf7c5fbd4140e4477..bba568ed5b7a0c4a95bd3bc8c5959b32278cda8d 100644 (file)
@@ -27,6 +27,7 @@ static bNodeSocketTemplate sh_node_tex_wave_in[] = {
     {SOCK_FLOAT, N_("Distortion"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
     {SOCK_FLOAT, N_("Detail"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 16.0f},
     {SOCK_FLOAT, N_("Detail Scale"), 1.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
+    {SOCK_FLOAT, N_("Detail Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
     {SOCK_FLOAT, N_("Phase Offset"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f},
     {-1, ""},
 };