当我在片段着色器的def list_recursive(mydict, path=()):
if type(mydict) is list:
for i, item in enumerate(mydict):
list_recursive(item, path=(*path, i))
return
for k, v in mydict.items():
if type(v) is str:
print(*map(
lambda x:f"['{x}']" if type(x) is str else f"[{x}]",
(*path, k)
), '=', v, sep='')
else:
list_recursive(v, path=(*path, k))
函数中通过fragColor
输出颜色时,颜色分量的强度被解释为线性RGB还是sRGB?或者换句话说,我是否必须在我的着色器中执行伽马校正,或者这已经得到解决?
如果没有通用答案,但取决于某些OpenGL属性:如何设置此属性?
为避免造成误解:各自的颜色完全是通过编程生成的,没有纹理等(可能需要 input 伽玛校正)。
答案 0 :(得分:3)
每个片段着色器的输出都路由到帧缓冲区(based on glDrawBuffers
state)中的特定图像。该图像具有格式。该格式定义了相应输出的默认色彩空间解释。
因此,如果您要以线性RGB格式向图像写入值,则系统会将其解释为线性RGB值。如果您要向an sRGB format中的图像写入值,则系统将在sRGB色彩空间中将该值解释为已经存在。因此将不执行任何转换;它将按原样写入纹理。如果启用了混合功能,则您写入的sRGB值将与sRGB色彩空间中图像中的sRGB值混合。
现在,当涉及到写入sRGB色彩空间图像时,通常不需要这种行为。如果您具有线性RGB值,则希望系统将该值转换为sRGB色彩空间(而不是假装已经存在)。同样重要的是,启用混合后,您希望将sRGB图像中的值转换为线性RGB,然后与片段着色器写入的线性值混合,最后转换回sRGB。否则,混合会产生可疑准确性的结果。
要实现所有这些,请must glEnable(GL_FRAMEBUFFER_SRGB)
。启用此功能后,写入任何色彩空间为sRGB的任何图像的片段着色器输出都会进行色彩空间转换。
此值默认为禁用。
因此,如果要写入线性RGB值并将其转换为sRGB以用于显示,则必须:
确保要写入的帧缓冲图像使用sRGB色彩空间。对于FBO,这是微不足道的。但是,如果要写入默认的帧缓冲区,则必须使用OpenGL初始化代码进行处理。
当您希望使用色彩空间转换时启用GL_FRAMEBUFFER_SRGB
。