在 opengl 中将立方体转换为球体
transform cube to sphere in opengl
我用三角形方法构建了一些立方体(每个立方体有 24 个顶点)。
现在我想把这个立方体变成一个球体(也许,我只想有圆角)(稍后,我想把这个变换动画化)。
我怎样才能意识到这一点?我可以使用纹理坐标或法线来做到这一点吗?
我找到了这个 thread,但对我没有帮助。
您可以将每个点缩放到球体
假设你的点是 x[i],那么要给球体带来一个点,你需要做
x[i] = x[i] * radius / norm( x[i] )
假设你的立方体以 0 为中心
如果要插值这个,好像很简单
我没说它有效,但在我看来它应该有效
要使用简单的 OpenGL 执行此操作,您需要使用更精细的立方体细分。不是只用两个三角形绘制每张脸,而是将其细分为更小的部分。最简单的镶嵌就是把面分割成更小的正方形,然后用三角条画出来。
如果将每条边分成 n
块,则每个面最终会得到 n x n
个正方形或 2 * n * n
个三角形。
然后您可以在顶点着色器中在立方体和球体之间进行插值。您绘制原始立方体。球体坐标是通过简单地归一化立方体坐标得到的
在顶点着色器中,InterpFract
是插值的分数(0 用于绘制立方体,1 用于绘制球体),代码可能如下所示:
uniform float InterpFract;
attribute vec3 CubeCoord;
void main() {
vec3 sphereCoord = normalize(CubeCoord);
gl_Position = vec4(mix(CubeCoord, sphereCoord, InterpFract), 1.0);
}
这是针对半径为 1 的球体。如果您需要不同的半径,可以将 sphereCoord
乘以半径。
如果您还需要法线,则需要更多的数学运算。以与位置插值相同的方式插值立方体的法线和球体的法线 而不是 会产生正确的法线。正确的解决方案是对梯度向量进行插值,然后将法线计算为插值梯度向量的叉积。
使用更高级的 OpenGL,您可以避免输入更多顶点,而是使用曲面细分着色器执行面的细分。
我用三角形方法构建了一些立方体(每个立方体有 24 个顶点)。
现在我想把这个立方体变成一个球体(也许,我只想有圆角)(稍后,我想把这个变换动画化)。
我怎样才能意识到这一点?我可以使用纹理坐标或法线来做到这一点吗? 我找到了这个 thread,但对我没有帮助。
您可以将每个点缩放到球体
假设你的点是 x[i],那么要给球体带来一个点,你需要做
x[i] = x[i] * radius / norm( x[i] )
假设你的立方体以 0 为中心
如果要插值这个,好像很简单
我没说它有效,但在我看来它应该有效
要使用简单的 OpenGL 执行此操作,您需要使用更精细的立方体细分。不是只用两个三角形绘制每张脸,而是将其细分为更小的部分。最简单的镶嵌就是把面分割成更小的正方形,然后用三角条画出来。
如果将每条边分成 n
块,则每个面最终会得到 n x n
个正方形或 2 * n * n
个三角形。
然后您可以在顶点着色器中在立方体和球体之间进行插值。您绘制原始立方体。球体坐标是通过简单地归一化立方体坐标得到的
在顶点着色器中,InterpFract
是插值的分数(0 用于绘制立方体,1 用于绘制球体),代码可能如下所示:
uniform float InterpFract;
attribute vec3 CubeCoord;
void main() {
vec3 sphereCoord = normalize(CubeCoord);
gl_Position = vec4(mix(CubeCoord, sphereCoord, InterpFract), 1.0);
}
这是针对半径为 1 的球体。如果您需要不同的半径,可以将 sphereCoord
乘以半径。
如果您还需要法线,则需要更多的数学运算。以与位置插值相同的方式插值立方体的法线和球体的法线 而不是 会产生正确的法线。正确的解决方案是对梯度向量进行插值,然后将法线计算为插值梯度向量的叉积。
使用更高级的 OpenGL,您可以避免输入更多顶点,而是使用曲面细分着色器执行面的细分。