一、建模
模型地址:https://models.readyplayer.me/685a49eb55c53bb7dad7a44a.glb
创建模型的工具: Ready Player Me - Create a Full-Body 3D Avatar From a Photo
我使用以上工具临时创建了一个3D人物,有想法的自行去尝试一下。
二、渲染模型
实现:渲染器(WebGLRenderer)和加载 GLTF 模型的方法
完整代码
<template>
<div class="peopleModel" id="peopleModel"></div>
</template>
<script setup>
import { nextTick, onMounted } from "vue";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
let scene, camera, renderer, model, controls, amlight, light, pointLight;
let boxWidth, boxHeight;
function init() {
// 获取容器宽高
boxWidth = document.querySelector("#peopleModel").clientWidth;
boxHeight = document.querySelector("#peopleModel").clientHeight;
// 创建场景
scene = new THREE.Scene();
// 背景颜色
scene.background = new THREE.Color(0xffffff);
// 添加环境光、平行光和点光源
amlight = new THREE.AmbientLight(0xffffff, 1); // 环境光
scene.add(amlight); // 将环境光添加到场景中
light = new THREE.DirectionalLight(0xffffff, 2); // 增强平行光的强度
// 添加一个点光源
pointLight = new THREE.PointLight(0xffffff, 2, 100); // 点光源:颜色强度,最大光照范围
// 创建相机
camera = new THREE.PerspectiveCamera(5, boxWidth / boxHeight, 0.1, 1000); //参数:视角,宽高比,近截面,远截面
camera.position.set(0, 1, 5); // 适当设置相机位置
// 创建渲染器
renderer = new THREE.WebGLRenderer();
renderer.setSize(boxWidth, boxHeight);
document.querySelector("#peopleModel").appendChild(renderer.domElement);
// 加载 GLB 模型---员工模型
const loader = new GLTFLoader();
loader.load(
new URL("../assets/json/user.glb", import.meta.url).href,
(gltf) => {
model = gltf.scene; // 获取模型
scene.add(model); // 将模型添加到场景中
model.position.set(0, -1.5, 0); // 调整模型位置
// 遍历模型的所有网格,设置材质
model.traverse((child) => {
if (child.isMesh) {
child.material = new THREE.MeshPhysicalMaterial({
color: child.material.color.getHex(), // 保持原有的颜色: 使用 getHex() 方法获取十六进制颜色值
roughness: 0.67, // 设置材质的粗糙度
roughnessMap: child.material.roughnessMap, // 使用原有的粗糙度贴图
metalness: 0, // 设置材质的金属度
map: child.material.map, // 如果有纹理贴图也需要传递
});
}
});
camera.lookAt(model.position); // 在模型加载后调整相机视角
// 设置点光源的位置正对模型
pointLight.position.set(
model.position.x,
model.position.y,
model.position.z
);
scene.add(pointLight); // 将点光源添加到场景中
light.position.set(model.position.x, model.position.y + 3, -model.position.z + 4); // 调整平行光的位置
scene.add(light);
},
undefined,
(error) => {
console.error("Error loading GLTF model:", error);
}
);
// 创建辅助坐标系
const axesHelper = new THREE.AxesHelper(150);
// scene.add(axesHelper);
// 初始化OrbitControls
controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
}
function animate() {
requestAnimationFrame(animate);
if (model) {
// model.rotation.y += 0.01; // 增加一些旋转效果
}
controls.update(); // 更新控制器
renderer.render(scene, camera);
}
onMounted(() => {
nextTick(() => {
init();
animate();
});
});
// 响应式窗口变化
window.onresize = function () {
boxWidth = document.querySelector("#peopleModel").clientWidth;
boxHeight = document.querySelector("#peopleModel").clientHeight;
renderer.setSize(boxWidth, boxHeight);
camera.aspect = boxWidth / boxHeight;
camera.updateProjectionMatrix();
};
</script>
<style scoped>
.peopleModel {
width: 100%;
height: 100vh;
}
</style>