Three.js高级应用--利用Three.js实现球体或立方体形天空盒子

通过对three.js的不断学习,我们在做三维应用场景建设过程中,除了快速的加载模型或实时构建模型以外,还有一件事情需要做,一般会在整个三维空间中模拟一块空间区域,可以是球形或立方体形状盒子、大范围海平面等。这一篇主要讲述如何利用Three.js构建这两种类型的天空盒子,并在这个天空盒子中加载三维模型,具体实现情况如下。Three.js的基础代码请参考其他四篇文章,大范围海平面效果参加我的另一篇文章

一、功能简述:实现球形或立方体形状的虚拟天空盒子,作为后续模型加载或者三维应用场景的基础背景,支持旋转、放大缩小、移动等。

二、实现效果:

    

三、关键代码如下(相机platform下的src/enter目录下的index.js和addComponent.js文件)

1.index.js文件是三维场景的整体路由调度组件,详见 上一篇文章
2. addComponent.js文件 需要引入加载各个三维组件对应的js,详见上一篇文章 每个组件是一个类。 记得修改import的js文件,具体如下:
import { SkyBoxSphere } from '../effect/skyBox-Sphere.js'
import { SkyBoxCube } from '../effect/skyBox-Cube.js'
// 在构造函数最后记得调用initeffect,initeffect具体代码如下:
initEffect() {
    new SkyBoxSphere(this.scene);//天空盒子
    // new SkyBoxCube(this.scene);//天空盒子
}

3.skyBox-Sphere.js和skyBox-Cube.js完整文件如下

//skyBox-Sphere.js
import * as THREE from 'three'
export class SkyBoxSphere {
  constructor(scene) {
    this.scene = scene;
    this.url = '../../src/assets/earth6.jpg';
    this.init();
  }

  // 创建球体形天空盒子
  init() {
    // 创建一个纹理加载器
    const loader = new THREE.TextureLoader()

    const geometry = new THREE.SphereGeometry(5000, 32, 32);
    const material = new THREE.MeshBasicMaterial({
      side: THREE.DoubleSide,
      map: loader.load(this.url)
    })

    const sphere = new THREE.Mesh(geometry, material)

    sphere.position.copy({
      x: 0,
      y: 0,
      z: 0,
    })

    this.scene.add(sphere);
  }
}
//skyBox-Cube.js
import * as THREE from 'three'
export class SkyBoxCube {
  constructor(scene) {
    this.scene = scene;
    this.init();
  }

  // 创建立方体形天空盒子
  init() {
    //设置立方体6个面各自的纹理照片
    const imgs = [
      '../../src/assets/sky/right.jpg',
      '../../src/assets/sky/left.jpg',
      '../../src/assets/sky/top.jpg',
      '../../src/assets/sky/bottom.jpg',
      '../../src/assets/sky/front.jpg',
      '../../src/assets/sky/back.jpg',
    ]

    // 给每个面填充不同的材质,利用THREE.TextureLoader创建一个纹理加载器进行各个面材质的加载,并将其放在list中
    const mats = [];
    for (let i = 0; i < imgs.length; i++) {
      mats.push(new THREE.MeshBasicMaterial({
        map: new THREE.TextureLoader().load(imgs[i]),
        side: THREE.DoubleSide,
      }))
    }

    // 创建虚拟的场景
    const boxGeometry =new THREE.BoxGeometry(5000,5000,5000)
    const skybox = new THREE.Mesh(boxGeometry,mats)//直接将MeshBasicMaterial对象组成的list作为材质
    skybox.position.copy({
      x: 0,
      y: 0,
      z: 0,
    })
    this.scene.add(skybox)
  }
}

猜你喜欢

转载自blog.csdn.net/hhue2007/article/details/129425576