diff options
-rw-r--r-- | source/blender/blenlib/intern/noise.cc | 204 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc | 483 |
2 files changed, 512 insertions, 175 deletions
diff --git a/source/blender/blenlib/intern/noise.cc b/source/blender/blenlib/intern/noise.cc index 5fa2746d07f..4259237af6e 100644 --- a/source/blender/blenlib/intern/noise.cc +++ b/source/blender/blenlib/intern/noise.cc @@ -1528,9 +1528,15 @@ void voronoi_f1( targetPosition = pointPosition; } } - *r_distance = minDistance; - *r_color = hash_float_to_float3(cellPosition + targetOffset); - *r_w = targetPosition + cellPosition; + if (r_distance != nullptr) { + *r_distance = minDistance; + } + if (r_color != nullptr) { + *r_color = hash_float_to_float3(cellPosition + targetOffset); + } + if (r_w != nullptr) { + *r_w = targetPosition + cellPosition; + } } void voronoi_smooth_f1(const float w, @@ -1555,14 +1561,26 @@ void voronoi_smooth_f1(const float w, 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness); float correctionFactor = smoothness * h * (1.0f - h); smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor; - correctionFactor /= 1.0f + 3.0f * smoothness; - const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset); - smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor; - smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor; + if (r_color != nullptr || r_w != nullptr) { + correctionFactor /= 1.0f + 3.0f * smoothness; + if (r_color != nullptr) { + const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset); + smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor; + } + if (r_w != nullptr) { + smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor; + } + } + } + if (r_distance != nullptr) { + *r_distance = smoothDistance; + } + if (r_color != nullptr) { + *r_color = smoothColor; + } + if (r_w != nullptr) { + *r_w = cellPosition + smoothPosition; } - *r_distance = smoothDistance; - *r_color = smoothColor; - *r_w = cellPosition + smoothPosition; } void voronoi_f2( @@ -1596,9 +1614,15 @@ void voronoi_f2( positionF2 = pointPosition; } } - *r_distance = distanceF2; - *r_color = hash_float_to_float3(cellPosition + offsetF2); - *r_w = positionF2 + cellPosition; + if (r_distance != nullptr) { + *r_distance = distanceF2; + } + if (r_color != nullptr) { + *r_color = hash_float_to_float3(cellPosition + offsetF2); + } + if (r_w != nullptr) { + *r_w = positionF2 + cellPosition; + } } void voronoi_distance_to_edge(const float w, const float randomness, float *r_distance) @@ -1706,9 +1730,15 @@ void voronoi_f1(const float2 coord, } } } - *r_distance = minDistance; - *r_color = hash_float_to_float3(cellPosition + targetOffset); - *r_position = targetPosition + cellPosition; + if (r_distance != nullptr) { + *r_distance = minDistance; + } + if (r_color != nullptr) { + *r_color = hash_float_to_float3(cellPosition + targetOffset); + } + if (r_position != nullptr) { + *r_position = targetPosition + cellPosition; + } } void voronoi_smooth_f1(const float2 coord, @@ -1737,15 +1767,28 @@ void voronoi_smooth_f1(const float2 coord, 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness); float correctionFactor = smoothness * h * (1.0f - h); smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor; - correctionFactor /= 1.0f + 3.0f * smoothness; - const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset); - smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor; - smoothPosition = float2::interpolate(smoothPosition, pointPosition, h) - correctionFactor; + if (r_color != nullptr || r_position != nullptr) { + correctionFactor /= 1.0f + 3.0f * smoothness; + if (r_color != nullptr) { + const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset); + smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor; + } + if (r_position != nullptr) { + smoothPosition = float2::interpolate(smoothPosition, pointPosition, h) - + correctionFactor; + } + } } } - *r_distance = smoothDistance; - *r_color = smoothColor; - *r_position = cellPosition + smoothPosition; + if (r_distance != nullptr) { + *r_distance = smoothDistance; + } + if (r_color != nullptr) { + *r_color = smoothColor; + } + if (r_position != nullptr) { + *r_position = cellPosition + smoothPosition; + } } void voronoi_f2(const float2 coord, @@ -1787,9 +1830,15 @@ void voronoi_f2(const float2 coord, } } } - *r_distance = distanceF2; - *r_color = hash_float_to_float3(cellPosition + offsetF2); - *r_position = positionF2 + cellPosition; + if (r_distance != nullptr) { + *r_distance = distanceF2; + } + if (r_color != nullptr) { + *r_color = hash_float_to_float3(cellPosition + offsetF2); + } + if (r_position != nullptr) { + *r_position = positionF2 + cellPosition; + } } void voronoi_distance_to_edge(const float2 coord, const float randomness, float *r_distance) @@ -1928,9 +1977,15 @@ void voronoi_f1(const float3 coord, } } } - *r_distance = minDistance; - *r_color = hash_float_to_float3(cellPosition + targetOffset); - *r_position = targetPosition + cellPosition; + if (r_distance != nullptr) { + *r_distance = minDistance; + } + if (r_color != nullptr) { + *r_color = hash_float_to_float3(cellPosition + targetOffset); + } + if (r_position != nullptr) { + *r_position = targetPosition + cellPosition; + } } void voronoi_smooth_f1(const float3 coord, @@ -1960,16 +2015,29 @@ void voronoi_smooth_f1(const float3 coord, 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness); float correctionFactor = smoothness * h * (1.0f - h); smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor; - correctionFactor /= 1.0f + 3.0f * smoothness; - const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset); - smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor; - smoothPosition = float3::interpolate(smoothPosition, pointPosition, h) - correctionFactor; + if (r_color != nullptr || r_position != nullptr) { + correctionFactor /= 1.0f + 3.0f * smoothness; + if (r_color != nullptr) { + const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset); + smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor; + } + if (r_position != nullptr) { + smoothPosition = float3::interpolate(smoothPosition, pointPosition, h) - + correctionFactor; + } + } } } } - *r_distance = smoothDistance; - *r_color = smoothColor; - *r_position = cellPosition + smoothPosition; + if (r_distance != nullptr) { + *r_distance = smoothDistance; + } + if (r_color != nullptr) { + *r_color = smoothColor; + } + if (r_position != nullptr) { + *r_position = cellPosition + smoothPosition; + } } void voronoi_f2(const float3 coord, @@ -2013,9 +2081,15 @@ void voronoi_f2(const float3 coord, } } } - *r_distance = distanceF2; - *r_color = hash_float_to_float3(cellPosition + offsetF2); - *r_position = positionF2 + cellPosition; + if (r_distance != nullptr) { + *r_distance = distanceF2; + } + if (r_color != nullptr) { + *r_color = hash_float_to_float3(cellPosition + offsetF2); + } + if (r_position != nullptr) { + *r_position = positionF2 + cellPosition; + } } void voronoi_distance_to_edge(const float3 coord, const float randomness, float *r_distance) @@ -2166,9 +2240,15 @@ void voronoi_f1(const float4 coord, } } } - *r_distance = minDistance; - *r_color = hash_float_to_float3(cellPosition + targetOffset); - *r_position = targetPosition + cellPosition; + if (r_distance != nullptr) { + *r_distance = minDistance; + } + if (r_color != nullptr) { + *r_color = hash_float_to_float3(cellPosition + targetOffset); + } + if (r_position != nullptr) { + *r_position = targetPosition + cellPosition; + } } void voronoi_smooth_f1(const float4 coord, @@ -2200,18 +2280,30 @@ void voronoi_smooth_f1(const float4 coord, 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness); float correctionFactor = smoothness * h * (1.0f - h); smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor; - correctionFactor /= 1.0f + 3.0f * smoothness; - const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset); - smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor; - smoothPosition = float4::interpolate(smoothPosition, pointPosition, h) - - correctionFactor; + if (r_color != nullptr || r_position != nullptr) { + correctionFactor /= 1.0f + 3.0f * smoothness; + if (r_color != nullptr) { + const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset); + smoothColor = float3::interpolate(smoothColor, cellColor, h) - correctionFactor; + } + if (r_position != nullptr) { + smoothPosition = float4::interpolate(smoothPosition, pointPosition, h) - + correctionFactor; + } + } } } } } - *r_distance = smoothDistance; - *r_color = smoothColor; - *r_position = cellPosition + smoothPosition; + if (r_distance != nullptr) { + *r_distance = smoothDistance; + } + if (r_color != nullptr) { + *r_color = smoothColor; + } + if (r_position != nullptr) { + *r_position = cellPosition + smoothPosition; + } } void voronoi_f2(const float4 coord, @@ -2258,9 +2350,15 @@ void voronoi_f2(const float4 coord, } } } - *r_distance = distanceF2; - *r_color = hash_float_to_float3(cellPosition + offsetF2); - *r_position = positionF2 + cellPosition; + if (r_distance != nullptr) { + *r_distance = distanceF2; + } + if (r_color != nullptr) { + *r_color = hash_float_to_float3(cellPosition + offsetF2); + } + if (r_position != nullptr) { + *r_position = positionF2 + cellPosition; + } } void voronoi_distance_to_edge(const float4 coord, const float randomness, float *r_distance) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc index 574260f3c36..9fcc331e486 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc @@ -239,16 +239,16 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { return params.readonly_single_input<float>(param_index, "Randomness"); }; auto get_r_distance = [&](int param_index) -> MutableSpan<float> { - return params.uninitialized_single_output<float>(param_index, "Distance"); + return params.uninitialized_single_output_if_required<float>(param_index, "Distance"); }; auto get_r_color = [&](int param_index) -> MutableSpan<ColorGeometry4f> { - return params.uninitialized_single_output<ColorGeometry4f>(param_index, "Color"); + return params.uninitialized_single_output_if_required<ColorGeometry4f>(param_index, "Color"); }; auto get_r_position = [&](int param_index) -> MutableSpan<float3> { - return params.uninitialized_single_output<float3>(param_index, "Position"); + return params.uninitialized_single_output_if_required<float3>(param_index, "Position"); }; auto get_r_w = [&](int param_index) -> MutableSpan<float> { - return params.uninitialized_single_output<float>(param_index, "W"); + return params.uninitialized_single_output_if_required<float>(param_index, "W"); }; int param = 0; @@ -263,6 +263,9 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; @@ -271,12 +274,16 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { exponent[i], rand, SHD_VORONOI_MINKOWSKI, - &r_distance[i], - &col, - &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float2::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, 0.0f); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + pos = float2::safe_divide(pos, scale[i]); + r_position[i] = float3(pos.x, pos.y, 0.0f); + } } break; } @@ -288,6 +295,9 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; @@ -296,12 +306,16 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { exponent[i], rand, SHD_VORONOI_MINKOWSKI, - &r_distance[i], - &col, - &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float2::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, 0.0f); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + pos = float2::safe_divide(pos, scale[i]); + r_position[i] = float3(pos.x, pos.y, 0.0f); + } } break; } @@ -314,6 +328,9 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f); const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); @@ -324,12 +341,16 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { exponent[i], rand, SHD_VORONOI_MINKOWSKI, - &r_distance[i], - &col, - &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float2::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, 0.0f); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + pos = float2::safe_divide(pos, scale[i]); + r_position[i] = float3(pos.x, pos.y, 0.0f); + } } break; } @@ -346,6 +367,9 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; @@ -353,11 +377,15 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { exponent[i], rand, SHD_VORONOI_MINKOWSKI, - &r_distance[i], - &col, - &r_position[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_position[i] = float3::safe_divide(r_position[i], scale[i]); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &r_position[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + r_position[i] = float3::safe_divide(r_position[i], scale[i]); + } } break; } @@ -369,6 +397,9 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; @@ -376,11 +407,15 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { exponent[i], rand, SHD_VORONOI_MINKOWSKI, - &r_distance[i], - &col, - &r_position[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_position[i] = float3::safe_divide(r_position[i], scale[i]); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &r_position[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + r_position[i] = float3::safe_divide(r_position[i], scale[i]); + } } break; } @@ -393,6 +428,9 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f); const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); @@ -402,11 +440,15 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { exponent[i], rand, SHD_VORONOI_MINKOWSKI, - &r_distance[i], - &col, - &r_position[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_position[i] = float3::safe_divide(r_position[i], scale[i]); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &r_position[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + r_position[i] = float3::safe_divide(r_position[i], scale[i]); + } } break; } @@ -425,16 +467,34 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i]; float3 col; float4 pos; - noise::voronoi_f1(p, exponent[i], rand, SHD_VORONOI_F1, &r_distance[i], &col, &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float4::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, pos.z); - r_w[i] = pos.w; + noise::voronoi_f1(p, + exponent[i], + rand, + SHD_VORONOI_F1, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position || calc_w ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position || calc_w) { + pos = float4::safe_divide(pos, scale[i]); + if (calc_position) { + r_position[i] = float3(pos.x, pos.y, pos.z); + } + if (calc_w) { + r_w[i] = pos.w; + } + } } break; } @@ -448,17 +508,34 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i]; float3 col; float4 pos; - noise::voronoi_f2( - p, exponent[i], rand, SHD_VORONOI_MINKOWSKI, &r_distance[i], &col, &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float4::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, pos.z); - r_w[i] = pos.w; + noise::voronoi_f2(p, + exponent[i], + rand, + SHD_VORONOI_MINKOWSKI, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position || calc_w ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position || calc_w) { + pos = float4::safe_divide(pos, scale[i]); + if (calc_position) { + r_position[i] = float3(pos.x, pos.y, pos.z); + } + if (calc_w) { + r_w[i] = pos.w; + } + } } break; } @@ -473,18 +550,36 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f); const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i]; float3 col; float4 pos; - noise::voronoi_smooth_f1( - p, smth, exponent[i], rand, SHD_VORONOI_MINKOWSKI, &r_distance[i], &col, &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float4::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, pos.z); - r_w[i] = pos.w; + noise::voronoi_smooth_f1(p, + smth, + exponent[i], + rand, + SHD_VORONOI_MINKOWSKI, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position || calc_w ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position || calc_w) { + pos = float4::safe_divide(pos, scale[i]); + if (calc_position) { + r_position[i] = float3(pos.x, pos.y, pos.z); + } + if (calc_w) { + r_w[i] = pos.w; + } + } } break; } @@ -572,16 +667,16 @@ class VoronoiMetricFunction : public fn::MultiFunction { return params.readonly_single_input<float>(param_index, "Randomness"); }; auto get_r_distance = [&](int param_index) -> MutableSpan<float> { - return params.uninitialized_single_output<float>(param_index, "Distance"); + return params.uninitialized_single_output_if_required<float>(param_index, "Distance"); }; auto get_r_color = [&](int param_index) -> MutableSpan<ColorGeometry4f> { - return params.uninitialized_single_output<ColorGeometry4f>(param_index, "Color"); + return params.uninitialized_single_output_if_required<ColorGeometry4f>(param_index, "Color"); }; auto get_r_position = [&](int param_index) -> MutableSpan<float3> { - return params.uninitialized_single_output<float3>(param_index, "Position"); + return params.uninitialized_single_output_if_required<float3>(param_index, "Position"); }; auto get_r_w = [&](int param_index) -> MutableSpan<float> { - return params.uninitialized_single_output<float>(param_index, "W"); + return params.uninitialized_single_output_if_required<float>(param_index, "W"); }; int param = 0; @@ -595,13 +690,24 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float p = w[i] * scale[i]; const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; - noise::voronoi_f1(p, rand, &r_distance[i], &col, &r_w[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_w[i] = safe_divide(r_w[i], scale[i]); + noise::voronoi_f1(p, + rand, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_w ? &r_w[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_w) { + r_w[i] = safe_divide(r_w[i], scale[i]); + } } break; } @@ -612,13 +718,24 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float p = w[i] * scale[i]; const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; - noise::voronoi_f2(p, rand, &r_distance[i], &col, &r_w[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_w[i] = safe_divide(r_w[i], scale[i]); + noise::voronoi_f2(p, + rand, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_w ? &r_w[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_w) { + r_w[i] = safe_divide(r_w[i], scale[i]); + } } break; } @@ -630,14 +747,26 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float p = w[i] * scale[i]; const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f); const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; - noise::voronoi_smooth_f1(p, smth, rand, &r_distance[i], &col, &r_w[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_w[i] = safe_divide(r_w[i], scale[i]); + noise::voronoi_smooth_f1(p, + smth, + rand, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_w ? &r_w[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_w) { + r_w[i] = safe_divide(r_w[i], scale[i]); + } } break; } @@ -653,6 +782,9 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; @@ -661,12 +793,16 @@ class VoronoiMetricFunction : public fn::MultiFunction { 0.0f, rand, metric_, - &r_distance[i], - &col, - &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float2::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, 0.0f); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + pos = float2::safe_divide(pos, scale[i]); + r_position[i] = float3(pos.x, pos.y, 0.0f); + } } break; } @@ -677,6 +813,9 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; @@ -685,12 +824,16 @@ class VoronoiMetricFunction : public fn::MultiFunction { 0.0f, rand, metric_, - &r_distance[i], - &col, - &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float2::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, 0.0f); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + pos = float2::safe_divide(pos, scale[i]); + r_position[i] = float3(pos.x, pos.y, 0.0f); + } } break; } @@ -702,6 +845,9 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f); const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); @@ -712,12 +858,16 @@ class VoronoiMetricFunction : public fn::MultiFunction { 0.0f, rand, metric_, - &r_distance[i], - &col, - &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float2::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, 0.0f); + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + pos = float2::safe_divide(pos, scale[i]); + r_position[i] = float3(pos.x, pos.y, 0.0f); + } } break; } @@ -733,13 +883,25 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; - noise::voronoi_f1( - vector[i] * scale[i], 0.0f, rand, metric_, &r_distance[i], &col, &r_position[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_position[i] = float3::safe_divide(r_position[i], scale[i]); + noise::voronoi_f1(vector[i] * scale[i], + 0.0f, + rand, + metric_, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &r_position[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + r_position[i] = float3::safe_divide(r_position[i], scale[i]); + } } break; } @@ -750,13 +912,25 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); float3 col; - noise::voronoi_f2( - vector[i] * scale[i], 0.0f, rand, metric_, &r_distance[i], &col, &r_position[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_position[i] = float3::safe_divide(r_position[i], scale[i]); + noise::voronoi_f2(vector[i] * scale[i], + 0.0f, + rand, + metric_, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &r_position[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + r_position[i] = float3::safe_divide(r_position[i], scale[i]); + } } break; } @@ -768,21 +942,31 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<float> r_distance = get_r_distance(param++); MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); - for (int64_t i : mask) { - const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f); - const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); - float3 col; - noise::voronoi_smooth_f1(vector[i] * scale[i], - smth, - 0.0f, - rand, - metric_, - &r_distance[i], - &col, - &r_position[i]); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - r_position[i] = float3::safe_divide(r_position[i], scale[i]); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); + { + for (int64_t i : mask) { + const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f); + const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); + float3 col; + noise::voronoi_smooth_f1(vector[i] * scale[i], + smth, + 0.0f, + rand, + metric_, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position ? &r_position[i] : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position) { + r_position[i] = float3::safe_divide(r_position[i], scale[i]); + } + } } + break; } } @@ -799,16 +983,34 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i]; float3 col; float4 pos; - noise::voronoi_f1(p, 0.0f, rand, metric_, &r_distance[i], &col, &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float4::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, pos.z); - r_w[i] = pos.w; + noise::voronoi_f1(p, + 0.0f, + rand, + metric_, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position || calc_w ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position || calc_w) { + pos = float4::safe_divide(pos, scale[i]); + if (calc_position) { + r_position[i] = float3(pos.x, pos.y, pos.z); + } + if (calc_w) { + r_w[i] = pos.w; + } + } } break; } @@ -821,16 +1023,34 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i]; float3 col; float4 pos; - noise::voronoi_f2(p, 0.0f, rand, metric_, &r_distance[i], &col, &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float4::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, pos.z); - r_w[i] = pos.w; + noise::voronoi_f2(p, + 0.0f, + rand, + metric_, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position || calc_w ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position || calc_w) { + pos = float4::safe_divide(pos, scale[i]); + if (calc_position) { + r_position[i] = float3(pos.x, pos.y, pos.z); + } + if (calc_w) { + r_w[i] = pos.w; + } + } } break; } @@ -844,17 +1064,36 @@ class VoronoiMetricFunction : public fn::MultiFunction { MutableSpan<ColorGeometry4f> r_color = get_r_color(param++); MutableSpan<float3> r_position = get_r_position(param++); MutableSpan<float> r_w = get_r_w(param++); + const bool calc_distance = !r_distance.is_empty(); + const bool calc_color = !r_color.is_empty(); + const bool calc_position = !r_position.is_empty(); + const bool calc_w = !r_w.is_empty(); for (int64_t i : mask) { const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f); const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f); const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i]; float3 col; float4 pos; - noise::voronoi_smooth_f1(p, smth, 0.0f, rand, metric_, &r_distance[i], &col, &pos); - r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); - pos = float4::safe_divide(pos, scale[i]); - r_position[i] = float3(pos.x, pos.y, pos.z); - r_w[i] = pos.w; + noise::voronoi_smooth_f1(p, + smth, + 0.0f, + rand, + metric_, + calc_distance ? &r_distance[i] : nullptr, + calc_color ? &col : nullptr, + calc_position || calc_w ? &pos : nullptr); + if (calc_color) { + r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f); + } + if (calc_position || calc_w) { + pos = float4::safe_divide(pos, scale[i]); + if (calc_position) { + r_position[i] = float3(pos.x, pos.y, pos.z); + } + if (calc_w) { + r_w[i] = pos.w; + } + } } break; } |