OpenGL編程語言-glsl基礎(chǔ)

前言

作為一個開發(fā)者,有一個學(xué)習(xí)的氛圍跟一個交流圈子特別重要這是一個我的iOS交流群:776598941衙耕,不管你是小白還是大牛歡迎入駐 瀑凝,分享BAT,阿里面試題、面試經(jīng)驗臭杰,討論技術(shù), 大家一起交流學(xué)習(xí)成長谚中!

最近在研究OpenGL 被各種陌生的名詞虐成狗,所以記錄下來一些學(xué)習(xí)知識點供學(xué)習(xí)和參考.

GLSL是什么?

GLSL(OpenGL Shading Language) 是OpenGL的著色器語言,純粹的和GPU打交道的計算機語言.可以理解為C的變種專門針對OpenGL編程,不支持指針等等一些C的特性等. (名詞解釋:著色器(Shader))

GPU是多線程并行處理器渴杆,GLSL直接面向單指令流多數(shù)據(jù)流(SIMD)模型的多線程計算。

GLSL編寫的著色器函數(shù)是對每個數(shù)據(jù)同時執(zhí)行的宪塔。

每個頂點都會由頂點著色器中的算法處理磁奖,每個像素也都會由?片段著色器(也有叫片元著色器)中的算法處理。

初學(xué)者在編寫自己的著色器時某筐,需要考慮到SIMD的并發(fā)特性比搭,并用并行計算的思路來思考問題 這就是GLSL.

我們最常見的用法是在?頂點著色器里生成所需要的值,然后傳給?片斷著色器用.

GLSL能做什么

日以逼真的材質(zhì) – 金屬南誊,巖石身诺,木頭,油漆等

日益逼真的光照效果 – 區(qū)域光和軟陰影

非現(xiàn)實材質(zhì) – 美術(shù)效果抄囚,鋼筆畫霉赡,水墨畫和對插畫技術(shù)的模擬

針對紋理內(nèi)存的新用途

更少的紋理訪問

圖形處理 – 選擇,邊緣鈍化遮蔽和復(fù)雜混合

動畫效果 – 關(guān)鍵幀插值幔托,粒子系統(tǒng)

用戶可編程的反走樣方法

GLSL注意

GLSL支持函數(shù)重載(就是父類定義方法,子類復(fù)寫該方法叫重載)

GLSL不存在數(shù)據(jù)類型的自動提升(就是不支持類型自動向上轉(zhuǎn)換 eg:float 轉(zhuǎn) double)穴亏,類型必須嚴(yán)格保持一致.

GLSL不支持指針,字符串重挑,字符嗓化,它基本上是一種處理數(shù)字?jǐn)?shù)據(jù)的語言

GLSL不支持聯(lián)合(union)、枚舉類型(enum)谬哀、結(jié)構(gòu)體(stuct)位字段(>> or << 左右移)及按位運算符(| or &這種按位與)(就是干掉麻煩的C操作 讓這個更單純的處理圖形數(shù)據(jù)使用)

GLSL的數(shù)據(jù)類型

GLSL有三種基本數(shù)據(jù)類型:

float

int

double

由float刺覆、int、double組成的array[]或者結(jié)構(gòu)體

42// 十進(jìn)制?

042// 八進(jìn)制?

0x2A// 十六進(jìn)制

注意:GLSL不支持指針,GLSL把向量和矩陣作為基本數(shù)據(jù)類型

向量(vector):有起始位置有方向的線段,也稱作?矢量(不要被這些名詞嚇到,我記得這個向量是我高二的時候數(shù)學(xué)學(xué)的東西).

矢量

矢量可以和標(biāo)量甚至矩陣做加減乘除(必須遵守一定規(guī)則才可以 否則報錯)

vec2,? vec3,? vec4? //包含2/3/4個浮點數(shù)的矢量(浮點型)

ivec2, ivec3, ivec4 //包含2/3/4個整數(shù)的矢量(整形數(shù) 前邊帶i 代表integer)

bvec2, bvec3, bvec4 //包含2/3/4個布爾值的矢量(bool不用解釋)

上邊這些是一種GLSL的數(shù)據(jù)類型, 可以簡單理解為?vec+數(shù)字?就代表 是一個數(shù)組里面放幾個元素(應(yīng)該都是 vec2~vec4之間,沒見過 vec5以上和vec2以下,好像這就代表幾維坐標(biāo)系),默認(rèn)元素是float浮點類型,前邊帶i代表integer整形,b代表bool.

vec如何聲明使用玻粪?

vec3 v; //聲明三維浮點型向量v

v[1] = 3.0;? //給向量v的第二個元素賦值(數(shù)組從0開始,下標(biāo)為1就是第二個元素)

//下面兩種等價

vec3 v = vec3(0.6); //數(shù)組是連續(xù)的存儲空間 相當(dāng)于其它元素默認(rèn)被這個0.6值填充

vec3 v = vec3(0.6,0.6,0.6);

注意: 除了用索引方式外,還能用選擇運算符的方式來使用向量.擇運算符是對于向量的各個元素(最多為4個)約定俗成的名稱隅津,用一個小寫拉丁字母來表示诬垂。根據(jù)向量表示對象的意義不同,可以使用以下選擇運算符:

表示頂點可以用 (x伦仍、y结窘、z、w) (坐標(biāo)系)

表示顏色可以用 (r充蓝、g隧枫、b、a) (顏色值帶透明)

表示紋理坐標(biāo)用 (s谓苟、t官脓、p、q)

三種任選一種都一樣,作用都是等效的. 也就是說涝焙,如果v是一個向量卑笨,那么:

v[0]

v.x

v.r

v.s

都指的是向量v的第一個元素。

例如:

//用構(gòu)造函數(shù)的方式聲明并初始化四維浮點型

vec4v1 =vec4(1.0,2.0,3.0,4.0);

vec4v2;

v2.xy=v1.yz;//將v1的第二個和第三個元素復(fù)制到v2的第一個和第二個元素

v2.z=2.0;//給v2的第三個元素賦值?

v2.xy=v1.yx;//將v1的頭兩個元素互換仑撞,再復(fù)制到v2的頭兩個元素中

矩陣(matrix)

矩陣(matrix)以下類型都以mat開頭

mat2?代表2x2的矩陣

mat3?代表3x3的矩陣

mat4?代表4x4的矩陣

注意:矩陣是按列順序組織的赤兴,先列后行

如下代碼:

mat4m;//聲明四維浮點型方陣m?

m[2][3]=2.0;//給方陣的第三列、第四行元素賦值

// 下面兩種等價隧哮,初始化矩陣對角

mat2m =mat2(1.0)

mat2m =mat2(1.0,0.0,0.0,1.0);

取樣器(Sampler)

紋理查找需要制定哪個紋理或者紋理單元將制定查找.

sampler1D// 訪問一個一維紋理

sampler2D// 訪問一個二維紋理? ? ? ? ?

sampler3D// 訪問一個三維紋理

samplerCube// 訪問一個立方貼圖紋理

sampler1DShadow// 訪問一個帶對比的一維深度紋理

sampler2DShadow// 訪問一個帶對比的二維深度紋理

uniformsampler2Dgrass;

vcc2 coord =vec2(100,100);

vec4color =texture2D(grass, coord);

如果一個著色器在程序里結(jié)合多個文理, 可以使用取樣器數(shù)組.

constinttex_nums =4;

uniformsampler2Dtextures[tex_nums];

for(inti =0; i < tex_nums; ++i) {

sampler2Dtex = textures[i];

// todo ...

}

結(jié)構(gòu)體

這是唯一的用戶能用的自定義類型

struct light?

{?

vec3position;

vec3color;

};?

light ceiling_light;

數(shù)組

數(shù)組索引是從0開始的桶良,而且沒有指針概念

// 創(chuàng)建一個10個元素的數(shù)組?

vec4points[10];

// 創(chuàng)建一個不指定大小的數(shù)組

vec4points[];

points[2] =vec4(1.0);// points現(xiàn)在大小為3

points[7] =vec4(2.0);// points現(xiàn)在大小為8

void

只能用于聲明函數(shù)返回值

類型轉(zhuǎn)換

必須明確地進(jìn)行類型轉(zhuǎn)換,不會自動類型提升

floatf =2.3;

boolb =bool(f);// b is true

限定符

GLSL中有4個限定符(variable qualifiers)可供使用沮翔,它們限定了被標(biāo)記的變量不能被更改的”范圍”.

const

attribute

uniform

varying

const: 和C++里差不多陨帆,定義不可變常量

表示限定的變量在編譯時不可被修改.

attribute:是應(yīng)用程序傳給頂點著色器用的

不允許聲明時初始化

attribute限定符標(biāo)記的是一種全局變量,該變量在頂點著色器中是只讀(read-only)的,該變量被用作從OpenGL應(yīng)用程序向頂點著色器中傳遞參數(shù)采蚀,因此該限定符僅能用于頂點著色器.

attribute變量是只能在vertex shader中使用的變量

它不能在fragment shader中聲明attribute變量瑰步,

也不能被fragment shader中使用)

在application中,一般用函數(shù)glBindAttribLocation()來綁定每個attribute變量的位置,然后用函數(shù)

glVertexAttribPointer()為每個attribute變量賦值。

以下是例子:

uniform mat4 u_matViewProjection;

attribute vec4 a_position;

attribute vec2 a_texCoord0;

varying vec2 v_texCoord;

void main(void)

{

? gl_Position = u_matViewProjection * a_position;

? v_texCoord = a_texCoord0;

}

uniform:一般是應(yīng)用程序用于設(shè)定頂點著色器和片斷著色器相關(guān)初始化值.不允許聲明時初始化.uniform限定符標(biāo)記的是一種全局變量,該變量對于一個圖元(primitive)來說是不可更改的 它可以從OpenGL應(yīng)用程序中接收傳遞來的參數(shù)

uniform變量 外部程序傳遞給shader的變量.

函數(shù)glUniform**()函數(shù)賦值的.

shader 中是只讀變量,不能被 shader 修改.

uniform變量一般用來表示:變換矩陣,材質(zhì)齿税,光照參數(shù)和顏色等信息。

uniform mat4 viewProjMatrix; //投影+視圖矩陣

uniform mat4 viewMatrix;? ? ? ? //視圖矩陣

uniform vec3 lightPosition;? ? //光源位置

varying:用于傳遞頂點著色器的值給片斷著色器.它提供了從頂點著色器向片段著色器傳遞數(shù)據(jù)的方法,varying限定符可以在頂點著色器中定義變量芜壁,然后再傳遞給光柵化器纫溃,光柵化器對數(shù)據(jù)插值后疗锐,再將每個片段的值交給片段著色器.

varying變量是vertex和fragment shader之間做數(shù)據(jù)傳遞用的口芍。

一般vertex shader修改varying變量的值关划,

然后fragment shader使用該varying變量的值。

因此varying變量在vertex和fragment shader二者之間的聲

明必須是一致的呵扛。

application不能使用此變量烫堤。

以下是例子:

// Vertex shaderuniform

mat4 u_matViewProjection;

attribute vec4 a_position;

attribute vec2 a_texCoord0;

varying vec2 v_texCoord; // Varying in vertex shader

void main(void)

{?

? gl_Position = u_matViewProjection * a_position;

? v_texCoord = a_texCoord0;

}

// Fragment shaderprecision

mediump float;

varying vec2 v_texCoord; // Varying in fragment shader

uniform sampler2D s_baseMap;

uniform sampler2D s_lightMap;

void main()

{

? vec4 baseColor;

? vec4 lightColor;

? baseColor = texture2D(s_baseMap, v_texCoord);

? lightColor = texture2D(s_lightMap, v_texCoord);

? gl_FragColor = baseColor * (lightColor + 0.25);

}

注意:以上這幾種限定符很重要

限制性

不能在if-else中聲明變量

用于判斷的條件必須是bool類型(if,while,for…)

(?:)操作符后兩個參數(shù)必須類型相同

不支持switch語句

vec4toonify(infloatintensify)

{

vec4color;

color =vec4(0.8,0.8,0.8,0.8)

returncolor;

}

discard

discard關(guān)鍵字可以避免片段更新幀緩沖區(qū)剩燥,當(dāng)流控制遇到這個關(guān)鍵字時变擒,正在處理的片段就會被標(biāo)記為丟.

如果不理解什么叫標(biāo)記為丟 可以參考一下UIView的繪制過程

函數(shù)

函數(shù)名可以通過參數(shù)類型重載,但是和返回值類型無關(guān)

所有參數(shù)必須完全匹配材部,參數(shù)不會自動

函數(shù)不能被遞歸調(diào)用

函數(shù)返回值不能是數(shù)組

函數(shù)參數(shù)標(biāo)識符

in: 進(jìn)復(fù)制到函數(shù)中毫缆,但不返回的參數(shù)(默認(rèn))

out: 不將參數(shù)復(fù)制到函數(shù)中,但返回參數(shù)

inout: 復(fù)制到函數(shù)中并返回

混合操作

通過在選擇器(.)后列出各分量名乐导,就可以選擇這些分量

vec4v4;

v4.rgba;// 得到vec4

v4.rgb;// 得到vec3

v4.b;// 得到float

v4.xy;// 得到vec2

v4.xgba;// 錯誤苦丁!分量名不是同一類

v4.wxyz;// 打亂原有分量順序

v4.xxyy;// 重復(fù)分量

最后推薦一個GLSL編輯調(diào)試工具OpenGL Shader Builder(Graphics Tools.dmg)

文章來源于網(wǎng)絡(luò),如有侵權(quán)物臂,請聯(lián)系小編刪除旺拉!

全文完

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市棵磷,隨后出現(xiàn)的幾起案子账阻,更是在濱河造成了極大的恐慌,老刑警劉巖泽本,帶你破解...
    沈念sama閱讀 210,835評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淘太,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機蒲牧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,900評論 2 383
  • 文/潘曉璐 我一進(jìn)店門秽之,熙熙樓的掌柜王于貴愁眉苦臉地迎上來症副,“玉大人,你說我怎么就攤上這事⌒醵蹋” “怎么了六剥?”我有些...
    開封第一講書人閱讀 156,481評論 0 345
  • 文/不壞的土叔 我叫張陵佛玄,是天一觀的道長腰根。 經(jīng)常有香客問我,道長遵倦,這世上最難降的妖魔是什么尽超? 我笑而不...
    開封第一講書人閱讀 56,303評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮梧躺,結(jié)果婚禮上似谁,老公的妹妹穿的比我還像新娘。我一直安慰自己掠哥,他們只是感情好巩踏,可當(dāng)我...
    茶點故事閱讀 65,375評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著续搀,像睡著了一般塞琼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上禁舷,一...
    開封第一講書人閱讀 49,729評論 1 289
  • 那天屈梁,我揣著相機與錄音,去河邊找鬼榛了。 笑死,一個胖子當(dāng)著我的面吹牛煞抬,可吹牛的內(nèi)容都是我干的霜大。 我是一名探鬼主播,決...
    沈念sama閱讀 38,877評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼革答,長吁一口氣:“原來是場噩夢啊……” “哼战坤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起残拐,我...
    開封第一講書人閱讀 37,633評論 0 266
  • 序言:老撾萬榮一對情侶失蹤途茫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后溪食,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囊卜,經(jīng)...
    沈念sama閱讀 44,088評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,443評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了栅组。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雀瓢。...
    茶點故事閱讀 38,563評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖玉掸,靈堂內(nèi)的尸體忽然破棺而出刃麸,到底是詐尸還是另有隱情,我是刑警寧澤司浪,帶...
    沈念sama閱讀 34,251評論 4 328
  • 正文 年R本政府宣布泊业,位于F島的核電站,受9級特大地震影響啊易,放射性物質(zhì)發(fā)生泄漏吁伺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,827評論 3 312
  • 文/蒙蒙 一认罩、第九天 我趴在偏房一處隱蔽的房頂上張望箱蝠。 院中可真熱鬧,春花似錦垦垂、人聲如沸宦搬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,712評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽间校。三九已至,卻和暖如春页慷,著一層夾襖步出監(jiān)牢的瞬間憔足,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,943評論 1 264
  • 我被黑心中介騙來泰國打工酒繁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留滓彰,地道東北人。 一個月前我還...
    沈念sama閱讀 46,240評論 2 360
  • 正文 我出身青樓州袒,卻偏偏與公主長得像揭绑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子郎哭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,435評論 2 348

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