本篇文章我们通过介绍3D影院的视觉原理,并介绍了three.js事件处理过程,全面分析了实现3D影院的基础知识。
1.创建一个3d的空间
可以想象一下我们在房间内,房间是一个立方体,如果你有生活品味,可能会在房间内贴上壁纸,three.js可以很方便的创建一个立方体,并且给它的周围贴上纹理,让照相机在立方体之中,照相机可以360旋转,就模拟了一个真实的场景。
转换为代码:
const path = 'assets/image/'
const format = '.jpg'
const urls = [
`${path}px${format}`, `${path}nx${format}`,
`${path}py${format}`, `${path}ny${format}`,
`${path}pz${format}`, `${path}nz${format}`
]
const materials = []
urls.forEach(url => {
const textureLoader = new TextureLoader()
textureLoader.setCrossOrigin(this.crossOrigin)
const texture = textureLoader.load(url)
materials.push(new MeshBasicMaterial({
map: texture,
overdraw: true,
side: BackSide
}))
})
const cube = new Mesh(new CubeGeometry(9000, 9000, 9000), new MeshFaceMaterial(materials))
this.scene.add(cube)
CubeGeometry创建一个超大的立方体 MeshFaceMaterial给立方体贴上文理,由于视角是在立方体内部,所以side:BackSide 2.粒子效果
一个3d模型是由点,线,面组成的,可以遍历模型的每一个点,把每一个点转换为几何模型,并且给它贴上文理,拷贝每一个点的位置,用这些几何模型重新构成一个只有点的模型,这就是粒子效果的基本原理。
this.points = new Group()
const vertices = []
let point
const texture = new TextureLoader().load('assets/image/dot.png')
geometry.vertices.forEach((o, i) => {
// 记录每个点的位置
vertices.push(o.clone())
const _geometry = new Geometry()
// 拿到当前点的位置
const pos = vertices[i]
_geometry.vertices.push(new Vector3())
const color = new Color()
color.r = Math.abs(Math.random() * 10)
color.g = Math.abs(Math.random() * 10)
color.b = Math.abs(Math.random() * 10)
const material = new PointsMaterial({
color,
size: Math.random() * 4 + 2,
map: texture,
blending: AddEquation,
depthTest: false,
transparent: true
})
point = new Points(_geometry, material)
point.position.copy(pos)
this.points.add(point)
})
return this.points
new Group创建一个群,可以说是粒子的集合通过point.position.copy(pos)设置粒子和位置,坐标和模型中对应点的位置相同 3.点击事件的处理
three.js的点击事件需要借助光线投射器(Raycaster),为了方便理解,请先看一张图:

Raycaster发射一个射线,intersectObject监测射线命中的物体
this.raycaster = new Raycaster()
// 把你要监听点击事件的物体用数组储存起来
this.seats.push(seat)
onTouchStart(event) {
event.preventDefault()
event.clientX = event.touches[0].clientX;
event.clientY = event.touches[0].clientY;
this.onClick(event)
}
onClick(event) {
const mouse = new Vector2()
mouse.x = ( event.clientX / this.renderer.domElement.clientWidth ) * 2 - 1
mouse.y = - ( event.clientY / this.renderer.domElement.clientHeight ) * 2 + 1;
this.raycaster.setFromCamera(mouse, this.camera)
// 检测命中的座位
const intersects = this.raycaster.intersectObjects(this.seats)
if (intersects.length > 0) {
intersects[0].object.material = new MeshLambertMaterial({
color: 0xff0000
})
}
}
内容版权声明:除非注明,否则皆为本站原创文章。
