以創建一個立方體為例

安裝
安裝three:npm i three

使用
參考
引入three以及three中自帶的相機控制元件OrbitControls用以操控相機:

初始化場景
scene:場景所有three事物均在其中,
camera:使用PerspectiveCamera透視相機,引數需注意調整否則會看不見物體與場景,引數依次為:fov視場,即可看到的角度范圍,aspect長寬比,通常為視窗長寬比,near近面,基于相機位置開始渲染場景的位置一般較小默認0.1,far遠面,基于相機位置結束渲染場景的位置,過大會影響渲染效率默認1000,
renderer:渲染器,用于生成canvas及設定其引數,需要將其appendChild至dom中指定元素,

天空盒子
創建天空盒子(一個包裹場景物體的立方體,可隨滑鼠拖動而變化角度),其中六張立方體貼圖對應的順序是右、左、上、下、前、后,圖片需是特別制作的全景圖,否者場景世界會出現明顯的拼接邊角:

也可直接使用一張貼圖作為場景的背景,但使用此法場景不會隨著滑鼠變換角度與縮放:

相機控制元件
創建相機控制元件,其中需將相機與渲染的canvas元素添加到控制元件OrbitControls中,可通過控制元件控制拖拽、縮放、阻尼、偏角、自轉(此種自轉方式區別于模型自轉,模型自轉是通過控制物體mesh的rotation實作自轉,該文章使用的是模型自轉)等:

光源
創建光源,可設定環境光、點光源,最終顯示出的光影效果是通過各種光效一起計算后渲染出來的:

立方體
創建的mesh(可理解為創建的物體)都是要通過add添加到場景中的,而mesh中有geometry(幾何體)與material(材質),立方體的geometry可以利用three的BoxGeometry,而material可以使用MeshLambertMaterial材質,該材質對光照有反應,用于創建暗淡的不發光的物體,自身可設定顏色,自身顏色不受環境的影響,也可給材質設定紋理map(需匯入圖片作為紋理):

持續渲染
對場景與相機進行持續渲染,其中requestAnimationFrame為請求影片幀,以60hz重繪(但在高重繪屏中會頻繁觸發),用戶切換標簽時會暫停渲染,節省cpu開銷,滑鼠控制元件需要在渲染中呼叫update()更新:

完整代碼
點擊查看代碼
<template>
<div >
<div id="container">
<!--畫布的容器-->
</div>
</div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; //滑鼠控制
import cubeImg from "@/assets/img/cube.png";
import BgImg from "@/assets/img/bg.png";
import right from "@/assets/img/space/right.jpg";
import left from "@/assets/img/space/left.jpg";
import top from "@/assets/img/space/top.jpg";
import bottom from "@/assets/img/space/bottom.jpg";
import front from "@/assets/img/space/front.jpg";
import back from "@/assets/img/space/back.jpg";
export default {
components: {},
data() {
return {
scene: "", //場景
camera: "", //相機
renderer: "", //渲染器
mouseControls: "", //軌道控制
pointLight: "", //點光源
ambientLight: "", //環境光
cube: "", //立方體
cubeImg: cubeImg, //立方體貼圖
};
},
mounted() {
this.init();
},
methods: {
//初始化場景
init() {
this.scene = new THREE.Scene(); //新建場景
let width = window.innerWidth; //視窗寬度
let height = window.innerHeight; //視窗高度
let k = width / height; //視窗寬高比
this.camera = new THREE.PerspectiveCamera(60, k, 0.1, 10); //透視相機
this.camera.position.set(0, 0, 2.5); //設定相機位置
//創建渲染器
this.renderer = new THREE.WebGLRenderer({
antialias: true, //抗鋸齒
alpha: true,
});
this.renderer.setSize(width, height); //設定渲染區域尺寸
document
.getElementById("container")
.appendChild(this.renderer.domElement); //將畫布添加到container中
let axes = new THREE.AxesHelper(1); //坐標系(輔助開發)
axes.rotation.x = 0.1;
// this.scene.add(axes);
this.createSkyBox();
// this.createUniverse();
this.createOrbitControls();
this.createLight();
this.createCube();
this.repeatRender();
},
//創建天空盒子
createSkyBox() {
//加載天空盒子紋理
let cubeTexture = new THREE.CubeTextureLoader().load(
[right,left,top,bottom,front,back]
);
this.scene.background = cubeTexture; //設定場景背景
},
//創建宇宙背景
createUniverse(){
let texture = new THREE.TextureLoader().load(BgImg);//加載背景貼圖
this.scene.background = texture;//設定場景背景
},
//創建軌道控制
createOrbitControls() {
//沒有縮放阻尼
this.mouseControls = new OrbitControls(
this.camera,
this.renderer.domElement
); //創建控制元件物件
this.mouseControls.enablePan = false; //右鍵平移拖拽
this.mouseControls.enableZoom = true; //滑鼠縮放
this.mouseControls.minDistance = 2; //相機距離原點的距離范圍
this.mouseControls.maxDistance = 5;
this.mouseControls.enableDamping = true; //滑動阻尼
this.mouseControls.dampingFactor = 0.1; //(默認.25)
this.mouseControls.maxPolarAngle = (Math.PI / 4) * 3; //y旋轉角度范圍
this.mouseControls.minPolarAngle = Math.PI / 4;
// this.mouseControls.autoRotate = true; //自轉(相機)
// this.mouseControls.autoRotateSpeed = 5; //自轉速度
},
//創建光源
createLight() {
this.ambientLight = new THREE.AmbientLight(0x666666); //設定環境光
this.scene.add(this.ambientLight); //將環境光添加到場景中
this.pointLight = new THREE.PointLight(0xffffff, 1, 0);
this.pointLight.position.set(200, 200, 200); //設定點光源位置
this.scene.add(this.pointLight); //將點光源添加至場景
},
//創建立方體
createCube() {
let geometry = new THREE.BoxGeometry(1, 1, 1); //幾何體
//材質
let material = new THREE.MeshLambertMaterial({
map: new THREE.TextureLoader().load(this.cubeImg), //匯入圖片紋理
});
this.cube = new THREE.Mesh(geometry, material); //將幾何體與材質添加到網格中
this.cube.rotation.set(10, 10, 0);
this.scene.add(this.cube); //將立方體網格添加到場景中
},
//重復渲染
repeatRender() {
//請求影片幀,螢屏每重繪一次呼叫一次,系結螢屏重繪頻率
requestAnimationFrame(this.repeatRender);
this.mouseControls.update(); //實時更新軌道控制
this.cube.rotation.y += .01;//以y為軸心的旋轉角度每幀自加0.01
this.renderer.render(this.scene, this.camera); //將場景和相機進行渲染
},
},
};
</script>
<style scoped>
</style>
圖片素材
天空盒子貼圖
back.jpg:

bottom.jpg:

front.jpg:

left.jpg:

right.jpg:

top.jpg:

立方體貼圖
cube.png:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/433307.html
標籤:其他
上一篇:認識 WebAssembly
下一篇:React腳手架配置代理總結
