ThreeJS 在Vue中创建天空盒子,解决纹理贴图和模型不显示的其中一种情况


前言

在Vue项目中创建一个天空盒子,解决盒子对应的6个面图片不显示问题,对于模型不加载问题也可能是相同原因造成的。


一、问题描述

刚开始在目录里添加了一个static文件夹存放图片
在这里插入图片描述

在App.vue中加载图片

// 天空盒子纹理图
        let materialArray = [];
        let texture_ft = new Three.TextureLoader().load("../static/skyBox/ft.jpg");
        let texture_bk = new Three.TextureLoader().load("../static/skyBox/bk.jpg");
        let texture_up = new Three.TextureLoader().load("../static/skyBox/up.jpg");
        let texture_dn = new Three.TextureLoader().load("../static/skyBox/dn.jpg");
        let texture_rt = new Three.TextureLoader().load("../static/skyBox/rt.jpg");
        let texture_lf = new Three.TextureLoader().load("../static/skyBox/lf.jpg");

在这里插入图片描述
发现盒子加载成功,但是盒子颜色为黑色,没有图片加载。

二、解决方法

原因是是图片加载的路径问题,该解决方法也适用于面模型加载不出来。

图片加载有一个默认地址public文件夹,把图片和模型放在该文件夹下
在这里插入图片描述

// 天空盒子纹理图
        let materialArray = [];
        let texture_ft = new Three.TextureLoader().load("static/skyBox/ft.jpg");
        let texture_bk = new Three.TextureLoader().load("static/skyBox/bk.jpg");
        let texture_up = new Three.TextureLoader().load("static/skyBox/up.jpg");
        let texture_dn = new Three.TextureLoader().load("static/skyBox/dn.jpg");
        let texture_rt = new Three.TextureLoader().load("static/skyBox/rt.jpg");
        let texture_lf = new Three.TextureLoader().load("static/skyBox/lf.jpg");

三、代码

<template>
    <div>
      <div id="container"></div>
    </div>
</template>
 
<script>
import * as Three from 'three'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { mergeUniforms } from 'three';
 
export default {
  name: 'ThreeTest',
  data() {
    return {
      camera: null,
      scene: null,
      renderer: null,
      loader:null,
      light:null,
      controls:null
      // mesh: null
    }
  },
  methods: {
    init: function() {
        let container = document.getElementById('container');
 
        this.camera = new Three.PerspectiveCamera(45, container.clientWidth/container.clientHeight, 0.01, 10000);
        this.camera.position.set(-350,50,70);
 
        this.scene = new Three.Scene();
        let _this=this
        this.loader = new GLTFLoader()// 设置默认路径
        // 创建时钟
        // clock = new THREE.Clock()
        this.loader.load("static/caifuxingyuan.glb", function (gltf) {
          console.log(gltf)
            _this.scene.add(gltf.scene)
        })
        this.scene.add(this.mesh);
        this.light = new Three.PointLight(0xffffff)// 半球形光源
        this.light.position.set(0, 200, 0);//  光源位置
        this.scene.add(this.light)// 将光源添加到场景
        // 添加平行
        var directionalLight = new Three.DirectionalLight( 0xf2f2f2, 3 );
        directionalLight.position.set(-40, 60, -10);
        directionalLight.shadow.camera.near = 20; //产生阴影的最近距离
        directionalLight.shadow.camera.far = 200; //产生阴影的最远距离
        //这两个值决定使用多少像素生成阴影 默认512
        directionalLight.shadow.mapSize.height = 1024;
        directionalLight.shadow.mapSize.width = 1024;
        // 设置计算阴影的区域,最好刚好紧密包围在对象周围
        // 计算阴影的区域过大:模糊  过小:看不到或显示不完整
        directionalLight.shadow.camera.near = 0.5;
        directionalLight.shadow.camera.far = 100;
        directionalLight.shadow.camera.left = -10;
        directionalLight.shadow.camera.right = 10;
        directionalLight.shadow.camera.top = 20;
        directionalLight.shadow.camera.bottom = -10;
        this.scene.add( directionalLight );
 
        this.renderer = new Three.WebGLRenderer({antialias: true});
        this.renderer.setSize(container.clientWidth, container.clientHeight);
        this.renderer.setClearColor(0xcccccc, 1); //设置背景颜色
        container.appendChild(this.renderer.domElement);
        this.controls = new OrbitControls(this.camera,this.renderer.domElement)
        this.controls.minDistance = 200;
        this.controls.maxDistance = 1000;
        this.controls.update()
        var line = new Three.AxesHelper(500)//辅助线
        this.scene.add(line)

        // 天空盒子纹理图
        let materialArray = [];
        let texture_ft = new Three.TextureLoader().load("static/skyBox/ft.jpg");
        let texture_bk = new Three.TextureLoader().load("static/skyBox/bk.jpg");
        let texture_up = new Three.TextureLoader().load("static/skyBox/up.jpg");
        let texture_dn = new Three.TextureLoader().load("static/skyBox/dn.jpg");
        let texture_rt = new Three.TextureLoader().load("static/skyBox/rt.jpg");
        let texture_lf = new Three.TextureLoader().load("static/skyBox/lf.jpg");

        materialArray.push(new Three.MeshBasicMaterial({ map: texture_ft }));
        materialArray.push(new Three.MeshBasicMaterial({ map: texture_bk }));
        materialArray.push(new Three.MeshBasicMaterial({ map: texture_up }));
        materialArray.push(new Three.MeshBasicMaterial({ map: texture_dn }));
        materialArray.push(new Three.MeshBasicMaterial({ map: texture_rt }));
        materialArray.push(new Three.MeshBasicMaterial({ map: texture_lf }));

        for (let i = 0; i < 6; i++) materialArray[i].side = Three.BackSide;
        let skyboxGeo = new Three.BoxGeometry(10000, 10000, 10000);
        let skybox = new Three.Mesh(skyboxGeo, materialArray);
        this.scene.add(skybox);
 
    },
    animate: function() {
        requestAnimationFrame(this.animate);
        this.renderer.render(this.scene, this.camera);
    }
  },
  mounted() {
      this.init();
      this.animate()
  }
}
</script>
<style scoped>
  #container {
    height: 900px;
    width: 1900px;
  }
</style>

天空盒子代码部分可以换成简便写法,下面这一种写法是把图片作为背景

this.scene.background = new Three.CubeTextureLoader()
          .setPath("static/skyBox/")
          .load(['ft.jpg', 'bk.jpg', 'up.jpg', 'dn.jpg', 'rt.jpg', 'lf.jpg'])

总结

加载图片和模型的资源需要放在public文件夹下才能生效

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值