Math 在三维曲面上使用分析Perlin噪波导数

Math 在三维曲面上使用分析Perlin噪波导数,math,3d,derivative,procedural-generation,perlin-noise,Math,3d,Derivative,Procedural Generation,Perlin Noise,我试图学习如何创建并使用柏林噪声的分析导数快速生成法线。我一直在使用其中一个的代码进行实验,虽然我得到了假设“向上”轴为1并在二维平面上采样时进行规格化的想法,但我找不到任何关于在三维曲面上采样时要做什么的信息 这就是我想要的(使用中心差分法线): 这就是这些法线在世界空间中的样子: 但我得到的导数是这样的: 看起来它们可能是相对于未展开球体的曲面的,所以这是否意味着我需要使用未展开球体的法线来重新定向它们?这样做之后,我如何将导数转化为法线?我想出了一个解决方案。我所做的是使用世界空间曲

我试图学习如何创建并使用柏林噪声的分析导数快速生成法线。我一直在使用其中一个的代码进行实验,虽然我得到了假设“向上”轴为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)));
}
float3 qRotateVector(float3 v,float4 q){
浮动3 t=2.0*交叉(q.xyz,v);
返回v+q.w*t+cross(q.xyz,t);
}
浮动4 QfRottoRotation(浮动3 v){
浮动3向上=浮动3(0.0,1.0,0.0);
浮动d=点(向上,v);
如果(d<-0.999999){
返回浮动4(0.0,0.0,1.0,0.0);
}
否则,如果(d>0.999999){
返回浮动4(0.0,0.0,0.0,1.0);
}
否则{
返回正常化(浮动4(交叉(向上,v),d+1.0));
}
}
浮动噪声斜率(浮动3导数,浮动3法线){
float4 noiseRotation=qFromToRotation(正常);
float3-derivativeNormal=qRotateVector(导数,float4(-noiseRotation.xyz,noiseRotation.w));
返回abs(点(标准化(float3(-developerativenormal.x,1.0,-developerativenormal.z)),float3(0.0,1.0,0.0));
}
(我最初尝试使用矩阵,但在万向节锁定方面一直存在问题)


在我进行了实验之后,我发现还有一个例子,通过将高度除以1+点(导数.yz,导数.yz),而不是旋转噪声,通过斜率进行混合,我也将尝试处理噪声。

您还没有显示任何自己的代码。如果教程代码不起作用,您必须对其进行自己的修改。我知道这是一个老问题,但是,如果有人在第三张图像中遇到相同的问题,请执行以下操作:
vec3 normal=vec3(normalize(vertex.xyz-(derivative.xyz*0.45))。这将为您提供正确的顶点法线。