Add Fractal Voronoi Noise V.2 #106827

Merged
Jacques Lucke merged 77 commits from Hoshinova/blender:add-fractal-voronoi into main 2023-06-13 09:18:18 +02:00
6 changed files with 1112 additions and 1724 deletions
Showing only changes of commit 12a269d34f - Show all commits

File diff suppressed because it is too large Load Diff

@ -1 +1 @@
Subproject commit 4a581c54af9b92cb670d750951b9382160f10f3e
Subproject commit e398d3c4969a37ae2ecff388344dd780bc1cfe82

@ -1 +1 @@
Subproject commit 0b0052bd53ad8249ed07dfb87705c338af698bde
Subproject commit 90c87dd771e027e0ffa157a0e294399bfd605d99

View File

@ -304,12 +304,30 @@ float musgrave_hetero_terrain(
/** \name Voronoi Noise
* \{ */
void voronoi_f1(float w, float randomness, float *r_distance, float3 *r_color, float *r_w);
void voronoi_smooth_f1(
float w, float smoothness, float randomness, float *r_distance, float3 *r_color, float *r_w);
void voronoi_f2(float w, float randomness, float *r_distance, float3 *r_color, float *r_w);
void voronoi_distance_to_edge(float w, float randomness, float *r_distance);
void voronoi_n_sphere_radius(float w, float randomness, float *r_radius);
void voronoi_f1(const float w,
float exponent,
float randomness,
int metric,
float *r_distance,
float3 *r_color,
float *r_w);
void voronoi_smooth_f1(const float w,
float smoothness,
float exponent,
float randomness,
int metric,
float *r_distance,
float3 *r_color,
float *r_w);
void voronoi_f2(const float w,
float exponent,
float randomness,
int metric,
float *r_distance,
float3 *r_color,
float *r_w);
void voronoi_distance_to_edge(const float w, float randomness, float *r_distance);
void voronoi_n_sphere_radius(const float w, float randomness, float *r_radius);
void voronoi_f1(const float2 coord,
float exponent,
@ -386,6 +404,182 @@ void voronoi_f2(const float4 coord,
void voronoi_distance_to_edge(const float4 coord, float randomness, float *r_distance);
void voronoi_n_sphere_radius(const float4 coord, float randomness, float *r_radius);
/* Fractal Voronoi template functions */
template<typename T>
void fractal_voronoi_f1(const T coord,
const float detail,
const float roughness,
const float lacunarity,
const float exponent,
const float randomness,
const float max_distance,
float *max_amplitude,
const int metric,
float *r_distance,
float3 *r_color,
T *r_position)
{
float octave_scale = lacunarity;
float octave_amplitude = roughness;
float octave_distance = 0.0f;
for (int i = 0; i < int(detail); ++i) {
voronoi_f1(
coord * octave_scale, exponent, randomness, metric, &octave_distance, r_color, r_position);
*max_amplitude += max_distance * octave_amplitude;
if (r_distance != nullptr) {
*r_distance += octave_distance * octave_amplitude;
}
octave_scale *= lacunarity;
octave_amplitude *= roughness;
}
if (r_position != nullptr) {
*r_position /= octave_scale / lacunarity;
}
float remainder = detail - int(detail);
if (remainder != 0.0f) {
voronoi_f1(
coord * octave_scale, exponent, randomness, metric, &octave_distance, r_color, r_position);
*max_amplitude += max_distance * octave_amplitude;
float lerp_distance = *r_distance + octave_distance * octave_amplitude;
if (r_distance != nullptr) {
*r_distance = (1.0f - remainder) * (*r_distance) + remainder * lerp_distance;
}
if (r_position != nullptr) {
*r_position /= octave_scale;
}
}
}
template<typename T>
void fractal_voronoi_smooth_f1(const T coord,
const float detail,
const float roughness,
const float lacunarity,
const float smoothness,
const float exponent,
const float randomness,
const float max_distance,
float *max_amplitude,
const int metric,
float *r_distance,
float3 *r_color,
T *r_position)
{
float octave_scale = lacunarity;
float octave_amplitude = roughness;
float octave_distance = 0.0f;
for (int i = 0; i < int(detail); ++i) {
voronoi_smooth_f1(coord * octave_scale,
smoothness,
exponent,
randomness,
metric,
&octave_distance,
r_color,
r_position);
*max_amplitude += max_distance * octave_amplitude;
if (r_distance != nullptr) {
*r_distance += octave_distance * octave_amplitude;
}
octave_scale *= lacunarity;
octave_amplitude *= roughness;
}
if (r_position != nullptr) {
*r_position /= octave_scale / lacunarity;
}
float remainder = detail - int(detail);
if (remainder != 0.0f) {
voronoi_smooth_f1(coord * octave_scale,
smoothness,
exponent,
randomness,
metric,
&octave_distance,
r_color,
r_position);
*max_amplitude += max_distance * octave_amplitude;
float lerp_distance = *r_distance + octave_distance * octave_amplitude;
if (r_distance != nullptr) {
*r_distance = (1.0f - remainder) * (*r_distance) + remainder * lerp_distance;
}
if (r_position != nullptr) {
*r_position /= octave_scale;
}
}
}
template<typename T>
void fractal_voronoi_f2(const T coord,
const float detail,
const float roughness,
const float lacunarity,
const float exponent,
const float randomness,
const float max_distance,
float *max_amplitude,
const int metric,
float *r_distance,
float3 *r_color,
T *r_position)
{
float octave_scale = lacunarity;
float octave_amplitude = roughness;
float octave_distance = 0.0f;
for (int i = 0; i < int(detail); ++i) {
voronoi_f2(
coord * octave_scale, exponent, randomness, metric, &octave_distance, r_color, r_position);
*max_amplitude += max_distance * octave_amplitude;
if (r_distance != nullptr) {
*r_distance += octave_distance * octave_amplitude;
}
octave_scale *= lacunarity;
octave_amplitude *= roughness;
}
if (r_position != nullptr) {
*r_position /= octave_scale / lacunarity;
}
float remainder = detail - int(detail);
if (remainder != 0.0f) {
voronoi_f2(
coord * octave_scale, exponent, randomness, metric, &octave_distance, r_color, r_position);
*max_amplitude += max_distance * octave_amplitude;
float lerp_distance = *r_distance + octave_distance * octave_amplitude;
if (r_distance != nullptr) {
*r_distance = (1.0f - remainder) * (*r_distance) + remainder * lerp_distance;
}
if (r_position != nullptr) {
*r_position /= octave_scale;
}
}
}
template<typename T>
void fractal_voronoi_distance_to_edge(const T coord,
const float detail,
const float lacunarity,
const float randomness,
const bool normalize,
float *r_distance)
{
float octave_scale = lacunarity;
float octave_distance = 0.0f;
for (int i = 0; i < detail; ++i) {
voronoi_distance_to_edge(coord * octave_scale, randomness, &octave_distance);
*r_distance = std::min(*r_distance, octave_distance / octave_scale);
octave_scale *= lacunarity;
}
if (normalize) {
*r_distance *= octave_scale / lacunarity;
}
}
/** \} */
} // namespace blender::noise

View File

@ -1376,8 +1376,13 @@ BLI_INLINE float voronoi_distance(const float a, const float b)
return std::abs(b - a);
}
void voronoi_f1(
const float w, const float randomness, float *r_distance, float3 *r_color, float *r_w)
void voronoi_f1(const float w,
const float exponent,
const float randomness,
const int metric,
float *r_distance,
float3 *r_color,
float *r_w)
{
Hoshinova marked this conversation as resolved Outdated

Use UNUSED_VARS. Arguably, params shouldn't be passed in here in this case, but it's fine for now. Maybe it will be removed as part of a more general optimization pass on the code in the future.

Use `UNUSED_VARS`. Arguably, `params` shouldn't be passed in here in this case, but it's fine for now. Maybe it will be removed as part of a more general optimization pass on the code in the future.

/* params */ ?

`/* params */` ?

That's even better.

That's even better.
const float cellPosition = floorf(w);
const float localPosition = w - cellPosition;
@ -1409,7 +1414,9 @@ void voronoi_f1(
void voronoi_smooth_f1(const float w,
const float smoothness,
const float exponent,
const float randomness,
const int metric,
float *r_distance,
float3 *r_color,
float *r_w)
@ -1452,8 +1459,13 @@ void voronoi_smooth_f1(const float w,
}
}
void voronoi_f2(
const float w, const float randomness, float *r_distance, float3 *r_color, float *r_w)
void voronoi_f2(const float w,
const float exponent,
const float randomness,
const int metric,
float *r_distance,
float3 *r_color,
float *r_w)
{
const float cellPosition = floorf(w);
const float localPosition = w - cellPosition;
@ -2337,6 +2349,10 @@ void voronoi_n_sphere_radius(const float4 coord, const float randomness, float *
*r_radius = math::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
}
/* **** Fractal Voronoi **** */
/* The Fractal Voronoi template functions are defined in BLI_noise.hh */
/** \} */
} // namespace blender::noise

File diff suppressed because it is too large Load Diff