一、快速入门
1、基础案例
<template>
<div class="three-container" ref="domElement"></div>
</template>
<script>
import { defineComponent, ref, onMounted } from "vue";
// 类型支持需安装:npm i -D @types/three
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import Stats from "three/examples/jsm/libs/stats.module";
export default defineComponent({
name: "HomePage",
setup() {
/** @type {import("vue").Ref<HTMLDivElement>} */
const domElement = ref();
onMounted(() => {
// 宽高
const domRect = domElement.value.getBoundingClientRect();
// 场景
const scene = new THREE.Scene();
// 网格模型
const geometry = new THREE.BoxGeometry(50, 50, 50);
const material = new THREE.MeshLambertMaterial({
color: 0x00ffff,
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0);
scene.add(mesh);
// 点光源
const pointLight = new THREE.PointLight(0xffffff, 1.0);
pointLight.decay = 0.0;
pointLight.position.set(100, 100, 100);
scene.add(pointLight);
// 点光源辅助器
const pointLightHelper = new THREE.PointLightHelper(pointLight, 10);
scene.add(pointLightHelper);
// 环境光
const ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);
// 坐标
const axesHelper = new THREE.AxesHelper(250);
scene.add(axesHelper);
// 网格地面
const gridHelper = new THREE.GridHelper(500, 20);
scene.add(gridHelper);
// 相机
const camera = new THREE.PerspectiveCamera(
50,
domRect.width / domRect.height,
0.1,
2000
);
camera.position.set(500, 500, 500);
camera.lookAt(0, 0, 0);
// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(domRect.width, domRect.height);
domElement.value.appendChild(renderer.domElement);
// 性能监视器
const stats = new Stats();
domElement.value.appendChild(stats.dom);
// 动画渲染
function render() {
stats.update();
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
// 相机控制器
new OrbitControls(camera, domElement.value);
// 窗口事件
window.onresize = function () {
const domRectResize = domElement.value.getBoundingClientRect();
renderer.setSize(domRectResize.width, domRectResize.height);
camera.aspect = domRectResize.width / domRectResize.height;
camera.updateProjectionMatrix();
};
});
return {
domElement,
};
},
});
</script>
<style scoped>
.three-container {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
2、gui.js
<template>
<div></div>
</template>
<script>
import { defineComponent } from "vue";
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";
export default defineComponent({
name: "GUIPage",
setup() {
const gui = new GUI();
const controllerObj = {
numb: 50,
color: 0x888888,
arrSelect: 10,
objSelect: "relative",
bool: true,
str: "你好",
};
const folder1 = gui.addFolder("组1");
folder1.close();
folder1
.add(controllerObj, "numb", 0, 100)
.name("命名")
.step(1) // 默认0.1
.onChange(function (value) {
console.log(value);
});
folder1.addColor(controllerObj, "color").onChange(function (value) {
console.log(`0x${value.toString(16)}`);
});
folder1
.add(controllerObj, "arrSelect", [0, 10, 100])
.onChange(function (value) {
console.log(value);
});
const folder2 = gui.addFolder("组2");
folder2.close();
folder2
.add(controllerObj, "objSelect", {
默认值: "static",
相对定位: "relative",
绝对定位: "absolute",
})
.onChange(function (value) {
console.log(value);
});
folder2.add(controllerObj, "bool", null).onChange(function (value) {
console.log(value);
});
folder2.add(controllerObj, "str", null).onChange(function (value) {
console.log(value);
});
return {};
},
});
</script>
<style scoped></style>
3、知识点
* 文档网站
- threejs官网:https://threejs.org/
- threejs中文网:http://www.webgl3d.cn/
4、加载外部三维模型(gltf)
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
const loader = new GLTFLoader();
const model = new THREE.Group();
/**
* * blender导出
* - gltf二进制(.glb)
* - gltf嵌入式(.gltf)
* - gltf分离(.gltf+.bin+纹理)
*/
loader.load("/工厂.gltf", function (gltf) {
model.add(gltf.scene);
});
export default model;