在Phong模型的Wikipedia页面上,它表示环境项是一个常数,只是将其添加到其他项上。但是在像LearnOpenGL这样的其他页面上,它说您应该使用环境术语并将其乘以对象的颜色。哪个是正确的?

评论

请注意,在文章的后面,维基百科说:“当颜色以RGB值表示时(在计算机图形学中通常是这种情况,该方程式通常针对R,G和B强度分别建模,从而允许不同的反射常数ka,{\ displaystyle k _ {\ text {a}},} k _ {\ text {a}},kd {\ displaystyle k _ {\ text {d}}} k _ {\ text {d}}和ks {\ displaystyle k _ {\ text {s}}} k _ {\ text {s}}用于不同的颜色通道。“

#1 楼

正确的是OpenGL方式。如果您发出白光(例如vec3(255,255,255))
,而只是将其添加到蓝色对象(vec3(0,0,255))中,则该对象似乎是白色的,这是错误的。但是,如果要乘以这些颜色,则对象将被完全照亮并正确地变成蓝色(这是所需的产品)。

带有环境光的东西是它仅受环境光强度的影响以及物体的颜色,这意味着它不受灯光位置,方向或任何种类的影响。这就是为什么您可以将其视为“简单地将其添加为常量”的原因。
我们主要使用环境光来模拟场景中的反射光,否则很难模拟(没有光线追踪) 。这是一个相当不错且便宜的选择。

评论


$ \ begingroup $
谢谢!您的回答以及Dan的回答都很好地涵盖了我的问题。我将确保使用这一新知识。
$ \ endgroup $
–丹尼尔·卡瑞(Daniel Kareh)
17年7月5日在16:24

#2 楼

Wikipedia页面上的相关等式如下:

$$
I_ \ text {p} = k_ \ text {a} i_ \ text {a} + \ sum_ {m \; \ in \; \ text {lights}}(k_ \ text {d}(\ hat {L} _m \ cdot \ hat {N})i_ {m,\ text {d}} + k_ \ text {s}(\ hat {R} _m \ cdot \ hat {V})^ {\ alpha} i_ {m,\ text {s}})
$$

在此等式中,所有$ k $和$ i $术语不是数字,而是颜色(RGB强度)。其中包括$ k_a $和$ i_a $:对象的环境颜色和环境照明颜色。环境项不是常数:它是强度和反照率的乘积,就像镜面反射项和漫反射项一样。唯一的区别是,在此术语中,照明和视图方向不是因素。

$ k_a $与漫反射颜色不同是非常不寻常的,因此您可以将其乘以“对象的颜色”。就是说,$ i_a $是一种独特的颜色是很常见的:例如,如果您在阳光直射下使用偏黄色的定向光,则可能希望环境光偏蓝以代替天光。

评论


$ \ begingroup $
谢谢!您的回答和Michal的回答都很好地向我解释了它。下次我必须记住此代码着色器。
$ \ endgroup $
–丹尼尔·卡瑞(Daniel Kareh)
17年7月5日在16:23

#3 楼

我认为我们既要兼有又要有一个基于材料的因素

某些材料具有很高的扩散性,因此它将仅反射其自身颜色的光。但是某些材料也可以照原样反射某些光。对于Phong着色器,我认为我们使用了附加的环境,因为Phong对象倾向于反射所有光,因此可以用该光的颜色将环境光照亮,但是其他光也用于制作漫反射色

与兰伯特相反,如果我知道正确的话,是材质具有高扩散性,因此将环境光添加到照明中并乘以材质的颜色

我想现代着色器应该设置一个参数这个因子并写出这样的方程式

float factor; // 0.0 - 1.0 maybe reflectiveness?
float3 light = (factor * ambient.rgb); // ambient light
light += _MainLightColor.rgb * dot(normal,_MainLightDirection); // lambert
// maybe also specular
float3 color = ((1 - factor) * ambient.rgb) + (matColor * light);


实际上我是从PBR材料中得出这个概念的,其中有一个节能的概念。所有的光都可能通过漫射或反射来照亮对象,但是为了节省能量,漫反射的颜色越多意味着反射越少。因此,环境光只会增加更多的光能,然后像对待其他光一样被对待