OpenGL中的着色语言


Glimpse

GLSL是专门用来OpenGL shader的语言,shader是可以直接在GPU上运行的小程序,一般以字符串的方式在代码中使用。shader分为vertex shader(顶点着色器)与fragment shader(片段着色器)两种,顶点shader在每个顶点执行一次,片段shader在每个像素执行一次,两者配合决定模型的渲染结果。

变量类型

GLSL中用来传递值的变量类型有三种:attributeuniformvarying

  • attribute
    attribute变量只存在于顶点shader,用于顶点shader接收CPU传来的数据,多为顶点相关的数据。attribute给了CPU一个向shader传递值的接口,CPU通过变量名获取attribute变量在GPU的地址,使用glVertexAttribPointer命令向其赋值。通常CPU将模型的顶点数据传给shader,shader会依次对每个顶点通过一系列矩阵操作,确定其最终位置,赋值给顶点shader内建的输出变量gl_position供渲染管线下一步使用。
//get attribute slot position
_vertexPosition = glGetAttribLocation(_programHandle, "vertexPosition");
//feed attribute slot
glVertexAttribPointer(_vertexPosition, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, 0);
  • uniform
    uniform常量在shader中不可变,不同于attribute变量,其在顶点shader和片段shader中都可以使用,如果两个shader中都声明了同一个uniform变量,那么他们值是相同的。CPU通过变量名获取uniform变量在GPU的地址,使用glUniform1i命令向其赋值。通常CPU通过uniform常量向GPU传递纹理等数据块。
//get uniform slot position
GLint yuvType = glGetUniformLocation(_programHandle, "yuvType");
//feed uniform slot
glUniform1i(1, yuvType);
  • varying
    顶点shader用varying变量向片段shader传递值。使用时,在顶点shader与片段shader中定义同一个varying变量,顶点shader在顶点执行完之后,会自动将值传递给片段shader。varying变量CPU是不可见的,一般是顶点shader中计算并赋值。通常varying变量用来传递顶点的颜色值、纹理坐标。渐变量有一个重要的特点是可以自动插值。从CPU传给GPU的只是模型每个顶点的属性,对于顶点之间的线或面上的像素属性(主要是其颜色和纹理坐标),渐变量可以根据该像素在顶点间的位置自动插值出来。 这个特点也是为符合其用途的需要。

GLSL有一些特定的数据类型,如vec表示向量、mat表示矩阵、sample2D/sample3D表示纹理。
除此之外GLSL还拥有自己的内建变量,即以gl_开头的变量。可以看这里查阅

语法

GLSL的是基于C的一种语言,语法与其相同,每个shader都由main函数作为程序入口。不同的是shader都有自己的内建变量,使用它们可以与渲染管线通信。例如顶点shader的任务就是计算顶点的最终位置并赋值给gl_Position,片段shader计算每个像素的颜色并赋值给gl_FragColor

以下是一对简单的shader,顶点shader接受CPU传来的vertexPosition与pixelColor,再将pixelColor传递给片段shader,GPU根据它们的计算结果渲染结果。

vertex shader:

//attribute 关键字用来描述传入shader的变量
attribute vec4 vertexPosition; // 需要从外部获取的4分量vector
attribute vec4 pixelColor; 
//varying 关键字用来描述从vertex shader传递给fragment shader的变量
//精度修饰符分为三种:highp, mediump, lowp
varying mediump vec4 finalPixelColor; //mediumP修饰代表中等精度,提高效率。
 
void main(void) { 
    finalPixelColor = pixelColor; // 将pixelColor的值通过finalPixelColor传递给fragment shader
    gl_Position = vertexPosition; // gl_Position是vertex shader的内建变量,gl_Position中的顶点值最终输出到渲染管线中
}

fragment shader:

varying mediump vec4 finalPixelColor; 
 
void main(void) { 
    gl_FragColor = finalPixelColor; // gl_FragColor是fragment shader的内建变量,gl_FragColor中的像素值最终输出到渲染管线中
}

最后

我这里只是基本介绍了下Shader的知识,实际上Shader是支撑各种炫酷特效的幕后功臣,相关的技术也非常深,感兴趣的小伙伴可以去ShaderToy里看一下大神写的Shader是什么样的。

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

推荐阅读更多精彩内容