webgl入門(2)-初識webgl和着色器

前言

原書中第2章很是長,若是整理成一個文檔的話,得看好多天。爲了瀏覽方便,我將其拆分紅若干小節,方便你們學習。javascript

webgl採用HTML5中引入的canvas元素來定義頁面的繪圖區域。若是沒有WegGL,js只能在canvas上繪製二維圖形。html

在這一章中,咱們將經過建立若干個示例程序,一步步的介紹一些核心的webgl函數。java

1.最短的webgl程序:清空繪圖區

咱們要開始編寫最短的webgl程序,這個程序的主要功能是使用背景色清空canvas標籤的繪圖區。(這裏的清空,是指用背景色填充的意思)web

html代碼以下;編程

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>webgl學習</title>
</head>

<body>
  <canvas id="canvas" width="400" height="400"></canvas>
  <script src="./index.js"></script>
</body>

</html>
複製代碼

js代碼以下:canvas

// 獲取canvas
var canvas = document.getElementById('canvas')
// 獲取webgl繪圖上下文
var gl = canvas.getContext('webgl')

if (!gl) {
  console.log('Failed to get the rendering context')
}
// 指定清空canvas的顏色
gl.clearColor(0.0, 0.0, 0.0, 1.0)

// 清空canvas
gl.clear(gl.COLOR_BUFFER_BIT)

複製代碼

示例程序的執行步驟以下:數組

  1. 獲取canvas元素
  2. 獲取webgl的繪圖上下文
  3. 設置背景色
  4. 清空canvas

點擊查看效果瀏覽器

2. 程序解析

2.1 獲取canvas元素

咱們經過getElementById獲取canvas元素bash

var canvas = document.getElementById('canvas')
複製代碼

2.2 爲webgl獲取繪圖上下文

這裏傳入的參數是‘webgl’而不是‘3d’。咱們之前使用canvas畫2d圖形的時候傳入的是‘2d’。因此這裏要注意下,不要傳錯了。編程語言

var gl = canvas.getContext('webgl')
複製代碼

2.3 設置canvas的背景色

gl.clearColor(0.0, 0.0, 0.0, 1.0)
複製代碼

gl.clearColor採用RGBA的方式設置背景色:

gl.clearColor(red,green,blue,alpha)
複製代碼
參數 含義
red 指定紅色值(從0.0到1.0)
green 指定綠色值(從0.0到1.0)
blue 指定藍色值(從0.0到1.0)
alpha 指定透明度(從0.0到1.0)
返回值
錯誤

若是任何值小於0或者大於1,那麼就會被截斷爲0.0或者1.0

示例程序執行gl.clearColor(0.0, 0.0, 0.0, 1.0),背景色就被指定爲了黑色。

咱們通常指定顏色時,顏色的值是0到255之間的,可是因爲webgl是繼承自OpenGL,因此它遵循傳統OpenGL顏色份量的取值範圍。

一旦指定的背景色,背景色就會駐存在WegGL系統中,在下一次調用gl.clearColor以前都不會改變。若是你未來還想用同一個顏色清空繪圖區,就沒必需要再指定一次背景色。

2.4 清空canvas

gl.clear(gl.COLOR_BUFFER_BIT);
複製代碼

函數參數是gl.COLOR_BUFFER_BIT,這是由於WebGL中,gl.clear()方法實際上繼承自OpenGL,它基於多基本緩衝區模型。這比二維繪圖上下文複雜的多。清空繪圖區域,實際上在清空顏色緩衝區,傳遞參數gl.COLOR_BUFFER_BIT就是告訴WebGL清空顏色緩衝區。除了顏色緩衝區,WebGL還有其餘種類的緩衝區,好比深度緩衝區和模板緩衝區。

gl.clear(buffer)的用法

buffer是指定待清空的顏色緩衝區,位操做符OR(|)可用於指定多個緩衝區

參數 含義
gl.COLOR_BUFFER_BIT 顏色緩衝區
gl.DEPTH_BUFFER_BIT 深度緩衝區
gl.STENCIL_BUFFER_BIT 指定模板緩衝區
返回值
錯誤 INVALID_VALUE 緩衝區不是以上三種類型

3. 繪製一個點

以前的章節,咱們學習如何創建一個wegl程序,以及如何使用一些簡單的webgl函數。這一節咱們將進一步在一個示例程序中繪製一個最簡單的圖形,一個點。

注意這裏的html比上一次的html多了一些script。這些script是一些工具函數,避免重複的寫大量的代碼。代碼很簡單,能夠直接打開查看。這裏就不解釋了。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>webgl學習</title>
</head>

<body>
  <canvas id="canvas" width="400" height="400"></canvas>
  <!-- 引入幾個webgl幫助函數,這裏的代碼很簡單,你能夠直接點擊查看 -->
  <script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/webgl-utils.js"></script>
  <script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/webgl-debug.js"></script>
  <script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/cuon-utils.js"></script>
  <script src="./index.js"></script>
</body>

</html>
複製代碼

javascript代碼:

// 頂點着色器 注意這裏的\n不能省略。不然不符合語法
var VSHADER_SOURCE = ` void main(){\n gl_Position = vec4(0.0,0.0,0.0,1.0);\n gl_PointSize = 10.0;\n }\n `
// 片斷(片元)着色器
var FSHADER_SOURCE = ` void main(){\n gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n }\n `

function main() {
  // 獲取canvas
  var canvas = document.getElementById('canvas')
  // 獲取webgl繪圖上下文
  var gl = canvas.getContext('webgl')

  if (!gl) {
    console.log('Failed to get the rendering context')
    retun
  }

  // 初始化着色器函數
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log("設置着色器失敗")
    return
  }

  // 指定清空canvas的顏色
  gl.clearColor(0.0, 0.0, 0.0, 1.0)

  // 清空canvas
  gl.clear(gl.COLOR_BUFFER_BIT)
  // 畫一個點
  gl.drawArrays(gl.POINTS, 0, 1)
}

window.onload = function () {
  main()
}
複製代碼

點擊查看效果

3.1 着色器是什麼?

要使用webgl進行繪圖必須使用着色器,在代碼中,着色器是以字符串的形式「嵌入」到js中的。

webgl的着色器分兩種

  • 頂點着色器:頂點着色器用來描述頂點的特性(如位置、顏色等)的程序,頂點是指二維或者三維空間的一個點,好比二維或者三維圖形的端點和交點。
  • 片元着色器:也叫片斷着色器。負責進行逐片元處理過程如光照的程序。片元是webgl的一個術語。你能夠理解它爲像素。

在三維場景中,僅僅用線條和顏色把圖形畫出來是遠遠不夠的,必需要考慮光照上去或者觀察者視角發生變化時,對場景有什麼影響。着色器能夠高度靈活的完成這些工做。提供各類渲染效果。

上述程序執行流程:

  • 先運行javascript程序
  • 調用webgl的相關方法
  • 執行頂點着色器
  • 執行片元着色器
  • 在顏色緩衝區進行繪製
  • 清空繪圖區
  • 顏色緩衝區的內容自動在瀏覽器的canvas上顯示出來

3.2 initShaders

initShaders(),該函數定義在cuon.util.js中,是專爲本書編寫的一個工具函數。其用法說明以下:

initShaders(gl,vshader,fshader)
參數 取值 含義
gl vshader 指定頂點着色器程序代碼
fshader 指定片元着色器程序代碼
返回值 true 初始化着色器成功
fase 初始化着色器失敗

3.3 頂點着色器

var VSHADER_SOURCE = ` void main(){\n gl_Position = vec4(0.0,0.0,0.0,1.0);\n gl_PointSize = 10.0;\n }\n `
複製代碼

頂點着色器必須和c語言同樣,必須包含一個main函數。main前面的void表示這個函數不會有返回值。

首先將頂點位置賦值給gl_Position變量。

在將頂點尺寸賦值給gl_PointSize。

這兩個變量內置在頂點着色器中,有特殊的含義。以下:

類型和變量名 含義
vec4 gl_Position 表示頂點的位置
float gl_PointSize 表示頂點的尺寸

vec4 表示由4個浮點數組成的矢量。

注意:GLSL ES是一種強類型編程語言,比10是整型,10.0就是浮點數,傳錯類型就會報錯。

gl_Position其類型爲vec4,可是咱們只有3個浮點數(0.0,0.0,0.0),既x、y、z座標值。須要用某種方式把它轉爲vec4類型的變量。好在着色器爲咱們提供了內置函數vec4(),幫助你建立vec4類型的變量。(原書中這一段有錯誤,已糾正)

在賦值gl_Position的矢量中,咱們添加了1.0做爲第4個份量。由4個份量組成的矢量稱爲齊次座標。,由於它可以提升處理三維數據的效率。因此被大量使用。雖然齊次座標是四維的,可是若是最後一個份量爲1.0,那麼齊次座標就能夠表示「前三個份量爲座標值」的那個點。

3.4 片元着色器

片元着色器是用來設置顏色的,這裏設置爲紅色。

var FSHADER_SOURCE = ` void main(){\n gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n }\n `
複製代碼

gl_FragColor的用法以下:

類型和變量名 含義
vec4 gl_FragColor 指定片元顏色(RGBA格式)

3.5 繪製操做

咱們使用drawArrays()進行繪製。

gl.drawArrays(gl.POINTS, 0, 1)
複製代碼

gl.drawArrays(mode,first,count)

參數 含義
mode 指定繪製的方式,能夠接受如下常量符號: gl.POINTS ,gl.LINES ,gl.LINE_STRIP ,gl.LINE_LOOP ,gl.TRIANGLES ,gl.TRIANGLE_STRIP ,gl.TRIANGLE_FAN
first 指定從哪一個點開始繪製
count 指定繪製多少個點
錯誤 INVALID_ENUM 傳入的mode參數不是前述參數之一
錯誤 INVALID_VALUE 參數first或者count爲負數

總結:以上咱們簡單介紹了兩個webgl程序,並初步認識了着色器。後續的章節咱們將學習webgl的座標系統和更多着色器的相關知識。欲知後事如何,請動動你的手指,關注下我,我會繼續帶來webgl的分享,哈哈

相關文章
相關標籤/搜索