我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情
写在前面
本篇文章主要写了用vue+threejs进行物体效果的变化,包括物体的显示、隐藏以及透明度的设置。
演示gif如下:
本篇文章不进行vue和threejs的入门说明。
正文
创建一个容器
<template>
<div class="item">
<div id="THREE31"></div>
</div>
</template>
引入threejs需要的模块
OrbitControls - 轨道控制器模块,可以使得相机围绕目标进行轨道运动
ThreeMFLoader - 用来引入.3mf文件的模型
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { ThreeMFLoader } from "three/examples/jsm/loaders/3MFLoader.js";
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";
mounted() 方法
mounted() {
this.initThreejs();
},
initThreejs() 方法
camera - 相机
scene - 场景
renderer - 渲染器
model - 用于保存加载的.3mf模型
settings - gui的初始值设置
let camera, scene, renderer;
let model, settings;
init();
function init() {
// threejs的一些代码
}
function createPanel() {
// gui的一些代码
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
init() 方法
1、创建场景
创建一个场景并且设置背景颜色和每个物体的雾的类型。
scene = new THREE.Scene();
scene.background = new THREE.Color(0x8cc7de);
scene.fog = new THREE.Fog(0xa0a0a0, 10, 500);
2、创建相机
创建一个透视相机,并将其放置在(-100, 80, 100)。
camera = new THREE.PerspectiveCamera(
35,
(window.innerWidth - 201) / window.innerHeight,
1,
500
);
camera.position.set(-100, 80, 100);
scene.add(camera);
3、半球光
创建一个半球光,并将其放置在(0, 100, 0)。
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 100, 0);
scene.add(hemiLight);
4、平行光
创建一个平行光,并将其放置在(0, 40, 50)。
castShadow - 是否有阴影
shadow - 关于阴影的一些设置
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(0, 40, 50);
dirLight.castShadow = true;
dirLight.shadow.camera.top = 50;
dirLight.shadow.camera.bottom = -25;
dirLight.shadow.camera.left = -25;
dirLight.shadow.camera.right = 25;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 200;
dirLight.shadow.mapSize.set(1024, 1024);
scene.add(dirLight);
5、渲染器
创建一个渲染器,并将其插入定义的id容器中。
setPixelRatio - 设置设备像素比
setSize - 将输出canvas的大小调整为(width, height)并考虑设备像素比
outputEncoding - 渲染器的输出编码
shadowMap.enabled - 是否有阴影
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth - 201, window.innerHeight);
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.getElementById("THREE31").appendChild(renderer.domElement);
6、使用ThreeMFLoader引入.3mf 模型
child.castShadow - 设置模型有阴影
child.material.transparent - 设置模型可改变其透明度
child.material.opacity - 设置模型透明度
model = object - 将导入的模型赋值给一开始定义的midel字段
const loader = new ThreeMFLoader();
loader.load("models/models/3mf/truck.3mf", function (object) {
object.quaternion.setFromEuler(new THREE.Euler(-Math.PI / 2, 0, 0)); // z-up conversion
object.traverse(function (child) {
child.castShadow = true;
if (child.material) {
child.material.transparent = true;
child.material.opacity = 1;
}
});
model = object;
scene.add(object);
createPanel();
animate();
});
7、地面模型
创建一个地面
rotation - 旋转
receiveShadow - 是否接收阴影
const ground = new THREE.Mesh(
new THREE.PlaneGeometry(1000, 1000),
new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false })
);
ground.rotation.x = -Math.PI / 2;
ground.position.y = 11;
ground.receiveShadow = true;
scene.add(ground);
8、轨道控制器
minDistance - 能够将相机向内移动多少
maxDistance - 能够将相机向外移动多少
minPolarAngle - 能够垂直旋转的角度的下限
maxPolarAngle - 能够垂直旋转的角度的上限
enablePan - 启用或禁用摄像机平移
target - 焦点,控制器的轨道围绕它运行
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", render);
controls.minDistance = 50;
controls.maxDistance = 200;
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 2;
controls.enablePan = false;
controls.target.set(0, 20, 0);
controls.update();
createPanel() 方法
const panel = new GUI({ width: 310 });
const folder1 = panel.addFolder("物体效果");
settings = {
"隐藏/显示": true,
透明度: 1,
};
folder1.add(settings, "隐藏/显示").onChange((val) => {
model.visible = val;
});
folder1.add(settings, "透明度", 0.0, 1.0, 0.05).onChange((val) => {
model.traverse(function (child) {
if (child.material) {
child.material.opacity = val;
}
});
});
folder1.open();
以上就是全部的代码以及对应的解释。
最后
如果觉得有帮助的话,请点个赞哟~❤❤❤