线和点的点画(stipple)模式。它还负责为光滑的点,线和多边形产生边缘的覆盖值,这些覆盖在后面片段着色器的alpha混合中会用到。如果需要,光栅化器会裁剪正面或者反面的多边形,应用多边形偏移。
? ? 除了点,线,面,光栅化也负责产生位图和像素矩形(使用glDrawPixels绘制的)的片段。
?
? ? ? 与固定功能管线相同的,雾坐标,纹理坐标和颜色可用于片段着色器。最后输出单一的颜色与先前的固定函数管线的雾阶段输出相同。在片段着色器,我们可以选择自己的方法来处理这些片段。
?
? ? 纹理查找是片段着色器中一项重要的功能。绝大部分与固定函数的方式相同,在纹理着色器外,设置纹理的状态和纹理环???,以及纹理的图片。主要的不同是,你可以在着色器中决定何时、是否执行纹理查找,以及纹理坐标如何使用。
? ? 第1个纹理坐标不一定用于索引第1个纹理图片。你可以在不同的纹理中使用同一个纹理坐标,也可以在同一个纹理中使用不同的纹理坐标。甚至,你可以在运行时去计算纹理坐标。这种灵活性在固定函数的方式是不可能实现的。
? ? 在之前的固定函数的方式中,纹理环境的设置中包含了一项决定如何进行片段的颜色和纹理查找结果混合。如(glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV, GL_DECAL))。这个在片段着色器中被忽略了。如何进行混合完全取决于你的片段着色器的操作。当然片段着色器也可以不做事情,只是简单的把输入的主颜色拷贝到输出的颜色中。
?
? ? 这个阶段的处理非常简单,仅仅是把主颜色和辅助颜色相加。如果我们不使用辅助颜色,就直接忽略它。
?
? ? 雾的应用也是简单的。首先我们根据公式用雾坐标和雾浓度的常量来计算雾因子。在固定的函数管线中,有几个固定编码的方程式,线性的,指数的,二次指数的方程。但在着色器中你可以编写自己的方程式来计算雾因子。如果我们不使用雾,那我们就不需要在着色器中添加任何关于雾的指令。
OpenGL着色器语言的简单的例子
顶点着色器:
void main(void)
{
? ? //输入的顶点执行变换,变换到裁剪坐标
? ? vec4 clipCoord = gl_ModelViewProjectionMatrix * gl_Vertex;
? ? //复制到输出的位置
? ? gl_Position = clipCoord;
? ? //复制主颜色
? ? gl_FrontColor = gl_Color;
//规格化坐标
? ? vec3 ndc = clipCoord.xyz / clipCoord.w;
? ? // 输出前把[-1,1]映射到[0,1]
? ? gl_SecondaryColor = (ndc * 0.5) + 0.5;
}
片段着色器
void main(void)
{
? ? //混合主颜色和辅助颜色
? ? gl_FragColor = mix(gl_Color, vec4(vec3(gl_SecondaryColor), 1.0), 0.5);
}
上面的着色器简单的模拟了一些固定函数管道的一些功能。其中以gl_为前缀的是GLSL内置的变量。其中gl_Vertex代表输入的顶点,gl_ModelViewProjectionMatrix是模型视图矩阵和投影矩阵的结合,我们用gl_ModelViewProjectionMatrix * gl_Vertex; 就可以得到裁剪的坐标了。 gl_Position是输出的顶点的位置。 gl_Color在顶点着色器和片段着色器中有着不同的含义。在顶点着色器中gl_Color代表着用户的输入,即通过glColor等方式的输入。而在片段着色器中的gl_Color代表经过插值的片段的颜色。
在编写完上面两个着色器,并编译连接应用后,每个顶点及其附属的属性都会经过顶点着色器的处理器,然后裁剪,光栅化成片段,然后片段再经过片段着色器的处理。
后面再详细介绍GLSL语言。。。