使用波状顶点着色器计算整个球体的法线

Calculating Normals across a sphere with a wave-like vertex shader

我一直在尝试为我正在使用顶点着色器弄乱的球体获取正确的法线。该算法可以简单地归结为

vert.xyz += max(0, sin(time + 0.004*vert.x))*10*normal.xyz

这会导致波浪在球体上滚动。 为了使我的法线正确,我还需要对它们进行转换。我可以取给定 x、y、z 处的切线向量,得到垂直向量 (0, -vert.z, vert.y),然后将切线与 perp 向量相交。

虽然我在数学上遇到了一些问题,但此时它已成为个人恩怨。我已经解决了数百次导数,但我一直不正确。我怎样才能得到切线? 分解上面的行,我可以做一个数学函数

f(x,y,z) = max(0, sin(time + 0.004*x))*10*Norm(x,y,z) + (x,y,z)

其中 Norm(..) 是 Normalize((x,y,z) - CenterOfSphere)

After applying f(x,y,z), unchanged normals

正确的 f '(x,y,z) 是多少?

我已经解释了 f(...) 中的最大值引起的怪异,所以这不是问题。

编辑:我目前最成功的算法如下:

正切vector.x = 0.004*10*cos(0.004*vert.x + 时间)*norm.x + 10*sin(0.004*vert.x + 时间) + 1

正切vector.y = 10*sin(0.004*vert.x + 时间) + 1

正切vector.z = 10*sin(0.004*vert.x + 时间) + 1

2 次切线 vector.x = 0

第二切线vector.y = -norm.z

第二切线vector.z = norm.y

将两者归一化,并执行 Cross(Tangent2, Tangent1)。再次归一化,完成(应该是 Cross(Tangent1, Tangent2),但这似乎有更好的结果......更多提示我的数学问题!)。

这会产生 this

如果您的曲面点呈非线性分布和/或存在某些数学奇点,或者如果您犯了数学错误(99.99% 的情况就是这种情况),则通过函数导数获取 tangent/normal 有时会失败。不管怎样,你总是可以使用几何方法:

1.你可以通过

轻松获得切线
  • U(x,y,z)=f(x+d,y,z)-f(x,y,z);
  • V(x,y,z)=f(x,y+d,z)-f(x,y,z);
  • 其中 d 是足够小的步长
  • f(x,y,z)是你当前的表面点计算
  • 不确定为什么要使用 3 个输入变量我只使用 2
  • 但是因此如果移动点与未移动点相同
  • 改用这个 =f(x,y,z+d)-f(x,y,z);
  • 最后不要忘记将U,V大小归一化为单位向量

2。下一步

  • 如果项目符号 1 导致正确的法线
  • 那么你可以简单地用代数方法求解 U,V
  • 所以将 U(x,y,z)=f(x+d,y,z)-f(x,y,z); 重写为完整的等式
  • f(x,y,z)代入表面点方程
  • 并简化

[注释]

  • 有时选择得当d可以简化归一化以乘以常数
  • 你应该像这样添加法线可视化:
  • 实际查看实际情况(用于调试目的)