Использование аналитических производных шума Perlin на трехмерной поверхности - PullRequest
0 голосов
/ 09 декабря 2018

Я пытаюсь научиться создавать и использовать аналитические производные перлин-шума для быстрой генерации нормалей.Я экспериментировал с кодом из одного из обучающих программ Catlike Coding , и хотя у меня появилась идея предположить, что ось 'вверх' равна 1, и нормализуется при выборке на 2D-плоскости, я не могу найти никакой информациио том, что делать при выборке на трехмерной поверхности.

Это то, что я ищу (здесь используются центральные разности):

И вот как эти нормали выглядят вмировое пространство:

Но производные, которые я получаю, выглядят так:

Кажется, что они могут быть относительно поверхности неразмещенной сферы, так чтозначит, мне нужно переориентировать их с помощью нормальных сфер?И как мне превратить производные в нормали после этого?

1 Ответ

0 голосов
/ 20 декабря 2018

Я нашел решение.Что я сделал, так это построил кватернион вращения, используя нормаль к поверхности мирового пространства, повернул производный вектор обратно пропорционально этому вращению, затем превратил его в нормаль, как вы бы делали на плоскости, и снова повернул обратно с нормальным вращением.

Использование производных в качестве нормалей поверхности теперь выглядит следующим образом

А теперь смешивание октав на основе наклона нормали выглядит следующим образом ...

И это ...

И это

А вот код, который находит нормаль и наклон:

float3 qRotateVector(float3 v, float4 q) {
    float3 t = 2.0 * cross(q.xyz, v);
    return v + q.w * t + cross(q.xyz, t);
}

float4 qFromToRotation(float3 v) {
    float3 up = float3(0.0, 1.0, 0.0);
    float d = dot(up, v);

    if (d < -0.999999) {
        return float4(0.0, 0.0, 1.0, 0.0);
    }
    else if (d > 0.999999) {
        return float4(0.0, 0.0, 0.0, 1.0);
    }
    else {
        return normalize(float4(cross(up, v), d + 1.0));
    }
}

float noiseSlope(float3 derivatives, float3 normal) {
    float4 noiseRotation = qFromToRotation(normal);
    float3 derivativeNormal = qRotateVector(derivatives, float4(-noiseRotation.xyz, noiseRotation.w));
    return abs(dot(normalize(float3(-derivativeNormal.x, 1.0, -derivativeNormal.z)), float3(0.0, 1.0, 0.0)));
}

(Первоначально я пытался использовать матрицы, но у меня продолжали возникать проблемы с блокировкой карданного подвеса)

После того, как я поэкспериментировал с этим, я обнаружил Inigo Quilez также имеет примермикширование по наклону путем деления высоты на 1 + точка (производная.yz, производная.yz) вместо вращения шума, с которым я тоже попытаюсь поиграть.

...