webGL的3D世界主要由三大要素構(gòu)成:場景(scene)、相機(camera)和渲染器(renderer)咬腕,三者缺一不可欢峰。渲染的原理是:我們將創(chuàng)建的物體,添加到場景中涨共,再通過相機(可以理解為人的視角)渲染到渲染器纽帖,從而呈現(xiàn)在網(wǎng)頁中。three.js是webGL一款比較熱門的類庫举反,本文以"three.js": "^0.77.1"為例懊直,通過網(wǎng)上教程和自身實踐整理成這篇筆記。
1.場景(scene)
場景就是所有物體的容器火鼻,只需創(chuàng)建一個室囊。假設(shè)我們要顯示一個蘋果,那么就將蘋果加入到場景中即可魁索,多個物體可加入到一個場景融撞。
構(gòu)造函數(shù):
var scene = new THREE.Scene();
2.相機(camera)
相機決定了場景中哪個角度的景色會顯示出來,就像人的視角粗蔚,分為正投影相機(THREE.OrthographicCamera)和透視投影相機(THREE.PerspectiveCamera)尝偎,正投影和透視投影的區(qū)別是:透視投影有一個基本點,就是遠處的物體比近處的物體小,一般我們采用透視投影相機的情況比較多致扯。
構(gòu)造函數(shù):
//正投影相機
var camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
//參數(shù)詳解:
//left:左平面距離相機中心點的垂直距離
//right:右平面距離相機中心點的垂直距離
//top:頂平面距離相機中心點的垂直距離
//bottom:底平面距離相機中心點的垂直距離
//near:近平面距離相機中心點的垂直距離
//far:遠平面距離相機中心點的垂直距離
//透視投影相機
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
//參數(shù)詳解:
//視角fov:可以理解為視角的大小肤寝,如果設(shè)置為0,相當(dāng)于沒有了視角抖僵,什么也看不到鲤看;如果為180,那么可以認為你的視界很廣闊裆针,但在180度的時候刨摩,往往物體很小,因為物體在你整個可視區(qū)域中的比例變小了
//近平面near:表示近處的裁面的距離世吨,也可以認為是眼睛到近處的距離澡刹,不能為負數(shù)
//遠平面far:表示遠處的裁面的距離
//縱橫比aspect:實際窗口的縱橫比,即寬度除以高度耘婚,這個值越大罢浇,說明寬度越大
3.渲染器(renderer)
渲染器決定了渲染結(jié)果應(yīng)掛接在頁面的什么元素上,并以怎樣的方式繪制沐祷。
構(gòu)造函數(shù):
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);//設(shè)置渲染區(qū)域大小
document.body.appendChild(renderer, domElement);//渲染在domElement并掛接到body下
renderer.render(scene, camera); //將場景通過相機視角渲染出來
如果要讓物體動起來嚷闭,那么我們可以利用循環(huán)渲染:requestAnimationFrame
4.光源
光是我們看見物體的關(guān)鍵,用Light表示赖临,是所有光源的基類胞锰,底下還有很多分類,我舉幾個最常用的:
環(huán)境光:環(huán)境光是經(jīng)過多次反射惹來的光兢榨,無法確定其最初的方向嗅榕,是一種無處不在的光。環(huán)境光源放出的光線被認為來自任何方向吵聪。因此凌那,當(dāng)你僅為場景設(shè)定環(huán)境光時,所有的物體無論法向量如何吟逝,都將表現(xiàn)為同樣的明暗程度帽蝶。
構(gòu)造函數(shù):
THREE.AmbientLight(hex); //hex為一個16進制的顏色值
平行光:是一組沒有衰減的平行的光線,類似太陽光的效果
THREE.DirectionalLight(hex, intensity)
點光源:由這種光源放出的光線來自同一點块攒,且方向輻射自四面八方
THREE.PointLight(color, intensity, distance)励稳;
//color代表光的顏色
//intensity:代表光的強度,默認1.0囱井,表示100%強度的燈光
//distance:代表光的距離麦锯,從光源所在的位置,經(jīng)過distance這段距離之后琅绅,光的強度將從Intensity衰減為0,默認0.0鹅巍,表示光源強度不衰減
聚光燈:這種光源的光線從一個椎體中射出千扶,在被照射的物體上產(chǎn)生聚光的效果
THREE.SpotLight(hex, intensity, distance, angle, exponent)
//angle:聚光燈著色的角度料祠,用弧度作為單位,這個角度是和光源的方向形成的角度
//exponent:光源模型中澎羞,衰減的一個參數(shù)髓绽,越大衰減越快
5.物體
創(chuàng)建一個物體可以包含多種元素,幾何體妆绞,材質(zhì)顺呕,紋理等,創(chuàng)建一個小球的簡單示例:
let geometry =new THREE.SphereGeometry(3, 16, 16); //球體
let material = new THREE.MeshPhongMaterial({color:0x48D1CC,specular:0xffffff,shininess:100}); //材質(zhì)
var ball = new THREE.Mesh(geometry, material); //兩者共同組成一個球體
scene.add(ball); //將球體添加至場景中
關(guān)于幾何體括饶,材質(zhì)等種類非常多株茶,具體可以參考[three.js源碼]:https://github.com/mrdoob/three.js/
6.動畫
總結(jié)上述步驟:
創(chuàng)建場景、相機图焰、渲染器
創(chuàng)建光源
創(chuàng)建物體并添加至場景中
渲染出場景
這樣就構(gòu)成了一個完整的但也是最基礎(chǔ)的流程启盛,網(wǎng)頁中能看到我們創(chuàng)造的物體,接下來說到動畫技羔,3D世界中的運動方式總結(jié)為三種:移動僵闯,旋轉(zhuǎn)和縮放。
運動是相對的藤滥,場景動起來有兩種方式:
1). 物體在坐標系中移動鳖粟,相機不動
function animate(){
ball.position.x += 1;
renderer.render(scene, camera);
requestAnimationFrame(animation);
}
2). 相機在坐標系中移動,物體不動
function animate(){
camera.position.x += 1;
renderer.render(scene, camera);
requestAnimationFrame(animation);
}
[demo展示中心]:https://yomonah.github.io/project/app.html#/webGL-icosahedron
[源碼]:https://github.com/yomonah/react-demo/tree/master/src/components/webGL_ball