sRGB纹理.这样对吗? [英] sRGB textures. Is this correct?

查看:67
本文介绍了sRGB纹理.这样对吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在阅读一些有关sRGB格式的信息,以及它们如何使硬件为典型的显示器自动执行色彩校正.作为阅读的一部分,我发现您可以使用普通纹理和返回结果上的pow函数来模拟此步骤.

I've recently been reading a little about sRGB formats and how they allow the hardware to automatically perform colour correction for typical monitors. As part of my reading, I see that you can simulate this step with an ordinary texture and a pow function on the return result.

无论如何,我想问两个问题,因为我以前从未使用过此功能.首先,任何人都可以从我的屏幕快照中确认这是您期望看到的吗?左图为普通RGBA,右图为sRGB目标.场景中没有环境照明,模型是沼泽标准Phong(灯光是聚光灯).

Anyway I want to ask two questions as I've never used this feature before. Firstly, can anyone confirm from my screenshot that this is what you would expect to see? The left picture is ordinary RGBA and the right picture is with an sRGB target. There is no ambient lighting in the scene and the model is bog standard Phong (the light is a spotlight).

我要问的第二个问题是,硬件实际上在什么时候进行了校正?例如,我正在将帧写入FBO,然后稍后使用FBO颜色缓冲区将屏幕大小的四边形渲染到后缓冲区(我打算很快切换到延迟阴影).我应该使用附在FBO上的sRGB纹理,还是只需要指定sRGB纹理作为后缓冲目标?如果您使用的是sRGB,则所有纹理资源都应该是sRGB吗?

The second question I would like to ask is at what point is the correction actually performed by the hardware? For example I am writing frames to an FBO, then later I'm rendering a screen-sized quad to the back buffer using an FBO colour buffer (I'm intending to switch to deferred shading soon). Should I use sRGB textures attached to the FBO, or do I only need to specify an sRGB texture as the back buffer target? If you're using sRGB, should ALL texture resources be sRGB?

推荐答案

注意:以下讨论假定您了解sRGB颜色空间是什么,伽玛校正是什么,线性RGB颜色空间是什么,等等.这主要集中在该技术的OpenGL实现上.

Note: the following discussion assumes you understand what the sRGB colorspace is, what gamma correction is, what a linear RGB colorspace is, and so forth. This focuses primarily on the OpenGL implementation of the technology.

如果您想对这些主题进行深入的讨论,我建议您参考我在

If you want an in-depth discussion of these subjects, I would suggest looking at my tutorials on HDR/Gamma correction (to understand linear colorspaces and gamma), as well the tutorial on sRGB images and how they handle gamma correction.

首先,任何人都可以从我的屏幕快照中确认这是您期望看到的吗?

Firstly, can anyone confirm from my screenshot that this is what you would expect to see?

我不确定我是否理解你这个问题的意思.如果您应用适当的伽玛校正(这是sRGB或多或少的功能),通常会在图像的较暗区域获得更多细节,并获得更明亮"的结果.

I'm not sure I understand what you mean by that question. If you apply proper gamma correction (which is what sRGB does more or less), you will generally get more detail in darker areas of the image and a "brighter" result.

但是,正确的思考方式是直到您要进行正确的伽玛校正所有图像都出错了.您的图像太暗了,伽马校正现在使它们具有适当的亮度.您对事物应该是什么颜色以及应该如何明亮的灯光做出的每个决定都是错误.

However, the correct way to think about it is that until you do proper gamma correction all of your images have been wrong. Your images have been too dark, and the gamma correction is now making them the appropriate brightness. Every decision you've made about what colors things should be and how bright lights ought to be has been wrong.

我要问的第二个问题是硬件实际在什么时候进行校正?

The second question I would like to ask is at what point is the correction actually performed by the hardware?

与您继续介绍封面的例如"部分相比,这是一个非常不同的问题.

This is a very different question than the "for example" part that you continue on with covers.

sRGB图像(请记住:纹理包含图像,但是帧缓冲区也可以包含图像)可以在以下上下文中使用:

sRGB images (remember: a texture contains images, but framebuffers can have images too) can be used in the following contexts:

  • 将数据从用户直接传输到图像(例如,使用glTexSubImage2D等). OpenGL 假定,您所提供的数据已经在sRGB色彩空间中.因此,上传数据时不会翻译数据.这样做是因为这是最有意义的:通常,从艺术家那里获得的任何图像都将在sRGB色彩空间中,除非该艺术家竭尽全力将其放置在其他色彩空间中.实际上,每个图像编辑器都可以直接在sRGB中工作.

  • Transferring data from the user directly to the image (for example, with glTexSubImage2D and so forth). OpenGL assumes that you are providing data that is already in the sRGB colorspace. So there is no translation of the data when you upload it. This is done because it makes the most sense: generally, any image you get from an artist will be in the sRGB colorspace unless the artist took great pains to put it in some other colorspace. Virtually every image editor works directly in sRGB.

通过采样器读取着色器中的值(即:访问纹理).这也很简单. OpenGL知道图像中的纹理数据位于sRGB色彩空间中. OpenGL假定着色器需要 linear RGB颜色数据.因此,所有尝试从具有 sRGB图像格式的纹理中采样的尝试都会导致sRGB-> lRGB转换.顺便说一句,这是免费的.

Reading values in shaders via samplers (ie: accessing a texture). This is quite simple as well. OpenGL knows that the texel data in the image is in the sRGB colorspace. OpenGL assumes that the shader wants linear RGB color data. Therefore, all attempts to sample from a texture with an sRGB image format will result in the sRGB->lRGB conversion. Which is free, btw.

从好的方面来说,如果您拥有支持GL 3.x +的硬件,则几乎可以肯定会在线性色彩空间中进行过滤,这是有道理的. sRGB是一种非线性色彩空间,因此sRGB值的线性插值始终是错误的.

And on the plus side, if you've got GL 3.x+ capable hardware, you'll almost certainly get filtering done in the linear colorspace, where it makes sense. sRGB is a non-linear colorspace, so linear interpolation of sRGB values is always wrong.

将从片段着色器输出的值存储到帧缓冲区图像.这是有点复杂的地方.即使您要渲染的帧缓冲图像在sRGB色彩空间中,也不足以强制转换.您必须明确地glEnable(GL_FRAMEBUFFER_SRGB);这告诉OpenGL,您从片段着色器写入的值是线性色彩空间值.因此,在将它们存储在图像中时,OpenGL需要将它们转换为sRGB

Storing values output from the fragment shader to the framebuffer image(s). This is where it gets slightly complicated. Even if the framebuffer image you're rendering to is in the sRGB colorspace, that's not enough to force conversion. You must explicitly glEnable(GL_FRAMEBUFFER_SRGB); this tells OpenGL that the values you're writing from your fragment shader are linear colorspace values. Therefore, OpenGL needs to convert these to sRGB when storing them in the image

同样,如果您拥有GL 3.x +硬件,几乎可以肯定会在线性色彩空间中进行混合.也就是说,OpenGL将从帧缓冲区读取sRGB值,将其转换为线性RGB值,将其与传入的线性RGB值(您从着色器写入的值)混合,将混合后的值转换为sRGB色彩空间并存储它.再次,这就是您想要的;在sRGB颜色空间中混合总是不好的.

Again, if you've got GL 3.x+ hardware, you'll almost certainly get blending in the linear colorspace. That is, OpenGL will read the sRGB value from the framebuffer, convert it to a linear RGB value, blend it with the incoming linear RGB value (the one you wrote from your shader), convert the blended value into the sRGB colorspace and store it. Again, that's what you want; blending in the sRGB colorspace is always bad.

现在我们了解了,让我们看一下您的示例.

Now that we understand that, let's look at your example.

例如,我正在将帧写入FBO,然后使用FBO颜色缓冲区将屏幕大小的四边形渲染到后缓冲区(我打算很快切换到延迟阴影).

For example I am writing frames to an FBO, then later I'm rendering a screen-sized quad to the back buffer using an FBO colour buffer (I'm intending to switch to deferred shading soon).

问题是您没有问正确的问题.在进入延迟渲染时,尤其要记住的是 这个问题:

The problem with this is that you're not asking the right questions. What you need to keep in mind, especially as you move into deferred rendering, is this question:

是线性RGB吗?

通常,您应该尽可能长时间不将任何中间数据存储在伽马正确的空间中.因此,任何中间缓冲区(即,您在其中积累光的地方)都应该不是为sRGB.

In general, you should hold off on storing any intermediate data in gamma-correct space for as long as possible. So any intermediate buffers (ie: where you accumulate your lights) should not be sRGB.

这与转换成本无关;这真的是关于你在做什么.如果您要进行延迟渲染,那么您可能也在进行HDR照明等等.因此,您的光累积缓冲区需要为浮点数.浮动缓冲区始终是线性的;没有理由他们不是线性的.

This isn't about the cost of the conversion; it's really about what you're doing. If you're doing deferred rendering, then you're probably also doing HDR lighting and so forth. So your light accumulation buffer needs to be floating-point. And float buffers are always linear; there's no reason for them to not be linear.

如果要利用免费的伽玛校正(并且您可以这样做),则最终图像(默认图像缓冲)必须是sRGB.如果您在HDR浮动缓冲区中进行所有工作,然后将结果色调映射为最终显示,则应将其写入sRGB图像.

Your final image, the default framebuffer, must be sRGB if you want to take advantage of free gamma correction (and you do). If you do all your work in HDR float buffers, and then tone-map the result down for the final display, you should write that to an sRGB image.

这篇关于sRGB纹理.这样对吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆