iOS OpenGL ES 2.0上的sRGB

Ste*_* Lu 9 opengl-es ios opengl-es-2.0

根据我能找到的少数相关主题我收集的是,获取正确照明计算的取幂步骤可能必须在iOS应用程序的最终片段着色器中完成.

我一直在使用最新最好的Xcode 5 OpenGL调试器进行分析,并且片段的取幂会占用大量的计算量.这条线在整个着色器中花费的时间最长(其余的性能都被norm点光源所需的各种调用所吸引).

glEnable(GL_FRAMEBUFFER_SRGB);不幸的GL_FRAMEBUFFER_SRGB是,没有宣布的工作.

当然,我应该用于GL ES的实际枚举可能会有所不同.

根据Apple的说法:

仅SGX 543和554处理器支持以下扩展:

EXT_color_buffer_half_float
EXT_occlusion_query_boolean
EXT_pvrtc_sRGB
EXT_shadow_samplers
EXT_sRGB
EXT_texture_rg
OES_texture_half_float_linear

嗯,这很好,没有543或554的最新设备是iPhone 4.

扩展名的文本文件看起来我可以设置SRGB8_ALPHA8_EXTinternalformat参数RenderbufferStorage,但没有说明如何让正常的最终帧缓冲区为我们免费应用sRGB.

现在sRGB校正似乎是获得正确颜色的缺失步骤.我在我的应用程序中处理可怕的"曝光不足"颜色的方法是在片段着色器中手动应用像这样的伽马校正:

mediump float gammaf = 1.0/1.8; // this line declared outside of `main()`
// it specifies a constant 1.8 gamma
mediump vec4 gamma = vec4(gammaf, gammaf, gammaf, 1.0);
gl_FragColor = pow(color, gamma); // last line of `main()`
Run Code Online (Sandbox Code Playgroud)

现在我认识到典型的渲染管道涉及一个或多个渲染到纹理,然后是FS四边形绘制,这将使我有机会使用SRGB8_ALPHA_EXT渲染缓冲区,但是如果没有渲染缓冲区我应该做什么呢?我是SOL吗?

如果是这种情况,那么这个pow电话会吸收很多时间,以至于我几乎可以通过构建一个1D纹理进行采样并将其用作伽玛查找表来挤出更多的信息.然后可以使用此纹理以自定义方式调整输出颜色强度(与仅原始取幂相比,获得更好的sRGB近似值).但这一切似乎都是错误的,因为据说sRGB是免费的.

另外有点令人担忧的是srgb在GL ES 2.0规范中没有提到任何字符串.根据glm GL ES 的制造商的说法,完全忽略了sRGB.

我知道我已经使用我的代码来渲染纹理(我制作了一个基本的OpenGL驱动的图像查看器,渲染PVRTC纹理)并且它们没有"变暗".我认为那里发生的事情是由于GL ES 2缺乏sRGB意识,纹理被加载到线性空间中并以相同的方式写回.在那种情况下,由于没有应用光照(所有颜色都被乘以1.0),结果没有发生任何不良.

Piv*_*vot 8

iOS 7.0添加了新的颜色格式kEAGLColorFormatSRGBA8,您可以设置它而不是kEAGLColorFormatRGBA8(字典中的)kEAGLDrawablePropertyColorFormat键中的(默认值).如果您正在使用GLKit来管理主帧缓冲区,则可以通过将其属性设置为来创建sRGB渲染缓冲区.drawablePropertiesCAEAGLLayerGLKViewdrawableColorFormatGLKViewDrawableColorFormatSRGBA8888

请注意,OpenGL ES版本的EXT_sRGB行为就像GL_FRAMEBUFFER_SRGB始终启用一样.如果要在没有sRGB转换到目标帧缓冲区的情况下进行渲染,则需要使用具有非sRGB内部格式的其他附件.


Tar*_*ark 7

我认为你在EXT_sRGB和ARB_framebuffer_sRGB扩展之间感到困惑.EXT_sRGB是最近的扩展,是iOS设备支持的扩展.这与ARB_framebuffer_sRGB的一个重要方面不同,没有必要在帧缓冲区上调用glEnable(GL_FRAMEBUFFER_SRGB)来启用伽马校正,它始终处于启用状态.您需要做的就是使用sRGB内部格式创建帧缓冲区并渲染线性纹理.

这本身并不是非常有用,因为纹理很少在线性颜色空间中.幸运的是,扩展还包括将sRGB纹理转换为线性空间的功能.通过使用内部格式sRGB8_ALPHA8_EXT上传纹理,在着色器中免费采样时,它们将转换为线性空间.这允许您使用具有更好感知编码颜色范围的sRGB纹理,混合更高精度的线性空间,然后将结果编码回渲染缓冲区中的sRGB,而无需任何着色器成本和精确的伽马校正.