vue+threejs写物体效果:更改模型颜色

1,255 阅读2分钟

本文已参加「新人创作礼」活动,一起开启掘金创作之旅。


写在前面

本次研究的是用vue+threejs更改导入的模型的颜色,目前只是初步了解,很多问题有待深入研究,欢迎有更深研究的大佬留言指导,鞠躬感谢!

使用的模型来自threejs例子。

效果演示

20220915_164937.gif

完整代码讲解

  1. 创建一个id容器
<template>
  <div class="item">
    <div id="THREE35"></div>
  </div>
</template>
  1. 引入需要的模块

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";
  1. mounted() 方法
mounted() {
  this.initThreejs();
},
  1. initThreejs() 方法
initThreejs() {
  let camera, scene, renderer;

  let settings = {};

  init();

  function init() {
    // threejs的一些代码
  }

  function createPanel() {
    // gui的一些代码
  }

  function animate() {
    requestAnimationFrame(animate);

    render();
  }

  function render() {
    renderer.render(scene, camera);
  }
},
  1. init() 方法

5.1 创建场景、相机、灯光,这些就不详细说明了,是threejs最基础的三件套

// 场景
scene = new THREE.Scene();
scene.background = new THREE.Color(0x8cc7de);
scene.fog = new THREE.Fog(0xa0a0a0, 10, 500); // 边缘雾化
// 相机
camera = new THREE.PerspectiveCamera(
  35,
  (window.innerWidth - 201) / window.innerHeight,
  1,
  500
);
camera.position.set(-100, 80, 100); // 相机位置
scene.add(camera);
// 半球光
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 100, 0); // 灯光位置
scene.add(hemiLight);
// 平行光
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.2 创建渲染器、轨道控制器

// 渲染器
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("THREE35").appendChild(renderer.domElement);
// 轨道控制器
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();

5.3 创建地面

创建一个长1000,宽1000的正方形地面

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);
  1. createPanel() 方法

很简洁的几行代码,在阴差阳错下发现gui的addColor可以这么写,settings的键命名为模型中material的name后,选择颜色后,响应的material的颜色自动发生更改。

const panel = new GUI({ width: 310 });

const folder1 = panel.addFolder("物体各部分颜色");

for (let prop in settings) {
  folder1.addColor(settings, prop);
}

folder1.open();

写在最后

以上就是所有的代码和说明,大家看完不要忘记点赞哟~