天天看點

Three.js快速入門ThreeJS開發

ThreeJS快速入門

  • ThreeJS開發
    • 學習準備
    • 安裝
    • 基本使用
      • 效果圖
    • 控制器
    • 物體移動
      • 效果圖
    • 物體縮放與旋轉
    • Clock跟蹤時間
    • Gsap動畫
    • 自适應
    • Gui
      • 效果圖
    • BufferGeometry(設定頂點)
      • 設定頂點建立矩形
      • 實作三角形
    • 材質與紋理
    • 标準網格材質
      • 效果圖
    • 環境貼圖
      • 效果圖
    • 燈光與陰影
      • 效果圖
    • 平行光的陰影屬性
    • 聚光燈
      • 效果圖
    • 點光源
      • 效果圖

ThreeJS開發

該教程由本人學習記錄下來的筆記供大家學習
  • 初識ThreeJS它是一個web端3D開發的好幫手
  • 本人對3D的熱愛探索便前往學習了解了一番
  • 特此整理以下筆記供大家參閱

學習準備

這裡我使用vue腳手架去建立的項目

目錄結構:

Three.js快速入門ThreeJS開發

安裝

這裡可以單獨安裝依賴,我這裡安裝好了,大家隻需要在package.json中放入以下代碼塊

"dependencies": {
    "dat.gui": "^0.7.9",
    "gsap": "^3.11.0",
    "three": "^0.143.0",
    "vue": "^3.0.4"
  },
           
  • three肯定是必不可少的
  • 其次dat.gui是three提供的一款gui界面調試的工具
  • gsap是一款動畫庫,用于實作動畫
  • vue則是腳手架建立項目時自動安裝好的

放入以上代碼後則使用以下指令進行安裝依賴

npm i
           

基本使用

這裡簡單使用three實作一個平面圖形

在index.html中編寫代碼并且下方js檔案

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Three開發---碰磕</title>
</head>
<body>
  <div id="app"></div>
  <script type="module" src="./src/3D/threeBasic.js"></script>
</body>
</html>

           

threeBasic.js

1.引入three.js

2.建立一個場景

3.建立一個相機

設定相機位置x,y,z并放入場景中

camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中
           

4.添加物體

這裡建立一個平面圖形
//建立幾何體
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将幾何體添加到場景中
           

5.初始化渲染器

const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高
           

6.将渲染的内容添加到dom節點中

7、使用渲染器,通過相機将場景渲染進來

以上代碼即可實作簡單的效果

npm run dev
           

運作看看效果圖吧!!!

效果圖

Three.js快速入門ThreeJS開發

現在開始一步一步系統學習吧!

控制器

使用控制器檢視3d物體

這裡我就直接貼代碼了,代碼中都給了注釋,index.html中别忘了引入該js

/**
 * 使用控制器檢視3d物體
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();
//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将幾何體添加到場景中

//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);

//編寫渲染函數
function render(){
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數
           

以上代碼即可實作3D效果了,可拉近拉遠,可旋轉

物體移動

實作3d物體移動
/**
 * 實作3d物體移動
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将幾何體添加到場景中

//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);


//編寫渲染函數
function render(){
    cube.position.x+=0.01;
    if(cube.position.x>5){
        cube.position.x=0
        
    }
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數
           
  • 通過new $Three.AxesHelper(5)建立了坐标軸,使得物體移動看着更清晰
  • 再通過控制position去修改它的位置

效果圖

效果圖如下:它是一直在動的哈

Three.js快速入門ThreeJS開發

物體縮放與旋轉

實作3d物體縮放
/**
 * 實作3d物體縮放
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将幾何體添加到場景中
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//6、使用渲染器,通過相機将場景渲染進來
// renderer.render(scene,camera);

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);


//編寫渲染函數
function render(){
    cube.position.x+=0.01;
    cube.scale.x+=0.01;//縮放scale
    cube.rotation.x+=0.01//旋轉rotation
    if(cube.position.x>5){
        cube.position.x=0
        cube.scale.x=1
        cube.rotation.x=0
    }
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數
           
  • 旋轉通過控制rotation屬性
  • 縮放通過控制scale屬性

以上代碼即可看到該圖形邊變長邊旋轉…

Clock跟蹤時間

/**
 * Clock跟蹤時間
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将幾何體添加到場景中
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//設定時鐘
const clock=new $Three.Clock();

//編寫渲染函數
function render(){
    //擷取時鐘運作的總時長
    let time=clock.getElapsedTime();
    let deltaTime=clock.getDelta();
    // console.log("時鐘運作總時長:",time);
    // console.log("兩次擷取時間的間隔::",deltaTime);
    let t=time%5;
    cube.position.x =t*1;
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數
           
  • 以上代碼主要是運用一下Three中的Clock()時鐘

Gsap動畫

gsap設定各種動畫效果

官網:https://github.com/greensock/GSAP

如果沒安裝該依賴則手動安裝一下,跟着教程的話一開始即安裝好了,沒有安裝請安裝

npm install gsap
           

開始使用:

/**
 * gsap設定各種動畫效果
 * npm install gsap
 * 官網:https://github.com/greensock/GSAP
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//導入動畫庫
import gsap from 'gsap'
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将幾何體添加到場景中

//修改幾何體的位置
// cube.position.set(5,0,0)
// cube.position.x=3;
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//6、使用渲染器,通過相機将場景渲染進來
// renderer.render(scene,camera);

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//設定時鐘
// const clock=new $Three.Clock();

//設定動畫to(物體的屬性,{需要執行的操作..},ease執行方式,repeat:重複的次數(死循環設定-1),yoyo:往返移動,delay:延遲移動,onComplete:()=>完成執行的回調函數,onStart:()=>動畫開始執行)
var maveposition=gsap.to(cube.position,{x: 5,duration:5,repeat:2,yoyo:true,delay:1,ease: "power1.inOut",
onComplete:()=>{
    console.log("移動完成")
},
onStart:()=>{
    console.log("動畫開始")
}
});
window.addEventListener('click',()=>{
    //isActive()表示是否在運作移動
    if(maveposition.isActive()){
        maveposition.pause();//動畫暫停
    }else{
        maveposition.resume();//動畫繼續
    }
})
gsap.to(cube.rotation,{x:2*Math.PI,duration:6,ease: "power1.inOut"})

//編寫渲染函數
function render(){
    
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數
           
  • 如何使用代碼中都進行了注釋,自行看看咯

自适應

以上代碼均沒有做一個自适應處理
  • 當你放大縮小頁面時,頁面内容還是保持不變,是以我們要解決這個問題!!!
  • 通過監聽畫面變化,更新畫面
/**
 * 頁面自适應
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//導入動畫庫
import gsap from 'gsap'
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将幾何體添加到場景中

//修改幾何體的位置
// cube.position.set(5,0,0)
// cube.position.x=3;
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//設定動畫to(物體的屬性,{需要執行的操作..},ease執行方式,repeat:重複的次數(死循環設定-1),yoyo:往返移動,delay:延遲移動,onComplete:()=>完成執行的回調函數,onStart:()=>動畫開始執行)
var maveposition=gsap.to(cube.position,{x: 5,duration:5,repeat:2,yoyo:true,delay:1,ease: "power1.inOut",
onComplete:()=>{
    console.log("移動完成")
},
onStart:()=>{
    console.log("動畫開始")
}
});
window.addEventListener('click',()=>{
    //isActive()表示是否在運作移動
    if(maveposition.isActive()){
        maveposition.pause();//動畫暫停
    }else{
        maveposition.resume();//動畫繼續
    }
})
gsap.to(cube.rotation,{x:2*Math.PI,duration:6,ease: "power1.inOut"})

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
})
           
  • resize表示頁面大小被改變時觸發的事件

Gui

通過gui界面更改參數

沒安裝的話請安裝

npm install --save dat.gui
           

使用:

/**
 * gui界面更改參數
 * npm install --save dat.gui
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//導入動畫庫
import gsap from 'gsap'
//導入gui
import * as dat from 'dat.gui'
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
const cubeGeometry=new $Three.BoxGeometry();
const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const cube=new $Three.Mesh(cubeGeometry,cubeMaterial);
scene.add(cube)//将幾何體添加到場景中

const gui=new dat.GUI()
gui.add(cube.position,"x").min(0).max(5).step(0.02).name("正方體x坐标").onChange((val)=>{
    console.log("你修改了x=",val)
}).onFinishChange((val)=>{
    console.log("完全停下來..",val)
})
//修改物體顔色
let params={
    color:'#ffff00',
    fn:()=>{
        gsap.to(cube.rotation,{x: 5,duration:5,repeat:2,yoyo:true,delay:1,ease: "power1.inOut"})
    },
}
gui.addColor(params,'color').onChange((val)=>cube.material.color.set(val));
//設定頁籤
gui.add(cube,'visible').name("是否顯示");
var folder=gui.addFolder("設定立方體");
folder.add(cube.material,"wireframe");
//設定按鈕點選觸發某個事件
gui.add(params,"fn").name("立方體運動")
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//6、使用渲染器,通過相機将場景渲染進來
// renderer.render(scene,camera);

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//設定時鐘
// const clock=new $Three.Clock();

//設定動畫to(物體的屬性,{需要執行的操作..},ease執行方式,repeat:重複的次數(死循環設定-1),yoyo:往返移動,delay:延遲移動,onComplete:()=>完成執行的回調函數,onStart:()=>動畫開始執行)
var maveposition=gsap.to(cube.position,{x: 5,duration:5,repeat:2,yoyo:true,delay:1,ease: "power1.inOut",
onComplete:()=>{
    console.log("移動完成")
},
onStart:()=>{
    console.log("動畫開始")
}
});
window.addEventListener('click',()=>{
    //isActive()表示是否在運作移動
    if(maveposition.isActive()){
        maveposition.pause();//動畫暫停
    }else{
        maveposition.resume();//動畫繼續
    }
})
gsap.to(cube.rotation,{x:2*Math.PI,duration:6,ease: "power1.inOut"})

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           

效果圖

Three.js快速入門ThreeJS開發

BufferGeometry(設定頂點)

設定頂點建立矩形

BufferGeometry設定頂點建立矩形
/**
 * BufferGeometry設定頂點建立矩形
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//導入動畫庫
import gsap from 'gsap'
//導入gui
import * as dat from 'dat.gui'
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
const cubeGeometry=new $Three.BufferGeometry();
const vertices=new Float32Array([
    -1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0
]);
cubeGeometry.setAttribute("position",new $Three.BufferAttribute(vertices,3));

const cubeMaterial=new $Three.MeshBasicMaterial({color: 0x00ff00});//使用基礎材質并設定顔色
//根據幾何體和材質建立物體
const mesh=new $Three.Mesh(cubeGeometry,cubeMaterial)

scene.add(mesh)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           

實作三角形

通過循環建立多個角度不同的三角形,要的就是雜亂無章的感覺
/**
 * 使用BufferGeometry實作酷炫三角形
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//導入動畫庫
import gsap from 'gsap'
//導入gui
import * as dat from 'dat.gui'
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//3、添加物體
//建立幾何體
for(let i=0;i<50;i++){
    const cubeGeometry=new $Three.BufferGeometry();
    const positionArr=new Float32Array(9);
    //3個頂點(每個頂點3個值)
    for(let j=0;j<9;j++){
        positionArr[j]=Math.random()*5-1;
    }
    cubeGeometry.setAttribute("position",new $Three.BufferAttribute(positionArr,3));
    let color=new $Three.Color(Math.random(),Math.random(),Math.random());//随機顔色
    const cubeMaterial=new $Three.MeshBasicMaterial({color: color,transparent:true,opacity:0.5});//使用基礎材質并設定顔色
    //根據幾何體和材質建立物體
    const mesh=new $Three.Mesh(cubeGeometry,cubeMaterial)

    scene.add(mesh)
}


//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           

材質與紋理

  • 通過enableDamping設定阻尼讓物體有重量感
  • 代碼中示範了紋理的一些常用屬性
/**
 * 材質與紋理
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();
//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//導入紋理
const textureloader=new $Three.TextureLoader();
const myTextloader=textureloader.load('../chunyu02.jpg')//加載本地圖檔

/**
 * 紋理常用的屬性
 */
myTextloader.offset.set(0.1,0)//偏移
myTextloader.center.set(0.5,0.5)//旋轉的原點
myTextloader.rotation=Math.PI/4//旋轉45deg
myTextloader.repeat.set(2,3);//重複
myTextloader.wrapS=$Three.RepeatWrapping;//設定重複模式(該值表示無限重複)
//添加物體
const geometry=new $Three.BoxBufferGeometry(1,1,1);
//材質
const basicMaterial=new $Three.MeshBasicMaterial({
    color:"#ffff00",
    map:myTextloader
})
const cube=new $Three.Mesh(geometry,basicMaterial);
scene.add(cube)

//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//6、使用渲染器,通過相機将場景渲染進來
// renderer.render(scene,camera);

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           

以上代碼主要是對材質與紋理的一個了解使用

标準網格材質

通過MeshStandardMaterial建立标準網格材質
/**
 * 标準網格材質
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中



let event={}
//單張紋理圖的加載
event.onLoad=function(){
    console.log("加載完成...")
}
event.onProgress=function(e,sum,total){
    console.log("正在加載的路徑",e)
    console.log("加載進度",sum)
    console.log("需要加載的總進度:",total)
    console.log("加載進度百分比:",((sum/total)*100).toFixed(2)+'%');
}
event.onError=function(){
    console.log("加載失敗")
}
//設定加載管理器
const loadingManager=new $Three.LoadingManager(
    event.onLoad,
    event.onProgress,
    event.onError
);
//導入紋理
const textureloader=new $Three.TextureLoader(loadingManager);
const myTextloader=textureloader.load('../chunyu02.jpg')//event.onLoad,event.onProgress,event.onError加載本地圖檔
/**
 * 紋理常用的屬性
 */
myTextloader.offset.set(0.1,0)//偏移
myTextloader.center.set(0.5,0.5)//旋轉的原點
myTextloader.rotation=Math.PI/4//旋轉45deg
myTextloader.repeat.set(2,3);//重複
myTextloader.wrapS=$Three.RepeatWrapping;//設定重複模式(該值表示無限重複)
//添加物體
const geometry=new $Three.BoxBufferGeometry(1,1,1);
//材質
const material=new $Three.MeshStandardMaterial({
    color:"#ffff00",
    map:myTextloader,
    roughness:0,//粗糙度
    metalness:0,//金屬度
})
//燈光
const light1=new $Three.AmbientLight(0xffffff,0.5);//環境光
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.position.set(10,10,10)//設定平行光照的位置
scene.add(light2)
const cube=new $Three.Mesh(geometry,material);
scene.add(cube)

//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//6、使用渲染器,通過相機将場景渲染進來
// renderer.render(scene,camera);

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           

效果圖

Three.js快速入門ThreeJS開發

環境貼圖

這裡我要推薦一個素材網:[Textures - Poliigon](https://www.poliigon.com/textures)

自行去下載下傳hdr圖檔,這裡再推薦個圖檔格式轉換:

[Convertio — 檔案轉換器](https://www.poliigon.com/textures)

/**
 * 環境貼圖
 */
import * as $Three from 'three'
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//加載hdr環境圖
const rgbeLoader=new RGBELoader();
rgbeLoader.loadAsync('./public/HdrOutdoorBeachBlueHourCloudy002_HDR_4K.hdr').then(res=>{
    res.mapping=$Three.EquirectangularReflectionMapping;//設定映射
    scene.background=res;
    scene.environment=res;
})
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中

//設定cube紋理加載器
const cubeTextureloader=new $Three.CubeTextureLoader()
// const envMapTexture=cubeTextureloader.load([
//     "/public/bg1.jpg",
//     "/public/chunyu02.jpg",
//     "/public/bg2.jpg",
//     "/public/chunyu02.jpg",
//     "/public/chunyu02.jpg",
//     "/public/chunyu02.jpg", 
// ]);

const sphereGeo=new $Three.SphereBufferGeometry(1,20,20);
const textureloader=new $Three.TextureLoader();
const myTextloader=textureloader.load('./public/HdrOutdoorBeachBlueHourCloudy002_JPG_4K.jpg')
const material=new $Three.MeshStandardMaterial({
    metalness: 0.7,
    roughness: 0.1,
    // envMap:rgbeLoader
    map:myTextloader
})
const sphere=new $Three.Mesh(sphereGeo,material);
scene.add(sphere)
//設定環境背景
// scene.background=envMapTexture;
//設定預設環境背景
// scene.environment=envMapTexture;
//燈光
const light1=new $Three.AmbientLight(0xffffff,0.5);//環境光
scene.add(light1)
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.position.set(10,10,10)//設定平行光照的位置
scene.add(light2)

//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高

//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           
  • 通過loadAsync異步加載hdr環境圖
  • 以上代碼即可實作身臨其境般的感覺

效果圖

Three.js快速入門ThreeJS開發

還可以360°旋轉呢

燈光與陰影

建立一個平面與一個球實作對燈光以及陰影的使用
/**
 * 燈光與陰影
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中


const sphereGeo=new $Three.SphereBufferGeometry(1,20,20);
const material=new $Three.MeshStandardMaterial()
const sphere=new $Three.Mesh(sphereGeo,material);
sphere.castShadow=true;//設定球投射陰影
scene.add(sphere)

//建立平面
const planeGeo=new $Three.PlaneBufferGeometry(10,10);
const plane=new $Three.Mesh(planeGeo,material);
plane.position.set(0,-1,0);
plane.rotation.x=-Math.PI/2;

plane.receiveShadow=true//接收陰影
scene.add(plane)
//燈光
const light1=new $Three.AmbientLight(0xffffff,0.5);//環境光
scene.add(light1)
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.castShadow=true;//設定光線投射陰影
light2.position.set(10,10,10)//設定平行光照的位置
scene.add(light2)

//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高
//開啟陰影計算
renderer.shadowMap.enabled=true;
//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           
  • castShadow投射陰影
  • receiveShadow接收陰影
  • renderer.shadowMap.enabled=true;開啟陰影計算
  • AmbientLight環境光
  • DirectionalLight平行光

效果圖

Three.js快速入門ThreeJS開發

平行光的陰影屬性

舉例一些常見的
/**
 * 平行光陰影屬性
 */
light2.shadow.radius=20;//陰影模糊度
light2.shadow.mapSize.set(1080,1080);//陰影貼圖分辨率(預設512*512)
//設定平行光投影相機的屬性(近端、遠端、上、下、左、右)
light2.shadow.camera.near=0.5;
light2.shadow.camera.far=500;
light2.shadow.camera.top=5;
light2.shadow.camera.bottom=-5;
light2.shadow.camera.left=5;
light2.shadow.camera.right=-5;
scene.add(light2)
           

聚光燈

通過SpotLight去建立聚光燈
/**
 * 聚光燈
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中


const sphereGeo=new $Three.SphereBufferGeometry(1,20,20);
const material=new $Three.MeshStandardMaterial()
const sphere=new $Three.Mesh(sphereGeo,material);
sphere.castShadow=true;//設定球投射陰影
scene.add(sphere)

//建立平面
const planeGeo=new $Three.PlaneBufferGeometry(20,20);
const plane=new $Three.Mesh(planeGeo,material);
plane.position.set(0,-1,0);
plane.rotation.x=-Math.PI/2;

plane.receiveShadow=true//接收陰影
scene.add(plane)
//燈光
const light1=new $Three.AmbientLight(0xffffff,0.5);//環境光
scene.add(light1)
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.castShadow=true;//設定光線投射陰影
light2.position.set(10,10,10)//設定平行光照的位置
/**
 * 平行光陰影屬性
 */
light2.shadow.radius=20;//陰影模糊度
light2.shadow.mapSize.set(1080,1080);//陰影貼圖分辨率(預設512*512)
//設定平行光投影相機的屬性(近端、遠端、上、下、左、右)
light2.shadow.camera.near=0.5;
light2.shadow.camera.far=500;
light2.shadow.camera.top=5;
light2.shadow.camera.bottom=-5;
light2.shadow.camera.left=5;
light2.shadow.camera.right=-5;
// scene.add(light2)
/**
 * 聚光燈
 */
const light3=new $Three.SpotLight(0xffffff,1);
//調節亮度
light3.intensity=3
light3.position.set(5,5,5);
light3.castShadow=true;
light3.shadow.mapSize.set(1080,1080);
light3.target=sphere;//聚光燈照明目标(設定為球)
sphere.position.x=2//球移動聚光燈追随
light3.angle=Math.PI/6;//聚光燈角度(預設180deg/3)
light3.distance=15;//光的衰減效果
light3.penumbra=0;//伴影的衰減效果
light3.decay=0.1;//沿着光照距離的衰減(需要給渲染器設定)
scene.add(light3)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高
//開啟陰影計算
renderer.shadowMap.enabled=true;
renderer.physicallyCorrectLights=true;//使用實體上正确的光照模式
//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//6、使用渲染器,通過相機将場景渲染進來
// renderer.render(scene,camera);

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//編寫渲染函數
function render(){
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           
  • 以上代碼并且示範了聚光燈的一些屬性

效果圖

Three.js快速入門ThreeJS開發

點光源

通過PointLight建立
/**
 * 點光源
 */
import * as $Three from 'three'
//導入軌道控制器
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
//1、建立一個場景
const scene= new $Three.Scene();

//2、建立一個相機
const camera=new $Three.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

//設定相機位置 x,y,z
camera.position.set(0,0,10);
scene.add(camera);//相機放入場景中


const sphereGeo=new $Three.SphereBufferGeometry(1,20,20);
const material=new $Three.MeshStandardMaterial()
const sphere=new $Three.Mesh(sphereGeo,material);
sphere.castShadow=true;//設定球投射陰影
scene.add(sphere)

//建立平面
const planeGeo=new $Three.PlaneBufferGeometry(20,20);
const plane=new $Three.Mesh(planeGeo,material);
plane.position.set(0,-1,0);
plane.rotation.x=-Math.PI/2;

plane.receiveShadow=true//接收陰影
scene.add(plane)
//燈光
const light1=new $Three.AmbientLight(0xffffff,0.5);//環境光
scene.add(light1)

/**
 * 添加小球
 */
const smallBall=new $Three.Mesh(
    new $Three.SphereBufferGeometry(0.1,20,20),
    new $Three.MeshBasicMaterial({color: 0xff0000})
)
smallBall.position.set(2,2,2)
scene.add(smallBall)
const light2=new $Three.DirectionalLight(0xffffff,1)//平行光
light2.castShadow=true;//設定光線投射陰影
light2.position.set(10,10,10)//設定平行光照的位置
/**
 * 平行光陰影屬性
 */
light2.shadow.radius=20;//陰影模糊度
light2.shadow.mapSize.set(1080,1080);//陰影貼圖分辨率(預設512*512)
//設定平行光投影相機的屬性(近端、遠端、上、下、左、右)
light2.shadow.camera.near=0.5;
light2.shadow.camera.far=500;
light2.shadow.camera.top=5;
light2.shadow.camera.bottom=-5;
light2.shadow.camera.left=5;
light2.shadow.camera.right=-5;
// scene.add(light2)
/**
 * 點光源
 */
const light4=new $Three.PointLight(0xfff00f,1);
light4.intensity=2;
scene.add(light4)
//4、初始化渲染器
const renderer=new $Three.WebGLRenderer();
//設定渲染大小
renderer.setSize(window.innerWidth,window.innerHeight);//寬、高
//開啟陰影計算
renderer.shadowMap.enabled=true;
renderer.physicallyCorrectLights=true;//使用實體上正确的光照模式
//5、将渲染的内容添加到dom節點中
document.body.appendChild(renderer.domElement)

//建立軌道控制器
const controls=new OrbitControls(camera,renderer.domElement);
//設定控制器阻尼,更有重量感,然後必須在動畫循環調用update()
controls.enableDamping=true;

//建立坐标軸
const xy=new $Three.AxesHelper(5);
scene.add(xy);

//設定時鐘
const clock=new $Three.Clock();
//編寫渲染函數
function render(){
    let time=clock.getElapsedTime()
    smallBall.position.x=Math.sin(time)*3;
    smallBall.position.z=Math.cos(time)*3;
    smallBall.position.y=2+Math.sin(time*10);
    controls.update();//調用update實作阻尼
    renderer.render(scene,camera);//每一幀就進行一次渲染...
    requestAnimationFrame(render);//浏覽器自帶方法請求幀
}
render();//調用渲染函數

//監聽畫面變化,更新畫面
window.addEventListener('resize',()=>{
    //更新攝像頭
    camera.aspect=window.innerWidth/window.innerHeight;
    //更新攝像頭投影矩陣
    camera.updateProjectionMatrix();
    //更新渲染器
    renderer.setSize(window.innerWidth,window.innerHeight);
    //設定渲染像素比
    renderer.setPixelRatio(window.devicePixelRatio);
});
           
  • 實作了小球圍繞大球轉

效果圖

Three.js快速入門ThreeJS開發

一直轉着呢…

了解這些就差不多了,可以去實作一些案例了

繼續閱讀