一、import引入相关功能
import * as THREE from "three"; // 引入three.js
import { LinearMipMapLinearFilter, RGBFormat } from "three"; // 引入三维纹理类型
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; // 引入控制器
import { Reflector } from "three/examples/jsm/objects/Reflector"; // 反光球/反射器/镜子
二、基础场景搭建
let scene, camera, renderer, container, light, controls; // 定义变量
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(0, 0, -200);
camera.lookAt(scene.position);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
container = this.$refs.three;
container.appendChild(renderer.domElement);
light = new THREE.AmbientLight();
scene.add(light);
controls = new OrbitControls(camera, renderer.domElement);
三、第一种实现方案(天空盒)
六张不同视角的图片
let geometry = new THREE.BoxGeometry(5, 5, 5);
geometry.scale(1, 1, -1);
let materials = []; // 贴图数组
for (let i = 0; i < 6; i++) {
let texture = new THREE.TextureLoader().load(
require(`../../assets/image/${i + 1}.jpg`)
);
materials.push(new THREE.MeshBasicMaterial({ map: texture }));
}
let mesh = new THREE.Mesh(geometry, materials);
mesh.position.set(0, 0, 0);
scene.add(mesh);
camera.position.set(0, 0, 0.01); // 相机位置
camera.lookAt(0, 0, 0);
效果如下
四、第二种实现方案(环境贴图)
let urls = [
require("../../assets/image/pos-x.jpg"),
require("../../assets/image/neg-x.jpg"),
require("../../assets/image/pos-y.jpg"),
require("../../assets/image/neg-y.jpg"),
require("../../assets/image/pos-z.jpg"),
require("../../assets/image/neg-z.jpg"),
];
let cubeLoader = new THREE.CubeTextureLoader();
let cubMap = cubeLoader.load(urls);
scene.background = cubMap;
效果如下
五、加入反光球
1.使用环境贴图
let sphereGeometry = new THREE.SphereGeometry(30, 60, 60);
let sphereMaterial = new THREE.MeshPhongMaterial({
envMap: cubMap, // 使用环境贴图
});
let sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(100, 0, 0);
scene.add(sphere);
效果图
使用环境贴图只会反射贴图,并不会与周围环境有交互效果,想要与周围环境有反射效果需要使用
CubeCamera
2.使用CubeCamera
let cubeRenderTarget = new THREE.WebGLCubeRenderTarget(256, {
format: RGBFormat,
generateMipmaps: true,
minFilter: LinearMipMapLinearFilter,
});
let cubeCamera = new THREE.CubeCamera(1, 10000, cubeRenderTarget);
scene.add(cubeCamera);
// 加入一个新的球体
let sphereGeometry1 = new THREE.SphereGeometry(30, 32, 32);
let sphereMaterial1 = new THREE.MeshBasicMaterial({
color: "#f00",
});
let sphere1 = new THREE.Mesh(sphereGeometry1, sphereMaterial1);
sphere1.position.set(-100, 0, 0);
// 原来的反光球只需要更改envMap属性
let sphereGeometry = new THREE.SphereGeometry(30, 60, 60);
let sphereMaterial = new THREE.MeshPhongMaterial({
envMap: cubeRenderTarget.texture, //使用CubeCamera
});
let sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(100, 0, 0);
scene.add(sphere);
效果图
六、加入镜子
let glass = new THREE.PlaneGeometry(300, 300);
let glassPlane = new Reflector(glass, {
clipBias: 0.003,
textureWidth: window.innerWidth * window.devicePixelRatio,
textureHeight: window.innerHeight * window.devicePixelRatio,
}); //第一面镜子
let glassPlaneCopy = new Reflector(glass, {
clipBias: 0.003,
textureWidth: window.innerWidth * window.devicePixelRatio,
textureHeight: window.innerHeight * window.devicePixelRatio,
}); // 第二面镜子
glassPlane.position.set(1, 0, 0);
glassPlane.rotation.y = Math.PI / 2;
glassPlaneCopy.position.set(-1, 0, 0);
glassPlaneCopy.rotation.y = -Math.PI / 2;
scene.add(glassPlane, glassPlaneCopy);
最终效果