封装three.js工具库

本文介绍了如何在JavaScript中使用THREE.js库构建一个3D场景,包括初始化场景、相机、灯光、控制器,以及加载GLTF模型和HDR环境贴图。代码示例展示了如何动态调整模型和贴图的加载方式。
摘要由CSDN通过智能技术生成
import * as THREE from 'three'
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js"
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
/**
 * @class 
 * @param {String} domID 
 * @param {Object} options 
 
 * 
 * */
class ini1{
    constructor(options,domID ) {
       
        this.aac=aac;
        this.init(options)
     }
    //  初始化
     init(){
        // 初始化场景
       
       this.scene = this.createScene() 
       let scene = this.scene 
    //    初始化灯光
       let ambientLight = this.createLight({
        'type':'Directional', 
        'color':0xFFFFFF
       })
       
       scene.add(ambientLight)
     
    //    初始化相机
       this.camera = this.createCamera({
        'type':'Perspective',
       
       })
       scene.add(this.camera)
       this.camera.position.set(- 1.8, 0.6, 2.7)
      //  初始化控制器
      this.createControls()
    //    初始化渲染
       this.initRenderer()
       this.renders()
// 加载模型
     this.models=this.loadModel({
      'type':'gltf'
     }); 
     scene.add(this.models)
    //  
   this.rLoade= this.createRgbel({
    'type':'hdr'
   })
   scene.add(this.rLoade)
    window.addEventListener('resize', this.onWindowResize.bind(this));
     }
 // 创建场景
     createScene () {
       return new THREE.Scene()
     }
    //  创建相机
    createCamera(options) {
      
        // 透视相机
        if(options.type=='Perspective'){
          return new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.25,200);
        }
        // 正交相机
        if(options.type == 'Orthographic'){
          return new THREE.OrthographicCamera(left, right, top, bottom, near, 2000)
        }
      }
    
     //创建灯光
     createLight(options) {
      // 基础光
        if(options.type == 'Ambient'){
            return new THREE.AmbientLight(options.color);
        }
        // 环境光
        if(options.type == 'Hemisphere'){
            return new THREE.HemisphereLight();
        }
        // 点光源
        if(options.type == 'Point'){
          const pointLight = new THREE.PointLight(options.color)
          pointLight.position.set(0, 100, 100)
          return pointLight
        }
        // 方向光
        if(options.type == 'Directional'){
          const directionalLight = new THREE.DirectionalLight(options.color, 1) // 创建方向光
          // directionalLight.position.set(100,100,100)
          // // 是否产生阴影
          directionalLight.castShadow = true
          // directionalLight.shadow.camera.far = 1000
          // directionalLight.shadow.camera.near = 0.5
          // directionalLight.shadow.camera.left = 1000
          // directionalLight.shadow.camera.right = -1000
          // directionalLight.shadow.camera.top = 1000
          // directionalLight.shadow.camera.bottom = -1000
          return directionalLight
        }
       
      }
// 控制器
createControls(){
  this.controls = new OrbitControls(this.camera, this.aac)
    return this.controls
    
}
//这边被的大佬说了渲染、模型、和环境贴图的参数要在init方法调用的时候写才会更好点,不然每次调用的时候都要跑到下面
    //   渲染
      initRenderer() {
        this.renderer = new THREE.WebGLRenderer({
          antialias: true,
          alpha:true
        })
        this.renderer.setClearColor(0xEEEEEE, 0.0) 
        this.renderer.setPixelRatio( window.devicePixelRatio );
        this.renderer.setSize( window.innerWidth, window.innerHeight );
        this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
				this.renderer.toneMappingExposure = 1;
				this.renderer.outputEncoding = THREE.sRGBEncoding;
        aac.appendChild(this.renderer.domElement)

      }
      // 模型

      loadModel(options) {
        if(options.type=='gltf'){
          const loader = new GLTFLoader();
          loader.load(
            'models/gltf/feiji.glb',
            (gltf) => {
              gltf.scene.scale.set(0.05,0.05,0.05)
              this.scene.add(gltf.scene);
            },
            undefined,
            (error) => {
              console.error(' hhhhhh ', error);
            }
          );
          return loader
          }
       
      }
      // 环境贴图
      createRgbel(options){
        if(options.type=='hdr'){
          const rLoader = new RGBELoader().setPath('textures/equirectangular/')
          rLoader.load(
            'royal_esplanade_1k.hdr',
            (texture) => {
              texture.mapping = THREE.EquirectangularReflectionMapping;
              scene.environment = texture;
            },
            undefined,
            (error) => {
              console.error(' hhhhhh ', error);
            }
          );
          return rLoader
          }
      }
      renders(){
        this.scene.rotation.x += 0.01; 
        this.scene.rotation.y += 0.01; 
        this.renderer.render(this.scene,this.camera)
        requestAnimationFrame(this.renders.bind(this))
      }

      onWindowResize() {
        const width = window.innerWidth;
        const height = window.innerHeight;
      
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();
      
        this.renderer.setSize(width, height);
      }
   

}
export default ini1;

更新了环境贴图和模型导入的部分

import * as THREE from 'three'
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js"
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
/**
 * @class 
 * @param {String} domID 
 * @param {Object} options 
 
 * 
 * */
class ini1{
    constructor(options,domID ) {
       
        this.aac=aac;
        this.init(options)
     }
    //  初始化
     init(){
// 初始化场景
    this.scene = this.createScene() 
    let scene = this.scene 


//    初始化灯光
    let ambientLight = this.createLight({
    'type':'Directional', 
    'color':0xFFFFFF
    })      
    scene.add(ambientLight)


//    初始化相机
    this.camera = this.createCamera({
    'type':'Perspective',
    
    })
    scene.add(this.camera)
    this.camera.position.set(- 1.8, 0.6, 2.7)


//  初始化控制器
    this.createControls()

//    初始化渲染
    this.renderer=this.initRenderer()//调用封装的方法
    this.renderer.setClearColor(0xEEEEEE, 0.0) //设置颜色和透明度
    this.renderer.setPixelRatio( window.devicePixelRatio );
    this.renderer.setSize( window.innerWidth, window.innerHeight );
    this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
    this.renderer.toneMappingExposure = 1;
    this.renderer.outputEncoding = THREE.sRGBEncoding;
    aac.appendChild(this.renderer.domElement)
    this.renders()


// 加载模型
    this.models=this.loadModel({
      'type':'gltf'
    }); 
    this.models.load(
      'models/gltf/feiji.glb',
      (gltf) => {
        gltf.scene.scale.set(0.05,0.05,0.05)
        this.scene.add(gltf.scene);
      },
      undefined,
      (error) => {
        console.error(' cuolalalal ', error);
      }
    );
    scene.add(this.models)


//  环境贴图
   this.rLoade= this.createRgbel({
      'type':'hdr',
   })
   this.rLoade.setPath('textures/equirectangular/')
    this.rLoade.load(
      'royal_esplanade_1k.hdr',
      (texture) => {
        texture.mapping = THREE.EquirectangularReflectionMapping;
        scene.environment = texture;
      },
      undefined,
      (error) => {
        console.error(' hhhhhh ', error);
      }
    );
   scene.add(this.rLoade)
   console.log(this.rLoade)

// 监听窗口大小
    window.addEventListener('resize', this.onWindowResize.bind(this));
    }


 // 创建场景
     createScene () {
       return new THREE.Scene()
     }
    //  创建相机
    createCamera(options) {
      
        // 透视相机
        if(options.type=='Perspective'){
          return new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.25,200);
        }

        // 正交相机
        if(options.type == 'Orthographic'){
          return new THREE.OrthographicCamera(left, right, top, bottom, near, 2000)
        }
      }
    
     //创建灯光
     createLight(options) {
      // 基础光
        if(options.type == 'Ambient'){
            return new THREE.AmbientLight(options.color);
        }
        // 环境光
        if(options.type == 'Hemisphere'){
            return new THREE.HemisphereLight();
        }
        // 点光源
        if(options.type == 'Point'){
          return new THREE.PointLight(options.color)
          // pointLight.position.set(0, 100, 100)
          // return pointLight
        }
        // 方向光
        if(options.type == 'Directional'){
         return new THREE.DirectionalLight(options.color, 1) // 创建方向光
          // directionalLight.position.set(100,100,100)
          // // 是否产生阴影
          // directionalLight.castShadow = true
        }
       
      }
// 控制器
createControls(){
  this.controls = new OrbitControls(this.camera, this.aac)
    return this.controls
    
}
    //   渲染
      initRenderer() {
        return new THREE.WebGLRenderer({
          antialias: true,
          alpha:true
        })
        

      }
      // 模型
      loadModel(options) {
        if(options.type=='gltf'){
          return new GLTFLoader();
          }
       
      }
      // 环境贴图
      createRgbel(options){
        if(options.type=='hdr'){
          return new RGBELoader()
          }
      }
      renders(){
        this.renderer.render(this.scene,this.camera)
        requestAnimationFrame(this.renders.bind(this))
      }

      onWindowResize() {
        const width = window.innerWidth;
        const height = window.innerHeight;
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(width, height);
      }
   

}
export default ini1;

大佬说上面的写的不好给我改了







init(){
// 加载模型
    this.models=this.loadModel({
      'type':'gltf',
      'src':'models/gltf/feiji.glb',
      'callback':function(data){
        data.scene.scale.set(0.05,0.05,0.05)
        scene.add(data.scene);
      }
    }); 
    scene.add(this.models)



//  环境贴图
   this.rLoade= this.createRgbel({
      'type':'hdr',
      'path':'textures/equirectangular/',
      'src':'royal_esplanade_1k.hdr',
      'callback':function(data){
        data.mapping = THREE.EquirectangularReflectionMapping;
        scene.environment = data;
      }
   })
   
   scene.add(this.rLoade)
}

 // 模型
      loadModel(options) {

        if(options.type=='gltf'){
          const mo = new GLTFLoader();
          mo.load(
            options.src,
            (gltf) => {
              options.callback(gltf)

            }
          );
          }
       
      }
      // 环境贴图
      createRgbel(options){
        if(options.type=='hdr'){
          const ro = new RGBELoader()
          ro.setPath(options.path)
      ro.load(
      options.src,
      (texture) => {
        options.callback(texture)
       
      }
    );
          }
      }

vue中

<template>
  <div id="3dmap">
    <div id="aac" ref="aac"></div>
  </div>
</template>

<script>
import * as THREE from 'three';
import ini1 from '../common/mapLib/Map/ini1.js';

export default {
  name: 'map3d1',
  data() {
    return {};
  },
  mounted() {
    const ma = this.$refs.aac;

    let map;
    map = new ini1(ma);
    console.log(map)
//前面封装的时候我已经从外部导入模型了,下面可以自己创建模型
    // const geometry = new THREE.BoxGeometry(5, 5, 5);
    // const material = new THREE.MeshBasicMaterial({ color: 0x00ff00
    //  });
    // const cube = new THREE.Mesh(geometry, material);
    
    // map.scene.add(cube);
    // map.camera.lookAt(cube.position)
    // console.log(map.scene)
  },
};
</script>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值