有人可以解释这个代码如何将每个顶点光照转换为每个像素?

时间:2010-09-17 13:40:57

标签: opengl

在教程中,有一个类型

的漫反射值计算
float diffuse_value = max(dot(vertex_normal, vertex_light_position), 0.0);

..在顶点着色器上。

如果稍后在片段着色器上,那应该是按顶点照明。

gl_FragColor = gl_Color * diffuse_value;

然后当他将第一行 - 适当地(通过输出vertex_normal和vertex_light_position到片段) - 移动到片段着色器时,它应该将方法转换为“每像素着色”。

怎么回事?第一种方法似乎是每个像素都进行diffuse_value计算!

3 个答案:

答案 0 :(得分:1)

第一种情况下的

diffuse_value是在顶点着色器中计算的。所以它只在每个顶点完成。

在顶点着色器输出值之后,光栅化器获取这些值(每个矢量每个三角形3个)并且插值(以透视正确方式)它们为每个像素提供不同的值。实际上,插入这样的矢量(法线和光线方向矢量)是不合适的,因为它失去了它们的归一化属性。许多实现实际上会首先将片段着色器中的向量标准化。

但是插入2个矢量的点(矢量照明有效地做了什么)更糟糕。比如说你的所有顶点都是N = + Z而另一个是L = norm(Z-X)而另一个是L = norm(Z + X)。

N.L = 1/sqrt(2) for both vertices. 

插值将为您提供平坦的光照,而实际插入N和L分别和重新归一化将为您提供您期望的结果,一个正好在多边形中间达到峰值的光照。 (因为规范(Z-X)和范数(Z + X)的插值一旦归一化就会给出正确的Z。)

答案 1 :(得分:0)

嗯......顶点着色器中的代码仅按顶点进行评估,并使用该顶点的输入值。

但是当移动到片段着色器时,它会按照每个像素进行评估,即每个像素,并在顶点之间插入适当的输入值。

至少这是我的理解,但我对着色器编程很生疏。

答案 2 :(得分:0)

如果在顶点着色器中计算diffuse_value,则表示它是按顶点计算的。然后,它在三角形的像素上进行线性插值,并输入像素着色器。 (如果没有每像素法线,那么就可以做到。)然后,在像素着色器中,使用该diffuse_value调制多边形颜色(插值)。