在教程中,有一个类型
的漫反射值计算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计算!
答案 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调制多边形颜色(插值)。