Fix T55284: error in Hybrid MultiFractal Musgrave texture

The calculation was revised to address two issues:
* Discontinuities occurring when detail was a non-integer greater than 2.
* Levels of detail in the interval [0,1) repeating the levels of detail in
  the interval [1,2).

This fixes Cycles, Eevee and geometry nodes.

Differential Revision: https://developer.blender.org/D15785
This commit is contained in:
Luis Pereira 2022-08-26 15:30:59 +02:00 committed by Brecht Van Lommel
parent a1c8a17b4d
commit 763cafc2b1
Notes: blender-bot 2023-06-26 11:58:59 +02:00
Referenced by issue #55284, Hybrid Multifractal bug in formula
4 changed files with 161 additions and 112 deletions

View File

@ -114,13 +114,12 @@ float noise_musgrave_hybrid_multi_fractal_1d(
{
float p = co;
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
float value = safe_snoise(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0;
float value = 0.0;
float weight = 1.0;
for (int i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
for (int i = 0; (weight > 0.001) && (i < (int)octaves); i++) {
if (weight > 1.0) {
weight = 1.0;
}
@ -133,8 +132,12 @@ float noise_musgrave_hybrid_multi_fractal_1d(
}
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
value += rmd * ((safe_snoise(p) + offset) * pwr);
if ((rmd != 0.0) && (weight > 0.001)) {
if (weight > 1.0) {
weight = 1.0;
}
float signal = (safe_snoise(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -279,13 +282,12 @@ float noise_musgrave_hybrid_multi_fractal_2d(
{
vector2 p = co;
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
float value = safe_snoise(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0;
float value = 0.0;
float weight = 1.0;
for (int i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
for (int i = 0; (weight > 0.001) && (i < (int)octaves); i++) {
if (weight > 1.0) {
weight = 1.0;
}
@ -298,8 +300,12 @@ float noise_musgrave_hybrid_multi_fractal_2d(
}
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
value += rmd * ((safe_snoise(p) + offset) * pwr);
if ((rmd != 0.0) && (weight > 0.001)) {
if (weight > 1.0) {
weight = 1.0;
}
float signal = (safe_snoise(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -444,13 +450,12 @@ float noise_musgrave_hybrid_multi_fractal_3d(
{
vector3 p = co;
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
float value = safe_snoise(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0;
float value = 0.0;
float weight = 1.0;
for (int i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
for (int i = 0; (weight > 0.001) && (i < (int)octaves); i++) {
if (weight > 1.0) {
weight = 1.0;
}
@ -463,8 +468,12 @@ float noise_musgrave_hybrid_multi_fractal_3d(
}
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
value += rmd * ((safe_snoise(p) + offset) * pwr);
if ((rmd != 0.0) && (weight > 0.001)) {
if (weight > 1.0) {
weight = 1.0;
}
float signal = (safe_snoise(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -609,13 +618,12 @@ float noise_musgrave_hybrid_multi_fractal_4d(
{
vector4 p = co;
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
float value = safe_snoise(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0;
float value = 0.0;
float weight = 1.0;
for (int i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
for (int i = 0; (weight > 0.001) && (i < (int)octaves); i++) {
if (weight > 1.0) {
weight = 1.0;
}
@ -628,8 +636,12 @@ float noise_musgrave_hybrid_multi_fractal_4d(
}
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
value += rmd * ((safe_snoise(p) + offset) * pwr);
if ((rmd != 0.0) && (weight > 0.001)) {
if (weight > 1.0) {
weight = 1.0;
}
float signal = (safe_snoise(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;

View File

@ -119,13 +119,12 @@ ccl_device_noinline_cpu float noise_musgrave_hybrid_multi_fractal_1d(
{
float p = co;
float pwHL = powf(lacunarity, -H);
float pwr = pwHL;
float value = snoise_1d(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0f;
float value = 0.0f;
float weight = 1.0f;
for (int i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
for (int i = 0; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@ -138,8 +137,12 @@ ccl_device_noinline_cpu float noise_musgrave_hybrid_multi_fractal_1d(
}
float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
value += rmd * ((snoise_1d(p) + offset) * pwr);
if ((rmd != 0.0f) && (weight > 0.001f)) {
if (weight > 1.0f) {
weight = 1.0f;
}
float signal = (snoise_1d(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -290,13 +293,12 @@ ccl_device_noinline_cpu float noise_musgrave_hybrid_multi_fractal_2d(
{
float2 p = co;
float pwHL = powf(lacunarity, -H);
float pwr = pwHL;
float value = snoise_2d(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0f;
float value = 0.0f;
float weight = 1.0f;
for (int i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
for (int i = 0; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@ -309,8 +311,12 @@ ccl_device_noinline_cpu float noise_musgrave_hybrid_multi_fractal_2d(
}
float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
value += rmd * ((snoise_2d(p) + offset) * pwr);
if ((rmd != 0.0f) && (weight > 0.001f)) {
if (weight > 1.0f) {
weight = 1.0f;
}
float signal = (snoise_2d(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -461,13 +467,13 @@ ccl_device_noinline_cpu float noise_musgrave_hybrid_multi_fractal_3d(
{
float3 p = co;
float pwHL = powf(lacunarity, -H);
float pwr = pwHL;
float value = snoise_3d(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0f;
float value = 0.0f;
float weight = 1.0f;
for (int i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
for (int i = 0; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@ -480,8 +486,12 @@ ccl_device_noinline_cpu float noise_musgrave_hybrid_multi_fractal_3d(
}
float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
value += rmd * ((snoise_3d(p) + offset) * pwr);
if ((rmd != 0.0f) && (weight > 0.001f)){
if (weight > 1.0f) {
weight = 1.0f;
}
float signal = (snoise_3d(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -632,13 +642,12 @@ ccl_device_noinline_cpu float noise_musgrave_hybrid_multi_fractal_4d(
{
float4 p = co;
float pwHL = powf(lacunarity, -H);
float pwr = pwHL;
float value = snoise_4d(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0f;
float value = 0.0f;
float weight = 1.0f;
for (int i = 1; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
for (int i = 0; (weight > 0.001f) && (i < float_to_int(octaves)); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@ -651,8 +660,12 @@ ccl_device_noinline_cpu float noise_musgrave_hybrid_multi_fractal_4d(
}
float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
value += rmd * ((snoise_4d(p) + offset) * pwr);
if ((rmd != 0.0f) && (weight > 0.001f)) {
if (weight > 1.0f) {
weight = 1.0f;
}
float signal = (snoise_4d(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;

View File

@ -809,15 +809,14 @@ float musgrave_hybrid_multi_fractal(const float co,
{
float p = co;
const float pwHL = std::pow(lacunarity, -H);
float pwr = pwHL;
float value = perlin_signed(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0f;
float value = 0.0f;
float weight = 1.0f;
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@ -830,8 +829,12 @@ float musgrave_hybrid_multi_fractal(const float co,
}
const float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
value += rmd * ((perlin_signed(p) + offset) * pwr);
if ((rmd != 0.0f) && (weight > 0.001f)) {
if (weight > 1.0f) {
weight = 1.0f;
}
float signal = (perlin_signed(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -961,15 +964,14 @@ float musgrave_hybrid_multi_fractal(const float2 co,
{
float2 p = co;
const float pwHL = std::pow(lacunarity, -H);
float pwr = pwHL;
float value = perlin_signed(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0f;
float value = 0.0f;
float weight = 1.0f;
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@ -982,8 +984,12 @@ float musgrave_hybrid_multi_fractal(const float2 co,
}
const float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
value += rmd * ((perlin_signed(p) + offset) * pwr);
if ((rmd != 0.0f) && (weight > 0.001f)) {
if (weight > 1.0f) {
weight = 1.0f;
}
float signal = (perlin_signed(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -1115,15 +1121,14 @@ float musgrave_hybrid_multi_fractal(const float3 co,
{
float3 p = co;
const float pwHL = std::pow(lacunarity, -H);
float pwr = pwHL;
float value = perlin_signed(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0f;
float value = 0.0f;
float weight = 1.0f;
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@ -1136,8 +1141,12 @@ float musgrave_hybrid_multi_fractal(const float3 co,
}
const float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
value += rmd * ((perlin_signed(p) + offset) * pwr);
if ((rmd != 0.0f) && (weight > 0.001f)) {
if (weight > 1.0f) {
weight = 1.0f;
}
float signal = (perlin_signed(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;
@ -1269,15 +1278,14 @@ float musgrave_hybrid_multi_fractal(const float4 co,
{
float4 p = co;
const float pwHL = std::pow(lacunarity, -H);
float pwr = pwHL;
float value = perlin_signed(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0f;
float value = 0.0f;
float weight = 1.0f;
const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
if (weight > 1.0f) {
weight = 1.0f;
}
@ -1290,8 +1298,12 @@ float musgrave_hybrid_multi_fractal(const float4 co,
}
const float rmd = octaves - floorf(octaves);
if (rmd != 0.0f) {
value += rmd * ((perlin_signed(p) + offset) * pwr);
if ((rmd != 0.0f) && (weight > 0.001f)) {
if (weight > 1.0f) {
weight = 1.0f;
}
float signal = (perlin_signed(p) + offset) * pwr;
value += rmd * weight * signal;
}
return value;

View File

@ -153,13 +153,12 @@ void node_tex_musgrave_hybrid_multi_fractal_1d(vec3 co,
float lacunarity = max(lac, 1e-5);
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
float value = snoise(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0;
float value = 0.0;
float weight = 1.0;
for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0) {
weight = 1.0;
}
@ -172,8 +171,12 @@ void node_tex_musgrave_hybrid_multi_fractal_1d(vec3 co,
}
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
value += rmd * ((snoise(p) + offset) * pwr);
if ((rmd != 0.0) && (weight > 0.001f)) {
if (weight > 1.0) {
weight = 1.0;
}
float signal = (snoise(p) + offset) * pwr;
value += rmd * weight * signal;
}
fac = value;
@ -375,13 +378,12 @@ void node_tex_musgrave_hybrid_multi_fractal_2d(vec3 co,
float lacunarity = max(lac, 1e-5);
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
float value = snoise(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0;
float value = 0.0;
float weight = 1.0;
for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0) {
weight = 1.0;
}
@ -394,8 +396,12 @@ void node_tex_musgrave_hybrid_multi_fractal_2d(vec3 co,
}
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
value += rmd * ((snoise(p) + offset) * pwr);
if ((rmd != 0.0) && (weight > 0.001f)) {
if (weight > 1.0) {
weight = 1.0;
}
float signal = (snoise(p) + offset) * pwr;
value += rmd * weight * signal;
}
fac = value;
@ -597,13 +603,12 @@ void node_tex_musgrave_hybrid_multi_fractal_3d(vec3 co,
float lacunarity = max(lac, 1e-5);
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
float value = snoise(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0;
float value = 0.0;
float weight = 1.0;
for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0) {
weight = 1.0;
}
@ -616,8 +621,12 @@ void node_tex_musgrave_hybrid_multi_fractal_3d(vec3 co,
}
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
value += rmd * ((snoise(p) + offset) * pwr);
if ((rmd != 0.0) && (weight > 0.001f)) {
if (weight > 1.0) {
weight = 1.0;
}
float signal = (snoise(p) + offset) * pwr;
value += rmd * weight * signal;
}
fac = value;
@ -819,13 +828,12 @@ void node_tex_musgrave_hybrid_multi_fractal_4d(vec3 co,
float lacunarity = max(lac, 1e-5);
float pwHL = pow(lacunarity, -H);
float pwr = pwHL;
float value = snoise(p) + offset;
float weight = gain * value;
p *= lacunarity;
float pwr = 1.0;
float value = 0.0;
float weight = 1.0;
for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
for (int i = 0; (weight > 0.001f) && (i < int(octaves)); i++) {
if (weight > 1.0) {
weight = 1.0;
}
@ -838,8 +846,12 @@ void node_tex_musgrave_hybrid_multi_fractal_4d(vec3 co,
}
float rmd = octaves - floor(octaves);
if (rmd != 0.0) {
value += rmd * ((snoise(p) + offset) * pwr);
if ((rmd != 0.0) && (weight > 0.001f)) {
if (weight > 1.0) {
weight = 1.0;
}
float signal = (snoise(p) + offset) * pwr;
value += rmd * weight * signal;
}
fac = value;