一直就很想學習WebGL相關的知識,如今也找到了工做,生活也差很少趨向穩定了,加上學校也沒那麼多課程了,因此我確定要利用起來這個時間啊!由於腿摔傷了,國慶估計是在家躺7天,因此更加要抓住這麼好的學習時機了。
如你所見,這系列文章都是我本身的碎碎叨,固然啦,目的是爲了能更好的梳理本身學習的知識,增強印象,順便再來作個總結,這樣能更加紮實的學習。
個人狀況是,有前端基礎,有PS基礎,無計算機圖形學基礎,沒有學過OpenGL,而我以爲,立體的圖像比起2D的來講,可能更難以理解,由於首先,沒有圖形學的基礎,遊戲建模的經驗,因此要經過聯想來達成對概念的理解是比較困難的,可是我以爲只要多看多試驗,實在不行就問問身邊的同窗,不必定要是圖形學的「專家」,美術生也是不錯的選擇哦!這樣總會明白的,因此讓咱們開始今天的學習吧!php
個人學習資料主要是來源於下面的清單(但是找了很久,才找到了這麼多😂,固然還有加上百度各類文章):html
WebGL也是在Canvas上繪製成的。
可是它仍是有一點不同,由於它除了要HTML、JS來寫以外,還須要一個叫作着色器語言的東西,而WebGL使用的是GLSL ES,這就是說做爲前端的咱們,還得去學習另外一門語言才行。
至於這其中的道理就是,Javascript經過瀏覽器的JS解釋器控制CPU,經過CPU來控制GPU,GPU就是圖形處理器,着色器語言構成的代碼被編譯後再交給GPU去執行。因此在寫WebGL的時候,你會看到一大段相似於C語言的代碼字符串被賦予給一個變量。
而對於咱們新手來講,確定是一臉懵逼的,因此咱們對WebGL有一個簡單的印象後,從Three.js開始入手學習,Three.js對這些都進行了一個很好的封裝,咱們就能夠先不去考慮這些稍微原生態的東西。前端
Github地址:https://github.com/mrdoob/thr...
咱們確定要先從簡單的入手啦!雖然官方git倉庫東西豐富,看的眼花繚亂!咱們能夠直接引入一個three.min.js的cdn連接就開始寫咱們的程序。git
通常狀況下,咱們能夠在HTML文檔裏先寫一個canvas標籤,最後把咱們的內容掛載上去,可是你們彷佛更傾向於一切都在JS代碼中完成,也就是最後appendChild到body上面去。github
咱們能夠想像本身是在拍攝一張照片!好比,要拍攝淘寶的商品圖片。
這時候咱們就須要佈置一個場景,咱們能夠放(add)一個蘋果,而後加一個光照,最後再拿相機擺好位置拍下來!而後再把成像洗出來。
而Three.js成像的過程也很相似於這樣,咱們每次要做一幅新畫的時候,就須要一個場景(Scene)對象、照相機(Camera)對象,還有渲染器(Renderer)!web
var scene = new THREE.Scene(); var box = new THREE.BoxGeometry(100, 100, 100); var material = new THREE.MeshLambertMaterial({color: 0x0000ff}); var mesh = new THREE.Mesh(box, material); scene.add(mesh); var point = new THREE.PointLight(0xffffff); point.position.set(400, 200, 300); scene.add(point); var ambient = new THREE.AmbientLight(0x444444); scene.add(ambient); var width = window.innerWidth; var height = window.innerHeight; var k = width / height; var s = 100; var camera = new THREE.OrthographicCamera(-s*k, s*k, s, -s, 1, 1000); camera.position.set(200, 300, 200); camera.lookAt(scene.position); var renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height); renderer.setClearColor(0xb9d3ff, 1); document.body.appendChild(renderer.domElement); renderer.render(scene, camera);
如下是下面這段代碼的預覽圖:canvas
以上的大段代碼來自於我學習資料中的第一個網站!看不懂不要緊,這時候其實我也還沒細細看呢,咱們一個個來看哦!api
第一段代碼,是關於咱們建立了一個場景對象的!
這個比較簡單,就是new了一個對象😅數組
var scene = new THREE.Scene();
不事後面咱們能夠看到相關的代碼還有scene.add(point);
之類的,其實就是相似於咱們說過的,向場景裏去添加東西啦!咱們能夠看看場景對象的內部結構:
眼花繚亂,東西好多啊!可是咱們能夠看到它有一個children屬性,下面放的就是一個數組,就是咱們add進去的東西哦!這樣就更好理解了!瀏覽器
能夠看到,這個場景,咱們就是放了一個正方體進去!
var box = new THREE.BoxGeometry(100, 100, 100); var material = new THREE.MeshLambertMaterial({color: 0x0000ff}); var mesh = new THREE.Mesh(box, material); scene.add(mesh);
固然就是建立一個「盒子」對象咯,也就是一個塊,長方體呀正方體啊均可以,給它設置參數就好了。三個參數分別表示width, height和depth。這裏都是100,因此就是一個正方體啦!(能夠本身修改下參數試試)
咱們能夠看到,咱們最後用Mesh這個方法,把Box和Material結合起來了,字如其名!Material就是材料啦!若是咱們不給Box添加任何材料的話,那就是一個」骨架」了,因此這裏可能和我一開始的想象不同,咱們須要給Box制定它的材質,這個東西才能出來!
咱們能夠想象,假如咱們東西都擺好了,可是沒有燈的話,就是一片漆黑,因此這裏還有不少光源的對象。這裏咱們就先了解這裏用的兩種光:點光源(point)和環境光(ambient)。
假如沒有任何的光,它就是烏漆麻黑的看不見!!
那麼首先咱們來研究一下點光源!
var point = new THREE.PointLight(0xffffff); point.position.set(400, 200, 300); scene.add(point);
咱們給它添加了白色的光,重要的是在於這個位置的理解。咱們根據經驗也能夠推斷是這是x,y和z三個座標值。通過我不斷的改變這個位置值,看下圖分別是(100, 100, 0)和(100, 100, 100)的狀況,咱們能夠根據光線的變化來推斷出光源的位置,從而知道座標軸的設置:
隨後查過資料後,發現Three.js使用的確實是右手座標系,這裏是與OpenGL同步默認的狀況:
下面我模擬了一下從(0, 0, 100)到(0, 200, 100)的變化狀況,也就是燈光從下一直上升到了上面。
咱們再來看看環境光~
我嘗試着只給Cube添加一個#FFF最亮的白光,能夠看到它所有都亮了,顏色就是咱們最初給Cube的顏色。咱們能夠發現這個環境光是均勻的,不會像點光源同樣有一個強弱的減小。也就是說咱們能夠利用它來給咱們提供一個佈景的基礎。
照相機我以爲對於咱們這種沒有圖形學基礎和建模經驗的人來講,應該是比較難理解的,首先是咱們要知道有兩種成像相機:
其中透視投影是符合咱們眼睛成像的原理的,就是說東西並非遠近同樣的大小,好比下面這張桌子,咱們能夠感受到離咱們近的這邊要更「大」一些:
而正交投影就不同了,好比咱們能夠看下面這張建模圖,就是方方正正的,參考線都是平行的:
好,下面咱們來認識一下照相機裏面的幾個參數:左、右、上、下、近、遠。
這就相似於你相機成像的位置,也就是說可能畫布是無限大的,可是相機只能拍出部分景象。
這裏比較難理解的就是近和遠,彷佛又和咱們想像的同樣,根據我本身的測試,我感受它更像一個盒子,就是說超出這個範圍的東西都會被割掉。
好比,當我把near值調大一點的時候,能夠看到出現了一個缺口,也就是說相機距離的很近,因此出現了一個三角形的缺口。
另外咱們能夠知道,這個左-右/上-下的比例應該與畫布的比例同樣,要否則圖像的寬高比確定會變化,會被壓縮。
固然啦,咱們有了一個相機,一定要設置好它的位置,以及它朝着的方向。
最後,一切就緒,咱們就能夠用渲染器把這個圖像渲染出來。
而後用document.body.appendChild(renderer.domElement);
把渲染器渲染出來的元素添加到body中,再調用render函數進行渲染,就完畢了。
若是想要作動畫效果,就再函數裏動態改變一些數值,從新調用渲染方法,就能夠達到了。
今天是我學習Three.js的第一天,我經過一個基本的例子,對Three.js裏面的一些基礎的概念有了一點了解。不過有的細節仍是不太懂,也有一些本身的疑問,這還須要後面更多的學習。另外,由於我也是新手,可能會有一些本身理解的不對的地方,歡迎指出來!^—^