0

我正在尝试创建一个插值曲面的示例。首先,我创建了一个插值三叶草的示例。 在此处输入图像描述

这里是我的例子的来源。然后我不得不注意到动画很慢,大约 20-30FPS。经过一些论文,我知道必须将三叶草的评估“移动”到 GPU 中。因此,我研究了一些关于曲面细分着色器的论文。目前我绑定以下简单的顶点着色器:

#version 130
in vec4 Position;
in vec3 Normal;

uniform mat4 Projection;
uniform mat4 Modelview;
uniform mat3 NormalMatrix;
uniform vec3 DiffuseMaterial;

out vec3 EyespaceNormal;
out vec3 Diffuse;

void main()
{
    EyespaceNormal = NormalMatrix * Normal;
    gl_Position = Projection * Modelview * Position;
    Diffuse = DiffuseMaterial;
}

现在我有很多问题:

  • 我是否像使用 Triangle_Strips 一样使用顶点数组来传递 GL_PATCHES ?哪种方式更快?绘图元素?

glDrawElements(GL_TRIANGLE_STRIP, Indices.Length, OpenGL.GL_UNSIGNED_SHORT, IntPtr.Zero);

还是我应该使用

glPatchParameteri(GL_PATCH_VERTICES,16);
glBegin(GL_PATCHES);
   glVertex3f(x0,y0,z0)
   ...
glEnd();
  • 索引数组呢?如何确定路径意味着补丁的传递顺序。

  • 我是否也计算着色器中的法线?

  • 我找到了一些镶嵌着色器的例子,但在#version400 我可以在移动设备上使用这个版本吗?(OpenGL ES)

  • 我可以通过多线程将多个补丁传递给 GPU 吗?

非常感谢提前。

4

1 回答 1

1

本质上,我不相信您必须根据索引(或顶点)向 GPU 发送任何内容,因为所有内容都可以合成。我不知道三叶结的评估是否直接映射到双线性补丁的结果镶嵌网格的连通性,但这可能有效。

您可以使用简单的顶点缓冲区,其中每个顶点是单个三叶结的位置。设置 glPatchParameteri(GL_PATCH_VERTICES​, 1)。然后,您可以通过一次调用 glDrawArrays 来绘制多个结:

glDrawArrays(GL_PATCHES, 0, numKnots);

镶嵌控制阶段可以是简单的通过阶段。然后在镶嵌评估着色器中,您可以使用四边形的抽象补丁类型。然后使用提供的 [u, v] 坐标将三叶结或任何其他双参数形状的评估移动到镶嵌评估着色器中。然后你可以通过输入顶点翻译每一个三叶草。法线也可以在着色器中计算。

或者,您可以使用几何着色器从一个输入顶点位置合成三叶草,使用作为输入图元,三角形条带作为输出图元。然后你可以再打电话

glDrawArrays(GL_POINTS, 0, numKnots);

并使用用于生成索引的函数在几何着色器中创建三叶草,以描述评估顺序并将生成的顶点与输入顶点进行平移。

在这两种情况下,都不需要多线程绘制调用,这对于 OpenGL 无论如何都是无效的。您受到每个补丁可以生成的最大顶点数的限制,对于曲面细分应该是 64 乘以 64,对于几何着色器应该是 GL_MAX_GEOMETRY_OUTPUT_VERTICES。

于 2017-12-13T11:26:57.890 回答