Я нашел решение.Что я сделал, так это построил кватернион вращения, используя нормаль к поверхности мирового пространства, повернул производный вектор обратно пропорционально этому вращению, затем превратил его в нормаль, как вы бы делали на плоскости, и снова повернул обратно с нормальным вращением.
Использование производных в качестве нормалей поверхности теперь выглядит следующим образом
А теперь смешивание октав на основе наклона нормали выглядит следующим образом ...
И это ...
И это
А вот код, который находит нормаль и наклон:
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) вместо вращения шума, с которым я тоже попытаюсь поиграть.