gl_FragColor值应该标准化吗?

时间:2014-05-15 20:39:15

标签: glsl shader normalization lighting phong

我正在写一个Phong灯光着色器,我很难确定传递给gl_FragColor的值是否应该归一化。

如果我使用标准化值,则灯光有点奇怪。例如,远离光源(未点亮)的物体的颜色将由发射分量,环境分量和全局环境光的总和确定。我们说这加起来是(0.3, 0.3, 0.3)。正常情况大致是(0.57, 0.57, 0.57),这比我期待的要亮得多。

但是,如果我使用非标准化值,对于近似对象,镜面反射区域变得非常非常明亮,我必须确保我的材质常数通常使用较低的值。

作为一个注释,我只规范了RGB组件,alpha组件始终为1。

我有点淹没,我找不到与此相关的任何内容。或者我的搜索完全错误。

1 个答案:

答案 0 :(得分:1)

没有。将颜色标准化会产生一种有趣的效果,但我认为如果不是所有的话,你并不是最想要它。

颜色输出的标准化会导致信息丢失,即使在某些情况下它似乎可以为场景提供更多细节。如果所有碎片的颜色都已标准化,则表示所有RGB矢量的范数均等于1。这意味着输出中根本不存在颜色:白色(norm = sqrt(3)),明亮的颜色(如黄色(norm = sqrt(2))),深色(如深红色(norm(0.5, 0.0, 0.0) = 0.5)),您可能面临的另一个问题是归零化零矢量(即黑色)。

另一种理解颜色归一化为何错误的方法,请考虑渲染灰度图像的一般情况。由于只有一个颜色组件,因此标准化根本没有意义,因为它会使您的所有颜色1.0


使用未经规范化的值的问题源于您的输出图像必须将其颜色值固定为固定间隔:[0, 255][0.0, 1.0]。由于物体的镜面反射部分反射的光比仅反射漫反射光的部分更多,因此很可能计算出的颜色值甚至可以超过(1.0, 1.0, 1.0),并且对于大部分镜面区域都会被钳制为白色,因此这些区域可能会变成太亮了。

一个简单的解决方案是降低材料常数值或光强度。您可以更进一步,确保选择材料常数和光强度的值,使计算出的颜色值不超过(1.0, 1.0, 1.0)。如果对场景中的所有材质和所有灯光使用一致的值,则可以通过简单划分计算的颜色值来实现相同的结果,但它有点矫枉过正,因为场景可能太暗。


更复杂但更好看的解决方案包括HDR rendering和曝光过滤器,例如bloom,以获得更逼真的照片。这基本上意味着将场景渲染成浮动缓冲区,该缓冲区可以处理比[0, 255] RGB缓冲区更大的范围,然后模拟适应特定光强度的相机或人眼行为以及由此机制引起的图像伪影(即绽放)。