什么是片段着色器中更快或变化或手动插值?

时间:2016-06-13 13:30:45

标签: opengl-es webgl fragment-shader varying

什么更快 - 让变量插入纹理坐标(以及其他一些逐渐变化的系数)或在片段着色器中手动计算它们?

有人会认为这个问题的答案是显而易见的,但后来我偶然发现有人提到(目前找不到来源)每一个额外的变化都会带来成本并导致性能下降。

更新 我正在进行图像重采样,所以基本上对于每个目标像素我需要从原始纹理中取几个样本然后进行插值。我可以预先计算顶点着色器中这些样本的精确坐标,并通过变换传递它们,或者我可以直接在片段着色器中计算它们。事实上,我没有看到有人通过改变来做这件事。而且我认为这背后应该有一个原因。

2 个答案:

答案 0 :(得分:2)

根据at least one guide using varings is faster

  

意识到动态纹理查找

     

当片段着色器计算纹理坐标而不是使用传递到着色器中的未修改纹理坐标时,会发生动态纹理查找(也称为从属纹理读取)。在支持OpenGL ES 3.0的硬件上支持无需性能的纹理读取;在其他设备上,依赖纹理读取会延迟纹素数据的加载,从而降低性能。当着色器没有依赖纹理读取时,图形硬件可以在着色器执行之前预取纹素数据,隐藏一些访问内存的延迟。

     

清单10-7显示了一个计算新纹理坐标的片段着色器。此示例中的计算可以在顶点着色器中轻松执行。通过将计算移动到顶点着色器并直接使用顶点着色器的计算纹理坐标,可以避免依赖纹理读取。

     

注意:它可能看起来不太明显,但对纹理坐标的任何计算都算作依赖纹理读取。例如,将多组纹理坐标打包到单个变化参数中,并使用swizzle命令提取坐标仍会导致依赖纹理读取。

     

清单10-7依赖纹理读取

varying vec2 vTexCoord;
uniform sampler2D textureSampler;

void main()
{
   vec2 modifiedTexCoord = vec2(1.0 - vTexCoord.x, 1.0 - vTexCoord.y);
   gl_FragColor = texture2D(textureSampler, modifiedTexCoord);
}

注意:这是假设,就像你提到的,我们正在谈论纹理坐标。您将用于在纹理中查找纹素的坐标。

我会说实话,我认为这不是文件所说的那么真实。我假设纹理与普通内存类似,因为有一个纹理缓存,如果你的纹理(或纹理的一部分)不在缓存中,那么就会出现缓存未命中。类似地,我假设缓存只是半自动拉动矩形区域(用于过滤),因此只要您以正常方式主要穿过纹理,我认为无论纹理坐标如何计算,您都会获得最佳性能。但是,至少根据该文件并非如此。

另一个是术语。我一直认为依赖纹理读取=通过查找其他纹理的结果查找一个纹理。一个典型的例子是调色板纹理,您可以使用8位单通道纹理来索引RGBA调色板纹理。那是一个依赖的纹理查找。但根据上面的文档,还有另一个依赖纹理查找的定义,显然任何纹理查找都不会直接使用未经修改的变化。

请注意上面的指南适用于PowerVR GPU(例如,在所有iPhone / iPad中)。其他GPU可能具有不同的性能特征。

答案 1 :(得分:0)

我可能会看到的唯一一个用例是全屏四边形渲染(你可以使用视口大小得到gl_FragCoord并推断uv coords)但在这种情况下你只有一两个变化因此我认为性能没有差异,但如果你进行很多后处理,可能值得比较两者。

在更一般的情况下,正如Nicol Bolas指出的那样,你可能仍然需要一些不同的数据来计算插值(例如系数),加上你的片段着色器中的更多数据(要线性插入你的uv,你需要uv&# 39;你的三角形的每个顶点的s。)