首页 > 解决方案 > 在 OpenGL ES 中缓存三角函数有意义吗?

问题描述

我知道在 GPU 之前做图形时,三角函数缓存非常流行,但是使用 1D 纹理查找表从 OpenGL ES 着色器中的预计算值计算 sin/cos 是否有意义?如果不需要超高精度,是否可以节省时间?

标签: opengl-esglsl

解决方案


是的,它确实有意义,你应该缓存它。

首先,我阅读了solidpixel 的答案(大部分是正确的),但我会与他有所不同。

所以,简而言之:你不应该在运行时计算 sin() 或 cos() (特别是在 android - 如果那是你的 GLES 情况),因为你不知道你的着色器将在哪个 GPU 上运行,而且很多只是简单永远不会优化它。除了使用纹理采样之外,还有更好的缓存方法。

如果您正在处理线性代数(大多数着色器程序都是简单的向量方程求解器),那么:您应该使用点积来代替对cos()和叉积的需要sin(),就像他说的那样。

但是,如果这不是您的情况,并且您确实需要调用 sin 和 cos,那么我建议您确定缓存它,这是我喜欢的 2 种最佳方式:

  • texture()确实相当昂贵,但您可以使用textureGrad()它比常规纹理查找速度更快,texture()因为它跳过了所有过滤,虽然它更受限制,但它非常适合缓存 sin 和 cos。
  • 另一个更好的解决方案是根本不使用纹理:使用统一缓冲区,它基本上是一个浮点数组(如纹理),但对 GPU 是明确的,因此您不需要通过采样(这特别昂贵在移动)。
  • 统一缓冲区有大小限制,因此如果您需要在角度的不同值上获得更高的精度,您可以使用类似于统一缓冲区但可以存储更多数据的 SSBO(着色器缓冲区存储对象)。

推荐阅读