![]()
<template>
<div class="home">
<div id="threeContainer" class="threeContainer"></div>
</div>
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' // 导入轨道控制器
// import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"
import * as dat from "dat.gui"
export default {
name: 'Home',
data () {
return {
scene: null, //场景对象
camera: null, //相机对象
cube: null, //物体
controls: null, //控制器
renderer: null, //渲染器对象
clock: null, //时间
smallBall: null,
}
},
mounted () {
this.init()
},
methods: {
init () {
// 1. 创建场景
this.scene = new THREE.Scene()
// 2. 创建相机
this.camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 )
this.camera.position.set( 0, 0, 10 ) // 设置相机位置
this.scene.add(this.camera)
// 3. 添加物体
// 创建一个物体 球
const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20)
const material = new THREE.MeshStandardMaterial()
const sphere = new THREE.Mesh(sphereGeometry, material);
// 投射阴影
sphere.castShadow = true
this.scene.add(sphere)
// 创建平面
const planeGeometry = new THREE.PlaneBufferGeometry(50, 50)
const plane = new THREE.Mesh(planeGeometry, material)
plane.position.set(0, -1, 0)
plane.rotation.x = - Math.PI / 2
// 接收阴影
plane.receiveShadow = true
this.scene.add(plane)
// 灯光
// 环境光
const light = new THREE.AmbientLight(0xffffff, 0.5); // soft white light
this.scene.add(light);
// 点光源
const pointLight = new THREE.PointLight(0xff0000, 1)
pointLight.position.set(2, 2, 2)
pointLight.castShadow = true
this.smallBall = new THREE.Mesh(
new THREE.SphereBufferGeometry(0.1, 20, 20),
new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
this.smallBall.position.set(2, 2, 2);
// // 设置阴影贴图模糊度
pointLight.shadow.radius = 20
// // 设置阴影贴图的分辨率
pointLight.shadow.mapSize.set(512, 512)
this.smallBall.add(pointLight)
this.scene.add(this.smallBall)
const gui = new dat.GUI()
gui.add(pointLight.position, "x").min(-5).max(5).step(0.1)
gui.add(pointLight, "distance").min(0).max(1).step(0.01)
gui.add(pointLight, "decay").min(0).max(5).step(0.01)
// 4. 初始化渲染器
this.renderer = new THREE.WebGLRenderer()
// 设置渲染器的尺寸大小
this.renderer.setSize( window.innerWidth, window.innerHeight )
// 开启场景中的阴影贴图
this.renderer.shadowMap.enabled = true
// 将webgl渲染的canvas内容添加到body中
document.getElementById('threeContainer').appendChild( this.renderer.domElement )
// 创建轨道控制器
this.controls = new OrbitControls( this.camera, this.renderer.domElement )
// 设置控制器阻尼,让控制器更真实
this.controls.enableDamping = true
// 添加坐标轴辅助器
const axesHelper = new THREE.AxesHelper( 5 )
this.scene.add( axesHelper )
// 设置时钟
this.clock = new THREE.Clock()
// 渲染函数
this.render()
// 监听尺寸变化
this.resize()
},
// 渲染函数
render () {
let time = this.clock.getElapsedTime()
this.smallBall.position.x = Math.sin(time) * 3
this.smallBall.position.z = Math.cos(time) * 3
this.smallBall.position.y = 2 + Math.sin(time * 10) / 2
this.controls.update()
this.renderer.render( this.scene, this.camera )
// 渲染下一帧的时候就会调用render函数
requestAnimationFrame( this.render )
},
// 监听尺寸变化,更新渲染页面
resize () {
window.addEventListener('resize', () => {
// 更新摄像头
this.camera.aspect = window.innerWidth / window.innerHeight
// 更新摄像机的投影矩阵
this.camera.updateProjectionMatrix()
// 更新渲染器
this.renderer.setSize( window.innerWidth, window.innerHeight )
// 设置渲染器的像素比
this.renderer.setPixelRatio(window.devicePixelRatio)
})
}
}
}
</script>