OpenGL GLSL語(yǔ)言

GLSL - OpenGL Shading Language也稱(chēng)作GLslang,是一個(gè)以C語(yǔ)言為基礎(chǔ)的高階著色語(yǔ)言。為開(kāi)發(fā)者提供對(duì)繪圖管線(xiàn)更多的直接控制牧牢,而無(wú)需使用匯編語(yǔ)言或硬件規(guī)格語(yǔ)言若贮。

GLSL類(lèi)型

OpenGL著色器語(yǔ)言規(guī)格定義了 22 個(gè)基本變量類(lèi)型,大部分用法與C語(yǔ)言相同,其它的是繪圖處理器特有的合武。

  • void – 用于沒(méi)有返回值的函數(shù)
  • bool – 條件類(lèi)型,其值可以是真或假
  • int – 有符號(hào)的整數(shù)
  • float – 浮點(diǎn)數(shù)
  • vec2 – 2 個(gè)浮點(diǎn)數(shù)組成的向量
  • vec3 – 3 個(gè)浮點(diǎn)數(shù)組成的向量
  • vec4 – 4 個(gè)浮點(diǎn)數(shù)組成的向量
  • bvec2 – 2個(gè)布爾類(lèi)型數(shù)組成的向量
  • bvec3 – 3個(gè)布爾類(lèi)型數(shù)組成的向量
  • bvec4 – 4個(gè)布爾類(lèi)型數(shù)組成的向量
  • ivec2 – 2個(gè)整數(shù)組成的向量
  • ivec3 – 3 個(gè)整數(shù)組成的向量
  • ivec4 – 4 個(gè)整數(shù)組成的向量
  • mat2 – 浮點(diǎn)數(shù)的2x2矩陣
  • mat3 – 浮點(diǎn)數(shù)的3x3矩陣
  • mat4 – 浮點(diǎn)數(shù)的4x4矩陣
  • sampler1D – 用來(lái)存取一維紋理的采樣器
  • sampler2D – 用來(lái)存取二維紋理的采樣器
  • sampler3D – 用來(lái)存取三維紋理的采樣器
  • samplerCube – 用來(lái)存取立方映射紋理的采樣器
  • sampler1Dshadow – 用來(lái)存取一維深度紋理的采樣器
  • sampler2Dshadow – 用來(lái)存取二維深度紋理的采樣器

從上面的類(lèi)型可以看出涡扼,GLSL著色器語(yǔ)言是由標(biāo)量稼跳、向量、矩陣吃沪、采樣器等基本數(shù)學(xué)數(shù)據(jù)元素類(lèi)型組成的汤善。這也是數(shù)學(xué)描素圖像學(xué)的基本數(shù)據(jù)類(lèi)型。當(dāng)然和C語(yǔ)言一樣票彪,GLSL語(yǔ)言也有能力用基本數(shù)據(jù)類(lèi)型構(gòu)成復(fù)雜的數(shù)據(jù)红淡。例如:支持結(jié)構(gòu)和數(shù)組。

注意:GLSL語(yǔ)言不支持雙精度浮點(diǎn)型降铸、字節(jié)類(lèi)型在旱、短整型、長(zhǎng)整型推掸。并且沒(méi)有聯(lián)合體桶蝎、枚舉類(lèi)型驻仅、無(wú)符號(hào)整型以及位運(yùn)算等特性。

數(shù)據(jù)類(lèi)型的使用

GLSL語(yǔ)言數(shù)據(jù)類(lèi)型的使用和C語(yǔ)言類(lèi)似登渣,都先聲明再使用噪服,有使用域,變量初始化也符合C語(yǔ)言語(yǔ)法胜茧。下面說(shuō)一下C語(yǔ)言沒(méi)有的類(lèi)型初始化和引用示例:

vec4 va = vec4(1.0,2.0,3.0,4.0);
vec3 vb = va.rgb; // 顏色相關(guān) argb
vec3 vc = va.xyz; // 坐標(biāo)相關(guān) xyzw
vec4 vd = va.stuv // 紋理相關(guān) stuv
vec4 vf = va.aagg // 可以組合粘优,但只能同類(lèi)型組合
mat3 ma = mat3(1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0);
mat3 mb = mat3(1.0) // 1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0;

特殊的內(nèi)建變量

著色器代碼的開(kāi)發(fā)中會(huì)使用到很多變量,其中大部分可能是由開(kāi)發(fā)人員根據(jù)需求自定義的竹揍,但著色器也提供了一些用來(lái)滿(mǎn)足特定需求的內(nèi)建變量敬飒,這些內(nèi)建變量不需要聲明即可使用,一般用來(lái)實(shí)現(xiàn)渲染管線(xiàn)固定功能部分與自定義頂點(diǎn)或片元著色器之間的信息交互芬位。

內(nèi)建變量根據(jù)信息傳遞的方向可以分為兩類(lèi):輸入與輸出變量无拗。輸入變量負(fù)責(zé)將渲染管線(xiàn)中固定功能部分產(chǎn)生的信息傳遞進(jìn)著色器,輸出變量負(fù)責(zé)將著色器產(chǎn)生的信息傳遞給渲染管線(xiàn)中固定功能部分昧碉。

內(nèi)建輸入變量

gl_Position
gl_PointSize
gl_FragCoord
gl_FrontFacing

內(nèi)建輸出變量

gl_FragColor
gl_FragData

限定符

和其它編程語(yǔ)言一樣英染,著色器中對(duì)變量也有很多可選的限定符,這些限定符中大部分只能用來(lái)修飾全局變量

限定符 說(shuō)明
attribute 一般用于每個(gè)頂點(diǎn)各不相同的量被饿,如頂點(diǎn)位置四康、顏色等
uniform 一般用于對(duì)同一組頂點(diǎn)組成的單個(gè)3D物體中所有頂點(diǎn)都相同的量,如當(dāng)前的光源位置
varying 一般用于頂點(diǎn)著色器傳遞給片元著色器的量
const 用于聲明常量
uniform mat4 uMVPMatrix;
attribute vec3 aPosition;
varying vec4 vColor;
const int lightsCount = 4;

限定符在使用時(shí)應(yīng)該放在變量類(lèi)型之前狭握,且使用attribute闪金、uniform以及varying限定符修飾的變量必須為全局變量。同時(shí)要注意论颅,著色器語(yǔ)言中沒(méi)有默認(rèn)限定符的概念哎垦,因此如果有需要,必須為全局變量明確指定需要的限定符恃疯。

attribute變量

attribute變量用來(lái)接收渲染管線(xiàn)傳遞進(jìn)頂點(diǎn)著色器的待處理頂點(diǎn)的各種屬性漏设,用于描述頂點(diǎn)的各項(xiàng)特征,如頂點(diǎn)坐標(biāo)今妄、法向量郑口、顏色、紋理坐標(biāo)等盾鳞。

用attribute限定符修飾的變量其值是由宿主程序 (可以是C犬性、java)批量傳入渲染管線(xiàn)的,渲染管線(xiàn)進(jìn)行基本處理后再傳給頂點(diǎn)著色器腾仅。數(shù)據(jù)中有多少頂點(diǎn)乒裆,管線(xiàn)就調(diào)用多少次頂點(diǎn)著色器,每次將頂點(diǎn)的各種屬性數(shù)據(jù)傳遞給頂點(diǎn)著色器中對(duì)應(yīng)的attribute變量攒砖。

attribute限定符只能用于頂點(diǎn)著色器缸兔,不能在片元著色器中使用日裙,且attribute限定符只能用來(lái)修飾浮點(diǎn)數(shù)標(biāo)量、浮點(diǎn)數(shù)向量及矩陣變量惰蜜,也就是說(shuō)它只能用來(lái)修飾浮點(diǎn)數(shù)昂拂。

attribute限定符修飾的變量其值是由宿主程序批量傳入渲染管線(xiàn)中的,相關(guān)代碼如下:

int positionHandle;
positionHandle = GLES20.glGetAttributeLocation(mProgram,"aPosition");
GLE20.glVertextAttributePointer(
     positionHandle,
     3,
     GLES20.GL_FLOAT,
     false,
     3*4,
     mVertexBuffer
);

uniform限定符

uniform為一致變量限定符抛猖,一致變量指的是對(duì)同一組頂點(diǎn)組成的單個(gè)3D物體中所有頂點(diǎn)都相同的量格侯。uniform可以用在頂點(diǎn)著色器或片元著色器中,其支持用來(lái)修飾所有的基本數(shù)據(jù)類(lèi)型财著。與屬性變量類(lèi)似联四,也是宿主程序傳入的。

uniform mat4 uMVPMatrix;
uniform vec3 uLightLocation;
uniform vec3 uCameraPosition;
int mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram,"uMVPMatrix");
GLES20.glUniformMatrix4fv(mvpMatrixHandle,1,false,mMatrix,0);

一致變量類(lèi)型的不同將值傳入渲染管線(xiàn)的方法也有所不同撑教,這些方法的名稱(chēng)都以glUniform開(kāi)頭朝墩,然后變量數(shù)據(jù)支持的數(shù)據(jù)和類(lèi)型。

varying變量

想要將頂點(diǎn)著色器的信息傳入到片元著色器中伟姐,就必須使用varying限定符收苏。易變變量是頂點(diǎn)著色器和片元著色器之間的動(dòng)態(tài)接口。

// vertex shader
uniform mat4 uMVPMatrix;
attribute vec aPosition;
attribute vec4 aColor;
varying vec4 vColor;
main() {
    gl_Position = uMVPMatrix * vec4(aPosition,1);
    vColor = aColor
}

// fragment shader
precision mediump float;
varying vec4 vColor;
void main() {
    gl_FragColor = vColor;
}

上面GLSL代碼中愤兵,頂點(diǎn)著色器的易變變量vColor,和片元著色器的易變變量vColor,就是頂點(diǎn)著色器和片元著色器之間的動(dòng)態(tài)接口鹿霸。

頂點(diǎn)著色器的vColor是每個(gè)頂點(diǎn)的顏色,但片元著色器的vColor并不是某個(gè)頂點(diǎn)賦的特定值秆乳。片元是通過(guò)插值得到的懦鼠,片元數(shù)量遠(yuǎn)大于頂點(diǎn),不是一個(gè)數(shù)量級(jí)屹堰。也就是說(shuō)肛冶,對(duì)頂點(diǎn)賦予的顏色值,會(huì)插成很多值双藕,并不是一一對(duì)應(yīng)的淑趾。這也易變變量本質(zhì)所在阳仔。

一般情況下對(duì)一個(gè)3D物體進(jìn)行渲染忧陪,片元著色器執(zhí)行次數(shù)會(huì)大大超過(guò)頂點(diǎn)著色器,因此片元著色器硬件單元數(shù)量會(huì)多于頂點(diǎn)著色器的近范,通過(guò)并行處理嘶摊,提高渲染速度。我們開(kāi)發(fā)程序也要注意评矩,能在頂點(diǎn)著色器處理的效果算法叶堆,盡管不要在片元著色器中處理。

const限定符

用const修飾的變量是不可變的斥杜,和c語(yǔ)言中的const類(lèi)似虱颗。只不過(guò)這些常量在著色器外部是不可見(jiàn)的沥匈。

算法

程序就是數(shù)據(jù)加算法。上面介紹了GLSL支持的數(shù)據(jù)類(lèi)型忘渔,就可以構(gòu)造數(shù)據(jù)了高帖。算法就是對(duì)數(shù)據(jù)的操作,是符合C語(yǔ)言的畦粮。運(yùn)算符散址、控制流程、函數(shù)等都和C語(yǔ)言類(lèi)似宣赔。只不過(guò)為了運(yùn)算的高效预麸,給開(kāi)發(fā)者提供高效的內(nèi)置函數(shù)。

內(nèi)置函數(shù)

內(nèi)置函數(shù)通常是以最優(yōu)的方式實(shí)現(xiàn)的儒将,有部分函數(shù)甚至是由硬件直接支持吏祸,這大大地提高了執(zhí)行效率。大部分內(nèi)置函數(shù)同時(shí)適用于頂點(diǎn)著色器與片元著色器钩蚊,但是也有部分內(nèi)置函數(shù)只適用于頂點(diǎn)著色器或者片元著色器犁罩。

內(nèi)置函數(shù)按照設(shè)計(jì)目的可以分為三個(gè)類(lèi)型:

  • 提供獨(dú)特的硬件功能訪(fǎng)問(wèn)接口,如紋理采樣系列函數(shù)两疚,這些函數(shù)用戶(hù)是無(wú)法自己開(kāi)發(fā)的床估。著色器語(yǔ)言通過(guò)提供特定內(nèi)置函數(shù)對(duì)這些硬件功能進(jìn)行封裝,建立了用戶(hù)調(diào)用這些硬件功能的接口诱渤。

  • 簡(jiǎn)單的數(shù)學(xué)函數(shù)丐巫,如abs、floor等勺美。這些數(shù)學(xué)函數(shù)本身非常簡(jiǎn)單递胧,開(kāi)發(fā)人員也可以自己開(kāi)發(fā),但可能由于對(duì)底層硬件不了解赡茸,采用的實(shí)現(xiàn)方式很低效缎脾。而內(nèi)置函數(shù)是廠(chǎng)商根據(jù)硬件的特點(diǎn)用最高效的方式實(shí)現(xiàn)的,調(diào)用內(nèi)置函數(shù)來(lái)完成這些簡(jiǎn)單的操作不但可以提高開(kāi)發(fā)效率還可以提高執(zhí)行效率占卧。

  • 一些復(fù)雜的函數(shù)遗菠,如三角函數(shù)等,用戶(hù)可以自己編寫(xiě)华蜒,但是編寫(xiě)過(guò)程特別煩瑣辙纬,要用到很多高等數(shù)學(xué)的知識(shí)。不但開(kāi)發(fā)煩瑣叭喜,可以想像效率也會(huì)低下贺拣。而當(dāng)下的主流硬件往往都有進(jìn)行這些計(jì)算的指令,因此對(duì)這些操作也提供了高效的內(nèi)置函數(shù)。

具體內(nèi)置函數(shù) https://cloud.tencent.com/developer/article/1148928

編譯和執(zhí)行

GLSL也是編譯執(zhí)行性語(yǔ)言譬涡,只不過(guò)編譯是動(dòng)態(tài)的闪幽,并且不是獨(dú)立的應(yīng)用,需要使用OpenGL API的宿主程序涡匀。

工具

GLSL著色器可以事先建立和測(cè)試沟使,現(xiàn)有以下GLSL開(kāi)發(fā)工具:

  • RenderMonkey 是由ATI制作的,提供界面用以建立渊跋、編譯和調(diào)試GLSL著色器腊嗡,和DirectX著色器一樣,僅能在Windows平臺(tái)上執(zhí)行拾酝。

  • GLSLEditorSample

  • Lumina

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末燕少,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蒿囤,更是在濱河造成了極大的恐慌客们,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件材诽,死亡現(xiàn)場(chǎng)離奇詭異底挫,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)脸侥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)建邓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人睁枕,你說(shuō)我怎么就攤上這事官边。” “怎么了外遇?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵注簿,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我跳仿,道長(zhǎng)诡渴,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任菲语,我火速辦了婚禮妄辩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谨究。我一直安慰自己恩袱,他們只是感情好泣棋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布胶哲。 她就那樣靜靜地躺著,像睡著了一般潭辈。 火紅的嫁衣襯著肌膚如雪鸯屿。 梳的紋絲不亂的頭發(fā)上澈吨,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音寄摆,去河邊找鬼谅辣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛婶恼,可吹牛的內(nèi)容都是我干的桑阶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼勾邦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蚣录!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起眷篇,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤萎河,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蕉饼,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體虐杯,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年昧港,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了擎椰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡创肥,死狀恐怖确憨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瓤的,我是刑警寧澤休弃,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站圈膏,受9級(jí)特大地震影響塔猾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稽坤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一丈甸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尿褪,春花似錦睦擂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春臼闻,著一層夾襖步出監(jiān)牢的瞬間鸿吆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工述呐, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惩淳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓乓搬,卻偏偏與公主長(zhǎng)得像思犁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子进肯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容