webgl 6.畫3個(gè)不同顏色的點(diǎn)

上節(jié)我們畫了 3 個(gè)紅色的點(diǎn)月而,點(diǎn)的顏色是寫死在 fragment shader 中柔袁。這節(jié)我們來畫 3 個(gè)不同顏色的點(diǎn)。

three colored points.png

首先現(xiàn)在除了頂點(diǎn)的坐標(biāo)之外還要把每個(gè)頂點(diǎn)的顏色傳到 shader 中。前面說過有 2 種方法,一是可以定義 2 個(gè)數(shù)組冀自,2 個(gè) buffer object 分別來傳遞坐標(biāo)和顏色,二是可以把每個(gè)頂點(diǎn)的坐標(biāo)和顏色都放在 1 個(gè)數(shù)組中用 1 個(gè) buffer object 傳過去然后再分開解析秒啦。兩種方法各有利弊熬粗,首先分開傳肯定沒有一塊傳效率高,而一塊傳的弊端是當(dāng)你只想更新顏色而坐標(biāo)不變時(shí)也必須更新整個(gè)數(shù)組余境,這個(gè)要看具體情況驻呐。用 2 個(gè) buffer object 分開傳的情況留給大家自己練習(xí),我們來看看一塊傳的情況葛超。

// vertex shader
var VERTEX_SHADER_SOURCE =
    'attribute vec4 a_Position;\n' +
    'attribute vec4 a_Color;\n' +
    'varying vec4 v_Color;\n' +

    'void main() {\n' +
    '   gl_Position = a_Position;\n' +
    '   gl_PointSize = 10.0;\n' +
    '   v_Color = a_Color;\n' +
    '}\n';

// fragment shader
var FRAGMENT_SHADER_SOURCE =
    'precision mediump float;\n' +
    'varying vec4 v_Color;\n' +

    'void main() {\n' +
    '   gl_FragColor = v_Color;\n' +
    '}\n';
  • attribute vec4 a_Color

增加了一個(gè) attribute 變量 a_Color 來接收顏色

但顏色是在 fragment shader 中計(jì)算的暴氏,怎么把 vertex shader 中的顏色傳遞到 fragment shader 中呢延塑? 這就要用到 varying 變量绣张, 當(dāng)同一個(gè) varying 變量 (類型和名字都一樣)同時(shí)定義在 vertex shader 和 fragment shader 中時(shí), varying 變量的值會(huì)自動(dòng)從 vertex shader 中傳遞到 fragment shader 中关带。

  • varying vec4 v_Color;
    v_Color = a_Color;

我們定義了 v_Color 這個(gè) varying 變量侥涵,并賦值為 a_Color

來個(gè)直觀的圖,大家感受一下

varyingvariable.png

attribute 和 varying 變量都必須定位為全局變量宋雏, main 是入口函數(shù)芜飘。

  • precision mediump float

這是什么意思呢? precision 是精度修飾符磨总,mediump (medium precision) 中等精度嗦明, 意思是 fragment shader 中所有的 float 都用中等精度表示。
fragment shader 中默認(rèn)沒有為 float 指定精度蚪燕,必須手動(dòng)指定娶牌,主要是為了在有些情況下必須使用 highp (高精度) 或用 lowp (低精度) 來提高性能奔浅。
vertex shader 中數(shù)據(jù)默認(rèn)都是 highp 的,因?yàn)檫@適用于大多數(shù)情況诗良。

現(xiàn)在頂點(diǎn)中要增加顏色信息

var vertices = new Float32Array([
    0.0, 0.5, 1.0, 0.0, 0.0, // (x,y) (r,g,b)
    -0.5, -0.5, 0.0, 1.0, 0.0,
    0.5, -0.5, 0.0, 0.0, 1.0
]);

每個(gè)頂點(diǎn)前 2 位表示位置汹桦,后 3 位表示顏色

var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
var a_Color = gl.getAttribLocation(gl.program, 'a_Color');

// 每個(gè)元素的字節(jié)數(shù), 這里是  float 類型, 所以是 4 個(gè)字節(jié)
var BYTES_PER_ELEMENT = vertices.BYTES_PER_ELEMENT;

// 屬性變量和數(shù)據(jù)關(guān)聯(lián)起來并指定解析方法
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 5 * BYTES_PER_ELEMENT, 0);
// enable the assignment to attribute variable
gl.enableVertexAttribArray(a_Position);

gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 5 * BYTES_PER_ELEMENT, 2 * BYTES_PER_ELEMENT);
gl.enableVertexAttribArray(a_Color);
  • vertices.BYTES_PER_ELEMEN

得到每個(gè)元素的字節(jié)數(shù), float 類型是 4 個(gè)字節(jié)

  • gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 5 * BYTES_PER_ELEMENT, 0);

a_Position 我們傳了 2 個(gè)值鉴裹, 元素類型是 float
倒數(shù)第二個(gè)參數(shù)表示各個(gè)坐標(biāo)之間間隔的字節(jié)數(shù)舞骆,每個(gè)頂點(diǎn)的坐標(biāo)之間間隔 5 * 4 = 20 個(gè)字節(jié)
最后一個(gè)參數(shù)表示第一個(gè)頂點(diǎn)坐標(biāo)的起始位置,這里是 0

  • gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 5 * BYTES_PER_ELEMENT, 2 * BYTES_PER_ELEMENT);

a_Color 我們傳了 3 個(gè)值径荔, 元素類型是 float
倒數(shù)第二個(gè)參數(shù)表示各個(gè)顏色之間間隔的字節(jié)數(shù)督禽,每個(gè)頂點(diǎn)的顏色之間間隔 5 * 4 = 20 個(gè)字節(jié)
最后一個(gè)參數(shù)表示第一個(gè)頂點(diǎn)顏色的起始位置,這里是 2 * 4 = 8 個(gè)字節(jié)

頂點(diǎn)中除了位置总处、顏色還可以攜帶 norm (法向量)赂蠢、texture coord (紋理坐標(biāo)) 等,一般都是一塊傳過去后再分開解析辨泳。

最后 draw 不變還是畫 3 個(gè)頂點(diǎn)

gl.drawArrays(gl.POINTS, 0, 3);

練習(xí):

  1. 用 2 個(gè) buffer object 分別傳遞位置和顏色

查看源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末虱岂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子菠红,更是在濱河造成了極大的恐慌第岖,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件试溯,死亡現(xiàn)場離奇詭異蔑滓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)遇绞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門键袱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摹闽,你說我怎么就攤上這事蹄咖。” “怎么了付鹿?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵澜汤,是天一觀的道長。 經(jīng)常有香客問我舵匾,道長俊抵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任坐梯,我火速辦了婚禮徽诲,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己谎替,他們只是感情好轩拨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著院喜,像睡著了一般亡蓉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喷舀,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天砍濒,我揣著相機(jī)與錄音,去河邊找鬼硫麻。 笑死爸邢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拿愧。 我是一名探鬼主播杠河,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼浇辜!你這毒婦竟也來了券敌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤柳洋,失蹤者是張志新(化名)和其女友劉穎待诅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熊镣,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卑雁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绪囱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片测蹲。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鬼吵,靈堂內(nèi)的尸體忽然破棺而出扣甲,到底是詐尸還是另有隱情,我是刑警寧澤而柑,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布文捶,位于F島的核電站荷逞,受9級(jí)特大地震影響媒咳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜种远,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一涩澡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧坠敷,春花似錦妙同、人聲如沸射富。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胰耗。三九已至,卻和暖如春芒涡,著一層夾襖步出監(jiān)牢的瞬間柴灯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工费尽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赠群,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓旱幼,卻偏偏與公主長得像查描,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子柏卤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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