<template>
<div class="box">
<div id="hezi"></div>
<div class="ysj"></div>
</div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import Stats from 'three/addons/libs/stats.module.js';
export default {
data() {
return {
// 场景
scene: null,
// 正方形
square: null,
// 球形
spheroid: null,
// 平面
plane: null,
// 摄像机
camera: null,
// 控件
control: null,
// 渲染器
renderer: null,
stats: null,
bouncingSpeed: 0,
};
},
mounted() {
this.init();
},
methods: {
// 初始化
init() {
this.createScene();
// this.createObject();
// this.createPlane();
this.createZL()
this.createLight();
this.createCamera();
this.createRenderer();
this.createControl();
this.scene.traverse(function (object) {
if (object instanceof THREE.Mesh) {
object.castShadow = true;
object.receiveShadow = true;
}
});
this.stats = new Stats();
document.body.appendChild(this.stats.domElement)
this.render();
},
// 创建多个
createZL() {
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
for (let z = 0; z < 4; z++) {
const Geometry = new THREE.BoxBufferGeometry(10, 10, 10);
const material1 = new THREE.MeshLambertMaterial({ color: 0xffffff });
const mesh = new THREE.Mesh(Geometry, material1)
mesh.position.set(i * 20, z * 20, j * 20)
this.scene.add(mesh);
}
}
}
},
// 创建场景
createScene() {
this.scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(200);
this.scene.add(axesHelper);
},
// 创建平面
createPlane() {
const Geometry = new THREE.PlaneGeometry(250, 80);
const material1 = new THREE.MeshLambertMaterial({ color: 0xffffff });
this.plane = new THREE.Mesh(Geometry, material1);
this.plane.rotation.x = -0.5 * Math.PI;
this.scene.add(this.plane);
},
// 创建方形和球
createObject() {
const geometry1 = new THREE.BoxBufferGeometry(30, 30, 30);
const material1 = new THREE.MeshLambertMaterial({ color: "#e21f1f" });
this.square = new THREE.Mesh(geometry1, material1);
this.square.position.set(-70, 30, 0);
this.scene.add(this.square);
const geometry2 = new THREE.SphereBufferGeometry(25);
const material2 = new THREE.MeshLambertMaterial({ color: "#1fe2e2" });
this.spheroid = new THREE.Mesh(geometry2, material2);
this.spheroid.position.set(70, 25, 0);
this.scene.add(this.spheroid);
},
// 创建灯光
createLight() {
// 环境光
// const AmbientLight = new THREE.AmbientLight(0xffffff, 0.4)
// AmbientLight.position.set(0, 20, 0)
// this.scene.add(AmbientLight)
// 点光源
const PointLight = new THREE.PointLight(0xffffff, 0.4)
PointLight.position.set(0, 80, 0)
this.scene.add(PointLight)
// 聚光灯
// const SpotLight = new THREE.SpotLight(0xffffff, 0.4)
// SpotLight.position.set(0, 20, 0)
// this.scene.add(SpotLight)
// 平行光
const DirectionalLight = new THREE.DirectionalLight(0xffffff, 0.4);
DirectionalLight.position.set(0, 20, 0);
this.scene.add(DirectionalLight);
},
// 创建相机
createCamera() {
const box = document.querySelector("#hezi");
console.log(box.clientWidth, box.clientHeight);
this.camera = new THREE.PerspectiveCamera(
100,
box.clientWidth / box.clientHeight,
0.1,
1000
);
this.camera.position.set(50, 50, 50);
this.camera.lookAt(0, 0, 0);
this.scene.add(this.camera);
},
// 创建渲染器
createRenderer() {
const box = document.querySelector("#hezi");
this.renderer = new THREE.WebGL1Renderer();
this.renderer.setSize(box.clientWidth, box.clientHeight);
this.renderer.setClearColor(0x3f3f3f, 1);
box.appendChild(this.renderer.domElement);
},
// 创建控件
createControl() {
this.control = new OrbitControls(this.camera, this.renderer.domElement);
},
// 渲染
render() {
// this.square.rotation.x += 0.02
// this.square.rotation.y += 0.02
// this.square.rotation.z += 0.02
// // 球上下跳动
// this.bouncingSpeed += 0.03
// this.spheroid.position.x = 20 + 10 * Math.cos(this.bouncingSpeed);
// this.spheroid.position.y = 10 + 10 * Math.abs(Math.sin(this.bouncingSpeed));
this.stats.update()
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(this.render);
},
},
};
</script>
<style lang="scss" scoped>
.box {
height: calc(100vh - 21px);
position: relative;
#hezi {
width: 100%;
height: 100%;
}
.ysj {
position: absolute;
top: 0;
right: 0;
width: 300px;
height: 500px;
border: 1px solid #f00;
}
}
</style>
物体变化操作
// 位置
mesh.position.set(0,0,0)
// 旋转
mesh.rotation.z = 45 / 180 * Math.PI
mesh.rotation.x = 45 / 180 * Math.PI
mesh.rotation.y = 45 / 180 * Math.PI
// 缩放
mesh.scale.set(1,1,1)
解决不同屏幕刷新率不同的情况
const clock = new THREE.Clock()
render (){
const time = clock.getElapsedTime()
mesh.position.set(1,1,1)
requestAnimationFrame(render)
}
render()
帧率检测
import Stats from 'three/addons/libs/stats.module.js';
//创建stats对象
const stats = new Stats();
// 渲染函数
function render() {
stats.update();
renderer.render(scene, camera); //执行渲染操作
requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
}
render();
窗口监听
window.addEventListener('resize', () => {
this.camera = new THREE.PerspectiveCamera(100, box.clientWidth / box.clientHeight, 0.1, 1000);
this.renderer.setSize(box.clientWidth, box.clientHeight);
})
贴图以及使用方法
let TextureLoader = new THREE.TextureLoader();
let texture1 = TextureLoader.load(url)
let texture2 = TextureLoader.load(url)
this.paotong = new THREE.Mesh(
new THREE.CylinderGeometry(10, 10, 120),
new THREE.MeshLambertMaterial({
// color: "#e21fff"
map: texture1
}))
this.paotong.position.set(-50, 25, 0)
this.paotong.rotation.z = 0.45 * Math.PI
this.car.add(this.paotong)