亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Three.js快速入門教程

 更新時(shí)間:2016年09月09日 15:35:24   作者:lijunfan1994  
這篇文章主要為大家詳細(xì)介紹了Three.js快速入門教程,幫助大家快速入門,感興趣的小伙伴們可以參考一下

引言

本文主要是講解Three.js的相關(guān)概念,幫助讀者對(duì)Three.js以及相關(guān)知識(shí)形成比較完整的理解。

近年來(lái)web得到了快速的發(fā)展。隨著HTML5的普及,網(wǎng)頁(yè)的表現(xiàn)能力越來(lái)越強(qiáng)大。網(wǎng)頁(yè)上已經(jīng)可以做出很多復(fù)雜的動(dòng)畫,精美的效果。
但是,人總是貪的。那么,在此之上還能做什么呢?其中一種就是通過(guò)WebGL在網(wǎng)頁(yè)中繪制高性能的3D圖形。

OpenGL,WebGL到Three.js

OpenGL大概許多人都有所耳聞,它是最常用的跨平臺(tái)圖形庫(kù)。
WebGL是基于OpenGL設(shè)計(jì)的面向web的圖形標(biāo)準(zhǔn),提供了一系列JavaScript API,通過(guò)這些API進(jìn)行圖形渲染將得以利用圖形硬件從而獲得較高性能。
Three.js是通過(guò)對(duì)WebGL接口的封裝與簡(jiǎn)化而形成的一個(gè)易用的圖形庫(kù)。

簡(jiǎn)單點(diǎn)的說(shuō)法:WebGL可以看成是瀏覽器給我們提供的接口,在javascript中可以直接用這些API進(jìn)行3D圖形的繪制;而Three.js就是在這些接口上又幫我們封裝得更好用一些。

WebGL與Three.js對(duì)比

既然有了WebGL,我們?yōu)槭裁催€需要Three.js?
這是因?yàn)閃ebGL門檻相對(duì)較高,需要相對(duì)較多的數(shù)學(xué)知識(shí)。雖然WebGL提供的是面向前端的API,但本質(zhì)上WebGL跟前端開發(fā)完全是兩個(gè)不同的方向,知識(shí)的重疊很少。相關(guān)性只是他們都在web平臺(tái)上,都是用javascript而已。一個(gè)前端程序員或許還熟悉解析幾何,但是還熟悉線性代數(shù)的應(yīng)該寥寥無(wú)幾了(比如求個(gè)逆轉(zhuǎn)置矩陣試試?),更何況使用中強(qiáng)調(diào)矩陣運(yùn)算中的物理意義,這在教學(xué)中也是比較缺失的。
因此,前端工程師想要短時(shí)間上手WebGL還是挺有難度的。
于是,Three.js對(duì)WebGL提供的接口進(jìn)行了非常好的封裝,簡(jiǎn)化了很多細(xì)節(jié),大大降低了學(xué)習(xí)成本。并且,幾乎沒(méi)有損失WebGL的靈活性。
因此,從Three.js入手是值得推薦的,這可以讓你在較短的學(xué)習(xí)后就能面對(duì)大部分需求場(chǎng)景。

Three.js的學(xué)習(xí)問(wèn)題

Three.js的入門是相對(duì)簡(jiǎn)單的,但是當(dāng)我們真的去學(xué)的時(shí)候,會(huì)發(fā)現(xiàn)一個(gè)很尷尬的問(wèn)題:相關(guān)的學(xué)習(xí)資料很少。
通常這種流行的庫(kù)都有很完善的文檔,很多時(shí)候跟著官方的文檔或官方的入門教程學(xué)習(xí)就是最好的路線。但Three不是的,它的文檔對(duì)初學(xué)者來(lái)說(shuō)太過(guò)簡(jiǎn)明扼要。
不過(guò)官方提供了非常豐富的examples,幾乎所有你需要的用法都在某個(gè)example中有所體現(xiàn)。但這些example不太適合用來(lái)入門,倒是適合入門之后的進(jìn)一步學(xué)習(xí)。

這里推薦一些相對(duì)較好的教程:
Three.js入門指南
這是一份很好的Three.js 輕量級(jí)入門教程,作者文筆很好,基礎(chǔ)知識(shí)講解得簡(jiǎn)明易懂。

Three.js開發(fā)指南(第一版中文版)

Learning Three.js- Second Edition
Learning Three.js:The JavaScript 3D Library for WebGL是現(xiàn)在不多的也是最好的Three.js入門書,比較全面地講解了Three.js的各種功能。
如果有能力的話,建議閱讀英文版第二版,出版于2015年,與現(xiàn)在的Three.js區(qū)別很小。
中文版翻譯自出版于2012年的原書第一版,大部分概念是適用的,但很多細(xì)節(jié)已經(jīng)有所改變。
Three.js入門教程
這是對(duì)國(guó)外一份教程的翻譯,一共六篇文章。講解不多,更多的是展示各個(gè)基本功能怎么用。更適合有一些圖形基礎(chǔ)的同學(xué)。

當(dāng)然,實(shí)際的學(xué)習(xí)過(guò)程中這些資料肯定是不太夠的,遇到問(wèn)題還是要自己去查資料。不過(guò)這里要提醒一下,Three.js的更新是相當(dāng)頻繁的,現(xiàn)在是r80版本,自2010年4月發(fā)布r1以來(lái),這已經(jīng)是第72個(gè)版本了(中間有的版本號(hào)跳過(guò)了)。因此,在網(wǎng)上找到的資料有些可能是不適合當(dāng)前版本的,需要注意甄別(前面推薦的資料也都或多或少存在這樣的問(wèn)題)。

Three.js中的一些概念

要在屏幕上展示3D圖形,思路大體上都是這樣的:

構(gòu)建一個(gè)三維空間
Three中稱之為場(chǎng)景(Scene)選擇一個(gè)觀察點(diǎn),并確定觀察方向/角度等
Three中稱之為相機(jī)(Camera)在場(chǎng)景中添加供觀察的物體
Three中的物體有很多種,包括Mesh,Line,Points等,它們都繼承自O(shè)bject3D類將觀察到的場(chǎng)景渲染到屏幕上的指定區(qū)域
Three中使用Renderer完成這一工作

下面來(lái)具體看一看Three中的這些概念。

Scene

場(chǎng)景是所有物體的容器,也對(duì)應(yīng)著我們創(chuàng)建的三維世界。

Camera 坐標(biāo)系

Camera是三維世界中的觀察者,為了觀察這個(gè)世界,首先我們要描述空間中的位置。

左手/右手坐標(biāo)系 

Three中使用采用常見的右手坐標(biāo)系定位。

三維投影

Three中的相機(jī)有兩種,分別是正投影相機(jī)THREE.OrthographicCamera和透視投影相機(jī)THREE.PerspectiveCamera。

這里寫圖片描述 

正交投影與透視投影的區(qū)別如上圖所示,左圖是正交投影,物體發(fā)出的光平行地投射到屏幕上,遠(yuǎn)近的方塊都是一樣大的;右圖是透視投影,近大遠(yuǎn)小,符合我們平時(shí)看東西的感覺(jué)。
維基百科:三維投影

正交投影相機(jī)

正交投影相機(jī) 

注:圖中的”視點(diǎn)”對(duì)應(yīng)著Three中的Camera。
這里補(bǔ)充一個(gè)視景體的概念:視景體是一個(gè)幾何體,只有視景體內(nèi)的物體才會(huì)被我們看到,視景體之外的物體將被裁剪掉。這是為了去除不必要的運(yùn)算。
正交投影相機(jī)的視景體是一個(gè)長(zhǎng)方體,OrthographicCamera的構(gòu)造函數(shù)是這樣的:OrthographicCamera( left, right, top, bottom, near, far )
Camera本身可以看作是一個(gè)點(diǎn),left則表示左平面在左右方向上與Camera的距離。另外幾個(gè)參數(shù)同理。于是六個(gè)參數(shù)分別定義了視景體六個(gè)面的位置。

可以近似地認(rèn)為,視景體里的物體平行投影到近平面上,然后近平面上的圖像被渲染到屏幕上。

透視投影相機(jī)

透視投影相機(jī) 

透視投影相機(jī)的視景體是個(gè)四棱臺(tái),它的構(gòu)造函數(shù)是這樣的:PerspectiveCamera( fov, aspect, near, far )
fov對(duì)應(yīng)著圖中的視角,是上下兩面的夾角。aspect是近平面的寬高比。在加上近平面距離near,遠(yuǎn)平面距離far,就可以唯一確定這個(gè)視景體了。
透視投影相機(jī)很符合我們通常的看東西的感覺(jué),因此大多數(shù)情況下我們都是用透視投影相機(jī)展示3D效果。

Objects

有了相機(jī),總要看點(diǎn)什么吧?在場(chǎng)景中添加一些物體吧。
Three中供顯示的物體有很多,它們都繼承自O(shè)bject3D類,這里我們主要看一下Mesh和Points兩種。

Mesh

我們都知道,計(jì)算機(jī)的世界里,一條弧線是由有限個(gè)點(diǎn)構(gòu)成的有限條線段連接得到的。線段很多時(shí),看起來(lái)就是一條平滑的弧線了。
計(jì)算機(jī)中的三維模型也是類似的,普遍的做法是用三角形組成的網(wǎng)格來(lái)描述,我們把這種模型稱之為Mesh模型。

Mesh Model 

這是那只著名的斯坦福兔子。它在3D圖形中的地位與數(shù)字圖像處理領(lǐng)域中著名的lena是類似的。
看這只兔子,隨著三角形數(shù)量的增加,它的表面越來(lái)越平滑/準(zhǔn)確。

在Three中,Mesh的構(gòu)造函數(shù)是這樣的:Mesh( geometry, material )
geometry是它的形狀,material是它的材質(zhì)。
不止是Mesh,創(chuàng)建很多物體都要用到這兩個(gè)屬性。下面我們來(lái)看看這兩個(gè)重要的屬性。

Geometry

Geometry,形狀,相當(dāng)直觀。Geometry通過(guò)存儲(chǔ)模型用到的點(diǎn)集和點(diǎn)間關(guān)系(哪些點(diǎn)構(gòu)成一個(gè)三角形)來(lái)達(dá)到描述物體形狀的目的。
Three提供了立方體(其實(shí)是長(zhǎng)方體)、平面(其實(shí)是長(zhǎng)方形)、球體、圓形、圓柱、圓臺(tái)等許多基本形狀;
你也可以通過(guò)自己定義每個(gè)點(diǎn)的位置來(lái)構(gòu)造形狀;
對(duì)于比較復(fù)雜的形狀,我們還可以通過(guò)外部的模型文件導(dǎo)入。

Material

Material,材質(zhì),這就沒(méi)有形狀那么直觀了。
材質(zhì)其實(shí)是物體表面除了形狀以為所有可視屬性的集合,例如色彩、紋理、光滑度、透明度、反射率、折射率、發(fā)光度。
這里講一下材質(zhì)(Material)、貼圖(Map)和紋理(Texture)的關(guān)系。
材質(zhì)上面已經(jīng)提到了,它包括了貼圖以及其它。
貼圖其實(shí)是‘貼'和‘圖',它包括了圖片和圖片應(yīng)當(dāng)貼到什么位置。
紋理嘛,其實(shí)就是‘圖'了。
Three提供了多種材質(zhì)可供選擇,能夠自由地選擇漫反射/鏡面反射等材質(zhì)。

Points

講完了Mesh,我們來(lái)看看另一種Object——Points。
Points其實(shí)就是一堆點(diǎn)的集合,它在之前很長(zhǎng)時(shí)間都被稱為ParticleSystem(粒子系統(tǒng)),r68版本時(shí)更名為PointCloud,r72版本時(shí)才更名為Points。更名主要是因?yàn)椋琈r.doob認(rèn)為,粒子系統(tǒng)應(yīng)當(dāng)是包括粒子和相關(guān)的物理特性的處理的一套完整體系,而Three中的Points簡(jiǎn)單得多。因此最終這個(gè)類被命名為Points。
Points能夠用來(lái)實(shí)現(xiàn)的典型效果是這樣的:官方example

Light

神說(shuō):要有光!
光影效果是讓畫面豐富的重要因素。
Three提供了包括環(huán)境光AmbientLight、點(diǎn)光源PointLight、 聚光燈SpotLight、方向光DirectionalLight、半球光HemisphereLight等多種光源。
只要在場(chǎng)景中添加需要的光源就好了。

Renderer

在場(chǎng)景中建立了各種物體,也有了光,還有觀察物體的相機(jī),是時(shí)候把看到的東西渲染到屏幕上了。這就是Render做的事情了。
Renderer綁定一個(gè)canvas對(duì)象,并可以設(shè)置大小,默認(rèn)背景顏色等屬性。
調(diào)用Renderer的render函數(shù),傳入scene和camera,就可以把圖像渲染到canvas中了。

讓畫面動(dòng)起來(lái)

現(xiàn)在,一個(gè)靜態(tài)的畫面已經(jīng)可以得到了,怎么才能讓它動(dòng)起來(lái)?
很簡(jiǎn)單的想法,改變場(chǎng)景中object的位置啊角度啊各種屬性,然后重新調(diào)用render函數(shù)渲染就好了。
那么重新渲染的時(shí)機(jī)怎么確定?
HTML5為我們提供了requestAnimFrame,它會(huì)自動(dòng)在每次頁(yè)面重繪前調(diào)用傳入的函數(shù)。
如果我們一開始這樣渲染:

function render()
{
 renderer.render(scene, camera);
}

只需要改成這樣:

function render()
{
 requestAnimationFrame(render);
 object.position.x += 1;
 renderer.render(scene, camera);
}

object就可以動(dòng)起來(lái)了!

舉個(gè)栗子

下面我們用一個(gè)簡(jiǎn)單的例子來(lái)梳理一下這個(gè)過(guò)程。
首先寫一個(gè)有Canvas元素的頁(yè)面吧。

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>立方體</title>
 <script src="http://sqimg.qq.com/qq_product_operations/mma/javanli_test/lib/three.min.js"></script>
 <style type="text/css">
 html, body {
 margin: 0;
 padding: 0;
 }
 #three_canvas {
 position: absolute;
 width: 100%;
 height: 100%;
 }
 </style>
</head>
<body>
 <canvas id="three_canvas"></canvas>
</body>
</html>

下面來(lái)做Javascript的部分
首先初始化Renderer

function initRenderer() {
 width = document.getElementById('three_canvas').clientWidth;
 height = document.getElementById('three_canvas').clientHeight;
 renderer = new THREE.WebGLRenderer({
 //將Canvas綁定到renderer
 canvas: document.getElementById('three_canvas')
 });
 renderer.setSize(width, height);//將渲染的大小設(shè)為與Canvas相同
 renderer.setClearColor(0xFFFFFF, 1.0);//設(shè)置默認(rèn)顏色與透明度
}


初始化場(chǎng)景:

function initScene() {
 scene = new THREE.Scene();
}

初始化相機(jī):

function initCamera() {
 //簡(jiǎn)單的正交投影相機(jī),正對(duì)著視口的中心,視口大小與Canvas大小相同。
 camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000);
 //設(shè)置相機(jī)的位置
 camera.position.x = 0;
 camera.position.y = 0;
 camera.position.z = 200;
 //設(shè)置相機(jī)的上方向
 camera.up.x = 0;
 camera.up.y = 1;
 camera.up.z = 0;
 //設(shè)置相機(jī)聚焦的位置(其實(shí)就是確定一個(gè)方向)
 camera.lookAt({
 x: 0,
 y: 0,
 z: 0
 });
}

要唯一確定一個(gè)相機(jī)的位置與方向,position、up、lookAt三個(gè)屬性是缺一不可的。
這里我們創(chuàng)建了一個(gè)正交投影相機(jī),這里我將視景體大小與屏幕分辨率保持一致只是為了方便,這樣坐標(biāo)系中的一個(gè)單位長(zhǎng)度就對(duì)應(yīng)屏幕的一個(gè)像素了。
我們將相機(jī)放在Z軸上,面向坐標(biāo)原點(diǎn),相機(jī)的上方向?yàn)閅軸方向,注意up的方向和lookAt的方向必然是垂直的(類比自己的頭就知道了)。

下面添加一個(gè)立方體到場(chǎng)景中:

function initObject() {
 //創(chuàng)建一個(gè)邊長(zhǎng)為100的立方體
 var geometry = new THREE.CubeGeometry(100, 100, 100);
 object = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial());
 scene.add(object);
}

注意我們使用了法向材質(zhì)MeshNormalMaterial,這樣立方體每個(gè)面的顏色與這個(gè)面對(duì)著的方向是相關(guān)的,更便于觀察/調(diào)試。

在這個(gè)簡(jiǎn)單的demo里我不打算添加光影效果,而法向材質(zhì)對(duì)光也是沒(méi)有反應(yīng)的。
最后來(lái)創(chuàng)建一個(gè)動(dòng)畫循環(huán)吧

function render() {
 requestAnimationFrame(render);
 object.rotation.x += 0.05;
 object.rotation.y += 0.05;
 renderer.render(scene, camera);
}

每次重繪都讓這個(gè)立方體轉(zhuǎn)動(dòng)一點(diǎn)點(diǎn)。
當(dāng)頁(yè)面加載好時(shí),調(diào)用前面這些函數(shù)就好了

function threeStart() {
 initRenderer();
 initCamera();
 initScene();
 initObject();
 render();
}
window.onload = threeStart();

完整的demo是這個(gè)樣子的:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>立方體</title>
 <script src="http://sqimg.qq.com/qq_product_operations/mma/javanli_test/lib/three.min.js"></script>
 <style type="text/css">
 html, body {
 margin: 0;
 padding: 0;
 }

 #three_canvas {
 position: absolute;
 width: 100%;
 height: 100%;
 }
 </style>
</head>
<body>
<canvas id="three_canvas"></canvas>
<script>
 var renderer, camera, scene, light, object;
 var width, height;
 function initRenderer() {
 width = document.getElementById('three_canvas').clientWidth;
 height = document.getElementById('three_canvas').clientHeight;
 renderer = new THREE.WebGLRenderer({
 canvas: document.getElementById('three_canvas')
 });
 renderer.setSize(width, height);
 renderer.setClearColor(0xFFFFFF, 1.0);
 }

 function initCamera() {
 camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000);
 camera.position.x = 0;
 camera.position.y = 0;
 camera.position.z = 200;
 camera.up.x = 0;
 camera.up.y = 1;
 camera.up.z = 0;
 camera.lookAt({
 x: 0,
 y: 0,
 z: 0
 });
 }
 function initScene() {
 scene = new THREE.Scene();
 }
 function initObject() {
 var geometry = new THREE.CubeGeometry(100, 100, 100);
 object = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial());
 scene.add(object);
 }
 function render() {
 requestAnimationFrame(render);
 object.rotation.x += 0.05;
 object.rotation.y += 0.05;
 renderer.render(scene, camera);
 }
 function threeStart() {
 initRenderer();
 initCamera();
 initScene();
 initObject();
 render();
 }
 window.onload = threeStart();
</script>
</body>
</html>

保存為html后打開,在屏幕中央會(huì)顯示這樣一個(gè)轉(zhuǎn)動(dòng)的立方體

cube

小結(jié)

對(duì)Three.js的介紹就到這里了,本文對(duì)Three中的重要組件基本上都有提到。其實(shí)想要總結(jié)的東西還有很多,但寫在這一篇里可能會(huì)顯得很累贅,這篇文章的初衷是想要讀者讀后對(duì)Three.js有一個(gè)直觀的大體上的理解,并不打算牽涉太多細(xì)節(jié)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論