Opengl es 在OpenGL ES中缓存三角函数有意义吗?

Opengl es 在OpenGL ES中缓存三角函数有意义吗?,opengl-es,glsl,Opengl Es,Glsl,我知道,在GPU之前进行图形处理时,trig函数缓存非常流行,但使用1D纹理查找表从OpenGL ES着色器中预先计算的值计算sin/cos是否有意义?如果不需要超高精度,是否可以节省时间?这是一个“视情况而定”的问题 特别是高精度的任意sin()和cos()往往是昂贵的操作,因为它们通常不直接用于图形中,而获得完全精度往往需要某种程度的优化迭代。所以就个人而言,如果纹理可以更快,我也不会感到惊讶 一些警告。首先,余弦在照明中的大多数用途是基于单位长度向量之间的角度,因此您不需要任意的cos()

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

这是一个“视情况而定”的问题

特别是高精度的任意
sin()
cos()
往往是昂贵的操作,因为它们通常不直接用于图形中,而获得完全精度往往需要某种程度的优化迭代。所以就个人而言,如果纹理可以更快,我也不会感到惊讶

一些警告。首先,余弦在照明中的大多数用途是基于单位长度向量之间的角度,因此您不需要任意的
cos()
——只需使用
dot()
,GPU在这方面非常有效

其次,值得注意的是,如果您以
mediump
精度计算,某些实现(尤其是移动GPU)可能已经能够提供更快、更不准确的结果。这将减少以下逻辑中
sin()
cos()
的任何基线成本

剩下的问题实际上是
sin()
的成本是否优于
纹理()
的成本,这可能在很大程度上取决于着色器程序的其余部分和目标GPU中的功能单元平衡

  • 如果由于其他不相关的纹理操作,着色器的纹理性能已占主导地位,则添加更多纹理将使其速度变慢,即使单个
    texture()
    调用单独比
    sin()快
  • 如果着色器由算术(或执行
    sin()
    调用的任何单元)控制,则性能可能会通过将一些负载转移到纹理路径来提高
      这是一个“视情况而定”的问题

      特别是高精度的任意
      sin()
      cos()
      往往是昂贵的操作,因为它们通常不直接用于图形中,而获得完全精度往往需要某种程度的优化迭代。所以就个人而言,如果纹理可以更快,我也不会感到惊讶

      一些警告。首先,余弦在照明中的大多数用途是基于单位长度向量之间的角度,因此您不需要任意的
      cos()
      ——只需使用
      dot()
      ,GPU在这方面非常有效

      其次,值得注意的是,如果您以
      mediump
      精度计算,某些实现(尤其是移动GPU)可能已经能够提供更快、更不准确的结果。这将减少以下逻辑中
      sin()
      cos()
      的任何基线成本

      剩下的问题实际上是
      sin()
      的成本是否优于
      纹理()
      的成本,这可能在很大程度上取决于着色器程序的其余部分和目标GPU中的功能单元平衡

      • 如果由于其他不相关的纹理操作,着色器的纹理性能已占主导地位,则添加更多纹理将使其速度变慢,即使单个
        texture()
        调用单独比
        sin()快
      • 如果着色器由算术(或执行
        sin()
        调用的任何单元)控制,则性能可能会通过将一些负载转移到纹理路径来提高
      是的,它确实有意义,您应该缓存它

      首先,我读了solidpixel的答案(基本上是正确的),但我会和他有点分歧

      因此,简言之:你不应该在运行时计算sin()或cos()(特别是在android中——如果你的情况是这样的话),因为你不知道你的着色器将在什么GPU上运行,而且很多着色器根本不会优化它。除了使用纹理采样,还有更好的缓存方法

      如果您正在处理线性代数(大多数着色器过程都是简单的向量方程解算器),则: 正如他所说,你应该使用点积来代替对
      cos()
      的需求和对
      sin()
      的叉积

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

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

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

      首先,我读了solidpixel的答案(基本上是正确的),但我会和他有点分歧

      因此,简言之:你不应该在运行时计算sin()或cos()(特别是在android中——如果你的情况是这样的话),因为你不知道你的着色器将在什么GPU上运行,而且很多着色器根本不会优化它。除了使用纹理采样,还有更好的缓存方法

      如果您正在处理线性代数(大多数着色器过程都是简单的向量方程解算器),则: 正如他所说,你应该使用点积来代替对
      cos()
      的需求和对
      sin()
      的叉积

      然而,如果这不是你的情况,你真的需要加入