Аналитическая производная для трехмерного шума Перлина создает линейные артефакты

Я реализую трехмерный генератор сферических планет на основе шума Перлина, но получаю линейные артефакты при попытке использовать аналитическую производную в расчетах шума. Я вычисляю аналитическую производную, используя подход Майло Йипа: Аналитическая производная трехмерного шума Перлина

Например, при попытке использовать шум IQ:

float IQturbulence(float3 p, int octaves, float freq, float amp, float gain, float lacunarity)
{
    float sum = 0.5;
    float3 dsum = float3(0,0,0);
    for(int i = 0; i < octaves; i++) 
    {
        float4 n = noiseDeriv((p*freq), (i)/256.0);
        dsum += n.yzw;
        sum += amp * n.x / (1 + dot(dsum,dsum));
        freq *= lacunarity;
        amp *= gain;
    }
    return sum;
}

Я получаю эти артефакты линий сетки, которые выглядят так:

https://imgur.com/CaNrdZ3

Однако эти строки только появляются, когда я использую скалярное произведение (скаляр) производной при вычислении шума,

i.e.

(1 + dot(deriv,deriv))

независимо от того, используется ли это для модуляции усиления, частоты и т. д., всегда кажется, что это создает артефакты.

При использовании производной для деформации домена я не получаю линейных артефактов.

ex.

float4 n = noiseDeriv((p + 0.15 * dsum) * freq, (i)/256.0);

Это просто ограничение классического шума Перлина? Я немного не решаюсь полностью менять алгоритмы шума на этом этапе моего проекта. : /

  • Примечание: при вычислении производной я использую квинтические функции.

person onehand    schedule 07.10.2017    source источник
comment
Интересно, что на этой странице де Карпентье использует другую производную d (w * f) / df и включив это в свой окончательный расчет производной (см. его метод perlinNoiseDeriv). // Get the derivative d(w*f)/df float2 dwp = f * f * f * (f * (f * 36 - 75) + 40); // 36f^5 - 75f^4 + 40f^3 Это не вторая производная, поэтому я не уверен, для чего предназначена эта кривая. Есть ли какие-нибудь математические волшебники, которые могли бы знать, как включить это в уравнение Майло Йипа? :) де Карпентье предназначен только для 2D.   -  person onehand    schedule 08.10.2017


Ответы (1)


Поэтому я не уверен, что я где-то напортачил или что, но мне удалось успешно удалить артефакты, заменив этот раздел на производную x из решения Milo:

float nx = gx000
    + uP * (dot100 - dot000)
    + u  * (gx100 - gx000)
    + v  * (gx010 - gx000)
    + w  * (gx001 - gx000)
    + uP * v * (dot110 - dot010 - dot100 + dot000)
    + u * v *  (gx110 - gx010 - gx100 + gx000)
    + uP * w * (dot101 - dot001 - dot100 + dot000)
    + u * w *  (gx101 - gx001 - gx100 - gx000)
    + v * w *  (gx011 - gx001 - gx010 + gx000)
    + uP * v * w * (dot111 - dot011 - dot101 + dot001 - dot110 + dot010 + dot100 - dot000)
    + u * v * w *  (gx111 - gx011 - gx101 + gx001 - gx110 + gx010 + gx100 - gx000);

с участием

float a = dot000;
float b = dot100;
float c = dot010;
float d = dot110;
float e = dot001;
float f = dot101;
float g = dot011;
float h = dot111;

float nx = uP*(b - a) 
    + uP*v*(a + d - b - c) 
    + uP*w*(a + f - b - e)
    + uP*v*w*(b + c + e + h - a - d - f - g);

Шум 3D IQ теперь выглядит отлично!

Я получил вывод здесь.

Мне не нужно было менять ny и nz, чтобы артефакты исчезли, но я пошел дальше и обновил и их.

float ny = vP*(c - a) 
    + u*vP*(a + d - b - c)
    + vP*w*(a + g - c - e)
    + u*vP*w*(b + c + e + h - a - d - f - g);

float nz = wP*(e - a)
    + u*wP*(a + f - b - e)
    + v*wP*(a + g - c - e)
    + u*v*wP*(b + c + e + h - a - d - f - g);
person onehand    schedule 09.10.2017