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.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战