vue+threejs写物体效果:显示、隐藏、透明度

639 阅读3分钟

我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情


写在前面

本篇文章主要写了用vue+threejs进行物体效果的变化,包括物体的显示、隐藏以及透明度的设置。

演示gif如下:

20220914_142306.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();

以上就是全部的代码以及对应的解释。

最后

如果觉得有帮助的话,请点个赞哟~❤❤❤