效果预览:效果预览
源码下载:关注公众号【RMRF】,回复【three6】可获取源码
一、安装
npm install three
二、App.vue
<template>
<div class="index">
<div id="container"></div>
</div>
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import TWEEN from '@tweenjs/tween.js'
export default {
data() {
return {
scene: null,
camera: null,
renderer: null,
composer: null,
light: null,
lightHelper: null,
light1: null,
lightHelper1: null,
light2: null,
lightHelper2: null
}
},
mounted() {
this.init()
},
methods: {
init() {
const el = document.getElementById('container')
this.initScene()
this.initCamera()
this.initRenderer(el)
this.initCube()
this.initPlane()
this.initOrbitControls()
this.initSpotLight()
this.render()
this.animate()
window.addEventListener('resize', this.onWindowResize)
},
initScene() {
this.scene = new THREE.Scene()
},
initCamera() {
this.camera = new THREE.PerspectiveCamera(
35,
window.innerWidth / window.innerHeight,
1,
2000
)
this.camera.position.set(46, 22, -21)
},
initRenderer(el) {
this.renderer = new THREE.WebGLRenderer({
antialias: true
})
this.renderer.setPixelRatio(window.devicePixelRatio)
this.renderer.setSize(window.innerWidth, window.innerHeight)
this.renderer.shadowMap.enabled = true
el.appendChild(this.renderer.domElement)
},
initOrbitControls() {
let controls = new OrbitControls(this.camera, this.renderer.domElement)
controls.target.set(0, 7, 0)
controls.maxPolarAngle = Math.PI / 2
controls.update()
},
render() {
TWEEN.update()
this.renderer.render(this.scene, this.camera)
if (this.lightHelper) {
this.lightHelper.update()
}
if (this.lightHelper1) {
this.lightHelper1.update()
}
if (this.lightHelper2) {
this.lightHelper2.update()
}
requestAnimationFrame(this.render)
},
onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
this.renderer.setSize(window.innerWidth, window.innerHeight)
},
initCube() {
const geometry = new THREE.BoxGeometry(3, 3, 3)
const material = new THREE.MeshPhongMaterial()
let cube = new THREE.Mesh(geometry, material)
cube.castShadow = true
cube.receiveShadow = true
this.scene.add(cube)
},
initPlane() {
let geometry = new THREE.PlaneGeometry(50, 50)
let material = new THREE.MeshPhongMaterial({
color: 0xffffff,
dithering: true
})
let planeMesh = new THREE.Mesh(geometry, material)
planeMesh.position.set(0, -3, 0)
planeMesh.receiveShadow = true
planeMesh.rotation.x = -Math.PI * 0.5
this.scene.add(planeMesh)
},
initSpotLight() {
const light1 = this.getSpotLight(0xffffff)
this.scene.add(light1)
this.light1 = light1
this.lightHelper1 = new THREE.SpotLightHelper(light1)
this.scene.add(this.lightHelper1)
const light2 = this.getSpotLight(0xffff00)
this.scene.add(light2)
this.light2 = light2
this.lightHelper2 = new THREE.SpotLightHelper(light2)
this.scene.add(this.lightHelper2)
const anbientLight = new THREE.AmbientLight(0x404040)
this.scene.add(anbientLight)
},
getSpotLight(color) {
const light = new THREE.SpotLight(color, 1)
light.castShadow = true
light.angle = 0.4
light.penumbra = 0.2
light.decay = 2
light.distance = 50
light.position.set(0, 20, 13)
return light
},
lightTween(light) {
new TWEEN.Tween(light).to({
angle: (Math.random() * 0.7) + 0.1,
penumbra: Math.random() + 1
}, Math.random() * 3000 + 2000)
.easing(TWEEN.Easing.Quadratic.Out).start()
new TWEEN.Tween(light.position).to({
x: (Math.random() * 30) - 15,
y: (Math.random() * 10) + 15,
z: (Math.random() * 30) - 15
}, Math.random() * 3000 + 2000)
.easing(TWEEN.Easing.Quadratic.Out).start()
},
animate() {
this.lightTween(this.light1)
this.lightTween(this.light2)
setTimeout(this.animate, 5000)
}
}
}
</script>
<style>
</style>