首页 > 代码库 > GLSL Core Tutorial – Vertex Shader
GLSL Core Tutorial – Vertex Shader
译自:http://www.lighthouse3d.com/tutorials/glsl-core-tutorial/vertex-shader/
一个顶点shader作用于一些独立的点,每个顶点操作一次。shader并不清楚其它组成图形图元的那些顶点,也没有说明作用的顶点属于哪种类型图元。对于每一个输入顶点,shader输出单一顶点(简单说就是顶点shader是逐顶点操作,作用结果还是一些顶点)
每一个顶点都有着用户定义的一些输入属性,例如:位置,法线向量,纹理坐标。顶点shader同样可以被uniform变量访问,它作为绘制命令中所有顶点的全局只读变量。
除了用户定义的变量,GLSL本身定义了一些顶点属性。
in int gl_VertexID;in int gl_InstanceID;
gl_VertexID是指向属性数组中顶点的索引。当使用instance时,shader对每一个顶点操作n次,n是在glDraw*命令中说明的instances数字gl_InstanceID提供instance的索引。如果不使用instances,n始终为0。
顶点shader获取输入属性,输出顶点,计算它们的属性。下面是在顶点shader中可写的固定输出属性。
out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[];};
对其中的任意项进行写操作是可选的;然而,在顶点shader之后的一些固定函数步骤期待gl_Position被写。这是因为这个变量的目的是存储输出顶点位置的齐次坐标。
除此之外,shader可以输出用户定义的每个顶点变量。
下面是展示顶点shader特性的一个简单例子:
#version 410 layout (std140) uniform Matrices { mat4 projModelViewMatrix; //mvp矩阵 mat3 normalMatrix; //法线矩阵}; in vec3 position; //顶点in vec3 normal; //法线in vec2 texCoord; //纹理 out VertexData { //输出顶点属性块 vec2 texCoord; vec3 normal;} VertexOut; void main(){ VertexOut.texCoord = texCoord; VertexOut.normal = normalize(normalMatrix * normal); gl_Position = projModelViewMatrix * vec4(position, 1.0); //对顶点进行坐标变换}
上面的顶点shader接收三个用户自定义的顶点属性:position, normal, texCoord。它接受一个叫做Matrices的 unifrom块,包含着两个对顶点和法线进行变换的矩阵。 顶点shader的输出同样是用户定义的属性,texCoorOut和normal, 和一个GLSL内置的属性gl_Position(以gl_开头的变量)。要注意的是输出变量也包含在一个名字块里。输出在main函数中计算得到。每一种shader都必须要main函数,跟C程序一样,也可以定义其它附加的函数。
ps:下面说的是一些使用顶点缓存和性能之间关系的内容。
Notes regarding performance
Performance wise, there is a vertex cache that stores the outputs of the last n processed vertices. Before a new vertex is processed, its index is checked against the indices in the vertex cache. If the index is in the vertex cache, the respective previously processed data is sent to the remaining of the pipeline without further processing.
Taking advantage of the vertex cache, can therefore improve performance when using indexes, either explicitly, or implicitly, as in triangle strips and fans. For instance, in a triangle strip, at most one vertex per new triangle will be processed. When using indexes with regular triangles, the gain is not as easy to compute, and the indices may require a reorganization of the vertex data to improve vertex cache hits.
When the vertex data is not a strip, it can be converted to a strip or a set of strips. NVTriStrip is a tool from NVIDIA that performes this task. It takes the array of indices and tries to create strips as large as possible. Other approaches, namely Tom Forsyth’s algorithm (based on a cache of vertices using a least recently used (LRU) replacement policy), reorganize the index data to increase hits, keeping the GL_TRIANGLES
mode. Tootle, Triangle Order Optimization Tool, is an AMD tool to optimize models, to reduce pixel overdraw and increase post-transform cache and vertex prefecth cache hits. This latter improvment is achieved by the reorganization of the vertex data itself, so that vertices in a triangle are close to each other on memory. Adrian Stone has written an article where several algorithms are disscussed and tested. Ignacio Castaño has focused on grids on this article.
GLSL Core Tutorial – Vertex Shader