threejs实现天空盒

谁都会走 提交于 2020-02-26 19:17:00

1.天空盒概述以及效果


类似这种全景图片,我们将图片切成六个小图片,分别将六个小图片贴在一个正方体的里面,这样当我们置身于这个正方体里面的时候,就像在看全景图一样。

效果如下:

2.threejs代码

     var path = '/sky/'
     var format = '.jpg'
     var urls = [
       path + 'px' + format, path + 'nx' + format,
       path + 'py' + format, path + 'ny' + format,
       path + 'pz' + format, path + 'nz' + format
     ]
     var materials = []
     for (var i = 0; i < urls.length; ++i) {
       var loader = new this.THREE.TextureLoader()
       // loader.setCrossOrigin( this.crossOrigin );
       var texture = loader.load(urls[i], function () {}, undefined, function () {})
       materials.push(new this.THREE.MeshBasicMaterial({
         map: texture,
         side: this.THREE.BackSide
         // transparent: true,
         // needsUpdate:true
       })
       )
     }
     var cube = new this.THREE.Mesh(new this.THREE.CubeGeometry(9000, 9000, 9000), materials)
     cube.name = 'sky'
     this.scene.add(cube)
     
     var axes = new this.THREE.AxesHelper(100000)
     this.scene.add(axes)

思路:首先创建一个materials的数组,数组中的每一个元素都是一个MeshBasicMaterial的实例,利用方法将材质贴图附着在正方体的内侧。
MeshBasicMaterial
参数map指的是贴图,默认值为null
参数side的含义是贴图的位置,这里我们选择的是this.THREE.BackSide,意味着贴图位于正方体的里面。
transparent: true当材质中包含有透明元素的时候需要用到,要不然透明的部位会有颜色存在。

this.THREE.Mesh(new this.THREE.CubeGeometry(9000, 9000, 9000), materials)
创建一个几何体,第二个参数是材质对象的数组
new this.THREE.AxesHelper(100000)
创建坐标轴,长度为100000

3.完整代码

<template>
   <div id="container">

   </div>
</template>

<style lang="scss">
html,body{
   padding: 0;
   margin: 0;
}
</style>

<script>
import { OBJLoader, MTLLoader } from 'three-obj-mtl-loader'
import OrbitControls from 'three-orbitcontrols'
export default {
 name: 'ThreeTest',
 data () {
   return {
     camera: null,
     scene: null,
     renderer: null,
     mesh: null,
     controls: null,
     crossOrigin: ''
   }
 },
 methods: {
   init: function () {
     const that = this
     this.scene = new this.THREE.Scene()
     
     var path = '/sky/'
     var format = '.jpg'
     var urls = [
       path + 'px' + format, path + 'nx' + format,
       path + 'py' + format, path + 'ny' + format,
       path + 'pz' + format, path + 'nz' + format
     ]
     var materials = []
     for (var i = 0; i < urls.length; ++i) {
       var loader = new this.THREE.TextureLoader()
       // loader.setCrossOrigin( this.crossOrigin );
       var texture = loader.load(urls[i], function () { console.log('q') }, undefined, function (e) { console.log(e) })
       materials.push(new this.THREE.MeshBasicMaterial({
         map: texture,
         side: this.THREE.BackSide
         // transparent: true,
         // needsUpdate:true
       })
       )
     }
     var cube = new this.THREE.Mesh(new this.THREE.CubeGeometry(9000, 9000, 9000), materials)
     cube.name = 'sky'
     this.scene.add(cube)

     var ambient = new this.THREE.AmbientLight(0xcccccc)
     this.scene.add(ambient)

     var axes = new this.THREE.AxesHelper(100000)
     this.scene.add(axes)

     var width = window.innerWidth// 窗口宽度
     var height = window.innerHeight// 窗口高度
     var k = width / height// 窗口宽高比
     // 创建相机对象
     this.camera = new this.THREE.PerspectiveCamera(45, width / height, 1, 1000000)
     this.camera.position.set(1000, 0, 1000)// 设置相机位置
     this.camera.lookAt(new this.THREE.Vector3(0, 0, 0))// 设置相机方向(指向的场景对象)
     /**
        * 创建渲染器对象
        */
     this.renderer = new this.THREE.WebGLRenderer()
     this.renderer.setSize(width, height)
     this.renderer.setClearColor(0xb9d3ff, 1)// 设置背景颜色
     document.getElementById('container').appendChild(this.renderer.domElement)// body元素中插入canvas对象
     // 执行渲染操作
     this.renderer.render(this.scene, this.camera)
     this.controls = new OrbitControls(this.camera, document.getElementById('container'))// 创建控件对象
     this.controls.addEventListener('change', this.animate())
   },
   animate: function () {
     requestAnimationFrame(this.animate)
     this.renderer.render(this.scene, this.camera)
   }
 },
 mounted () {
   this.init()
   // this.animate()
 }
}
</script>

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!