在opengl中将立方体转换成球体

时间:2021-10-20 18:09:59

I am built some Cubes with the triangle approach (24 verticies per cube).

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

Now I want to transform this cube to a sphere (maybe, I only want to have round corners) (later, I want to animate this transformation).

现在我想把这个立方体转换成一个球体(也许,我只想要圆角)(稍后,我想让这个变换有动画效果)。

How can I realize this? Can I use texture coordinates or normals to do this? I found this thread, but it doesn't help me.

我怎么能意识到这一点呢?我可以用纹理坐标或者法线来做这个吗?我找到了这条线,但它帮不了我。

2 个解决方案

#1


1  

To do this with simple OpenGL, you'll need to use a finer tessellate of the cube. Instead of drawing each face with only two triangles, you subdivide it into smaller pieces. The easiest tessellation is to split the faces into smaller squares, and drawing them with triangle strips.

要使用简单的OpenGL实现这一点,您需要使用多维数据集的更精细的tessellate。你不是用两个三角形来画每一张脸,而是把它细分成更小的部分。最简单的镶嵌是把脸分割成更小的方块,然后用三角形的条子画出来。

If you split each edge into n pieces, you'll end up with n x n squares or 2 * n * n triangles for each face.

如果你把每条边分割成n个部分,你会得到n个n个正方形或2个* n * n个三角形。

You can then interpolate between cube and sphere in the vertex shader. You draw the original cube. The sphere coordinates are obtained by simply normalizing the cube coordinates.

然后你可以在立方体和球体之间的顶点着色。你画出原来的立方体。球体坐标是通过简单的正规化立方体坐标得到的。

In the vertex shader, with InterpFract being the fraction of interpolation (0 for drawing the cube, 1 for drawing a sphere), the code could look something like this:

在顶点着色器中,InterpFract是插值的分数(绘制立方体的0,绘制球面的1),代码可以如下所示:

uniform float InterpFract;
attribute vec3 CubeCoord;

void main() {
    vec3 sphereCoord = normalize(CubeCoord);
    gl_Position = vec4(mix(CubeCoord, sphereCoord, InterpFract), 1.0);
}

This is for a sphere of radius 1. If you need a different radius, you can multiply sphereCoord by the radius.

这是一个半径为1的球体。如果你需要一个不同的半径,你可以把球弦乘以半径。

If you also need normals, it takes some more math. Interpolating the normal of the cube and the normal of the sphere the same way the positions are interpolated does not produce correct normals. The correct solution is to interpolate the gradient vectors, and then calculate the normal as the cross product of the interpolated gradient vectors.

如果你还需要法线,它需要更多的数学。用同样的方法插入立方体的法向量和球面的法向量并不会产生正确的法向量。正确的解决方法是对梯度向量进行插值,然后计算法向量作为插值梯度向量的叉积。

With more advanced OpenGL, you could avoid feeding in more vertices, and perform the subdivision of the faces with a tessellation shader instead.

使用更高级的OpenGL,您可以避免输入更多的顶点,而使用镶嵌着色器来执行对面的细分。

#2


1  

You could just scale each points to the sphere

你可以把每个点缩放到球面上。

let's say that your points are x[i], then to bring a point to the sphere, you do

假设你的点是x[i],为了给球面带来一个点,你需要

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

x[i] = x[i] *半径/范数(x[i])

assuming that your cube is centered on 0

假设立方体以0为中心

if you want to interpolate this, it seems simple

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

I don't say that it works, but it looks to me like it should work

我并不是说它起作用,但我觉得它应该起作用。

#1


1  

To do this with simple OpenGL, you'll need to use a finer tessellate of the cube. Instead of drawing each face with only two triangles, you subdivide it into smaller pieces. The easiest tessellation is to split the faces into smaller squares, and drawing them with triangle strips.

要使用简单的OpenGL实现这一点,您需要使用多维数据集的更精细的tessellate。你不是用两个三角形来画每一张脸,而是把它细分成更小的部分。最简单的镶嵌是把脸分割成更小的方块,然后用三角形的条子画出来。

If you split each edge into n pieces, you'll end up with n x n squares or 2 * n * n triangles for each face.

如果你把每条边分割成n个部分,你会得到n个n个正方形或2个* n * n个三角形。

You can then interpolate between cube and sphere in the vertex shader. You draw the original cube. The sphere coordinates are obtained by simply normalizing the cube coordinates.

然后你可以在立方体和球体之间的顶点着色。你画出原来的立方体。球体坐标是通过简单的正规化立方体坐标得到的。

In the vertex shader, with InterpFract being the fraction of interpolation (0 for drawing the cube, 1 for drawing a sphere), the code could look something like this:

在顶点着色器中,InterpFract是插值的分数(绘制立方体的0,绘制球面的1),代码可以如下所示:

uniform float InterpFract;
attribute vec3 CubeCoord;

void main() {
    vec3 sphereCoord = normalize(CubeCoord);
    gl_Position = vec4(mix(CubeCoord, sphereCoord, InterpFract), 1.0);
}

This is for a sphere of radius 1. If you need a different radius, you can multiply sphereCoord by the radius.

这是一个半径为1的球体。如果你需要一个不同的半径,你可以把球弦乘以半径。

If you also need normals, it takes some more math. Interpolating the normal of the cube and the normal of the sphere the same way the positions are interpolated does not produce correct normals. The correct solution is to interpolate the gradient vectors, and then calculate the normal as the cross product of the interpolated gradient vectors.

如果你还需要法线,它需要更多的数学。用同样的方法插入立方体的法向量和球面的法向量并不会产生正确的法向量。正确的解决方法是对梯度向量进行插值,然后计算法向量作为插值梯度向量的叉积。

With more advanced OpenGL, you could avoid feeding in more vertices, and perform the subdivision of the faces with a tessellation shader instead.

使用更高级的OpenGL,您可以避免输入更多的顶点,而使用镶嵌着色器来执行对面的细分。

#2


1  

You could just scale each points to the sphere

你可以把每个点缩放到球面上。

let's say that your points are x[i], then to bring a point to the sphere, you do

假设你的点是x[i],为了给球面带来一个点,你需要

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

x[i] = x[i] *半径/范数(x[i])

assuming that your cube is centered on 0

假设立方体以0为中心

if you want to interpolate this, it seems simple

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

I don't say that it works, but it looks to me like it should work

我并不是说它起作用,但我觉得它应该起作用。