gl_FragColor 值是不是应该标准化?

Posted

技术标签:

【中文标题】gl_FragColor 值是不是应该标准化?【英文标题】:Should the gl_FragColor value be normalized?gl_FragColor 值是否应该标准化? 【发布时间】:2014-05-15 20:39:14 【问题描述】:

我正在编写一个 Phong 光照着色器,我很难决定是否应该对传递给 gl_FragColor 的值进行归一化。

如果我使用标准化值,照明会有点奇怪。例如,远离光源(未点亮)的对象的颜色将由发射分量、环境分量和全局环境光的总和确定。让我们说加起来是(0.3, 0.3, 0.3)。正常情况大约是(0.57, 0.57, 0.57),比我预期的要亮得多。

但是,如果我使用非归一化值,对于近距离的物体,镜面反射区域会变得非常非常明亮,我必须确保我的材质常数通常使用较低的值。

请注意,我只对 RGB 分量进行归一化,而 alpha 分量始终为 1。

我有点不知所措,找不到与此相关的任何内容。要么那个,要么我的搜索完全错误。

【问题讨论】:

【参考方案1】:

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

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

另一种理解颜色归一化为什么错误的方法,考虑渲染灰度图像的不太一般的情况。由于只有一个颜色分量,归一化根本没有意义,因为它会使你的所有颜色都变成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缓冲区更大的范围,然后模拟相机或人眼适应一定光强度的行为以及由此机制引起的图像伪影(即绽放)。

【讨论】:

谢谢,我怀疑没有万无一失的方法,目前降低材料常数/光强度似乎是我最好和最简单的选择。

以上是关于gl_FragColor 值是不是应该标准化?的主要内容,如果未能解决你的问题,请参考以下文章

R中是不是有一种方法,如果一列的值满足另一列中的某个标准,则该列的值应该是上面的值

标准数字字符串

gl_FragColor 如何影响模板缓冲区?

我的OpenGL学习进阶之旅着色器GLSL运行时报错: ERROR: 0:40: ‘gl_FragColor‘ : undeclared identifier

我的OpenGL学习进阶之旅着色器GLSL运行时报错: ERROR: 0:40: ‘gl_FragColor‘ : undeclared identifier

查找具有特定标准的最大值并检查同一组是不是有更高/更低或任何值