初識(shí)three.js

Three.js是一款webGL框架柬讨,由于其易用性被廣泛應(yīng)用罚舱。Three.js在WebGL的api接口基礎(chǔ)上继薛,又進(jìn)行的一層封裝,所以不用擔(dān)心他得性能,和主機(jī)游戲一樣都是支持硬件加速的诫隅。它是由居住在西班牙巴塞羅那的程序員Ricardo Cabbello Miguel(https://ricardocabello.com/) 開發(fā)的,Three.js以簡單帐偎、直觀的方式封裝了3D圖形編程中常用的對(duì)象逐纬。Three.js在開發(fā)中使用了很多圖形引擎的高級(jí)技巧,極大地提高了性能肮街。Three.js還是完全開源的。
里面有很多圖形學(xué)的概念判导,比如坐標(biāo)變換嫉父,光照計(jì)算,同樣可以創(chuàng)建自己的Shader,調(diào)用底層的圖形接口眼刃,框架具有相當(dāng)高的靈活性绕辖。

Webgl和Three.js的關(guān)系

Webgl和Three.js的關(guān)系,相當(dāng)于JavaScript和Jquery的關(guān)系

創(chuàng)建一個(gè)場景

為了真正能夠讓你的場景借助three.js來進(jìn)行顯示擂红,我們需要以下幾個(gè)對(duì)象:場景仪际、相機(jī)和渲染器,這樣我們就能透過攝像機(jī)渲染出場景昵骤。

//創(chuàng)建場景
 const scene = new THREE.Scene();
 //創(chuàng)建一個(gè)立方體
 const geometry = new THREE.BoxGeometry( 1, 1, 1 );    //幾何形狀
 const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); //材質(zhì)
 const cube = new THREE.Mesh( geometry, material );
 scene.add( cube );

scene以樹結(jié)構(gòu)存放所有可見的和不可見的三維物體树碱,包括光源等等


image.png
 //創(chuàng)建一個(gè)攝像機(jī)
 const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
 camera.position.z = 5;

攝像機(jī)決定了我們從什么位置,什么角度觀察三維物體

const renderer = new THREE.WebGLRenderer();
 renderer.setSize( window.innerWidth, window.innerHeight );
 document.body.appendChild( renderer.domElement );

渲染器負(fù)責(zé)將我們的看到的場景樹渲染成二維圖像

const animate = ()=> {
   requestAnimationFrame( animate );
   //因?yàn)镴avaScript是單線程的,所以用requestAnimationFrame來請(qǐng)求瀏覽器定時(shí)回調(diào)這里的這個(gè)animate()
   cube.rotation.x += 0.01;
   cube.rotation.y += 0.01;
   renderer.render( scene, camera );
   //在循環(huán)中調(diào)用renderer的render()函數(shù)來渲染每一幀圖像
 }
 animate();

三角網(wǎng)Mesh

立方體是用Mesh(三角網(wǎng))表示的


image.png

因?yàn)槿切蔚娜齻€(gè)點(diǎn)可以空間中唯一地確定一個(gè)平面变秦,所以也是最常見的用于表示三維物體的一種方式

Geometry

Geometry代表幾何形狀成榜,由下面的一個(gè)個(gè)三角形和構(gòu)成他們的所有頂點(diǎn)組成


image.png

three.js里內(nèi)置了很多幾何形狀

http://www.webgl3d.cn/threejs/docs/#api/zh/geometries/CircleGeometry
    //創(chuàng)建場景
    const scene = new THREE.Scene();
    var geometry = new THREE.CircleBufferGeometry( 5, 32 );
    var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
    var circle = new THREE.Mesh( geometry, material );
    scene.add( circle );
    //創(chuàng)建一個(gè)攝像機(jī)
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 50;
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    const animate = () => {
        requestAnimationFrame(animate);
        circle.rotation.x += 0.01;
        circle.rotation.y += 0.01;
        renderer.render(scene, camera);
    }
    animate();

Material

Material代表三維物體幾何材質(zhì),不同的材質(zhì)在光照下會(huì)呈現(xiàn)不一樣的效果蹦玫,通過材質(zhì)可以給物體表面設(shè)定不同的顏色赎婚,光澤度,或者給物體加上貼圖


1632492310(1).png

基礎(chǔ)網(wǎng)格材質(zhì)(MeshBasicMaterial) 不參與光照計(jì)算樱溉,不會(huì)產(chǎn)生陰影挣输,使用這種材質(zhì)三維物體看上不去很不真實(shí)。

要想有光照效果可以使用下面的兩種材質(zhì):

  • Phong網(wǎng)格材質(zhì)(MeshPhongMaterial)
  • Lambert網(wǎng)格材質(zhì)(MeshLambertMaterial)
    可以用shininess屬性來調(diào)節(jié)物體表面光澤度
    也可以使用map添加貼圖
    const material = new THREE.MeshBasicMaterial({ 
        map:new THREE.TextureLoader().load('1.png'),
    }); //材質(zhì)

MeshStandardMaterialMeshPhysicalMaterial類是PBR物理材質(zhì)福贞,可以更好的模擬光照計(jì)算撩嚼,相比較高光網(wǎng)格材質(zhì)MeshPhongMaterial渲染效果更逼真。

emissive默認(rèn)黑色挖帘,設(shè)置為白色 發(fā)光顏色

emissiveMap 自發(fā)光貼圖

roughnessMap 粗糙度貼圖 設(shè)定表面不同位置的粗糙程度

normalMap 法線貼圖 給每個(gè)像素點(diǎn)設(shè)置不同的法向量 法線會(huì)影響光照的計(jì)算 可以用它模擬物體表面凹凸不平的效果

displacementMap 高度貼圖 它會(huì)上下偏移物體表面的頂點(diǎn)坐標(biāo)绢馍,從而做到真正的物體表面的起伏

aoMap 環(huán)境光遮罩貼圖 他會(huì)讓被遮蔽的區(qū)域看起來更暗,進(jìn)一步提升場景的真實(shí)感

    //創(chuàng)建場景
    const scene = new THREE.Scene();
    var geometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
    var texLoader = new THREE.TextureLoader()
    const material = new THREE.MeshPhongMaterial({ 
        emissive:0xffffff,
        // // 發(fā)光貼圖
        emissiveMap: texLoader.load("wenli.png"),
        // 法線貼圖
        normalMap: texLoader.load("faxian.png"),
        // 粗糙度貼圖
        roughnessMap: texLoader.load("cucao.png"),
        // //高度貼圖
        displacementMap:texLoader.load("weiyi.png"),
        //光罩貼圖肠套,會(huì)讓深坑得地方更暗舰涌,更有真實(shí)感
        aoMap:texLoader.load("aoMap.png"),
    }); //材質(zhì)
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    //創(chuàng)建一個(gè)攝像機(jī)
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 17;
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    const animate = () => {
        requestAnimationFrame(animate);
        //因?yàn)镴avaScript是單線程的,所以用requestAnimationFrame來請(qǐng)求瀏覽器定時(shí)回調(diào)這里的這個(gè)animate()
        cube.rotation.x += 0.01;
        cube.rotation.y += 0.01;
        renderer.render(scene, camera);
        //在循環(huán)中調(diào)用renderer的render()函數(shù)來渲染每一幀圖像
    }
    animate();

幾何轉(zhuǎn)換

創(chuàng)建Mesh之后,我們可以通過position修改幾何物體在空間的位置

    const material = new THREE.MeshPhongMaterial({ 
        emissive:0xffffff,
        // // 發(fā)光貼圖
        emissiveMap: texLoader.load("wenli.png"),
        // 法線貼圖
        normalMap: texLoader.load("faxian.png"),
        // 粗糙度貼圖
        roughnessMap: texLoader.load("cucao.png"),
        // //高度貼圖
        displacementMap:texLoader.load("weiyi.png"),
        //光罩貼圖你稚,會(huì)讓深坑得地方更暗瓷耙,更有真實(shí)感
        aoMap:texLoader.load("aoMap.png"),
    }); //材質(zhì)
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    cube.position.set(4,0,0)

scale用來轉(zhuǎn)換物體的大小 rotation旋轉(zhuǎn)物體

       const material = new THREE.MeshPhongMaterial({ 
        emissive:0xffffff,
        // // 發(fā)光貼圖
        emissiveMap: texLoader.load("wenli.png"),
        // 法線貼圖
        normalMap: texLoader.load("faxian.png"),
        // 粗糙度貼圖
        roughnessMap: texLoader.load("cucao.png"),
        // //高度貼圖
        displacementMap:texLoader.load("weiyi.png"),
        //光罩貼圖朱躺,會(huì)讓深坑得地方更暗,更有真實(shí)感
        aoMap:texLoader.load("aoMap.png"),
    }); //材質(zhì)
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    cube.scale.multiplyScalar(2)

攝像機(jī)

攝像機(jī)決定了我們應(yīng)當(dāng)從什么角度觀察這個(gè)三維場景

three.js中提供了兩種不同類型的攝像機(jī)

PerspectiveCamera

PerspectiveCamera和我們?nèi)搜鄢上裨眍愃聘橥矗吹降奈矬w呈遠(yuǎn)小近大的透視效果长搀。


1632492626(1).png

創(chuàng)建相機(jī)的時(shí)候先創(chuàng)建視錐


1632492654(1).png

在渲染的時(shí)候,計(jì)算機(jī)會(huì)將視錐中的所有三維物體投影到二維屏幕上
1632492676(1).png
    const camera = new THREE.PerspectiveCamera(
        75, //fov  代表垂直方向上視角的大小
        window.innerWidth / window.innerHeight, //aspect ratio 代表投影平面的縱寬比
        0.1, //near  代表相機(jī)能看到的最近的平面
        1000 //far   代表相機(jī)能看到的最遠(yuǎn)的平面鸡典,超出這個(gè)平面的場景會(huì)被自動(dòng)裁剪掉
    );

OrthographicCamera

OrthographicCamera正交投影相機(jī)源请,會(huì)將空間中的所有物體平行投影到投影面上,所以不會(huì)呈現(xiàn)近大遠(yuǎn)小的效果


1632492729(1).png

一般應(yīng)用在像CAD這種需要精確測量物體尺寸的應(yīng)用場景中


1632492749(1).png

比如用正交投影可以輕易的渲染出物體的三視圖等等

正交相機(jī)的視錐(Frustum)是一個(gè)長方體彻况,所以定義正交相機(jī)要先定義前后左右上下這6個(gè)面的位置

    const camera = new THREE.OrthographicCamera(
        -2,//left 
        2,//right 
        1.5,//top
        -1.5,//bottom
        1,//near
        10 //far
    );

一樣使用position屬性修改相機(jī)的位置

//三種修改position的方法
camera.position.set(0,1,5)
camera.position.y += 2
camera.translateZ(2)

camera.updateMatrix()
//更新相機(jī)的變換矩陣

參考資料
1.奇樂編程
2.http://www.yanhuangxueyuan.com/threejs/docs/index.html#manual/zh/introduction/Creating-a-scene

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谁尸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子纽甘,更是在濱河造成了極大的恐慌良蛮,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悍赢,死亡現(xiàn)場離奇詭異决瞳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)左权,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門皮胡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赏迟,你說我怎么就攤上這事胸囱。” “怎么了瀑梗?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵烹笔,是天一觀的道長。 經(jīng)常有香客問我抛丽,道長谤职,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任亿鲜,我火速辦了婚禮允蜈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒿柳。我一直安慰自己饶套,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布垒探。 她就那樣靜靜地躺著妓蛮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪圾叼。 梳的紋絲不亂的頭發(fā)上蛤克,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天捺癞,我揣著相機(jī)與錄音,去河邊找鬼构挤。 笑死髓介,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的筋现。 我是一名探鬼主播唐础,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矾飞!你這毒婦竟也來了一膨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤凰慈,失蹤者是張志新(化名)和其女友劉穎汞幢,沒想到半個(gè)月后驼鹅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體微谓,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年输钩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了豺型。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡买乃,死狀恐怖姻氨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情剪验,我是刑警寧澤肴焊,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站功戚,受9級(jí)特大地震影響娶眷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啸臀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一届宠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乘粒,春花似錦豌注、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至旦棉,卻和暖如春属桦,著一層夾襖步出監(jiān)牢的瞬間熊痴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來泰國打工聂宾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留果善,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓系谐,卻偏偏與公主長得像巾陕,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子纪他,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • What is Three.js 什么是threejs鄙煤,很簡單,你將它理解成three + js就可以了茶袒。thre...
    依依玖玥閱讀 1,530評(píng)論 0 2
  • Threejs 為什么梯刚? webGL太難用,太復(fù)雜薪寓! 但是現(xiàn)代瀏覽器都支持 WebGL 這樣我們就不必使用 Fla...
    強(qiáng)某某閱讀 6,065評(píng)論 1 21
  • Three.js 1.Three.js 介紹 OpenGL(英語:Open Graphics Library亡资,譯名...
    GuitarHusky閱讀 2,493評(píng)論 0 1
  • three之前的準(zhǔn)備 three.js是webGL的一個(gè)高級(jí)工具集,webGL則是從openGL ES 發(fā)展而來的...
    琙靈閱讀 1,658評(píng)論 0 2
  • Threejs中文文檔 郭隆邦技術(shù)博客 2018-09-21 20:40:17 關(guān)注 Three.js中文文檔 今...
    情人波閱讀 14,039評(píng)論 0 7