opengl-es - YUV图像使用单个纹理还是多个纹理更好

标签 opengl-es opengl-es-2.0

这个问题适用于 OpenGL ES 2.0(在 Android 上),但可能更适用于 OpenGL。

最终,所有性能问题都取决于实现,但是如果有人可以概括地回答这个问题或根据他们的经验回答这个问题,那将是有帮助的。我也在写一些测试代码。

我有一个 YUV (12bpp) 图像,我正在加载到我的片段着色器中的纹理和颜色转换中。一切正常,但我想看看哪里可以提高性能(以每秒帧数计)。

目前我实际上为每个图像加载了三个纹理 - 一个用于 Y 分量(类型为 GL_LUMINANCE),一个用于 U 分量(类型为 GL_LUMINANCE,当然是 Y 分量的 1/4),一个用于V 分量(GL_LUMINANCE 类型,当然是 Y 分量大小的 1/4)。

假设我可以得到任何排列的 YUV 像素(例如 U 和 V 在不同的平面中或穿插),将三个纹理合并为两个或一个更好?显然,无论你怎么做,推送到 GPU 的字节数都是相同的,但也许纹理越少,开销就越小。至少,它会使用更少的纹理单元。我的想法:

  • 如果 U 和 V 像素相互穿插,我可以将它们加载到具有两个组件的 GL_LUMINANCE_ALPHA 类型的单个纹理中。
  • 我可以将整个 YUV 图像加载为单个纹理(类型为 GL_LUMINANCE 但图像大小的 3/2),然后在片段着色器中我可以在同一纹理上调用 texture2D() 三次,做一些算术图输出正确的坐标传递给 texture2D 以获得 Y、U 和 V 分量的正确纹理坐标。
  • 最佳答案

    我会将数据组合成尽可能少的纹理。由于某些原因,较少的纹理通常是更好的选择。

  • 设置绘图调用的状态更改更少。
  • 片段着色器中获取的纹理越少越好。
  • 更少的上传时间。

  • 来源:

    我知道其中一些专注于更具体的硬件,但这些原则适用于大多数移动图形架构。

    Best Practices for Working with Texture Data

    Optimize OpenGL for Tegra

    Optimizing performance of a heavy fragment shader
  • “绑定(bind)到纹理需要 OpenGL ES 处理时间。减少对 OpenGL ES 状态所做更改数量的应用程序性能更好。”
  • “根据我的经验,移动 GPU 性能大致与 texture2D 调用的数量成正比。” “有两个纹理加载,所以纹理子单元的最小循环计数是两个。” (Tegra 有一个纹理单元,它必须运行一个循环才能读取纹理)
  • “调用 glTexSubImageglCopyTexSubImage 函数特别昂贵” - 上传操作必须停止管道,直到纹理被上传。将这些批处理到单个上传中比阻止一堆单独的时间更快。
  • 关于opengl-es - YUV图像使用单个纹理还是多个纹理更好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18113810/

    相关文章:

    ios - OpenGL 改变方向导致 iPad 重启

    javascript - 将向量数组传递给制服

    opengl-es - 如何在左轴和右轴之间转换opengl投影矩阵?

    android - 将触摸区域限制为 libgdx 中的纹理区域

    c - 错误信息 : *** glibc detected *** ./cube : double free or corruption (! prev): 0x0a4c4420 ***

    java - 为什么触摸屏幕时我的性能会提高?

    java - 我的应用程序崩溃了,因为根据垃圾收集器的说法,仅剩余 4% 的堆内存...我该如何防止这种情况发生?

    opencv - GLSL和OpenCV

    android - Google VR 如何使用 Daydream Controller 执行选择

    ios - 对齐顶点数据