我知道在GPU之前进行图形时,trig函数缓存非常流行,但是使用一维纹理查找表从OpenGL ES着色器中预先计算值计算sin/cos有意义吗?如果不需要超高精度,是否会节省时间?
发布于 2020-02-09 22:58:50
这是“视情况而定”的问题之一。
特别是高精度的任意sin()和cos()往往是昂贵的操作,因为它们不经常直接用于图形,而且获得完全的精度往往需要一定程度的精化迭代。因此,就个人而言,如果纹理可以更快的话,我也不会感到惊讶。
几个注意事项。首先,余弦用于照明是基于单位长度向量之间的角度,所以你不需要任意的cos() -只使用dot(),它的GPU是非常有效的。
其次,值得注意的是,一些实现(特别是移动GPU)可能已经能够为您提供更快、更不准确的结果,如果您是以mediump精度计算的话。在下面的逻辑中,这将降低sin()或cos()的任何基线成本。
剩下的问题是,sin()的成本是否优于texture()的成本,这很可能在很大程度上取决于着色程序的其余部分和目标GPU中的功能单元平衡。
如果您的着色器由于其他无关的纹理操作已经被纹理化性能所主导,那么添加更多的纹理处理将使其更慢,即使单个sin().
texture()单独更快--您的着色器主要是算术(或其他单元执行sin()调用)--那么通过将一些负载转移到纹理路径可以提高性能。发布于 2020-02-10 16:32:09
是的,这是有意义的,你应该把它缓存起来。
首先,我读了solid象素的答案(基本上是正确的),但我会与他有点分歧。
因此,简而言之:您不应该在运行时计算sin()或cos() (特别是在android中--如果这是您的GLES情况),因为您不知道您的着色器运行的是什么GPU,而且很多GPU根本就不会优化它。有更好的方法来缓存它,而不是使用纹理采样。
如果您正在处理线性代数(大多数着色过程是简单的向量方程求解程序),那么:就像他所说的那样,您应该使用点积来代替cos()的需要和sin()的交叉乘积。
但是,如果这不是您的情况,并且您确实需要调用sin和cos,那么我建议您一定要缓存它,下面是我喜欢的两种最佳方法:
texture()的确非常昂贵,但是您可以使用textureGrad(),因为它跳过了所有的筛选,所以比普通texture()的纹理查找要快得多,虽然它更有限,但它是缓存sin和cos的完美方法。https://stackoverflow.com/questions/60100429
复制相似问题