diff options
-rw-r--r-- | intern/cycles/kernel/shaders/node_noise.h | 52 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_noise_texture.osl | 44 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_wave_texture.osl | 9 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_fractal_noise.h | 52 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_noisetex.h | 91 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_wave.h | 32 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 46 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl | 52 | ||||
-rw-r--r-- | source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl | 64 | ||||
-rw-r--r-- | source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl | 5 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_tex_noise.c | 1 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_tex_wave.c | 1 |
13 files changed, 272 insertions, 181 deletions
diff --git a/intern/cycles/kernel/shaders/node_noise.h b/intern/cycles/kernel/shaders/node_noise.h index 23d1987a00e..ab4cd7792cc 100644 --- a/intern/cycles/kernel/shaders/node_noise.h +++ b/intern/cycles/kernel/shaders/node_noise.h @@ -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; } } diff --git a/intern/cycles/kernel/shaders/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl index 4121b415673..61c0216910b 100644 --- a/intern/cycles/kernel/shaders/node_noise_texture.osl +++ b/intern/cycles/kernel/shaders/node_noise_texture.osl @@ -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!"); } diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl index f17397be243..874bfb8d3af 100644 --- a/intern/cycles/kernel/shaders/node_wave_texture.osl +++ b/intern/cycles/kernel/shaders/node_wave_texture.osl @@ -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; } diff --git a/intern/cycles/kernel/svm/svm_fractal_noise.h b/intern/cycles/kernel/svm/svm_fractal_noise.h index 5b2e4a28fce..57fa8c690ac 100644 --- a/intern/cycles/kernel/svm/svm_fractal_noise.h +++ b/intern/cycles/kernel/svm/svm_fractal_noise.h @@ -17,114 +17,118 @@ 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; } } diff --git a/intern/cycles/kernel/svm/svm_noisetex.h b/intern/cycles/kernel/svm/svm_noisetex.h index 12884c6cb25..920dd7d9d02 100644 --- a/intern/cycles/kernel/svm/svm_noisetex.h +++ b/intern/cycles/kernel/svm/svm_noisetex.h @@ -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, diff --git a/intern/cycles/kernel/svm/svm_wave.h b/intern/cycles/kernel/svm/svm_wave.h index 64102535f7d..c4763475b47 100644 --- a/intern/cycles/kernel/svm/svm_wave.h +++ b/intern/cycles/kernel/svm/svm_wave.h @@ -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)) diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index ac07d91c4ca..4b4958fe3da 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -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); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index e201118574b..8316fa3cf9b 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -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; }; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl index 701b07b4aae..f25691c1a83 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_fractal_noise.glsl @@ -1,111 +1,115 @@ /* 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; } } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl index 6aeb23b1f99..d8d9ecdf287 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_noise.glsl @@ -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); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl index c72f9717af3..070f42a5e30 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl @@ -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), diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.c b/source/blender/nodes/shader/nodes/node_shader_tex_noise.c index 2205a1a86a3..7b67c2d1f2e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.c @@ -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, ""}, }; diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c index 0b6cd7ee4db..bba568ed5b7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c @@ -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, ""}, }; |