OpenGL-着色器

着色器(shader)

其本质是运行在GPU上的小程序,这些小程序为图形渲染管线的某个特点部分而运行。 从基本意义上来讲,着色器只是一种把输入转化为输出的程序。着色器之间相互独立,因为它们之间不能相互通信,它们之间唯一的沟通是通过输入和输出。

GLSL

OpenGL驱动使用的着色器语言是一种叫做GLSL的类C语言写成的,它包含一些针对向量和矩阵操作的有用特性。(D3D11驱动是使用的着色器语言是HLSL)。
着色器的开头总是要声明版本,接着是输入和输出变量,uniform和main函数。
每个着色器的入口点都是main函数,在这个函数中我们处理所有的输入变量,并将计算后的最终结果赋值给输出变量。
典型的着色器结构如下(伪代码):

//声明使用的GLSL版本,不同版本会存在接口差异
#version version_number

//输入变量
in type in_variable_name;
in type in_variable_name;

//输出变量
out type out_variable_name;

//uniform 变量
uniform type uniform_name;

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

注意 每个输入变量也叫顶点属性(Vertex Attribute)。我们能声明的顶点属性是有上限的,它一般由硬件决定。OpenGl确保至少有16个包含4分量的顶点属性可用,大部分情况下是够用的。

向量数据类型

GLSL中的向量是一个可以包含有1,2,3或者4个分量的容器,分量类型可以是其中默认基础类型的任意一个。它们可以是下面的形式(n代表分量的数量):

类型 含义
vecn 包含n个float分量的默认向量
bvecn 包含n个bool分量的向量
ivecn 包含n个int分量的向量
uvecn 包含n个unsigned int 分量的向量
dvecn 包含n个double分量的向量

大多数情况下我们使用vecn, 因为float可以满足大部分要求了。
一个向量的分量获取方式有多种,可以是xyzw, rgba或纹理stpq的形式。
向量还能允许一些灵活有趣的分量选择组合方式,叫做重组(Swizzling)。重组允许这样的语法:

vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;

我们也可以把一个向量作为一个参数传给不同的向量构造函数。

vec2 vect = vec2(0.5, 0.7);
vec4 result = vec4(vect, 0.0, 0.0);
vec4 otherResult = vec4(result.xyz, 1.0);

输入与输出

着色器之间通过输入和输出进行数据交流和传递。GLSL因此定义了inout关键字专门来实现这个目的。每个着色器使用这两个关键字设定输入和输出,只要一个输出变量和下一个着色器阶段的输入匹配, 它就会传递下去。
顶点着色器接收的是一种特殊形式的输入,否则会导致效率低下。顶点着色器的输入特殊在,它从顶点数据中直接接收输入。为了定义顶点数据是如何管理的,我们可以在着色器中使用location字段来指定输入变量位置。

location标识符也可以忽略,应用层在配置顶点属性时会指定location位置。
片段着色器需要一个vec4颜色输出变量,因为片段着色器需要生成一个最终输出的颜色值。

示例如下:
顶点着色器

#version 330 core
layout (location = 0) in vec3 aPos; //位置属性
out vec4 vertexColor; //为片段着色器指定的颜色输出

void main()
{
  gl_Postion = vec4(aPos, 1.0);
  vertexColor = vec4(0.5, 0.0, 0.0, 1.0);
}  

片段着色器

#version 330 core
out vec4 FragColor;
in vec4 vertexColor; // 从顶点着色器传来的输入变量 (名称相同,类型相同)
void main()
{
    FragColor = vertexColor;
}

Uniform

Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但和顶点属性有些不同。首先,uniform是全局的(global),这意味着uniform变量可以被任意阶段的任意着色器对象访问。第二点,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。

在着色器程序中无法对uniform的值进行更改

使用uniform实例如下
大致步骤: 一,我们需要找到着色器中uniform属性的索引/位置值。二,调用glUniform相关方法设置其值。
需要注意的是: 更新一个uniform之前,你必须先使用程序(调用glUseProgram),针对当前激活的着色器程序中的uniform。

// 随着时间变化更新uniform的值
float timeValue = glfwGetTime();
float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
glUseProgram(shaderProgram);
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容