Nodes: Add Hard option to Noise node #112640

Open
Charlie Jolly wants to merge 1 commits from CharlieJolly/blender:hard_noise into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
18 changed files with 315 additions and 136 deletions

View File

@ -936,6 +936,7 @@ static ShaderNode *add_node(Scene *scene,
NoiseTextureNode *noise = graph->create_node<NoiseTextureNode>();
noise->set_dimensions(b_noise_node.noise_dimensions());
noise->set_use_normalize(b_noise_node.normalize());
noise->set_hard(b_noise_node.hard());
BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping());
get_tex_mapping(noise, b_texture_mapping);
node = noise;

View File

@ -72,7 +72,8 @@ 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 roughness, float lacunarity, int use_normalize)
float fractal_noise(
float p, float details, float roughness, float lacunarity, int use_normalize, int hard)
{
float fscale = 1.0;
float amp = 1.0;
@ -82,6 +83,7 @@ float fractal_noise(float p, float details, float roughness, float lacunarity, i
int n = (int)octaves;
for (int i = 0; i <= n; i++) {
float t = safe_snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0, 1.0);
@ -90,6 +92,7 @@ float fractal_noise(float p, float details, float roughness, float lacunarity, i
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
float t = safe_snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
float sum2 = sum + t * amp;
return use_normalize ? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) :
mix(sum, sum2, rmd);
@ -100,7 +103,8 @@ float fractal_noise(float p, float details, float roughness, float lacunarity, i
}
/* The fractal_noise functions are all exactly the same except for the input type. */
float fractal_noise(vector2 p, float details, float roughness, float lacunarity, int use_normalize)
float fractal_noise(
vector2 p, float details, float roughness, float lacunarity, int use_normalize, int hard)
{
float fscale = 1.0;
float amp = 1.0;
@ -110,6 +114,7 @@ float fractal_noise(vector2 p, float details, float roughness, float lacunarity,
int n = (int)octaves;
for (int i = 0; i <= n; i++) {
float t = safe_snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0, 1.0);
@ -118,6 +123,7 @@ float fractal_noise(vector2 p, float details, float roughness, float lacunarity,
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
float t = safe_snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
float sum2 = sum + t * amp;
return use_normalize ? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) :
mix(sum, sum2, rmd);
@ -128,7 +134,8 @@ float fractal_noise(vector2 p, float details, float roughness, float lacunarity,
}
/* The fractal_noise functions are all exactly the same except for the input type. */
float fractal_noise(vector3 p, float details, float roughness, float lacunarity, int use_normalize)
float fractal_noise(
vector3 p, float details, float roughness, float lacunarity, int use_normalize, int hard)
{
float fscale = 1.0;
float amp = 1.0;
@ -138,6 +145,7 @@ float fractal_noise(vector3 p, float details, float roughness, float lacunarity,
int n = (int)octaves;
for (int i = 0; i <= n; i++) {
float t = safe_snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0, 1.0);
@ -146,6 +154,7 @@ float fractal_noise(vector3 p, float details, float roughness, float lacunarity,
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
float t = safe_snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
float sum2 = sum + t * amp;
return use_normalize ? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) :
mix(sum, sum2, rmd);
@ -156,7 +165,8 @@ float fractal_noise(vector3 p, float details, float roughness, float lacunarity,
}
/* The fractal_noise functions are all exactly the same except for the input type. */
float fractal_noise(vector4 p, float details, float roughness, float lacunarity, int use_normalize)
float fractal_noise(
vector4 p, float details, float roughness, float lacunarity, int use_normalize, int hard)
{
float fscale = 1.0;
float amp = 1.0;
@ -166,6 +176,7 @@ float fractal_noise(vector4 p, float details, float roughness, float lacunarity,
int n = (int)octaves;
for (int i = 0; i <= n; i++) {
float t = safe_snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0, 1.0);
@ -174,6 +185,7 @@ float fractal_noise(vector4 p, float details, float roughness, float lacunarity,
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
float t = safe_snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
float sum2 = sum + t * amp;
return use_normalize ? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) :
mix(sum, sum2, rmd);

View File

@ -49,6 +49,7 @@ float noise_texture(float co,
float lacunarity,
float distortion,
int use_normalize,
int hard,
output color Color)
{
float p = co;
@ -56,11 +57,13 @@ float noise_texture(float co,
p += safe_snoise(p + random_float_offset(0.0)) * distortion;
}
float value = fractal_noise(p, detail, roughness, lacunarity, use_normalize);
float value = fractal_noise(p, detail, roughness, lacunarity, use_normalize, hard);
Color = color(
value,
fractal_noise(p + random_float_offset(1.0), detail, roughness, lacunarity, use_normalize),
fractal_noise(p + random_float_offset(2.0), detail, roughness, lacunarity, use_normalize));
fractal_noise(
p + random_float_offset(1.0), detail, roughness, lacunarity, use_normalize, hard),
fractal_noise(
p + random_float_offset(2.0), detail, roughness, lacunarity, use_normalize, hard));
return value;
}
@ -70,6 +73,7 @@ float noise_texture(vector2 co,
float lacunarity,
float distortion,
int use_normalize,
int hard,
output color Color)
{
vector2 p = co;
@ -78,11 +82,13 @@ float noise_texture(vector2 co,
safe_snoise(p + random_vector2_offset(1.0)) * distortion);
}
float value = fractal_noise(p, detail, roughness, lacunarity, use_normalize);
float value = fractal_noise(p, detail, roughness, lacunarity, use_normalize, hard);
Color = color(
value,
fractal_noise(p + random_vector2_offset(2.0), detail, roughness, lacunarity, use_normalize),
fractal_noise(p + random_vector2_offset(3.0), detail, roughness, lacunarity, use_normalize));
fractal_noise(
p + random_vector2_offset(2.0), detail, roughness, lacunarity, use_normalize, hard),
fractal_noise(
p + random_vector2_offset(3.0), detail, roughness, lacunarity, use_normalize, hard));
return value;
}
@ -92,6 +98,7 @@ float noise_texture(vector3 co,
float lacunarity,
float distortion,
int use_normalize,
int hard,
output color Color)
{
vector3 p = co;
@ -101,11 +108,13 @@ float noise_texture(vector3 co,
safe_snoise(p + random_vector3_offset(2.0)) * distortion);
}
float value = fractal_noise(p, detail, roughness, lacunarity, use_normalize);
float value = fractal_noise(p, detail, roughness, lacunarity, use_normalize, hard);
Color = color(
value,
fractal_noise(p + random_vector3_offset(3.0), detail, roughness, lacunarity, use_normalize),
fractal_noise(p + random_vector3_offset(4.0), detail, roughness, lacunarity, use_normalize));
fractal_noise(
p + random_vector3_offset(3.0), detail, roughness, lacunarity, use_normalize, hard),
fractal_noise(
p + random_vector3_offset(4.0), detail, roughness, lacunarity, use_normalize, hard));
return value;
}
@ -115,6 +124,7 @@ float noise_texture(vector4 co,
float lacunarity,
float distortion,
int use_normalize,
int hard,
output color Color)
{
vector4 p = co;
@ -125,11 +135,13 @@ float noise_texture(vector4 co,
safe_snoise(p + random_vector4_offset(3.0)) * distortion);
}
float value = fractal_noise(p, detail, roughness, lacunarity, use_normalize);
float value = fractal_noise(p, detail, roughness, lacunarity, use_normalize, hard);
Color = color(
value,
fractal_noise(p + random_vector4_offset(4.0), detail, roughness, lacunarity, use_normalize),
fractal_noise(p + random_vector4_offset(5.0), detail, roughness, lacunarity, use_normalize));
fractal_noise(
p + random_vector4_offset(4.0), detail, roughness, lacunarity, use_normalize, hard),
fractal_noise(
p + random_vector4_offset(5.0), detail, roughness, lacunarity, use_normalize, hard));
return value;
}
@ -137,6 +149,7 @@ shader node_noise_texture(int use_mapping = 0,
matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
string dimensions = "3D",
int use_normalize = 0,
int hard = 0,
vector3 Vector = vector3(0, 0, 0),
float W = 0.0,
float Scale = 5.0,
@ -155,12 +168,18 @@ shader node_noise_texture(int use_mapping = 0,
float w = W * Scale;
if (dimensions == "1D")
Fac = noise_texture(w, Detail, Roughness, Lacunarity, Distortion, use_normalize, Color);
Fac = noise_texture(w, Detail, Roughness, Lacunarity, Distortion, use_normalize, hard, Color);
else if (dimensions == "2D")
Fac = noise_texture(
vector2(p[0], p[1]), Detail, Roughness, Lacunarity, Distortion, use_normalize, Color);
Fac = noise_texture(vector2(p[0], p[1]),
Detail,
Roughness,
Lacunarity,
Distortion,
use_normalize,
hard,
Color);
else if (dimensions == "3D")
Fac = noise_texture(p, Detail, Roughness, Lacunarity, Distortion, use_normalize, Color);
Fac = noise_texture(p, Detail, Roughness, Lacunarity, Distortion, use_normalize, hard, Color);
else if (dimensions == "4D")
Fac = noise_texture(vector4(p[0], p[1], p[2], w),
Detail,
@ -168,6 +187,7 @@ shader node_noise_texture(int use_mapping = 0,
Lacunarity,
Distortion,
use_normalize,
hard,
Color);
else
error("Unknown dimension!");

View File

@ -56,7 +56,7 @@ float wave(point p_input,
n += phase;
if (distortion != 0.0) {
n = n + (distortion * (fractal_noise(p * dscale, detail, droughness, 2.0, 1) * 2.0 - 1.0));
n = n + (distortion * (fractal_noise(p * dscale, detail, droughness, 2.0, 1, 0) * 2.0 - 1.0));
}
if (profile == "sine") {

View File

@ -10,7 +10,7 @@ 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, float roughness, float lacunarity, bool normalize)
float p, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0f;
float amp = 1.0f;
@ -20,6 +20,7 @@ ccl_device_noinline float fractal_noise_1d(
int n = float_to_int(octaves);
for (int i = 0; i <= n; i++) {
float t = snoise_1d(fscale * p);
t = hard ? fabsf(t) * 2.0f - 1.0f : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0f, 1.0f);
@ -28,6 +29,7 @@ ccl_device_noinline float fractal_noise_1d(
float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
float t = snoise_1d(fscale * p);
t = hard ? fabsf(t) * 2.0f - 1.0f : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
mix(sum, sum2, rmd);
@ -39,7 +41,7 @@ ccl_device_noinline float fractal_noise_1d(
/* 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, float roughness, float lacunarity, bool normalize)
float2 p, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0f;
float amp = 1.0f;
@ -49,6 +51,7 @@ ccl_device_noinline float fractal_noise_2d(
int n = float_to_int(octaves);
for (int i = 0; i <= n; i++) {
float t = snoise_2d(fscale * p);
t = hard ? fabsf(t) * 2.0f - 1.0f : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0f, 1.0f);
@ -57,6 +60,7 @@ ccl_device_noinline float fractal_noise_2d(
float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
float t = snoise_2d(fscale * p);
t = hard ? fabsf(t) * 2.0f - 1.0f : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
mix(sum, sum2, rmd);
@ -68,7 +72,7 @@ ccl_device_noinline float fractal_noise_2d(
/* 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, float roughness, float lacunarity, bool normalize)
float3 p, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0f;
float amp = 1.0f;
@ -78,6 +82,7 @@ ccl_device_noinline float fractal_noise_3d(
int n = float_to_int(octaves);
for (int i = 0; i <= n; i++) {
float t = snoise_3d(fscale * p);
t = hard ? fabsf(t) * 2.0f - 1.0f : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0f, 1.0f);
@ -86,6 +91,7 @@ ccl_device_noinline float fractal_noise_3d(
float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
float t = snoise_3d(fscale * p);
t = hard ? fabsf(t) * 2.0f - 1.0f : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
mix(sum, sum2, rmd);
@ -97,7 +103,7 @@ ccl_device_noinline float fractal_noise_3d(
/* 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, float roughness, float lacunarity, bool normalize)
float4 p, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0f;
float amp = 1.0f;
@ -107,6 +113,7 @@ ccl_device_noinline float fractal_noise_4d(
int n = float_to_int(octaves);
for (int i = 0; i <= n; i++) {
float t = snoise_4d(fscale * p);
t = hard ? fabsf(t) * 2.0f - 1.0f : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0f, 1.0f);
@ -115,6 +122,7 @@ ccl_device_noinline float fractal_noise_4d(
float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
float t = snoise_4d(fscale * p);
t = hard ? fabsf(t) * 2.0f - 1.0f : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
mix(sum, sum2, rmd);

View File

@ -48,6 +48,7 @@ ccl_device void noise_texture_1d(float co,
float lacunarity,
float distortion,
bool normalize,
bool hard,
bool color_is_needed,
ccl_private float *value,
ccl_private float3 *color)
@ -57,12 +58,14 @@ ccl_device void noise_texture_1d(float co,
p += snoise_1d(p + random_float_offset(0.0f)) * distortion;
}
*value = fractal_noise_1d(p, detail, roughness, lacunarity, normalize);
*value = fractal_noise_1d(p, detail, roughness, lacunarity, normalize, hard);
if (color_is_needed) {
*color = make_float3(
*value,
fractal_noise_1d(p + random_float_offset(1.0f), detail, roughness, lacunarity, normalize),
fractal_noise_1d(p + random_float_offset(2.0f), detail, roughness, lacunarity, normalize));
fractal_noise_1d(
p + random_float_offset(1.0f), detail, roughness, lacunarity, normalize, hard),
fractal_noise_1d(
p + random_float_offset(2.0f), detail, roughness, lacunarity, normalize, hard));
}
}
@ -72,6 +75,7 @@ ccl_device void noise_texture_2d(float2 co,
float lacunarity,
float distortion,
bool normalize,
bool hard,
bool color_is_needed,
ccl_private float *value,
ccl_private float3 *color)
@ -82,13 +86,14 @@ ccl_device void noise_texture_2d(float2 co,
snoise_2d(p + random_float2_offset(1.0f)) * distortion);
}
*value = fractal_noise_2d(p, detail, roughness, lacunarity, normalize);
*value = fractal_noise_2d(p, detail, roughness, lacunarity, normalize, hard);
if (color_is_needed) {
*color = make_float3(
*value,
fractal_noise_2d(p + random_float2_offset(2.0f), detail, roughness, lacunarity, normalize),
fractal_noise_2d(
p + random_float2_offset(3.0f), detail, roughness, lacunarity, normalize));
p + random_float2_offset(2.0f), detail, roughness, lacunarity, normalize, hard),
fractal_noise_2d(
p + random_float2_offset(3.0f), detail, roughness, lacunarity, normalize, hard));
}
}
@ -98,6 +103,7 @@ ccl_device void noise_texture_3d(float3 co,
float lacunarity,
float distortion,
bool normalize,
bool hard,
bool color_is_needed,
ccl_private float *value,
ccl_private float3 *color)
@ -109,13 +115,14 @@ ccl_device void noise_texture_3d(float3 co,
snoise_3d(p + random_float3_offset(2.0f)) * distortion);
}
*value = fractal_noise_3d(p, detail, roughness, lacunarity, normalize);
*value = fractal_noise_3d(p, detail, roughness, lacunarity, normalize, hard);
if (color_is_needed) {
*color = make_float3(
*value,
fractal_noise_3d(p + random_float3_offset(3.0f), detail, roughness, lacunarity, normalize),
fractal_noise_3d(
p + random_float3_offset(4.0f), detail, roughness, lacunarity, normalize));
p + random_float3_offset(3.0f), detail, roughness, lacunarity, normalize, hard),
fractal_noise_3d(
p + random_float3_offset(4.0f), detail, roughness, lacunarity, normalize, hard));
}
}
@ -125,6 +132,7 @@ ccl_device void noise_texture_4d(float4 co,
float lacunarity,
float distortion,
bool normalize,
bool hard,
bool color_is_needed,
ccl_private float *value,
ccl_private float3 *color)
@ -137,13 +145,14 @@ ccl_device void noise_texture_4d(float4 co,
snoise_4d(p + random_float4_offset(3.0f)) * distortion);
}
*value = fractal_noise_4d(p, detail, roughness, lacunarity, normalize);
*value = fractal_noise_4d(p, detail, roughness, lacunarity, normalize, hard);
if (color_is_needed) {
*color = make_float3(
*value,
fractal_noise_4d(p + random_float4_offset(4.0f), detail, roughness, lacunarity, normalize),
fractal_noise_4d(
p + random_float4_offset(5.0f), detail, roughness, lacunarity, normalize));
p + random_float4_offset(4.0f), detail, roughness, lacunarity, normalize, hard),
fractal_noise_4d(
p + random_float4_offset(5.0f), detail, roughness, lacunarity, normalize, hard));
}
}
@ -158,7 +167,7 @@ ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
uint vector_stack_offset, w_stack_offset, scale_stack_offset, detail_stack_offset;
uint roughness_stack_offset, lacunarity_stack_offset, distortion_stack_offset,
value_stack_offset;
uint color_stack_offset, dimensions, normalize;
uint color_stack_offset, dimensions, normalize, hard;
svm_unpack_node_uchar4(
offsets1, &vector_stack_offset, &w_stack_offset, &scale_stack_offset, &detail_stack_offset);
@ -167,7 +176,7 @@ ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
&lacunarity_stack_offset,
&distortion_stack_offset,
&value_stack_offset);
svm_unpack_node_uchar3(offsets3, &color_stack_offset, &dimensions, &normalize);
svm_unpack_node_uchar4(offsets3, &color_stack_offset, &dimensions, &normalize, &hard);
uint4 defaults1 = read_node(kg, &offset);
uint4 defaults2 = read_node(kg, &offset);
@ -193,6 +202,7 @@ ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
lacunarity,
distortion,
normalize,
hard,
stack_valid(color_stack_offset),
&value,
&color);
@ -204,6 +214,7 @@ ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
lacunarity,
distortion,
normalize,
hard,
stack_valid(color_stack_offset),
&value,
&color);
@ -215,6 +226,7 @@ ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
lacunarity,
distortion,
normalize,
hard,
stack_valid(color_stack_offset),
&value,
&color);
@ -226,6 +238,7 @@ ccl_device_noinline int svm_node_tex_noise(KernelGlobals kg,
lacunarity,
distortion,
normalize,
hard,
stack_valid(color_stack_offset),
&value,
&color);

View File

@ -57,7 +57,7 @@ ccl_device_noinline_cpu float svm_wave(NodeWaveType type,
n += phase;
if (distortion != 0.0f)
n += distortion * (fractal_noise_3d(p * dscale, detail, droughness, 2.0f, true) * 2.0f - 1.0f);
n += distortion * (fractal_noise_3d(p * dscale, detail, droughness, 2.0f, true, false) * 2.0f - 1.0f);
if (profile == NODE_WAVE_PROFILE_SIN) {
return 0.5f + 0.5f * sinf(n - M_PI_2_F);

View File

@ -1138,6 +1138,7 @@ NODE_DEFINE(NoiseTextureNode)
SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
SOCKET_BOOLEAN(use_normalize, "Normalize", true);
SOCKET_BOOLEAN(hard, "Hard", false);
SOCKET_IN_POINT(vector, "Vector", zero_float3(), SocketType::LINK_TEXTURE_GENERATED);
SOCKET_IN_FLOAT(w, "W", 0.0f);
@ -1185,7 +1186,7 @@ void NoiseTextureNode::compile(SVMCompiler &compiler)
lacunarity_stack_offset,
distortion_stack_offset,
fac_stack_offset),
compiler.encode_uchar4(color_stack_offset, dimensions, use_normalize));
compiler.encode_uchar4(color_stack_offset, dimensions, use_normalize, hard));
compiler.add_node(
__float_as_int(w), __float_as_int(scale), __float_as_int(detail), __float_as_int(roughness));
@ -1203,6 +1204,7 @@ void NoiseTextureNode::compile(OSLCompiler &compiler)
tex_mapping.compile(compiler);
compiler.parameter(this, "dimensions");
compiler.parameter(this, "use_normalize");
compiler.parameter(this, "hard");
compiler.add(this, "node_noise_texture");
}

View File

@ -229,6 +229,7 @@ class NoiseTextureNode : public TextureNode {
NODE_SOCKET_API(int, dimensions)
NODE_SOCKET_API(bool, use_normalize)
NODE_SOCKET_API(bool, hard)
NODE_SOCKET_API(float, w)
NODE_SOCKET_API(float, scale)
NODE_SOCKET_API(float, detail)

View File

@ -75,13 +75,13 @@ float perlin(float4 position);
/* Fractal perlin noise in the range [0, 1]. */
float perlin_fractal(
float position, float octaves, float roughness, float lacunarity, bool normalize);
float position, float octaves, float roughness, float lacunarity, bool normalize, bool hard);
float perlin_fractal(
float2 position, float octaves, float roughness, float lacunarity, bool normalize);
float2 position, float octaves, float roughness, float lacunarity, bool normalize, bool hard);
float perlin_fractal(
float3 position, float octaves, float roughness, float lacunarity, bool normalize);
float3 position, float octaves, float roughness, float lacunarity, bool normalize, bool hard);
float perlin_fractal(
float4 position, float octaves, float roughness, float lacunarity, bool normalize);
float4 position, float octaves, float roughness, float lacunarity, bool normalize, bool hard);
/* Positive distorted fractal perlin noise. */
@ -90,25 +90,29 @@ float perlin_fractal_distorted(float position,
float roughness,
float lacunarity,
float distortion,
bool normalize);
bool normalize,
bool hard);
float perlin_fractal_distorted(float2 position,
float octaves,
float roughness,
float lacunarity,
float distortion,
bool normalize);
bool normalize,
bool hard);
float perlin_fractal_distorted(float3 position,
float octaves,
float roughness,
float lacunarity,
float distortion,
bool normalize);
bool normalize,
bool hard);
float perlin_fractal_distorted(float4 position,
float octaves,
float roughness,
float lacunarity,
float distortion,
bool normalize);
bool normalize,
bool hard);
/* Positive distorted fractal perlin noise that outputs a float3. */
@ -117,25 +121,29 @@ float3 perlin_float3_fractal_distorted(float position,
float roughness,
float lacunarity,
float distortion,
bool normalize);
bool normalize,
bool hard);
float3 perlin_float3_fractal_distorted(float2 position,
float octaves,
float roughness,
float lacunarity,
float distortion,
bool normalize);
bool normalize,
bool hard);
float3 perlin_float3_fractal_distorted(float3 position,
float octaves,
float roughness,
float lacunarity,
float distortion,
bool normalize);
bool normalize,
bool hard);
float3 perlin_float3_fractal_distorted(float4 position,
float octaves,
float roughness,
float lacunarity,
float distortion,
bool normalize);
bool normalize,
bool hard);
/** \} */

View File

@ -533,7 +533,7 @@ float perlin(float4 position)
template<typename T>
float perlin_fractal_template(
T position, float octaves, float roughness, float lacunarity, bool normalize)
T position, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0f;
float amp = 1.0f;
@ -543,6 +543,7 @@ float perlin_fractal_template(
int n = int(octaves);
for (int i = 0; i <= n; i++) {
float t = perlin_signed(fscale * position);
t = hard ? math::abs(t) * 2.0f - 1.0f : t;
sum += t * amp;
maxamp += amp;
amp *= CLAMPIS(roughness, 0.0f, 1.0f);
@ -551,6 +552,7 @@ float perlin_fractal_template(
float rmd = octaves - std::floor(octaves);
if (rmd != 0.0f) {
float t = perlin_signed(fscale * position);
t = hard ? math::abs(t) * 2.0f - 1.0f : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
mix(sum, sum2, rmd);
@ -561,27 +563,27 @@ float perlin_fractal_template(
}
float perlin_fractal(
float position, float octaves, float roughness, float lacunarity, bool normalize)
float position, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
return perlin_fractal_template(position, octaves, roughness, lacunarity, normalize);
return perlin_fractal_template(position, octaves, roughness, lacunarity, normalize, hard);
}
float perlin_fractal(
float2 position, float octaves, float roughness, float lacunarity, bool normalize)
float2 position, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
return perlin_fractal_template(position, octaves, roughness, lacunarity, normalize);
return perlin_fractal_template(position, octaves, roughness, lacunarity, normalize, hard);
}
float perlin_fractal(
float3 position, float octaves, float roughness, float lacunarity, bool normalize)
float3 position, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
return perlin_fractal_template(position, octaves, roughness, lacunarity, normalize);
return perlin_fractal_template(position, octaves, roughness, lacunarity, normalize, hard);
}
float perlin_fractal(
float4 position, float octaves, float roughness, float lacunarity, bool normalize)
float4 position, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
return perlin_fractal_template(position, octaves, roughness, lacunarity, normalize);
return perlin_fractal_template(position, octaves, roughness, lacunarity, normalize, hard);
}
/* The following offset functions generate random offsets to be added to
@ -652,10 +654,11 @@ float perlin_fractal_distorted(float position,
float roughness,
float lacunarity,
float distortion,
bool normalize)
bool normalize,
bool hard)
{
position += perlin_distortion(position, distortion);
return perlin_fractal(position, octaves, roughness, lacunarity, normalize);
return perlin_fractal(position, octaves, roughness, lacunarity, normalize, hard);
}
float perlin_fractal_distorted(float2 position,
@ -663,10 +666,11 @@ float perlin_fractal_distorted(float2 position,
float roughness,
float lacunarity,
float distortion,
bool normalize)
bool normalize,
bool hard)
{
position += perlin_distortion(position, distortion);
return perlin_fractal(position, octaves, roughness, lacunarity, normalize);
return perlin_fractal(position, octaves, roughness, lacunarity, normalize, hard);
}
float perlin_fractal_distorted(float3 position,
@ -674,10 +678,11 @@ float perlin_fractal_distorted(float3 position,
float roughness,
float lacunarity,
float distortion,
bool normalize)
bool normalize,
bool hard)
{
position += perlin_distortion(position, distortion);
return perlin_fractal(position, octaves, roughness, lacunarity, normalize);
return perlin_fractal(position, octaves, roughness, lacunarity, normalize, hard);
}
float perlin_fractal_distorted(float4 position,
@ -685,10 +690,11 @@ float perlin_fractal_distorted(float4 position,
float roughness,
float lacunarity,
float distortion,
bool normalize)
bool normalize,
bool hard)
{
position += perlin_distortion(position, distortion);
return perlin_fractal(position, octaves, roughness, lacunarity, normalize);
return perlin_fractal(position, octaves, roughness, lacunarity, normalize, hard);
}
/* Positive distorted fractal perlin noise that outputs a float3. The arbitrary seeds are for
@ -699,15 +705,16 @@ float3 perlin_float3_fractal_distorted(float position,
float roughness,
float lacunarity,
float distortion,
bool normalize)
bool normalize,
bool hard)
{
position += perlin_distortion(position, distortion);
return float3(
perlin_fractal(position, octaves, roughness, lacunarity, normalize),
perlin_fractal(position, octaves, roughness, lacunarity, normalize, hard),
perlin_fractal(
position + random_float_offset(1.0f), octaves, roughness, lacunarity, normalize),
position + random_float_offset(1.0f), octaves, roughness, lacunarity, normalize, hard),
perlin_fractal(
position + random_float_offset(2.0f), octaves, roughness, lacunarity, normalize));
position + random_float_offset(2.0f), octaves, roughness, lacunarity, normalize, hard));
}
float3 perlin_float3_fractal_distorted(float2 position,
@ -715,15 +722,16 @@ float3 perlin_float3_fractal_distorted(float2 position,
float roughness,
float lacunarity,
float distortion,
bool normalize)
bool normalize,
bool hard)
{
position += perlin_distortion(position, distortion);
return float3(
perlin_fractal(position, octaves, roughness, lacunarity, normalize),
perlin_fractal(position, octaves, roughness, lacunarity, normalize, hard),
perlin_fractal(
position + random_float2_offset(2.0f), octaves, roughness, lacunarity, normalize),
position + random_float2_offset(2.0f), octaves, roughness, lacunarity, normalize, hard),
perlin_fractal(
position + random_float2_offset(3.0f), octaves, roughness, lacunarity, normalize));
position + random_float2_offset(3.0f), octaves, roughness, lacunarity, normalize, hard));
}
float3 perlin_float3_fractal_distorted(float3 position,
@ -731,15 +739,16 @@ float3 perlin_float3_fractal_distorted(float3 position,
float roughness,
float lacunarity,
float distortion,
bool normalize)
bool normalize,
bool hard)
{
position += perlin_distortion(position, distortion);
return float3(
perlin_fractal(position, octaves, roughness, lacunarity, normalize),
perlin_fractal(position, octaves, roughness, lacunarity, normalize, hard),
perlin_fractal(
position + random_float3_offset(3.0f), octaves, roughness, lacunarity, normalize),
position + random_float3_offset(3.0f), octaves, roughness, lacunarity, normalize, hard),
perlin_fractal(
position + random_float3_offset(4.0f), octaves, roughness, lacunarity, normalize));
position + random_float3_offset(4.0f), octaves, roughness, lacunarity, normalize, hard));
}
float3 perlin_float3_fractal_distorted(float4 position,
@ -747,15 +756,16 @@ float3 perlin_float3_fractal_distorted(float4 position,
float roughness,
float lacunarity,
float distortion,
bool normalize)
bool normalize,
bool hard)
{
position += perlin_distortion(position, distortion);
return float3(
perlin_fractal(position, octaves, roughness, lacunarity, normalize),
perlin_fractal(position, octaves, roughness, lacunarity, normalize, hard),
perlin_fractal(
position + random_float4_offset(4.0f), octaves, roughness, lacunarity, normalize),
position + random_float4_offset(4.0f), octaves, roughness, lacunarity, normalize, hard),
perlin_fractal(
position + random_float4_offset(5.0f), octaves, roughness, lacunarity, normalize));
position + random_float4_offset(5.0f), octaves, roughness, lacunarity, normalize, hard));
}
/** \} */

View File

@ -6,7 +6,8 @@
#pragma BLENDER_REQUIRE(gpu_shader_material_noise.glsl)
/* The fractal_noise functions are all exactly the same except for the input type. */
float fractal_noise(float p, float octaves, float roughness, float lacunarity, bool normalize)
float fractal_noise(
float p, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0;
float amp = 1.0;
@ -16,6 +17,7 @@ float fractal_noise(float p, float octaves, float roughness, float lacunarity, b
int n = int(octaves);
for (int i = 0; i <= n; i++) {
float t = snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0, 1.0);
@ -24,6 +26,7 @@ float fractal_noise(float p, float octaves, float roughness, float lacunarity, b
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
float t = snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) :
mix(sum, sum2, rmd);
@ -34,7 +37,8 @@ float fractal_noise(float p, float octaves, float roughness, float lacunarity, b
}
/* The fractal_noise functions are all exactly the same except for the input type. */
float fractal_noise(vec2 p, float octaves, float roughness, float lacunarity, bool normalize)
float fractal_noise(
vec2 p, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0;
float amp = 1.0;
@ -44,6 +48,7 @@ float fractal_noise(vec2 p, float octaves, float roughness, float lacunarity, bo
int n = int(octaves);
for (int i = 0; i <= n; i++) {
float t = snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0, 1.0);
@ -52,6 +57,7 @@ float fractal_noise(vec2 p, float octaves, float roughness, float lacunarity, bo
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
float t = snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) :
mix(sum, sum2, rmd);
@ -62,7 +68,8 @@ float fractal_noise(vec2 p, float octaves, float roughness, float lacunarity, bo
}
/* The fractal_noise functions are all exactly the same except for the input type. */
float fractal_noise(vec3 p, float octaves, float roughness, float lacunarity, bool normalize)
float fractal_noise(
vec3 p, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0;
float amp = 1.0;
@ -72,6 +79,7 @@ float fractal_noise(vec3 p, float octaves, float roughness, float lacunarity, bo
int n = int(octaves);
for (int i = 0; i <= n; i++) {
float t = snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0, 1.0);
@ -80,6 +88,7 @@ float fractal_noise(vec3 p, float octaves, float roughness, float lacunarity, bo
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
float t = snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) :
mix(sum, sum2, rmd);
@ -90,7 +99,8 @@ float fractal_noise(vec3 p, float octaves, float roughness, float lacunarity, bo
}
/* The fractal_noise functions are all exactly the same except for the input type. */
float fractal_noise(vec4 p, float octaves, float roughness, float lacunarity, bool normalize)
float fractal_noise(
vec4 p, float octaves, float roughness, float lacunarity, bool normalize, bool hard)
{
float fscale = 1.0;
float amp = 1.0;
@ -100,6 +110,7 @@ float fractal_noise(vec4 p, float octaves, float roughness, float lacunarity, bo
int n = int(octaves);
for (int i = 0; i <= n; i++) {
float t = snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
sum += t * amp;
maxamp += amp;
amp *= clamp(roughness, 0.0, 1.0);
@ -108,6 +119,7 @@ float fractal_noise(vec4 p, float octaves, float roughness, float lacunarity, bo
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
float t = snoise(fscale * p);
t = hard ? abs(t) * 2.0 - 1.0 : t;
float sum2 = sum + t * amp;
return normalize ? mix(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) :
mix(sum, sum2, rmd);

View File

@ -48,6 +48,7 @@ void node_noise_texture_1d(vec3 co,
float lacunarity,
float distortion,
float normalize,
float hard,
out float value,
out vec4 color)
{
@ -56,12 +57,21 @@ void node_noise_texture_1d(vec3 co,
p += snoise(p + random_float_offset(0.0)) * distortion;
}
value = fractal_noise(p, detail, roughness, lacunarity, normalize != 0.0);
color = vec4(
value,
fractal_noise(p + random_float_offset(1.0), detail, roughness, lacunarity, normalize != 0.0),
fractal_noise(p + random_float_offset(2.0), detail, roughness, lacunarity, normalize != 0.0),
1.0);
value = fractal_noise(p, detail, roughness, lacunarity, normalize != 0.0, hard != 0.0);
color = vec4(value,
fractal_noise(p + random_float_offset(1.0),
detail,
roughness,
lacunarity,
normalize != 0.0,
hard != 0.0),
fractal_noise(p + random_float_offset(2.0),
detail,
roughness,
lacunarity,
normalize != 0.0,
hard != 0.0),
1.0);
}
void node_noise_texture_2d(vec3 co,
@ -72,6 +82,7 @@ void node_noise_texture_2d(vec3 co,
float lacunarity,
float distortion,
float normalize,
float hard,
out float value,
out vec4 color)
{
@ -81,12 +92,21 @@ void node_noise_texture_2d(vec3 co,
snoise(p + random_vec2_offset(1.0)) * distortion);
}
value = fractal_noise(p, detail, roughness, lacunarity, normalize != 0.0);
color = vec4(
value,
fractal_noise(p + random_vec2_offset(2.0), detail, roughness, lacunarity, normalize != 0.0),
fractal_noise(p + random_vec2_offset(3.0), detail, roughness, lacunarity, normalize != 0.0),
1.0);
value = fractal_noise(p, detail, roughness, lacunarity, normalize != 0.0, hard != 0.0);
color = vec4(value,
fractal_noise(p + random_vec2_offset(2.0),
detail,
roughness,
lacunarity,
normalize != 0.0,
hard != 0.0),
fractal_noise(p + random_vec2_offset(3.0),
detail,
roughness,
lacunarity,
normalize != 0.0,
hard != 0.0),
1.0);
}
void node_noise_texture_3d(vec3 co,
@ -97,6 +117,7 @@ void node_noise_texture_3d(vec3 co,
float lacunarity,
float distortion,
float normalize,
float hard,
out float value,
out vec4 color)
{
@ -107,12 +128,21 @@ void node_noise_texture_3d(vec3 co,
snoise(p + random_vec3_offset(2.0)) * distortion);
}
value = fractal_noise(p, detail, roughness, lacunarity, normalize != 0.0);
color = vec4(
value,
fractal_noise(p + random_vec3_offset(3.0), detail, roughness, lacunarity, normalize != 0.0),
fractal_noise(p + random_vec3_offset(4.0), detail, roughness, lacunarity, normalize != 0.0),
1.0);
value = fractal_noise(p, detail, roughness, lacunarity, normalize != 0.0, hard != 0.0);
color = vec4(value,
fractal_noise(p + random_vec3_offset(3.0),
detail,
roughness,
lacunarity,
normalize != 0.0,
hard != 0.0),
fractal_noise(p + random_vec3_offset(4.0),
detail,
roughness,
lacunarity,
normalize != 0.0,
hard != 0.0),
1.0);
}
void node_noise_texture_4d(vec3 co,
@ -123,6 +153,7 @@ void node_noise_texture_4d(vec3 co,
float lacunarity,
float distortion,
float normalize,
float hard,
out float value,
out vec4 color)
{
@ -134,10 +165,19 @@ void node_noise_texture_4d(vec3 co,
snoise(p + random_vec4_offset(3.0)) * distortion);
}
value = fractal_noise(p, detail, roughness, lacunarity, normalize != 0.0);
color = vec4(
value,
fractal_noise(p + random_vec4_offset(4.0), detail, roughness, lacunarity, normalize != 0.0),
fractal_noise(p + random_vec4_offset(5.0), detail, roughness, lacunarity, normalize != 0.0),
1.0);
value = fractal_noise(p, detail, roughness, lacunarity, normalize != 0.0, hard != 0.0);
color = vec4(value,
fractal_noise(p + random_vec4_offset(4.0),
detail,
roughness,
lacunarity,
normalize != 0.0,
hard != 0.0),
fractal_noise(p + random_vec4_offset(5.0),
detail,
roughness,
lacunarity,
normalize != 0.0,
hard != 0.0),
1.0);
}

View File

@ -56,7 +56,7 @@ float calc_wave(vec3 p,
if (distortion != 0.0) {
n += distortion *
(fractal_noise(p * detail_scale, detail, detail_roughness, 2.0, true) * 2.0 - 1.0);
(fractal_noise(p * detail_scale, detail, detail_roughness, 2.0, true, false) * 2.0 - 1.0);
}
if (wave_profile == 0) { /* profile sin */

View File

@ -1260,7 +1260,8 @@ typedef struct NodeTexNoise {
NodeTexBase base;
int dimensions;
uint8_t normalize;
char _pad[3];
uint8_t hard;
char _pad[2];
} NodeTexNoise;
typedef struct NodeTexVoronoi {

View File

@ -4931,6 +4931,11 @@ static void def_sh_tex_noise(StructRNA *srna)
RNA_def_property_boolean_sdna(prop, nullptr, "normalize", 0);
RNA_def_property_ui_text(prop, "Normalize", "Normalize outputs to 0.0 to 1.0 range");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "hard", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "hard", 0);
RNA_def_property_ui_text(prop, "Hard", "Specifies whether noise is hard (sharp transitions) ");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_sh_tex_checker(StructRNA *srna)

View File

@ -47,6 +47,7 @@ static void node_shader_buts_tex_noise(uiLayout *layout, bContext * /*C*/, Point
{
uiItemR(layout, ptr, "noise_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "normalize", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
uiItemR(layout, ptr, "hard", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
}
static void node_shader_init_tex_noise(bNodeTree * /*ntree*/, bNode *node)
@ -56,6 +57,7 @@ static void node_shader_init_tex_noise(bNodeTree * /*ntree*/, bNode *node)
BKE_texture_colormapping_default(&tex->base.color_mapping);
tex->dimensions = 3;
tex->normalize = true;
tex->hard = false;
node->storage = tex;
}
@ -81,9 +83,10 @@ static int node_shader_gpu_tex_noise(GPUMaterial *mat,
const NodeTexNoise &storage = node_storage(*node);
float normalize = storage.normalize;
float hard = storage.hard;
const char *name = gpu_shader_get_name(storage.dimensions);
return GPU_stack_link(mat, node, name, in, out, GPU_constant(&normalize));
return GPU_stack_link(mat, node, name, in, out, GPU_constant(&normalize), GPU_constant(&hard));
}
static void node_shader_update_tex_noise(bNodeTree *ntree, bNode *node)
@ -100,9 +103,11 @@ class NoiseFunction : public mf::MultiFunction {
private:
int dimensions_;
bool normalize_;
bool hard_;
public:
NoiseFunction(int dimensions, bool normalize) : dimensions_(dimensions), normalize_(normalize)
NoiseFunction(int dimensions, bool normalize, bool hard)
: dimensions_(dimensions), normalize_(normalize), hard_(hard)
{
BLI_assert(dimensions >= 1 && dimensions <= 4);
static std::array<mf::Signature, 4> signatures{
@ -161,15 +166,25 @@ class NoiseFunction : public mf::MultiFunction {
if (compute_factor) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], lacunarity[i], distortion[i], normalize_);
r_factor[i] = noise::perlin_fractal_distorted(position,
detail[i],
roughness[i],
lacunarity[i],
distortion[i],
normalize_,
hard_);
});
}
if (compute_color) {
mask.foreach_index([&](const int64_t i) {
const float position = w[i] * scale[i];
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], lacunarity[i], distortion[i], normalize_);
const float3 c = noise::perlin_float3_fractal_distorted(position,
detail[i],
roughness[i],
lacunarity[i],
distortion[i],
normalize_,
hard_);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
});
}
@ -180,15 +195,25 @@ class NoiseFunction : public mf::MultiFunction {
if (compute_factor) {
mask.foreach_index([&](const int64_t i) {
const float2 position = float2(vector[i] * scale[i]);
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], lacunarity[i], distortion[i], normalize_);
r_factor[i] = noise::perlin_fractal_distorted(position,
detail[i],
roughness[i],
lacunarity[i],
distortion[i],
normalize_,
hard_);
});
}
if (compute_color) {
mask.foreach_index([&](const int64_t i) {
const float2 position = float2(vector[i] * scale[i]);
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], lacunarity[i], distortion[i], normalize_);
const float3 c = noise::perlin_float3_fractal_distorted(position,
detail[i],
roughness[i],
lacunarity[i],
distortion[i],
normalize_,
hard_);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
});
}
@ -199,15 +224,25 @@ class NoiseFunction : public mf::MultiFunction {
if (compute_factor) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], lacunarity[i], distortion[i], normalize_);
r_factor[i] = noise::perlin_fractal_distorted(position,
detail[i],
roughness[i],
lacunarity[i],
distortion[i],
normalize_,
hard_);
});
}
if (compute_color) {
mask.foreach_index([&](const int64_t i) {
const float3 position = vector[i] * scale[i];
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], lacunarity[i], distortion[i], normalize_);
const float3 c = noise::perlin_float3_fractal_distorted(position,
detail[i],
roughness[i],
lacunarity[i],
distortion[i],
normalize_,
hard_);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
});
}
@ -222,8 +257,13 @@ class NoiseFunction : public mf::MultiFunction {
const float position_w = w[i] * scale[i];
const float4 position{
position_vector[0], position_vector[1], position_vector[2], position_w};
r_factor[i] = noise::perlin_fractal_distorted(
position, detail[i], roughness[i], lacunarity[i], distortion[i], normalize_);
r_factor[i] = noise::perlin_fractal_distorted(position,
detail[i],
roughness[i],
lacunarity[i],
distortion[i],
normalize_,
hard_);
});
}
if (compute_color) {
@ -232,8 +272,13 @@ class NoiseFunction : public mf::MultiFunction {
const float position_w = w[i] * scale[i];
const float4 position{
position_vector[0], position_vector[1], position_vector[2], position_w};
const float3 c = noise::perlin_float3_fractal_distorted(
position, detail[i], roughness[i], lacunarity[i], distortion[i], normalize_);
const float3 c = noise::perlin_float3_fractal_distorted(position,
detail[i],
roughness[i],
lacunarity[i],
distortion[i],
normalize_,
hard_);
r_color[i] = ColorGeometry4f(c[0], c[1], c[2], 1.0f);
});
}
@ -254,7 +299,8 @@ class NoiseFunction : public mf::MultiFunction {
static void sh_node_noise_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const NodeTexNoise &storage = node_storage(builder.node());
builder.construct_and_set_matching_fn<NoiseFunction>(storage.dimensions, storage.normalize);
builder.construct_and_set_matching_fn<NoiseFunction>(
storage.dimensions, storage.normalize, storage.hard);
}
} // namespace blender::nodes::node_shader_tex_noise_cc

View File

@ -183,7 +183,7 @@ class WaveFunction : public mf::MultiFunction {
if (distortion[i] != 0.0f) {
n += distortion[i] *
(noise::perlin_fractal(p * dscale[i], detail[i], droughness[i], 2.0f, true) * 2.0f -
(noise::perlin_fractal(p * dscale[i], detail[i], droughness[i], 2.0f, true, false) * 2.0f -
1.0f);
}