如何传递GL_PATCHES

时间:2017-12-11 20:33:21

标签: opengl shader tessellation

我正在尝试创建插值曲面的示例。 首先,我创建了一个插值三叶草的例子。 enter image description here

这是example的来源。 然后我不得不注意到动画很慢,大约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;
}

现在我有多个问题:

  • 我是否使用顶点数组来传递GL_PATCHES,就像我已经使用Triangle_Strips一样?哪种方式更快? DrawElements?

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吗?

许多人提前感谢。

1 个答案:

答案 0 :(得分:1)

从本质上讲,我不相信你必须在索引(或顶点)方面向GPU发送任何东西,因为一切都可以合成。我不知道三叶形结的评估是否直接映射到双线性贴片的最终细分网格的连通性,但这可能有效。

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

glDrawArrays(GL_PATCHES,0,numKnots);

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

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

glDrawArrays(GL_POINTS,0,numKnots);

使用生成索引的函数在几何着色器中创建三叶形,以描述评估顺序并使用输入顶点转换生成的顶点。

在这两种情况下都不需要多线程绘制调用,这对OpenGL无效。您受限于每个补丁最多可生成的顶点数,对于镶嵌细分应为64倍,对于几何着色器应为GL_MAX_GEOMETRY_OUTPUT_VERTICES。