赞
踩
如上图所示,demo有以下几个功能
demo中大量用到add方法,该方法可以给场景中添加物体,其本质是给scene对象的children属性中添加加对象,已通过代码验证,验证过程如下
// 将生成的方块添加到场景
//方式一
this.scene.add(cube)
//方式二
this.scene.children.push(cube)
//this.scene.children.push(cube) 与 this.scene.add(cube) 一样的效果 也说明scene.add()方法操作的本质就是给scene对象中children属性中添加对象
该方法主要是从场景中删除物体,本质也一样是从scene对象中children属性移除对象,demo中移除方块的函数可以通过一行代码替代,请参阅以下代码
// 删除一个方块
removeCube () {
const allChildren = this.scene.children
const lastChildren = allChildren[allChildren.length - 1]
if (lastChildren instanceof THREE.Mesh) {
this.scene.remove(lastChildren)
}
}
//上面这个函数可直接用如下代码替换
this.scene.children.pop()
该方法是通过对象名称查找场景中的物体,demo中没有用的此方法,不对今后会有机会用到,暂且储备起来,使用的方式很简单只需要传入一个简单的name参数,到这里你是不是也想到另外一种替代的方式呢,是的,通过数组查找的方法去scene对象的children中去查找,不过这样做反而会增加代码量,个人推荐还是使用scene对象提供的方法
该方法会变量场景对象中的每个物体,参数是一个回调函数,我们可以依次访问每一个场景中的对象,同样在这里做一些处理,是不是想到一个数组的方法几乎一样的功能,对,就是你了 forEach,不过在使用时要注意this指向,请看以下例子
const THIS = this THIS.scene.traverse(function (e) { if (e instanceof THREE.Mesh && e !== THIS.plane) { e.rotation.x += THIS.rotationSpeed / 100 e.rotation.y += THIS.rotationSpeed / 100 e.rotation.z += THIS.rotationSpeed / 100 } }) //traverse函数完全可以用forEach函数替代,效果一样,代码几乎雷同,只不过是用scene对象的children属性获取了所有成员列表 THIS.scene.children.forEach(function (e) { if (e instanceof THREE.Mesh && e !== THIS.plane) { e.rotation.x += THIS.rotationSpeed / 100 e.rotation.y += THIS.rotationSpeed / 100 e.rotation.z += THIS.rotationSpeed / 100 } })
children属性就不用做过多介绍了,就是返回场景中所有子对象的列表,我们在demo中点击一下printScene按钮,看看console.log (点击按钮前添加了三个方块)
雾化属性很简单就是给场景添加雾化效果,这里介绍两个雾化函数吧
Fog函数
使用方式:fog = new THREE.Fog( [name,]color, near, far )
参数说明:
FogExp2
使用方式:fog = new THREE.FogExp2( [name,]color, density )
参数说明:
顺便贴一下demo中的代码
// 添加雾化效果
addFog () {
//使用Fog创建雾化
// this.scene.fog = new THREE.Fog(0xefefef, 0.15, 100)
//使用FogExp2创建雾化
this.scene.fog = new THREE.FogExp2(0xffffff, this.fogValue / 1000)
}
可以通过这个属性强制场景中的所有物体都使用相同的材质
<template> <div> <div id="container"></div> <div class="controls-box"> <span class="demonstration">rotationSpeed</span> <el-slider v-model="rotationSpeed" :max="50" :format-tooltip="formatTooltip"> </el-slider> <span class="demonstration">fogValue</span> <el-slider v-model="fogValue" :max="50" :format-tooltip="formatFogTooltip"> </el-slider> <br> <el-button type="primary" class="controls-button" size="mini" @click="addCube">addCube</el-button> <el-button type="primary" class="controls-button" size="mini" @click="removeCube">removeCube</el-button> <el-button type="primary" class="controls-button" size="mini" @click="outputObjects">printScene</el-button> </div> </div> </template> <script> import * as THREE from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' export default { data () { return { rotationSpeed: 2, fogValue: 2, camera: null, scene: null, renderer: null, planeGeometry: null, plane: null, controls: null } }, mounted () { this.init() }, methods: { formatTooltip (val) { return val / 100 }, formatFogTooltip (val) { return val / 1000 }, // 初始化 init () { this.createScene() // 创建场景 this.createMesh() // 创建网格模型 this.createLight() // 创建光源 this.createCamera() // 创建相机 this.createRender() // 创建渲染器 this.createControls() // 创建控件对象 this.addFog() // 添加雾化效果 this.render() // 渲染 }, // 创建场景 createScene () { this.scene = new THREE.Scene() }, // 创建网格模型 createMesh () { this.planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1) // 创建一个平面对象PlaneGeometry const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff }) // 材质对象Material this.plane = new THREE.Mesh(this.planeGeometry, planeMaterial) this.plane.receiveShadow = true // 设置平面位置 this.plane.rotation.x = -0.5 * Math.PI this.plane.position.set(0, 0, 0) // 平面对象添加到场景中 this.scene.add(this.plane) }, // 创建光源 createLight () { // 添加聚光灯 const spotLight = new THREE.SpotLight(0xffffff) spotLight.position.set(-40, 60, -10) spotLight.castShadow = true this.scene.add(spotLight) // 聚光灯添加到场景中 // 环境光 const ambientLight = new THREE.AmbientLight(0x0c0c0c) this.scene.add(ambientLight) }, // 创建相机 createCamera () { const element = document.getElementById('container') const width = element.clientWidth // 窗口宽度 const height = element.clientHeight // 窗口高度 const k = width / height // 窗口宽高比 // PerspectiveCamera( fov, aspect, near, far ) this.camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000) this.camera.position.set(-30, 40, 30) // 设置相机位置 this.camera.lookAt(this.scene.position) // 设置相机方向 this.scene.add(this.camera) }, // 创建渲染器 createRender () { const element = document.getElementById('container') this.renderer = new THREE.WebGLRenderer() this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸 this.renderer.setClearColor(0x3f3f3f, 1) // 设置背景颜色 this.renderer.shadowMapEnabled = true element.appendChild(this.renderer.domElement) }, render () { const THIS = this THIS.scene.traverse(function (e) { if (e instanceof THREE.Mesh && e !== THIS.plane) { e.rotation.x += THIS.rotationSpeed / 100 e.rotation.y += THIS.rotationSpeed / 100 e.rotation.z += THIS.rotationSpeed / 100 } }) // THIS.scene.traverse(fun) 与 THIS.scene.children.forEach(fun) 是一样的功能都是去遍历scene对象的成员 /* THIS.scene.children.forEach(function (e) { if (e instanceof THREE.Mesh && e !== THIS.plane) { e.rotation.x += THIS.rotationSpeed / 100 e.rotation.y += THIS.rotationSpeed / 100 e.rotation.z += THIS.rotationSpeed / 100 } }) */ this.addFog() this.renderer.render(this.scene, this.camera) requestAnimationFrame(this.render) }, // 创建控件对象 createControls () { this.controls = new OrbitControls(this.camera, this.renderer.domElement) }, // 给平面中添加方块 addCube () { const cubeSize = Math.ceil(Math.random() * 3) const cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize) const cubeMaterial = new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }) const cube = new THREE.Mesh(cubeGeometry, cubeMaterial) cube.castShadow = true cube.name = 'cube-' + this.scene.children.length // 给方块设置随机坐标 cube.position.x = -30 + Math.round(Math.random() * this.planeGeometry.parameters.width) cube.position.y = Math.round(Math.random() * 5) cube.position.z = -20 + Math.round(Math.random() * this.planeGeometry.parameters.height) // 将生成的方块添加到场景 this.scene.add(cube) // this.scene.children.push(cube) //与 this.scene.add(cube) 一样的效果 也是scene.add()操作的本质 }, // 删除一个方块 removeCube () { const allChildren = this.scene.children const lastChildren = allChildren[allChildren.length - 1] if (lastChildren instanceof THREE.Mesh) { this.scene.remove(lastChildren) } // this.scene.children.pop() //整个removeCube函数其实就是做这个操作 }, // 打印scene对象子元素 outputObjects () { console.log(this.scene) }, // 添加雾化效果 addFog () { // this.scene.fog = new THREE.Fog(0xefefef, 0.15, 100) this.scene.fog = new THREE.FogExp2(0xffffff, this.fogValue / 1000) } } } </script> <style> #container { position: absolute; width: 100%; height: 100%; } .controls-box { position: absolute; right: 5px; top: 5px; width: 300px; height: 180px; padding: 10px; background-color: #fff; border: 1px solid #c3c3c3; } .controls-button { margin: 3px 0px; } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。