math背后Phong阴影和添加剂混合

我对于和Phong底纹一起使用的添加剂混合背后的math感到困惑。 直观地看来,您似乎需要使用浮点帧缓冲和某种色调映射来实现许多光源的实际近似。 由于照明值被计算为diffuse + specular ,因此可以将多个光源编码为:

 finalColor = ambient for light in lights: finalColor += light.specular + light.diffuse 

现在,假设你有多个白色的灯光照射在一个完全分散的,但大部分是红色的球体上。 您添加的灯光越多,最终渲染的球体越接近球体的实际颜色。 在这种情况下,如果使用8位RGBA帧缓冲,则使用glBlend(GL_ONE, GL_ONE)进行渲染实际上会导致球体在极限内达到白色,与此问题中所述的效果类似。

我的问题是双重的:

  1. 我的直觉是否正确?
  2. 如果是这样,你如何对付这种情况呢? 如果没有,为什么不呢?

Solutions Collecting From Web of "math背后Phong阴影和添加剂混合"

这个问题并没有特别的加法math。 通过加法解决多个光源的贡献。 在渲染方程中我们可以清楚地看到。 在这里输入图像说明

正如我们在等式中看到的那样,光贡献在单位半球上被整合,包含所有光方向(Wi)的所有可能的值。 在实时计算机graphics中,我们只考虑直接连接到灯的方向(Wi),而不考虑完整的半球,因此这个方程转换成所有光贡献的总和。

我的观点是:加法math没有错。 问题在于8位数字的小dynamic范围。 将太阳光和灯泡表示为颜色(1,1,1)并不特别反映真实世界的辐射亮度值。 对于这种色调映射和其他技术的发明是能够渲染高dynamic范围的图像,并将其映射到32位帧缓冲区的有限范围。

我不认为这会发生,我还没有使用过它,但是如果你想一想,就会把光线的贡献乘上物体的颜色,就像你提供的方程一样

 finalColor = ambient for light in lights: finalColor += light.specular + light.diffuse finalColor *= objectColor; 

甚至在现实生活中,如果你看到它后打蜡,如果你有一个非常shiny的物品,如汽车底盘,那么它会看起来是白色的,所以你只需要混合设置来满足你的需要,一个提示你现在正在做的事渲染,gool运气:)。

Phong模型的最终颜色取决于材料的光泽度和镜面reflection率。 如果光泽度非常高或镜面reflection率低,则最终颜色接近球体的反照率。 否则,颜色接近浅色。

如果您在低dynamic范围(LDR)中进行渲染,尽管您可能会得到颜色饱和度并出现意想不到的结果,例如添加像rgb = [1,0.5,0.5]这样的微红颜色,将导致白色,因为rgb分量被钳位到范围[0,1]。 使用HDR,您可以获得超出该范围的值,并且可以使用全局色调映射操作符将其重新映射到常规监视器上显示的LDR [0,1]范围。

一些游戏用于呈现LDR目标,但在着色器中执行色调映射,然后将结果写出来以避开成本较高且内存沉重的HDR渲染部分和混合。 虽然它有一个明显的混合问题,例如混合在普通照明中的透明物体没有色调映射,所有的照明必须一次完成。