【问题标题】:transform cube to sphere in opengl在opengl中将立方体转换为球体
【发布时间】:2015-03-03 12:06:01
【问题描述】:

我用三角形方法构建了一些立方体(每个立方体 24 个顶点)。

现在我想把这个立方体转换成一个球体(也许,我只想有圆角)(稍后,我想为这个转换设置动画)。

我怎样才能意识到这一点?我可以使用纹理坐标或法线来执行此操作吗? 我找到了这个thread,但它对我没有帮助。

【问题讨论】:

  • 你想在立方体上有一个内切还是外切?
  • 不,我只想改变几何形状
  • 那么这很简单,您只需将每个点“标准化”为一个向量,而不是 1 的范数,而是预期半径的范数
  • 标准化 24 个点中的每一个?
  • @Guiroux 什么是标准化?几何坐标?我的原始立方体每个面只有 4 个顶点,所以球体看起来有点“边缘”?

标签: c++ opengl geometry normals


【解决方案1】:

要使用简单的 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,您可以避免输入更多顶点,而是使用曲面细分着色器执行面的细分。

【讨论】:

    【解决方案2】:

    您可以将每个点缩放到球体

    假设您的点是 x[i],那么要将一个点带到球体上,您可以这样做

    x[i] = x[i] * radius / norm( x[i] )

    假设你的立方体以 0 为中心

    如果你想插入这个,看起来很简单

    我并不是说它有效,但在我看来它应该有效

    【讨论】:

    • 谢谢,我认为这适用于每个面的大量三角形。我每张脸只使用 2 个三角形来减少开销。还有其他方法吗?
    • 更多三角形,我在mathproofs.blogspot.com.au/2005/07/mapping-cube-to-sphere.html找到了一篇文章
    • 我不明白它是如何“用于更多三角形”的,它只是映射具有某些属性,但两者都是从 3D 点映射到 3D 点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 2019-05-03
    • 2021-06-23
    • 1970-01-01
    相关资源
    最近更新 更多