GLSL語言O(shè)penGLES(二)

前言

opengl es通過頂點著色器程序和片段著色器程序來實現(xiàn)可編程的渲染,著色器程序也有自己的編程語言簡稱為GLSL,GLSL語言和C語言比較類似,接下來就是對GLSL語言特性的記錄。

GLSL(著色器編程語言)

  • 1责掏、介紹
    是一個和C語言語法比較類似的著色器變成語言
  • 2咕晋、注釋
    和C語言一樣
// this is a comment
/**
  *   this is muti comment
*/

備注:GLSL語言必須由ASCII碼字符組成涡拘,如果包括非ascii碼編譯會出錯

  • 3、變量命名
    GLSL的變量名必須以字母或者下劃線開頭亡蓉,由英文字母证芭,數(shù)字瞳浦,組成,且不能是gl或__開頭(都是系統(tǒng)預(yù)留的)废士,也不能是系統(tǒng)關(guān)鍵字
  • 4叫潦、預(yù)處理指令
    預(yù)處理指令以#開頭,#號之前不能有除了空白字符之外的任何字符官硝。每一個指令獨占一行矗蕊。內(nèi)置的預(yù)處理指令如下:
#define
#undef
#if
#ifdef
#ifndef
#else
#elif
#endif
#error
#pragma
#extension
#version
#line
#pragma
// 編譯指示。用來控制編譯器的一些行為氢架,開發(fā)和調(diào)試時可以設(shè)置為off傻咖,默認設(shè)為on。
#pragma optimize(on)
#pragma optimize(off)
// 開發(fā)和調(diào)試時可以打開debug選項岖研,以便獲取更多的調(diào)試信息卿操。默認設(shè)為off。
#pragma debug(on)
#pragma debug(off)
#extension
// 如果想使用GLGL默認不支持的操作孙援,則必須啟用對應(yīng)的擴展害淤,啟用一個擴展可以使用下面的命令:
#extension : behavior
#extension all : behavior
其中,extension_name是擴展的名稱拓售,all是指所有的編譯器支持的擴展窥摄。
behavior是指對該擴展的具體操作。比如啟用邻辉、禁用等等溪王。詳情如下:
behavior                       作用                             
require                         啟用該擴展。如果不支持值骇,則報錯莹菱。
enable                          啟用該擴展。如果不支持吱瘩,則會警告道伟。extension_name是all的時候會報錯。
warn                            啟用該擴展使碾。但是會檢測到所有使用該擴展的地方蜜徽,提出警告。
disable                         禁用該擴展票摇。如果該擴展不被支持拘鞋,則提出警告。
  • 5矢门、預(yù)定義的變量
    除此之外盆色,還預(yù)定義了一些變量:
    _LINE_ :int類型,當(dāng)前的行號祟剔,也就是在Source String中是第一行
    _FILE_ :int類型隔躲,當(dāng)前Source String的唯一ID標(biāo)識
    _VERSION_ :int類型,GLGL的版本
    GL_ES :對于嵌入式系統(tǒng)(Embed System物延,簡稱 ES)宣旱,它的值為1,否則為0

  • 6叛薯、運算符及其優(yōu)先級
    序號|運算符|描述|優(yōu)先級
    --|:--:|--:|--:
    | 1 | 小括號 |()| 從右往左 |
    | 2 | 乘除求余 | * / % | 從左往右 |
    | 3 | 加減法 | + - | 從左往右 |
    | 4 | 位運算 移位 | 左移<< 和 右移 >> | 從左往右 |
    | 5 | 大小關(guān)系 | < > <= >= | 從左往右 |
    | 6 | 相等性判斷 | == != | 從左往右 |
    | 7 | 位運算 與 | & | 從左往右 |
    | 8 | 位運算 非 | ^ | 從左往右 |
    | 9 | 位運算 或 | | | 從左往右 |
    | 10 | 邏輯與 | && | 從左往右 |
    | 11 | 邏輯或 | || | 從左往右 |

  • 7浑吟、關(guān)鍵詞
    列舉一下GLSL中的關(guān)鍵詞,這些全部是系統(tǒng)保留的案训,不可私自篡改买置。

attribute const uniform varying
break continue do for while
if else
in out inout
float int void bool true false
lowp mediump highp precision invariant
discard return
mat2 mat3 mat4
vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4
sampler2D samplerCube
struct

asm
class union enum typedef template this packed
goto switch default
inline noinline volatile public static extern external interface flat
long short double half fixed unsigned superp
input output
hvec2 hvec3 hvec4 dvec2 dvec3 dvec4 fvec2 fvec3 fvec4
sampler1D sampler3D
sampler1DShadow sampler2DShadow
sampler2DRect sampler3DRect sampler2DRectShadow
sizeof cast
namespace using

除此之外,所有的以__開頭的變量全部是預(yù)留的强霎,自定義的變量不能以__開頭忿项。

精度限定符

先看如下片段著色器的GLSL代碼

uniform sampler2D colorMap;
varying lowp vec2 varyingCoordPos;
void main() {
    vec4 color = texture2D(colorMap,varyingCoordPos);
    gl_FragColor = color;
}

這段代碼編譯時會提示"declaration must include a precision qualifier for type",意思就是聲明變量時沒有指定精度限定符

  • 1城舞、精度范圍
    對于單個變量使用精度限定符的語法為
    存儲限定符 精度限定符 數(shù)據(jù)類型 變量名轩触,比如:
    lowp float color;
    varying mediump vec2 Coord;
    highp mat4 m;
    浮點型變量的精度范圍
    highp (-2的62次方, 2的62次方);
    mediump (-2的14次方, 2的14次方);
    lowp (-2,2);
    整型變量的精度范圍
    highp (-2的16次方, 2的16次方);
    mediump (-2的10次方, 2的10次方);
    lowp (-2的8次方, 2的8次方);
    字符型和布爾型是沒有精度范圍的
    所以對于高精度和中精度,整型類變量(包括標(biāo)量和向量)可以準(zhǔn)確的的轉(zhuǎn)化為同樣精度修飾符修飾的浮點型類變量家夺,例如highp int 可以轉(zhuǎn)換為 highp float 脱柱,mediump int 可以轉(zhuǎn)換為 mediump float;但是lowp int 缺不可以轉(zhuǎn)化為 lowp float拉馋,因為會產(chǎn)生數(shù)據(jù)溢出榨为。
  • 2惨好、默認精度
    通過precision關(guān)鍵字來指定默認精度,這樣就不用每一個變量前面都聲明精度限定符了随闺,具體語法如下:
    precision highp|mediump|lowp type;
    那么從該語句之后所有的沒有精度限定符修飾的type數(shù)據(jù)類型的變量都將采用此默認精度日川,包括全局變量聲明、函數(shù)返回值聲明矩乐、函數(shù)參數(shù)聲明以及本地變量聲明等龄句,只要是沒有精度修飾符的變量將使用和它最近的precision語句中的精度。
    例如:
precision highp float;

代表之后所有和float有關(guān)的沒有精度限定符修飾的變量的精度都為float

  • 3散罕、預(yù)定義精度
    GLSL為我們預(yù)先設(shè)定了一些數(shù)據(jù)類型的默認精度分歇,頂點著色器的預(yù)定義全局默認精度語句:
    precision highp float;
    precision highp int;
    precision lowp sampler2D;
    precision lowp samplerCube;
    片元著色器預(yù)定義全局默認精度:
    precision mediump int;
    precision lowp sampler2D;
    precision lowp samplerCube;
    所以片元著色器對于浮點型變量是沒有設(shè)置預(yù)定義精度的,需要用前面的方式手動指定欧漱,這里也解釋了為什么前面的代碼編譯會出錯的原因职抡。

GLSL中矩陣和向量相關(guān)運算

引用GLSL官方文檔中的例子,這里以三維向量和三維矩陣為例硫椰,二維和四維類似

  • 例子1

向量與單個變量相加繁调,將向量中的每個元素分別于這個變量相加,結(jié)果仍然為向量靶草,且不區(qū)分向量和單個變量的順序即:
vec3 v, u;
float f;

v = u + f;
等價于
v.x = u.x + f;
v.y = u.y + f;
v.z = u.z + f;

v = f + u;
等價于
v.x = f + u.x;
v.y = f + u.y;
v.z = f + u.z;
備注:向量與單個變量的乘法一樣蹄胰。減法和除法則可以換成等價的加法和乘法

  • 例子2

兩個向量相加,分別將兩個向量對應(yīng)位置的元素相加奕翔,結(jié)果仍然為向量裕寨,且不區(qū)分向量和單個變量的順序即:
vec3 v, u, w;

w = v + u;
等價于
w.x = v.x + u.x;
w.y = v.y + u.y;
w.z = v.z + u.z;
乘法一樣

  • 例子3

向量乘以矩陣,分別將向量與矩陣的每一列相乘派继,結(jié)果為行向量(這里向量只有一行)
vec3 v, u;
mat3 m;
u = v * m;
等價于
u.x = v.x * m[0].x + v.y * m[0].y + v.z * m[0].z;
u.y = v.x * m[1].x + v.y * m[1].y + v.z * m[1].z;
u.z = v.x * m[2].x + v.y * m[2].y + v.z * m[2].z;

  • 例子4

矩陣乘以向量宾袜,分別矩陣的每一行與向量相乘,結(jié)果為列向量(這里向量只有一列)
vec3 v, u;
mat3 m;
u = m * v;
等價于
u.x = m[0].x * v.x + m[1].x * v.y + m[2].x * v.z;
u.y = m[0].y * v.x + m[1].y * v.y + m[2].y * v.z;
u.z = m[0].z * v.x + m[1].z * v.y + m[2].z * v.z;

這里與例子3的區(qū)別就是它的最終結(jié)果變成了列向量

  • 例子5
    矩陣乘以矩陣驾窟,滿足高度代數(shù)中矩陣相乘的算法
    mat m, n, r;
    r = m * n;
    等價于
    r[0].x = m[0].x * n[0].x + m[1].x * n[0].y + m[2].x * n[0].z;
    r[1].x = m[0].x * n[1].x + m[1].x * n[1].y + m[2].x * n[1].z;
    r[2].x = m[0].x * n[2].x + m[1].x * n[2].y + m[2].x * n[2].z;
    r[0].y = m[0].y * n[0].x + m[1].y * n[0].y + m[2].y * n[0].z;
    r[1].y = m[0].y * n[1].x + m[1].y * n[1].y + m[2].y * n[1].z;
    r[2].y = m[0].y * n[2].x + m[1].y * n[2].y + m[2].y * n[2].z;
    r[0].z = m[0].z * n[0].x + m[1].z * n[0].y + m[2].z * n[0].z;
    r[1].z = m[0].z * n[1].x + m[1].z * n[1].y + m[2].z * n[1].z;
    r[2].z = m[0].z * n[2].x + m[1].z * n[2].y + m[2].z * n[2].z;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末庆猫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绅络,更是在濱河造成了極大的恐慌月培,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恩急,死亡現(xiàn)場離奇詭異杉畜,居然都是意外死亡,警方通過查閱死者的電腦和手機衷恭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門此叠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人随珠,你說我怎么就攤上這事灭袁♀恚” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵茸歧,是天一觀的道長兔魂。 經(jīng)常有香客問我,道長举娩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任构罗,我火速辦了婚禮铜涉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘遂唧。我一直安慰自己芙代,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布盖彭。 她就那樣靜靜地躺著纹烹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪召边。 梳的紋絲不亂的頭發(fā)上铺呵,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音隧熙,去河邊找鬼片挂。 笑死,一個胖子當(dāng)著我的面吹牛贞盯,可吹牛的內(nèi)容都是我干的音念。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼躏敢,長吁一口氣:“原來是場噩夢啊……” “哼闷愤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起件余,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤讥脐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蛾扇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體攘烛,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年镀首,在試婚紗的時候發(fā)現(xiàn)自己被綠了坟漱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡更哄,死狀恐怖芋齿,靈堂內(nèi)的尸體忽然破棺而出腥寇,到底是詐尸還是另有隱情,我是刑警寧澤觅捆,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布赦役,位于F島的核電站,受9級特大地震影響栅炒,放射性物質(zhì)發(fā)生泄漏掂摔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一赢赊、第九天 我趴在偏房一處隱蔽的房頂上張望乙漓。 院中可真熱鬧,春花似錦释移、人聲如沸叭披。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涩蜘。三九已至,卻和暖如春熏纯,著一層夾襖步出監(jiān)牢的瞬間同诫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工樟澜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剩辟,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓往扔,卻偏偏與公主長得像贩猎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子萍膛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

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