Использование аналитических производных шума Перлина на трехмерной поверхности

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

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

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

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

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


person Chrism    schedule 08.12.2018    source источник
comment
Вы не показали никакого своего собственного кода. Если учебный код не работает, вы, должно быть, внесли в него свои собственные изменения.   -  person meowgoesthedog    schedule 09.12.2018
comment
Я знаю, что это старый вопрос, но если кто-то столкнется с той же проблемой на третьем изображении, просто сделайте следующее: vec3 normal = vec3(normalize(vertex.xyz - (derivative.xyz * 0.45)));. Это даст вам правильную вершину нормали.   -  person Pedro Henrique    schedule 26.01.2021


Ответы (1)


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

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

А теперь микширование октав на основе наклона нормалей выглядит так ...

А это ...

А это

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

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 также имеет пример микширования с помощью slope, разделив высоту на 1 + точку (производная.yz, производная.yz) вместо вращения шума, с которым я тоже собираюсь попробовать.

person Chrism    schedule 20.12.2018