WebGL之旅(一)canvas、WebGL和shader簡介
一 canvas
canvas(翻譯為畫布)是HTML5的一個標籤,canvas可以使用JavaScript在網頁上繪製圖像,例如下面的程式碼就使用canvas繪製一個簡單的矩形。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>WebGL</title>
</head>
<body onload="main()">
<canvas id="container" width="1280px" height="720px"></canvas>
</body>
</html>
<script type="text/javascript" src="main.js"></script>
main.js中的程式碼如下:
function main() {
var canvas = document.getElementById("container");
var context = canvas.getContext("2d");
context.fillStyle = "rgba(0, 0, 255, 1.0)" ;
context.fillRect(120, 10, 150, 150);
}
canvas只支援一些簡單的2d繪製,不支援3d,更重要的是效能有限,WebGL彌補了這兩方便的不足。
二 WebGL是什麼
WebGL(全寫Web Graphics Library)是一種3D繪圖標準,這種繪圖技術標準允許把JavaScript和OpenGL ES 2.0結合在一起,通過增加OpenGL ES 2.0的一個JavaScript繫結,WebGL可以為HTML5 Canvas提供硬體3D加速渲染。(摘自百度百度)
修改main.js中的程式碼如下:
function main() {
var canvas = document.getElementById("container");
var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
gl.clearColor(0.0, 0.0, 0.0, 1.0);// 指定清空canvas的顏色
gl.clear(gl.COLOR_BUFFER_BIT);// 清空canvas
}
上面是一個最簡單的WebGL程式,將canvas的顏色設定為黑色。
三 Shader
使用WebGL繪製,依賴於著色器(shader);
- 頂點著色器(Vertex shader): 繪製每個定點都會呼叫一次;
- 片段著色器(Fragment shader): 每個片源(可以簡單的理解為畫素)都會呼叫一次;
下面是一個簡單的例子:
/**
* 使用WebGL畫點
* [email protected]
* */
// 頂點著色器原始碼
var vertexShaderSrc = `
void main(){
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);// gl_Position 內建變數,表示點的位置,必須賦值
gl_PointSize = 10.0;// gl_PointSize 內建變數,表示點的大小(單位畫素),可以不賦值,預設為1.0,,繪製單個點時才生效
}`;
// 片段著色器原始碼
var fragmentShaderSrc = `
void main(){
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);// 記憶體變數,表示片元顏色RGBA
}`;
// 初始化使用的shader
function initShader(gl) {
var vertexShader = gl.createShader(gl.VERTEX_SHADER);// 建立頂點著色器
gl.shaderSource(vertexShader, vertexShaderSrc);// 繫結頂點著色器原始碼
gl.compileShader(vertexShader);// 編譯定點著色器
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);// 建立片段著色器
gl.shaderSource(fragmentShader, fragmentShaderSrc);// 繫結片段著色器原始碼
gl.compileShader(fragmentShader);// 編譯片段著色器
var shaderProgram = gl.createProgram();// 建立著色器程式
gl.attachShader(shaderProgram, vertexShader);// 指定頂點著色器
gl.attachShader(shaderProgram, fragmentShader);// 指定片段著色色器
gl.linkProgram(shaderProgram);// 連結程式
gl.useProgram(shaderProgram);//使用著色器
}
function main() {
var canvas = document.getElementById("container");
var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
initShader(gl);// 初始化著色器
gl.clearColor(0.0, 0.0, 0.0, 1.0);// 指定清空canvas的顏色
gl.clear(gl.COLOR_BUFFER_BIT);// 清空canvas
gl.drawArrays(gl.POINTS, 0, 1);// 畫點
}
四 座標系
WebGL使用的是右手系,x水平(右為正),y豎直(上為正),z垂直螢幕(外為正)。
WebGL的寬高範圍是從-1到1。
將前面vertexShaderSrc程式碼中的gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
分別修改為:
- gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
- gl_Position = vec4(-1.0, 0.0, 0.0, 1.0);
- gl_Position = vec4(0.0, 1.0, 0.0, 1.0);
- gl_Position = vec4(0.0, -1.0, 0.0, 1.0);
- gl_Position = vec4(1.0, 1.0, 0.0, 1.0);
- gl_Position = vec4-(1.0, 1.0, 0.0, 1.0);
- gl_Position = vec4(1.0, -1.0, 0.0, 1.0);
- gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);
可以看到點會被繪製在不同的位置。
五 向shader中傳值
向shader中傳值有兩種方式:
- attribute變數,傳遞與頂點相關的陣列,只能在頂點著色器中使用;
- uniform變數,傳遞與頂點無關的資料;
前面的程式碼將點的位置和大小都直接寫在了頂點著色器中,現在將其改為由外面的程式傳入。首先修改頂點著色器:
var vertexShaderSrc = `
attribute vec4 a_Position;// 接收傳入位置座標,必須宣告為全域性
attribute float a_PointSize;// 接收傳入位置座標,必須宣告為全域性
void main(){
gl_Position = a_Position;// gl_Position 內建變數,表示點的位置,必須賦值
gl_PointSize = a_PointSize;// gl_PointSize 內建變數,表示點的大小(單位畫素),可以不賦值,預設為1.0
}`;
然後在initShader的最後給這兩個變數賦值:
var a_Position = gl.getAttribLocation(shaderProgram, "a_Position");// 獲取shader中的a_Position變數
gl.vertexAttrib4f(a_Position, 0.0, 0.0, 0.0, 1.0);// 給變數a_Position賦值
var a_PointSize = gl.getAttribLocation(shaderProgram, "a_PointSize");// 獲取shader中的a_PointSize變數
gl.vertexAttrib1f(a_PointSize, 10.0);// a_PointSize
最終的效果跟前面看到的是一樣的。
相關推薦
WebGL之旅(一)canvas、WebGL和shader簡介
一 canvas canvas(翻譯為畫布)是HTML5的一個標籤,canvas可以使用JavaScript在網頁上繪製圖像,例如下面的程式碼就使用canvas繪製一個簡單的矩形。 <!DOCTYPE html> <html lang=
我的現代Javascript之旅(一)啟程、面向物件的現代Javascript
Javascript曾經被認為是一門小玩具似的指令碼語言。大部分 的程式設計師都覺得它只是輔助工具,用來頁面端校驗——僅此 而已。隨著Javascript語言的演變,其功能越來越強大。直到
css重構之旅(一)
rdquo lan set 變化 部分 網站 一個 寬度 lang css重構之旅 >前言: 今年我大一,馬上就要大二了。從高三畢業暑假到大學的這一年馬上過去,馬上迎來大二生活.學習前端也有將近一年了。一昧去追求那些視覺的效果和相對高端和新穎的技術,反而忽略了最基礎
小白的linux學習之旅(一)
探索linux一、進入系統*)普通用戶登陸student 普通用戶,密碼student*)超級用戶登陸 —〉not listed 點擊未列出 username 提示輸入用戶名稱 —〉root root 為系統超級用戶 passw
dotNet程序員的Java爬坑之旅(一)
是我 方法 轉java 自己的 java pri 也好 工作 計劃 仔細想了下還是轉java吧,因為後期不管是留在北京也好還是回老家也好,java的工作都會好找一點。現在的工作主要還是寫.net,目標是下一次離職的時候可以找到一份全職的java工作,我一直都覺得實踐
webpack入坑之旅(一)不是開始的開始
targe base 增加 -i pre 版本 uil 靜態頁 obi 最近學習框架,選擇了vue,然後接觸到了vue中的單文件組件,官方推薦使用 Webpack + vue-loader構建這些單文件 Vue 組件,於是就開始了webpack的入坑之旅。因為原來沒有用過
RabbitMQ學習之旅(一)
RabbitMQ學習總結(一) RabbitMQ簡介 RabbitMQ是一個訊息代理,其接收並轉發訊息。類似於現實生活中的郵局:你把信件投入郵箱的過程,相當於往佇列中新增資訊,因為所有郵箱中的信件最終都會彙集到郵局中;當郵遞員把你的新建傳送給收件人的時候,相當於訊息的轉發。 RabbitMQ中
Python學習之旅(一)
Python的簡介 Python是一種面向物件的、動態的指令碼語言,可用來設計網頁和開發後臺功能。其創始人Guido van Rossum於1989年聖誕節期間創造了這門語言。 (圖片來自百度) Python的種類 CPython Jython IronPython PyPy …… 與J
小程式wepy踩坑之旅(一)---- thirdScriptError sdk uncaught third Error module "npm/lodash/_nodeUtil.js
近期一直在學小程式,作為新手,比較了下mpvue和wepy兩個小程式框架,mpvue作為美團剛出來的vuejs開發看起來很不錯,學習成本很低,但是對於在實際專案開發中,mpvue剛出來,很多資料,比如踩坑,比較少,而we
記錄我的Python學習之旅(一)關於turtle庫的基本用法
關於庫函式的匯入方法:①import <> ②import <> as <> ③ from tutle import <> 1、turtle.setup(width,height,startx,starty) /
dart之旅(一)
console sta 環境安裝 ria odi 等價 app func tar 前言 最近在看 dart 了,本著 “紙上得來終覺淺,絕知此事 markdown” 的原則,準備邊學邊寫,寫一個系列,這是第一篇。學習過程中主要是參考 A Tour of the Dart L
Spring Boot 探索之旅(一)——Spring Boot 簡介
一、什麼是Spring Boot 隨著技術日新月異的發展,如今的軟體設計已不想曾經那般單一。業務複雜,功能繁瑣,大量三方元件的相互整合,成為了開發的一大難題。幸而,Spring Boot如同一道曙光,為我們java開發者帶來了福音,讓我們擺脫專案構架時各種配置的鬧心,得以專
學習Pytorch之旅----(一)
感覺很棒哦,大家可以動動手指到GitHub上點個Star偶~~ 言歸正傳,這是第一次記錄一個深度學習框架的部落格,加上作者自己的觀點和實踐,認真的分析和思考,之前都是寫在本子上@@ 1.Tensors張量 張量是用於GPU加速的類似於Numpy中ndarray的資料
C語言入門之旅 (一)
特殊的迴圈語句 ,讓for迴圈開始的方法: 將sum初始化為0;或者先在迴圈體外讀第一個數 注意要先判斷再運算,避免最後一個數據發生錯誤 for(sum=0;n!=-1;) { sum+=n; scanf(“%d”, n); } 輸入x,y之間的閏年 i
大疆無人機Android版SDK開發踩坑之旅(一)----前言
最近一段時間一直在做大疆無人機安卓版開發,這水也是挺深的,不仔細看官網SDK的介紹就會遇到各種各樣的坑,簡單記錄一下,希望可以讓其他人少走一些彎路。 安卓端用到的SDK大概有兩種:Android SDK和Android UX SDK Android SDK(官網介紹): 開發人員可以通過SDK
Java架構師之旅(一)
夜光序言: 如果世界和你,都掉進了河裡,我一定先救你,然後忘記世界的呼吸~ 正文: MVC框架的演變 我們安裝這個外掛解決沒有tomcat的問題,因為targ
小程式wepy踩坑之旅(一)---- thirdScriptError sdk uncaught third Error module "npm/lodash/_nodeUtil.js
近期一直在學小程式,作為新手,比較了下mpvue和wepy兩個小程式框架,mpvue作為美團剛出來的vuejs開發看起來很不錯,學習成本很低,但是對於在實際專案開發中,mpvue剛出來,
菜鳥與 cef 的邂逅之旅(一):cef 原始碼獲取與編譯
一、引言 最近工作中涉及到了有關嵌入瀏覽器控制元件的任務,並且要求支援 H5。之前使用了 wke,但是發現其對於 H5 的支援不夠好,因此只能選擇“聞名已久”的 cef。 cef 是什麼呢: CEF 全稱 Chromium Embedded Fram
Spring之旅(一)
Spring兩個重要的思想:依賴注入和麵向切片 看書後個人見解: 相同點:都是為了解耦,當然耦合度要適度不然都沒有關係和邏輯了 不同點:依賴注入注重解決物件和物件之間的解耦,每個物件不需
視訊學習之旅(一) SurfaceView控制元件--------------畫面重疊問題
有一個這樣的需求,下面有2個tab進行切換,第一個是錄影介面(暫定為介面A),第二個是拍照介面(暫定為介面B),我第一個想到的就是用SurfaceView控制元件來實現,在佈局檔案裡面它的屬性很簡單的。然後就想著錄影介面就顯示錄影預覽畫面,拍照介面就顯示拍照預覽畫面,但是當