webgl用的shader語言是glsl(opengl shading language),
shader的主要工作有:
1. 利用檢視和投影矩陣對點的位置進行變化
2. 如果需要利用法線的時候,也同樣需要利用檢視矩陣對其進行轉換
3. 紋理座標的產生和轉換
4. 頂點的光照或者象素光照的計算
5. 顏色計算
1-4在後面會詳細的介紹,本節我們利用5,顏色計算來展示下shader的基本工作流程,好現在進入本節的課程
void main(void)
被執行了6次,即該類似的vs(vertexshader)**執行的
個數=繪製的面數目*3
顯示卡的vs執行的偽**大致如下(呼叫drawelements()時執行):
for(var i = 0 ;i < 6 ; ++ i)}}
在來看shader-fs**,fs的執行比較複雜,大致是繪製圖形的每個畫素都要執行一次fs**,我們之前繪製的矩形大概要執行幾萬次fs**。所以fs**執行的效率是至關重要的
現在我要繪製乙個顏色漸變的矩形,該如何做呢?
先看看要使用的glsl的變數限定符與內建變數:
變數限定符:
attribute-- 用於經常更改的資訊,只可以再頂點著色器中使用
uniform-- 用於不經常更改的資訊,用於頂點著色器和片元著色器
varying-- 用於從頂點著色器傳遞到片元著色器的插值資訊
內建變數:
gl_position
vec4
輸出屬性-變換後的頂點的位置,用於後面的固定的裁剪等操作。所有的頂點著色器都必須寫這個值
gl_fragcolor
vec4
輸出的顏色用於隨後的畫素操作
現在的頂點資料陣列除了有頂點位置資訊外,還應該加上顏色資訊:
var jsarraydata =
[//x y z r g b a
-0.5, +0.5, 0.0, 1.0, 0.0, 0.0, 1.0,
+0.5, +0.5, 0.0, 0.0, 1.0, 0.0, 1.0,
+0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 1.0,
-0.5, -0.5, 0.0, 1.0, 1.0, 0.0, 1.0,
];
相應的shader-vs**要做相應的改變:
precision lowp float;//宣告精度為低精度浮點型,必須加上這一句,不然會報錯
attribute vec3 v3position;//位置資料輸入
attribute vec4 incolor;//顏色資料輸入
varying vec4 outcolor;//傳給fs的顏色輸入
void main(void)
shader-fs**:precision lowp float;//宣告精度為低精度浮點型
varying vec4 outcolor;//從vs傳過來的顏色資料
void main(void)
相應的,要宣告乙個incolor的變數:
var incolor = 1;//宣告乙個變數
......
webgl.bindattriblocation(programobject, v3positionindex, "v3position");
webgl.bindattriblocation(programobject, incolor, "incolor");//繫結incolor
......
webgl.enablevertexattribarray(v3positionindex);
webgl.enablevertexattribarray(incolor); //啟用incolor
webgl.vertexattribpointer(v3positionindex, 3, webgl.float, false, 4 * 7, 0);
webgl.vertexattribpointer(incolor, 4, webgl.float, false, 4 * 7, 4*3); //指定如何從頂點緩衝區中讀取顏色資訊,下面會詳細解釋為什麼最後乙個為啥是4*3
webgl.drawelements(webgl.********s,6,webgl.unsigned_short,0);
有人會迷糊為啥第二個vertexattribpointer()的最後乙個引數為4*3,改引數的意思是從頂點緩衝區偏移offset位元組開始讀資料,見頂點資料陣列jsarraydata,前3個資料是頂點位置資料,後4個才是顏色資料,乙個資料佔4個位元組,所裡讀顏色應偏移offset=4*3個位元組,見下圖:
所以比較完整的顯示卡vs執行偽**為:
for(var i = 0 ;i < 6 ; ++ i)}}
下面介紹下上面提到的
uniform,它是vs和fs的乙個共享的全域性變數,它在著色器執行期間一致變數的值是不變的。我們可以通過它來在程式外部控制矩形顏色,不在頂點資訊中加顏色資訊,shader**如下:
相應的webgl**:
var webgl = null;
var uniforcolor = 0;//宣告乙個變數與shader裡面的color繫結
var jsarraydata =
[-0.5, +0.5, 0.0,
+0.5, +0.5, 0.0,
+0.5, -0.5, 0.0,
-0.5, -0.5, 0.0,
];//右頂點
var indexdatas =
[0,1,2,
0,2,3,
];
......
webgl.useprogram(programobject);
......
uniforcolor = webgl.getuniformlocation(programobject,"color"); //獲取color的位置,該**位置必須在useprogram()呼叫之後
webgl.uniform4f(uniforcolor,0,1,0,1);//通過uniforcolor給shader-fs**裡面的 color賦值
.....
下面簡單看一看webgl的渲染管線:
我們今天主要講的是vertex shader 和 fragment shader ,只是介紹了一點點東西,其實這兩個shader要做的工作有很多,以後再慢慢談
好了,本節完
Shader之小白入門學習五
先實現乙個只有顏色屬性可調節的簡單材質效果,如下圖所示 模型可隨便找乙個,預設的幾何體也可以,在材質面板中只有乙個顏色屬性,當我們點開拾色器時,對應的模型也會自動發生變化。我們就用之前的myfirstshader來完善。在乙個shader中,可以有多個subshader以及乙個subshader中也...
webgl入門必備
由於最近在搞乙個其他的東西,所以我的webgl學習系列部落格都沒有更新了,所以在這裡先做乙個總結。我們對webgl有乙個初步的認識,就是需要先獲取到canvas的上下文,那麼我們今天就需要了解一下將影象發布到畫布上。思路將資料由main 函式傳到頂點著色器的attribute變數上去!先獲取到att...
Shader入門學習手記
shader程式的基本結構 在 中學習吧,注釋都寫好了。shader first fantasy water water diffuse 它只對2d,rect或者cube貼圖有關,在寫輸入時我們最少要在貼圖之後寫一對什麼都不含的空白的 當我們需要開啟特定選項時可以把其寫在這對花括號內。如果需要同時開...