OpenGL为什么在相同数量的片段上重复纹理会影响性能?

3
我有一个大小为单位的四元组,用无缝纹理渲染,并启用纹理重复。
对于纹理坐标,我从位置中获取。所以我可以通过将纹理坐标乘以N来人工提高纹理分辨率,这将使纹理在四元组上N*N次重复。
在我的代码中,我的纹理是一个法线图,并且在片段着色器中计算了镜面光。我注意到,我越多地乘以纹理坐标,我的性能就越差,但是在一定值之后,性能下降似乎是恒定的(例如,N = 1024和N = 10240之间没有区别)。
我不明白的是,四元组的大小保持不变,纹理的大小也相同,为什么将纹理坐标乘以相同数量的碎片会影响性能?

1
你使用mipmapping吗?使用哪种过滤模式?数据和缓存局部性在这里可能起到作用。N越大,纹理中相邻的片段距离越远。 - BDL
没有使用mipmapping,我在min和mag过滤器中都使用GL_LINEAR进行过滤。 - rejuto
1个回答

4

我不使用mipmapping,对于min和mag滤波器,我都使用GL_LINEAR。

当缩放比例增加时,片段着色器中相邻的像素对应于纹理中远离的纹素。使用GL_LINEAR,这意味着纹素不仅在纹理中相隔较远,而且在内存中也相隔较远。

当缩放比例接近1:1时,片段着色器中相邻的像素将来自于彼此相互靠近的纹素。这意味着它们在内存中也彼此相互靠近,因此具有更好的内存局部性,并需要从内存中获取的数据更少。

使用mipmapped纹理可以避免这个问题,而且通常看上去更好,因为它们不会像GL_LINEAR缩小一样出现混叠问题。

在CPU上模拟它

CPU也存在相同的内存读取问题。

float sum(float *arr, int size, int stride, int count) {
    int pos = 0;
    float sum = 0.0f;
    for (int i = 0; i < count; i++) {
        pos = (pos + stride) % size;
        sum += arr[pos];
    }
    return sum;
}

随着stride的增加,性能会变差。这是因为即使在CPU上发生,片段着色器的性能也会变差。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接