0

我编写了一个简单的 GL 片段着色器,它对图像执行 RGB 伽玛调整:

uniform sampler2D tex;
uniform vec3 gamma;

void main()
{
    vec3 texel = texture2D(tex, gl_TexCoord[0].st).rgb;
    texel = pow(texel, gamma);
    gl_FragColor.rgb = texel;
}

纹理绘制了大部分屏幕,我想到这是在屏幕上应用每个输出像素的调整,而不是纹理上的每个输入像素。虽然这并没有改变它的外观,但这个纹理与屏幕相比是很小的。

为了提高效率,如何让着色器处理纹理像素而不是屏幕像素?如果有帮助,我无论如何都会在每一帧上更改/重新加载这个纹理的数据,所以我不介意纹理是否被永久改变。

4

1 回答 1

2

我突然想到这是在屏幕上应用每个输出像素的调整

几乎。每个输出片段执行片段着色器(因此得名)。在写入像素之前,片段是光栅化的最小单位。被可见渲染几何体覆盖的每个像素都会变成一个或多个片段(是的,可能存在比被覆盖像素更多的片段,例如在绘制到抗锯齿帧缓冲区时)。

为了效率,

现代 GPU 甚至不会“注意到”略微减少的负载。这是一种微优化,处于不可测量的边缘。我的建议:不要担心。

如何让着色器处理纹理像素而不是屏幕像素?

您可以预处理纹理,首先通过纹理大小而不是抗锯齿的帧缓冲区对象将其渲染到中间纹理。但是,如果您的更改是非线性的,并且伽马调整正是如此,那么您不应该这样做。您希望在线性色彩空间中处理图像并尽可能晚地应用非线性变换。

于 2013-02-03T10:55:59.220 回答