我目前在 GLSL 中实现了一个 3D 噪声函数,用于置换球体的顶点以提供地形。我目前正在使用几何着色器来简单地计算每个面的法线(我也有镶嵌,因此我在这里这样做而不是顶点着色器)。现在我想计算每个顶点法线。
现在我看到了一些关于在置换平面网格时从噪声中计算法线的帖子,但似乎无法让它为自己工作。下面是我的镶嵌评估着色器的一个片段,它计算新顶点的位置。(这很好用)。
// Get the position of the newly created vert and push onto sphere's surface.
tePosition = normalize(point0 + point1 + point2) * Radius;
// Get the noise val at given location. (Using fractional brownian motion)
float noiseVal = fBM(tePosition, Octaves);
// Push out vertex by noise amount, adjust for amplitude desired.
tePosition = tePosition + normalize(tePosition) * noiseVal * Amplitude;
tePosition
然后进入几何着色器,其中三个用于计算三角形的表面法线。我将如何使用它来计算所述顶点的法线?
我试图通过在两个小偏移处重新采样噪声来执行“邻居”方法tePosition
(我将它们推回到球体上,然后用噪声值替换它们)。然后使用这两个新位置,我得到从 tePosition 到每个位置的向量,并使用叉积得到法线。然而,这导致许多区域是黑色的(表明法线是向后的),并且法线朝外的部分在球体周围似乎非常均匀(光照在光线的另一侧)。这是执行上述操作的代码:
// theta used for small offset
float theta = 0.000001;
// Calculate two new position on the sphere.
vec3 tangent = tePosition + vec3(theta, 0.0, 0.0);
tangent = normalize(tangent) * Radius;
vec3 bitangent = tePosition + vec3(0.0, theta, 0.0);
bitangent = normalize(bitangent) * Radius;
// Displace new positions by noise, then calculate vector from tePosition
float tanNoise = fBM(tangent, Octaves) * Amplitude;
tangent += normalize(tangent) * tanNoise;
tangent = tangent - tePosition;
float bitanNoise = fBM(bitangent, Octaves) * Amplitude;
bitangent += normalize(bitangent) * bitanNoise;
bitangent = bitangent - tePosition;
vec3 norm = normalize(cross(normalize(tangent), normalize(bitangent)));
我尝试改变theta
值并改变它用于抵消的方式,这会导致不同程度的“错误”。
有人对我如何正确计算法线有任何想法吗?