OpenGL - 頂點著色器

概述:
頂點著色器提供頂點操作的通用可編程方法.

屬性 :                    用頂點數(shù)組提供的逐頂點數(shù)據(jù).
統(tǒng)一變量和統(tǒng)一變量緩沖區(qū) :   頂點著色器使用的不變數(shù)據(jù)
采樣器 :                  代表頂點著色器使用的紋理的特殊統(tǒng)一變量類型.
著色器程序 :               頂點著色器程序源代碼或者描述在操作頂點的可執(zhí)行文件.
頂點著色器

一個典型的著色器有下面的結(jié)構(gòu):

#version version_number
in type in_variable_name;
in type in_variable_name;

out type out_variable_name;

uniform type uniform_name;

int main()
{
  // 處理輸入并進行一些圖形操作
  ...
  // 輸出處理過的結(jié)果到輸出變量
  out_variable_name = weird_stuff_we_processed;
}

修飾符

  • uniform
uniform變量是外部application程序傳遞給(vertex和fragment)shader的變量.
uniform變量一般用來表示:變換矩陣巩螃,材質(zhì)演怎,光照參數(shù)和顏色等信息。
以下是例子:
uniform mat4 viewProjMatrix; //投影+視圖矩陣
uniform mat4 viewMatrix;        //視圖矩陣
uniform vec3 lightPosition;     //光源位置
  • attribute
attribute變量是只能在vertex shader中使用的變量避乏。
它不能在fragment shader中聲明attribute變量爷耀,也不能被fragment shader中使用.
一般用attribute變量來表示一些頂點的數(shù)據(jù),如:頂點坐標拍皮,法線歹叮,紋理坐標,頂點顏色等铆帽。
  • varying
varying變量是vertex和fragment shader之間做數(shù)據(jù)傳遞用的咆耿。一般vertex shader修改varying變量的值丧没,
然后fragment shader使用該varying變量的值殷绍。因此varying變量在vertex和fragment shader二者之間的聲明必須是一致的。application不能使用此變量吃衅。

頂點著色器內(nèi)建變量

  • 特殊變量(頂點著色器的輸入輸出)
  • 統(tǒng)一狀態(tài)(如深度范圍)
  • 規(guī)定最大值(如屬性數(shù)量,頂點著色器輸出變量數(shù)量和統(tǒng)一變量數(shù)量)的常量

內(nèi)建特殊變量

  • gl_VertexID是一個輸入變量,用于保存頂點的整數(shù)索引.
這個整數(shù)型變量用highp精度限定符聲明.
  • gl_InstanceID是一個輸入變量,用于保存實例化繪圖調(diào)用中圖元的示例編號.
對于常規(guī)的繪圖調(diào)用,該值為0.
gl_InstanceID是一個整數(shù)型變量,用highp精度限定符聲明.
  • gl_Position用于輸出頂點位置的裁剪坐標.
該值在裁剪和視窗階段用于執(zhí)行相應的圖元裁剪以及從裁剪坐標到屏幕坐標的頂點位置轉(zhuǎn)換.
如果頂點著色器未寫入gl_Position.則該值未定義.
gl_Position是一個浮點變量,用highp精度限定符聲明.
  • gl_PointSize用于寫入以像素表示的點精靈尺寸,在渲染點精靈時使用.
頂點著色器輸出的gl_PointSize值被限定在OpenGL ES 3.0實現(xiàn)支持的非平滑點大小范圍之內(nèi).
該值是一個浮點變量,用highp精度限定符聲明.
  • gl_FrontFacing是一個特殊變量,但不是由頂點著色器直接寫入的,而是根據(jù)頂點著色器生成的位置和渲染的圖元類型生成的.
該值是一個布爾變量

內(nèi)建統(tǒng)一狀態(tài)

struct gl_DepthRangeParameters {
    highp float near;
    highp float far;
    highp float diff;
}
uniform gl_DepthRangeParameters gl_depthRange;

內(nèi)建常量

const mediump int gl_maxVertexAttribs                  = 16
const mediump int gl_maxVertexUniformVectors           = 256
const mediump int gl_maxVertexOutputVectors            = 16
const mediump int gl_maxVertexTextureImageUnits        = 16
const mediump int gl_maxCombindedTextureImageUnits     = 32
  • gl_maxVertexAttribs : 是可以指定的頂點屬性的最大數(shù)量.
  • gl_maxVertexUniformVectors : 頂點著色器可以使用的vec4統(tǒng)一變量項目的最大數(shù)量
  • gl_maxVertexOutputVectors : 輸出向量的最大數(shù)量
  • gl_maxVertexTextureImageUnits : 頂點著色器中可用的紋理單元的最大數(shù)量.
  • gl_maxCombindedTextureImageUnits : 頂點和片段著色器中可用紋理單元最大數(shù)量的總和.
PS : 以上的內(nèi)建常量指定的值是所有OpenGL ES 3.0 實現(xiàn)必須支持的最小值.實現(xiàn)各種可能支持超過上面所述的最小值的常量值.實際支持的值可以用下面的代碼查詢.
    GLint maxVerterAttribs,maxVerterUniforms, maxVaryings;
    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVerterAttribs);
    glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxVerterUniforms);
    glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
    
    GLint maxVerterTextureUnits,maxCombinedTextureUnits;
    glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVerterTextureUnits);
    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedTextureUnits);

精度限定符

highp lowp mediump

頂點著色器示例

演示如何在頂點著色器中實現(xiàn)如下功能

  • 用一個矩陣變化頂點位置
  • 進行照明計算,生成逐定點漫射和反射顏色
  • 紋理坐標生成
  • 頂點蒙皮
  • 用紋理查找值代替頂點位置

矩陣變化

描述一個用OpenGLES 著色器語言編寫的簡單頂點著色器.這個頂點著色器獲取一個位置和其相關的顏色數(shù)據(jù)作為輸入或者屬性.用一個4x4矩陣變換位置,并輸出變化后的位置和顏色.

#version 300 es
uniform mat4 u_mvpMatrix;
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec4 a_color;
out vec4 v_color;
void main() {
  v_color = a_color;
  gl_Position = u_mvpMatrix * a_position;
}

頂點著色器的位置輸入保存為物體坐標,而輸出位置保存為裁剪坐標.
MVP矩陣是3D圖形中進行這種變化的3個非常重要的變化矩陣的乘積:模型矩陣,視圖矩陣和投影矩陣.
組成MVP矩陣的每個單獨矩陣執(zhí)行的變化如下:

  • 模型矩陣 ---- 將 物體 坐標變換為 世界 坐標.
  • 視圖矩陣 ---- 將 世界 坐標變換為 眼鏡 坐標.
  • 投影矩陣 ---- 將 眼睛 坐標變換為 裁剪 坐標.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愧驱,一起剝皮案震驚了整個濱河市慰技,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌组砚,老刑警劉巖吻商,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異糟红,居然都是意外死亡艾帐,警方通過查閱死者的電腦和手機蚯舱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掩蛤,“玉大人枉昏,你說我怎么就攤上這事∽崮瘢” “怎么了兄裂?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阳藻。 經(jīng)常有香客問我晰奖,道長,這世上最難降的妖魔是什么腥泥? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任匾南,我火速辦了婚禮,結(jié)果婚禮上蛔外,老公的妹妹穿的比我還像新娘蛆楞。我一直安慰自己,他們只是感情好夹厌,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布豹爹。 她就那樣靜靜地躺著,像睡著了一般矛纹。 火紅的嫁衣襯著肌膚如雪臂聋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天或南,我揣著相機與錄音孩等,去河邊找鬼。 笑死采够,一個胖子當著我的面吹牛肄方,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吁恍,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼扒秸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冀瓦?” 一聲冷哼從身側(cè)響起伴奥,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翼闽,沒想到半個月后拾徙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡感局,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年尼啡,在試婚紗的時候發(fā)現(xiàn)自己被綠了暂衡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡崖瞭,死狀恐怖狂巢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情书聚,我是刑警寧澤唧领,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站雌续,受9級特大地震影響斩个,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驯杜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一受啥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸽心,春花似錦滚局、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冲九,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跟束,已是汗流浹背莺奸。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留冀宴,地道東北人灭贷。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像略贮,于是被迫代替她去往敵國和親甚疟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

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