Opengl ES 2.0:模型矩阵与逐顶点计算
Opengl ES 2.0: Model Matrix vs Per Vertex Calculation
我可能问了一个愚蠢的问题,但我对 opengl es 2.0 的性能有点好奇。
假设我有一个包含顶点数组 "VA"、缓冲区数组 "BA"、and/or 模型矩阵 "MM" 的绘图对象,我想每帧至少做一次平移和一次旋转。那么,最好的选择是什么?
- 对 VA 进行操作(Rot 和 Trans)并传递给 BA。
- 直接在 BA 上进行操作(Ror 和 Trans)。
- 对MM进行操作并将其传递给Opengl Vertex Shader。
我关心的是性能,processing/memory 比率。我认为第三个选项可能是最好的,因为 GPU,但在内存方面也是最昂贵的,因为每个对象都必须有一个 MM,对吗?
我认为的另一个解决方案是将平移和旋转参数传递给着色器和 assemble 着色器上的 MM。
如何做到最好?
这绝不是一个愚蠢的问题,但不幸的是,这完全取决于具体情况。一般来说,如果顶点数据不断变化,即使在 GPU 上使用顶点缓冲区也可能不是最好的主意,但我想这不是你遇到的情况。
所以您所想的两个主要区别是:
- 修改CPU中的每个顶点,然后将顶点数据发送到GPU。
- 保留 GPU 上的数据,并在顶点着色器中使用矩阵更改它们。
因此,如果顶点数据的变化超出了矩阵或任何其他类型的分析呈现的顶点变换所能呈现的范围,那么第一个选项实际上是好的。例如,如果您一直在 CPU 上生成随机位置。在这种情况下,即使使用顶点缓冲区实际上也没什么意义,因为无论如何您都需要在每次成名时继续流式传输顶点数据。
第二个在基础顶点数据相对静态(每一帧上变化不大)的情况下非常有用。您将顶点数据推送到 GPU 一次(或偶尔一次),然后使用顶点着色器为您转换顶点数据。 GPU 上的顶点着色器在这样做时非常有效,并且比在 CPU.
上应用相同的算法要快得多。
关于你的问题:
如果你有大量的顶点数据,第三个选项很可能是最好的,但我不会说它在内存方面很昂贵,因为矩阵由 16 个浮点数组成,应该相对较小,因为 6 个 3d 顶点位置会占用更多内存然后,所以你根本不应该担心这一点。如果有任何问题,您应该担心流式传输到 GPU 的数据量是此选项中最少的。
将平移和旋转传递给顶点着色器然后为每个顶点组成矩阵可能不是最好的主意。这里发生的事情是,您发送 4+3 个浮点数而不是 16 个浮点数,从而获得了 GPU 的一点流量,但只是开始时将它分成两个块发送,这会产生开销。其次,你消耗的内存要多于少,因为无论如何你都需要在着色器中创建矩阵。如果你这样做,你将为每个顶点着色器计算一个新矩阵,这意味着每个顶点。
现在关于这些矩阵和内存很难说它实际上会对内存本身产生任何影响。堆栈大小通常是固定的或至少是四舍五入的,因此在着色器中添加或不添加矩阵很可能对任何内存消耗没有任何影响。
谈到 openGL 和性能时,您主要需要关注的是:
- 内存消耗。这主要用于纹理,1024x1024 RGBA 将占用大约 4MB,相当于一百万个浮点数或大约 350k 个包含 3D 位置向量的顶点,因此矩阵之类的东西实际上效果很小。
- 数据流。这是您需要在每一帧上传递给 GPU 进行处理的数据量。这应该尽可能地减少,但再次发送几 MB 根本不成问题。
- 着色器的整体效率
- 绘制调用次数。如果可能,请尝试打包尽可能多的相似数据以减少绘制调用。
我可能问了一个愚蠢的问题,但我对 opengl es 2.0 的性能有点好奇。
假设我有一个包含顶点数组 "VA"、缓冲区数组 "BA"、and/or 模型矩阵 "MM" 的绘图对象,我想每帧至少做一次平移和一次旋转。那么,最好的选择是什么?
- 对 VA 进行操作(Rot 和 Trans)并传递给 BA。
- 直接在 BA 上进行操作(Ror 和 Trans)。
- 对MM进行操作并将其传递给Opengl Vertex Shader。
我关心的是性能,processing/memory 比率。我认为第三个选项可能是最好的,因为 GPU,但在内存方面也是最昂贵的,因为每个对象都必须有一个 MM,对吗?
我认为的另一个解决方案是将平移和旋转参数传递给着色器和 assemble 着色器上的 MM。
如何做到最好?
这绝不是一个愚蠢的问题,但不幸的是,这完全取决于具体情况。一般来说,如果顶点数据不断变化,即使在 GPU 上使用顶点缓冲区也可能不是最好的主意,但我想这不是你遇到的情况。
所以您所想的两个主要区别是:
- 修改CPU中的每个顶点,然后将顶点数据发送到GPU。
- 保留 GPU 上的数据,并在顶点着色器中使用矩阵更改它们。
因此,如果顶点数据的变化超出了矩阵或任何其他类型的分析呈现的顶点变换所能呈现的范围,那么第一个选项实际上是好的。例如,如果您一直在 CPU 上生成随机位置。在这种情况下,即使使用顶点缓冲区实际上也没什么意义,因为无论如何您都需要在每次成名时继续流式传输顶点数据。
第二个在基础顶点数据相对静态(每一帧上变化不大)的情况下非常有用。您将顶点数据推送到 GPU 一次(或偶尔一次),然后使用顶点着色器为您转换顶点数据。 GPU 上的顶点着色器在这样做时非常有效,并且比在 CPU.
上应用相同的算法要快得多。关于你的问题: 如果你有大量的顶点数据,第三个选项很可能是最好的,但我不会说它在内存方面很昂贵,因为矩阵由 16 个浮点数组成,应该相对较小,因为 6 个 3d 顶点位置会占用更多内存然后,所以你根本不应该担心这一点。如果有任何问题,您应该担心流式传输到 GPU 的数据量是此选项中最少的。
将平移和旋转传递给顶点着色器然后为每个顶点组成矩阵可能不是最好的主意。这里发生的事情是,您发送 4+3 个浮点数而不是 16 个浮点数,从而获得了 GPU 的一点流量,但只是开始时将它分成两个块发送,这会产生开销。其次,你消耗的内存要多于少,因为无论如何你都需要在着色器中创建矩阵。如果你这样做,你将为每个顶点着色器计算一个新矩阵,这意味着每个顶点。
现在关于这些矩阵和内存很难说它实际上会对内存本身产生任何影响。堆栈大小通常是固定的或至少是四舍五入的,因此在着色器中添加或不添加矩阵很可能对任何内存消耗没有任何影响。
谈到 openGL 和性能时,您主要需要关注的是:
- 内存消耗。这主要用于纹理,1024x1024 RGBA 将占用大约 4MB,相当于一百万个浮点数或大约 350k 个包含 3D 位置向量的顶点,因此矩阵之类的东西实际上效果很小。
- 数据流。这是您需要在每一帧上传递给 GPU 进行处理的数据量。这应该尽可能地减少,但再次发送几 MB 根本不成问题。
- 着色器的整体效率
- 绘制调用次数。如果可能,请尝试打包尽可能多的相似数据以减少绘制调用。