OpenGL - 顶点着色器

概述:
顶点着色器提供顶点操作的通用可编程方法.

属性 :                    用顶点数组提供的逐顶点数据.
统一变量和统一变量缓冲区 :   顶点着色器使用的不变数据
采样器 :                  代表顶点着色器使用的纹理的特殊统一变量类型.
着色器程序 :               顶点着色器程序源代码或者描述在操作顶点的可执行文件.
顶点着色器

一个典型的着色器有下面的结构:

#version version_number
in type in_variable_name;
in type in_variable_name;

out type out_variable_name;

uniform type uniform_name;

int main()
{
  // 处理输入并进行一些图形操作
  ...
  // 输出处理过的结果到输出变量
  out_variable_name = weird_stuff_we_processed;
}

修饰符

  • uniform
uniform变量是外部application程序传递给(vertex和fragment)shader的变量.
uniform变量一般用来表示:变换矩阵,材质,光照参数和颜色等信息。
以下是例子:
uniform mat4 viewProjMatrix; //投影+视图矩阵
uniform mat4 viewMatrix;        //视图矩阵
uniform vec3 lightPosition;     //光源位置
  • attribute
attribute变量是只能在vertex shader中使用的变量。
它不能在fragment shader中声明attribute变量,也不能被fragment shader中使用.
一般用attribute变量来表示一些顶点的数据,如:顶点坐标,法线,纹理坐标,顶点颜色等。
  • varying
varying变量是vertex和fragment shader之间做数据传递用的。一般vertex shader修改varying变量的值,
然后fragment shader使用该varying变量的值。因此varying变量在vertex和fragment shader二者之间的声明必须是一致的。application不能使用此变量。

顶点着色器内建变量

  • 特殊变量(顶点着色器的输入输出)
  • 统一状态(如深度范围)
  • 规定最大值(如属性数量,顶点着色器输出变量数量和统一变量数量)的常量

內建特殊变量

  • gl_VertexID是一个输入变量,用于保存顶点的整数索引.
这个整数型变量用highp精度限定符声明.
  • gl_InstanceID是一个输入变量,用于保存实例化绘图调用中图元的示例编号.
对于常规的绘图调用,该值为0.
gl_InstanceID是一个整数型变量,用highp精度限定符声明.
  • gl_Position用于输出顶点位置的裁剪坐标.
该值在裁剪和视窗阶段用于执行相应的图元裁剪以及从裁剪坐标到屏幕坐标的顶点位置转换.
如果顶点着色器未写入gl_Position.则该值未定义.
gl_Position是一个浮点变量,用highp精度限定符声明.
  • gl_PointSize用于写入以像素表示的点精灵尺寸,在渲染点精灵时使用.
顶点着色器输出的gl_PointSize值被限定在OpenGL ES 3.0实现支持的非平滑点大小范围之内.
该值是一个浮点变量,用highp精度限定符声明.
  • gl_FrontFacing是一个特殊变量,但不是由顶点着色器直接写入的,而是根据顶点着色器生成的位置和渲染的图元类型生成的.
该值是一个布尔变量

內建统一状态

struct gl_DepthRangeParameters {
    highp float near;
    highp float far;
    highp float diff;
}
uniform gl_DepthRangeParameters gl_depthRange;

內建常量

const mediump int gl_maxVertexAttribs                  = 16
const mediump int gl_maxVertexUniformVectors           = 256
const mediump int gl_maxVertexOutputVectors            = 16
const mediump int gl_maxVertexTextureImageUnits        = 16
const mediump int gl_maxCombindedTextureImageUnits     = 32
  • gl_maxVertexAttribs : 是可以指定的顶点属性的最大数量.
  • gl_maxVertexUniformVectors : 顶点着色器可以使用的vec4统一变量项目的最大数量
  • gl_maxVertexOutputVectors : 输出向量的最大数量
  • gl_maxVertexTextureImageUnits : 顶点着色器中可用的纹理单元的最大数量.
  • gl_maxCombindedTextureImageUnits : 顶点和片段着色器中可用纹理单元最大数量的总和.
PS : 以上的內建常量指定的值是所有OpenGL ES 3.0 实现必须支持的最小值.实现各种可能支持超过上面所述的最小值的常量值.实际支持的值可以用下面的代码查询.
    GLint maxVerterAttribs,maxVerterUniforms, maxVaryings;
    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVerterAttribs);
    glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxVerterUniforms);
    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
    
    GLint maxVerterTextureUnits,maxCombinedTextureUnits;
    glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVerterTextureUnits);
    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedTextureUnits);

精度限定符

highp lowp mediump

顶点着色器示例

演示如何在顶点着色器中实现如下功能

  • 用一个矩阵变化顶点位置
  • 进行照明计算,生成逐定点漫射和反射颜色
  • 纹理坐标生成
  • 顶点蒙皮
  • 用纹理查找值代替顶点位置

矩阵变化

描述一个用OpenGLES 着色器语言编写的简单顶点着色器.这个顶点着色器获取一个位置和其相关的颜色数据作为输入或者属性.用一个4x4矩阵变换位置,并输出变化后的位置和颜色.

#version 300 es
uniform mat4 u_mvpMatrix;
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec4 a_color;
out vec4 v_color;
void main() {
  v_color = a_color;
  gl_Position = u_mvpMatrix * a_position;
}

顶点着色器的位置输入保存为物体坐标,而输出位置保存为裁剪坐标.
MVP矩阵是3D图形中进行这种变化的3个非常重要的变化矩阵的乘积:模型矩阵,视图矩阵和投影矩阵.
组成MVP矩阵的每个单独矩阵执行的变化如下:

  • 模型矩阵 ---- 将 物体 坐标变换为 世界 坐标.
  • 视图矩阵 ---- 将 世界 坐标变换为 眼镜 坐标.
  • 投影矩阵 ---- 将 眼睛 坐标变换为 裁剪 坐标.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容