我真的不明白片段着色器是如何工作的。
我知道
由于片段着色器不适用于每个顶点,而是每个片段都不能将数据发送到片段着色器?顶点数量和片段数量不相等。
如何确定哪个片段属于哪个顶点?
为了理解这一点,您需要考虑整个渲染管道。顶点着色器的输出(除了特殊输出gl_Position
)作为顶点的“关联数据”传递到管道的下一级。
尽管顶点着色器一次只在一个顶点上工作,根本不关心基元,但管道的其他阶段确实考虑了基元类型(以及顶点连接性信息)。这就是通常所说的“原始程序集”。现在,我们仍然具有由VS生成的相关数据的单个顶点,但是我们也知道将哪些顶点组合在一起以定义基本的图元,例如点(1个顶点),线(2个顶点)或三角形(3顶点)。
在栅格化期间,将为属于图元的输出像素栅格中的每个像素位置生成片段。这样,可以插入定义原始数的顶点的相关数据遍及整个primitive。在一行中,这非常简单:完成了线性插值。让我们将端点A和B分别与一些关联的输出向量v一起调用,这样我们就有v_A和v_B。跨越这条线,我们获得v的内插值,即在每个端点处的v(x)=(1-x)* v_A + x * v_B,其中x在0(在A点)到1(在A点)的范围B)。对于三角形,使用所有3个顶点的数据之间的重心插值。因此,尽管在顶点和片段之间没有1:1映射,但是VS的输出仍然定义FS的相应输入的值,只是不是直接地,而是通过使用的原始类型的插值来间接地定义。
到目前为止,我给出的公式有些简化。实际上,默认情况下,实际上通过应用公式修改修正了透视图,从而考虑了透视图的失真效果。这只是意味着插值应该像在对象空间中线性应用那样起作用(在施加投影的失真之前)。例如,如果您有一个透视投影和一些不平行于图像平面的图元,则在屏幕空间中向右移动1个像素确实意味着在实际对象上移动可变的距离,具体取决于实际点到相机平面。
您可以通过noperspective
对GLSL中的in
/out
变量使用限定符来禁用透视校正。然后,如我所描述的那样使用线性/重心插值。
您也可以使用flat
限定符,它将完全禁用插值。在这种情况下,整个原始图元的所有片段都只使用一个顶点(所谓的“激发顶点”)的值。整数永远不能由GL自动插值,并且必须像flat
发送到片段着色器时一样被限定。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句