五 WebGL入門,shader剖析

2021-07-09 13:24:47 字數 3831 閱讀 8810

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貼圖有關,在寫輸入時我們最少要在貼圖之後寫一對什麼都不含的空白的 當我們需要開啟特定選項時可以把其寫在這對花括號內。如果需要同時開...