200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > three.js使用CubeCamera创建反光效果 动态环境贴图实现 立方体全景贴图(vue中使用three.js83)

three.js使用CubeCamera创建反光效果 动态环境贴图实现 立方体全景贴图(vue中使用three.js83)

时间:2021-12-01 09:46:13

相关推荐

three.js使用CubeCamera创建反光效果 动态环境贴图实现 立方体全景贴图(vue中使用three.js83)

使用CubeCamera创建反光效果

1.demo效果2. 实现要点2.1 创建立方体相机CubeCamera2.2 使用动态环境贴图材质2.3 render中更新立方体相机2.4 创建场景的全景贴图2.5 创建场景中的模型 3. demo代码

1.demo效果

2. 实现要点

2.1 创建立方体相机CubeCamera

创建立方体的语法如下

const cubeCamera = new THREE.CubeCamera( near, far, cubeRenderTarget)

参数说明

near – 远剪切面的距离far – 近剪切面的距离cubeRenderTarget – 立方体渲染器目标对象

如上参数可知创建CubeCamera对象需要三个参数,其中第三个参数是一个WebGLCubeRenderTarget类型的对象,所以需要首先创建这样一个对象,然后创建立方体对象,具体代码如下:

//创建立方体渲染器目标对象this.cubeRenderTarget = new THREE.WebGLCubeRenderTarget(128, {format: THREE.RGBFormat,generateMipmaps: true,minFilter: THREE.LinearMipmapLinearFilter})//创建立方体相机this.cubeCamera = new THREE.CubeCamera(1, 100000, this.cubeRenderTarget)this.scene.add(this.cubeCamera)

2.2 使用动态环境贴图材质

上一步中我们创建完立方体相机后,立方体渲染器目标对象上边生成了有相机获取的图形生成的纹理,并保存在cubeRenderTarget.texture之中,接下来把它当环境贴图创建材质,随后使用这个材质创建一个球体Mesh

//创建球体this.renderer.renderTargetconst dynamicEnvMapMaterial = new THREE.MeshPhongMaterial({envMap: this.cubeRenderTarget.texture})const sphereGeometry = new THREE.SphereGeometry(10, 15, 15)this.sphere = new THREE.Mesh(sphereGeometry, dynamicEnvMapMaterial)this.scene.add(this.sphere)

2.3 render中更新立方体相机

this.cubeCamera.update(this.renderer, this.scene) //立方体相机更新

通过以上三步就可以实现将场景中除球体以外的所有模型作为环境贴图添加到球体上,支持动态变化,除此之外还有几点需要说明一下,具体详见以下步骤

2.4 创建场景的全景贴图

这一步与上一篇文章一样,代码如下

// 创建场景createScene() {this.scene = new THREE.Scene()const publicPath = process.env.BASE_URL//创建全景贴图设置为场景背景this.scene.background = new THREE.CubeTextureLoader().setPath(`${publicPath}textures/cubemap/parliament/`).load(['posx.jpg','negx.jpg','posy.jpg','negy.jpg','posz.jpg','negz.jpg'])}

2.5 创建场景中的模型

模型包括一个立方体和一个球体,要注意一下几点

创建静态环境贴图材质

这里就是使用场景的背景创建环境贴图材质,只需要将场景的背景赋值给材质的envMap即可创建方块和圆环

这里使用BoxGeometry创建一个立方体模型,使用TorusGeometry创建一个圆环,它们使用的材质都是刚刚创建的环境贴图材质创建动态环境贴图的球体

这里文章中2.2已有说明,请直接看代码

// 创建模型createModels() {const material = new THREE.MeshPhongMaterial()material.envMap = this.scene.background //场景背景设置为材质的环境贴图//创建方块const boxGeometry = new THREE.BoxGeometry(15, 15, 15)this.cube = new THREE.Mesh(boxGeometry, material)this.cube.position.set(-22, 0, 0)this.scene.add(this.cube)//构建圆环const torusGeometry = new THREE.TorusGeometry(8, 3, 16, 100)this.torus = new THREE.Mesh(torusGeometry, material)this.torus.position.set(22, 0, 0)this.scene.add(this.torus)//创建球体this.renderer.renderTargetconst dynamicEnvMapMaterial = new THREE.MeshPhongMaterial({envMap: this.cubeRenderTarget.texture})const sphereGeometry = new THREE.SphereGeometry(10, 15, 15)this.sphere = new THREE.Mesh(sphereGeometry, dynamicEnvMapMaterial)this.scene.add(this.sphere)}

3. demo代码

<template><div><div id="container" /><div class="controls-box"><section><el-row><el-checkbox v-model="properties.rotate">rotate</el-checkbox></el-row><el-row><div v-for="(item,key) in properties" :key="key"><div v-if="item&&item.name!=undefined"><el-col :span="8"><span class="vertice-span">{{item.name }}</span></el-col><el-col :span="13"><el-slider v-model="item.value" :min="item.min" :max="item.max" :step="item.step" :format-tooltip="formatTooltip" @change="propertiesChange" /></el-col><el-col :span="3"><span class="vertice-span">{{item.value }}</span></el-col></div></div></el-row><el-row><el-col :span="8" class="label-col"><label>texture</label></el-col><el-col :span="16"><el-select v-model="properties.textureType" placeholder="请选择" @change="propertiesChange"><el-option v-for="item in texturesOptions" :key="item.value" :label="item.label" :value="item.value" /></el-select></el-col></el-row></section></div></div></template><script>import * as THREE from 'three'import {OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'export default {data() {return {texturesOptions: [{value: 'bathroom',label: 'bathroom'},{value: 'plaster',label: 'plaster'},{value: 'metal-floor',label: 'metal-floor'},{value: 'none',label: 'none'}],properties: {normalScale: {name: 'normalScale',value: 1,min: -2,max: 2,step: 0.1},reflectivity: {name: 'reflectivity',value: 1,min: 0,max: 2,step: 0.1},textureType: 'none',rotate: false},cube: null,sphere: null,torus: null,camera: null,cubeCamera: null,cubeRenderTarget: null,scene: null,renderer: null,controls: null}},mounted() {this.init()},methods: {formatTooltip(val) {return val},// 初始化async init() {this.createScene() // 创建场景await this.createRender() // 创建渲染器this.createCamera() // 创建相机this.createLight() // 创建光源this.createModels() // 创建模型this.createControls() // 创建控件对象this.render() // 渲染},// 创建场景createScene() {this.scene = new THREE.Scene()const publicPath = process.env.BASE_URL//创建全景贴图设置为场景背景this.scene.background = new THREE.CubeTextureLoader().setPath(`${publicPath}textures/cubemap/parliament/`).load(['posx.jpg','negx.jpg','posy.jpg','negy.jpg','posz.jpg','negz.jpg'])},// 创建模型createModels() {const material = new THREE.MeshPhongMaterial()material.envMap = this.scene.background //场景背景设置为材质的环境贴图//创建方块const boxGeometry = new THREE.BoxGeometry(15, 15, 15)this.cube = new THREE.Mesh(boxGeometry, material)this.cube.position.set(-22, 0, 0)this.scene.add(this.cube)//构建圆环const torusGeometry = new THREE.TorusGeometry(8, 3, 16, 100)this.torus = new THREE.Mesh(torusGeometry, material)this.torus.position.set(22, 0, 0)this.scene.add(this.torus)//创建球体this.renderer.renderTargetconst dynamicEnvMapMaterial = new THREE.MeshPhongMaterial({envMap: this.cubeRenderTarget.texture})const sphereGeometry = new THREE.SphereGeometry(10, 15, 15)this.sphere = new THREE.Mesh(sphereGeometry, dynamicEnvMapMaterial)this.scene.add(this.sphere)},// 创建光源createLight() {// 环境光const ambientLight = new THREE.AmbientLight(0xffffff) // 创建环境光this.scene.add(ambientLight) // 将环境光添加到场景const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯spotLight.position.set(0, 50, 50)spotLight.intensity = 2.2this.scene.add(spotLight)},// 创建相机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(0, 12, 68) // 设置相机位置this.camera.lookAt(new THREE.Vector3(0, 0, 0)) // 设置相机方向this.scene.add(this.camera)const renderTarget = this.renderer.getRenderTarget()//创建立方体渲染器目标对象this.cubeRenderTarget = new THREE.WebGLCubeRenderTarget(128, {format: THREE.RGBFormat,generateMipmaps: true,minFilter: THREE.LinearMipmapLinearFilter})//创建立方体相机this.cubeCamera = new THREE.CubeCamera(1, 100000, this.cubeRenderTarget)this.scene.add(this.cubeCamera)},// 创建渲染器createRender() {const element = document.getElementById('container')this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true })this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸this.renderer.shadowMap.enabled = true // 显示阴影// this.renderer.shadowMap.type = THREE.PCFSoftShadowMapthis.renderer.setClearColor(0xeeeeee, 1) // 设置背景颜色element.appendChild(this.renderer.domElement)},propertiesChange() {const publicPath = process.env.BASE_URL//如果不为none为方块加载纹理贴图if (this.properties.textureType !== 'none') {const texture = new THREE.TextureLoader().load(`${publicPath}textures/general/` +this.properties.textureType +'.jpg')this.cube.material.map = textureconst normal = new THREE.TextureLoader().load(`${publicPath}textures/general/` +this.properties.textureType +'-normal.jpg')this.cube.material.normalMap = normal// 更新法线缩放this.cube.material.normalScale.set(this.properties.normalScale.value,this.properties.normalScale.value) // normalScale(x,y)} else {this.cube.material = new THREE.MeshPhongMaterial({envMap: this.scene.background})}// 克隆方块材质赋值给圆环材质this.torus.material = this.cube.material.clone()//更新模型的材质折射率this.cube.material.reflectivity = this.properties.reflectivity.valuethis.torus.material.reflectivity = this.properties.reflectivity.value//更新材质中的纹理this.cube.material.needsUpdate = truethis.torus.material.needsUpdate = true},//模型旋转更新updateRotation() {if (this.properties.rotate) {this.cube.rotation.x += 0.01this.cube.rotation.y += 0.01this.torus.rotation.x += 0.01this.torus.rotation.y += 0.01}},render() {requestAnimationFrame(this.render)this.updateRotation() //模型旋转更新this.cubeCamera.update(this.renderer, this.scene) //立方体相机更新this.renderer.render(this.scene, this.camera)},// 创建控件对象createControls() {this.controls = new OrbitControls(this.camera, this.renderer.domElement)}}}</script><style>#container {position: absolute;width: 100%;height: 100%;}.controls-box {position: absolute;right: 5px;top: 5px;width: 300px;padding: 10px;background-color: #fff;border: 1px solid #c3c3c3;}.label-col {padding: 8px 5px;}.vertice-span {line-height: 38px;padding: 0 2px 0 10px;}</style>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。