第八章 顶点着色器
顶点着色器是对顶点,计算光照以及纹理坐标等相关的操作,第6章,“顶点属性、顶点数组和缓冲对象”,讨论了如何指定顶点属性和统一输入,并对OpenGL ES 2.0着色语言进行了很好的描述。在第7章“图元组装和光栅化”中,我们讨论了光栅化阶段如何使用顶点着色器的输出来生成每个片段的值,然后将这些值输入到片段着色器。这里,从顶点着色器的高级概述开始,包括它的输入和输出。然后,我们讨论OpenGL ES 2.0,然后我们通过讨论几个例子来描述如何编写顶点着色器。这些示例描述了一些常见的用例,
- 例如用模型视图和投影矩阵转换顶点位置
- 生成逐顶点漫反射和镜面反射颜色的顶点照明示例
- 纹理坐标生成和顶点蒙皮。
顶点着色器
顶点着色器提供了一种对顶点进行操作的通用可编程方法。顶点着色器的输入包括以下内容:
- 属性—使用顶点数组提供的每个顶点的数据。
- 统一-顶点着色器使用的恒定数据。
- 着色器程序-顶点着色器程序源代码或可执行文件,描述将在顶点上执行的操作。(我目前使用的范围内不常用)
顶点着色器的输出称为可变变量。在图元光栅化阶段,为每个生成的片段计算这些变量的插值,并将其作为输入传递给片段着色器。
内置变量
顶点着色器的内置变量可以分为由顶点着色器输出的特殊变量、统一状态(如深度范围)和指定最大值(如属性数量、变量数量和统一数量)的常数。
首先特殊变量
- GL _POSITION-位置用于输出片段坐标中的顶点位置。gl_Position值由裁剪和视口阶段用来执行图元的适当裁剪,并将顶点位置从裁剪坐标转换为屏幕坐标。
- gl_PointSize—gl_PointSize用于以像素为单位写入点精灵的大小。渲染点精灵时使用gl_PointSize。然后,顶点着色器输出的gl_PointSize值被箝位到OpenGL ES 2.0实现支持的混叠点大小范围内。gl_PointSize是使用mediump精度限定符声明的浮点变量。
- 这个特殊的变量,虽然不是由顶点着色器直接编写的,但是是基于顶点着色器生成的位置值和渲染的图元类型生成的。gl_FrontFacing是一个布尔变量。
内置统一状态
顶点着色器中唯一可用的内置统一状态是窗口坐标中的深度范围。这是由内置的统一名称gl _ DepthRange给出的,它被声明为gl _ DepthRangeParameters类型的统一。
struct gl_DepthRangeParameters {
highp float near; // near Z
highp float far; // far Z
highp float diff; // far - near
}
uniform gl_DepthRangeParameters gl_DepthRange;
内置常量
顶点着色器中还有以下内置常量
const medump int GL _ maxvertices = 8;
const medump int GL _ maxverticalxuriormvector = 128;
const mid UMP int GL _ maxvarying vectors = 8;
const medump int GL _ maxverticaltextureimageunits = 0;
const average UMP int GL _ maxcombinationed texture units = 8;
内置常数描述了以下最大项:
- 这是可以指定的顶点属性的最大数量。所有ES 2.0实现支持的最小值是8
- 这是顶点着色器中可以使用的vec4统一条目的最大数量。所有ES 2.0实现支持的最小值是128个vec4条目。开发人员实际可以使用的vec4统一条目的数量因实现和顶点着色器的不同而不同。例如,某些实现可能会根据统一限制对顶点着色器中使用的用户指定的文字值进行计数。在其他情况下,根据顶点着色器是否使用任何内置超越函数,可能需要包含特定于实现的统一(或常量)。目前还没有一种机制可以让应用程序找到在特定顶点着色器中可以使用的统一条目的数量。顶点着色器编译将会失败,并且在编译日志中可能会有提供关于所使用的统一条目数量的特定信息的信息。但是,编译日志返回的信息是特定于实现的。我们在本章中提供了一些指导,以帮助最大限度地利用顶点着色器中可用的顶点统一条目。
- GL _ MaxVaryingVectors—这是可变向量的最大数量;也就是说,顶点着色器可以输出的vec4条目的数量。所有ES 2.0实现支持的最小值是八个vec4条目。
- 是顶点着色器中可用的纹理单元的最大数量。最小值为0,这意味着该实现不支持顶点纹理提取。
- 这是顶点+片段着色器中可用的纹理单元的最大数量的总和。最小值为八。
为每个内置常量指定的值是所有OpenGL ES 2.0实现必须支持的最小值。实现可能支持大于所述最小值的值。可以使用以下代码查询实际支持的值。
精度限定符
精度限定符可用于指定任何基于浮点或整数的变量的精度。用于指定精度的关键字有低、中、高。此处显示了一些带有精度限定符的声明示例。
highp vec4 position;
varying lowp vec4 color;
mediump float specularExp;
没有声明变量的精度,就会使用该类型的精度。
precision highp float;
precision mediump int;
浮点指定精度将基于浮点的所有变量的默认精度,如果都没有指定,那么就会使用int和float的默认精度的最高精度。
精度选择:
- 对于通常在顶点着色器中执行的操作,最可能需要的精度限定符是高精度限定符。
- 用矩阵变换位置,变换法线和纹理坐标,或者生成纹理坐标的操作需要高精度地完成。
- 颜色计算和光照方程很可能以中等精度完成。
这将取决于正在执行的颜色计算的种类以及正在执行的操作所需的范围和精度。我们相信highp很可能是顶点着色器中大多数操作使用的默认精度,因此在下面的示例中使用highp作为默认精度限定符。
ES2.0顶点着色器限制
open el es着色器语言的限制,帮助开发者编写便捷式的顶点着色器。
顶点着色器的长度
没有办法在所有的open gl中实现查询顶点着色器支持的最大指令数量,指定计数超过顶点着色器的最大指令数,顶点着色器将无法编译。