three.js封装

1.vue3页面"three版本为": “^0.162.0”,

<script setup>
import * as THREE from 'three'
// import renderer from './twin(废弃).js'
import { onMounted, ref } from 'vue'
import twin from './twin.js'
twin.loader.load('./public/模型Draco.glb', function (gltf) {
  twin.scene.add(gltf.scene)
  gltf.scene.traverse(function (obj) {
    if (obj.isMesh) {
      obj.material.envMapIntensity = 1.0 //折射率
    }
  })

  // 给场景添加一个物体
  const geometry = new THREE.SphereGeometry(300)

  // 设置天空盒子背景图
  const texture = new THREE.TextureLoader().load('./全景贴图.jpeg')
  texture.colorSpace = THREE.SRGBColorSpace //与webgl渲染器的outputColorSpace属性值一样
  const material = new THREE.MeshBasicMaterial({
    side: THREE.BackSide,
    map: texture,
  })
  const mesh = new THREE.Mesh(geometry, material)
  twin.scene.add(mesh)
  if (twin.gui) {
    twin.gui
      .add({ envMapIntensity: 2.0 }, 'envMapIntensity', 0, 5)
      .name('环境贴图的影响')
      .onChange(function (v) {
        gltf.scene.traverse(function (obj) {
          if (obj.isMesh) {
            obj.material.envMapIntensity = v
          }
        })
      })
  }
})
const webgl = ref(null)
onMounted(() => {
  // webgl.value.appendChild(renderer.domElement)
})
</script>

<template>
  <div ref="webgl"></div>
</template>

<style scoped></style>

2.新建CreateTwin.js文件

import * as THREE from 'three'
// 解压缩
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js"
// 轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"
// 引入gltf加载器
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js"

import Helper from './Helper'
export default class CreateTwin {
  constructor(params = {}) {

    const {
      logPosTargetBool = false,
      helperBool = true//默认创建辅助工具
    } = params

    // 场景
    this.scene = new THREE.Scene();

    // 相机
    const width = window.innerWidth
    const height = window.innerHeight

    // 实例化一个透视相机对象
    this.camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
    this.camera.position.set(1.24, 13.03, 67.5)
    this.camera.lookAt(0, 0, 0)

    // 渲染器
    this.renderer = new THREE.WebGLRenderer({
      antialias: true,//优化锯齿
      logarithmicDepthBuffer: true//开启对数深度缓冲  削弱深度冲突
    })
    this.renderer.setSize(width, height)
    this.renderer.setPixelRatio(window.devicePixelRatio)//设备像素比
    document.body.appendChild(this.renderer.domElement)

    // gltf加载
    const draco = new DRACOLoader()//解压对象
    draco.setDecoderPath('./draco/')//根据public里面解压文件结构设置

    // 实例化一个加载器对象
    this.loader = new GLTFLoader()
    this.loader.setDRACOLoader(draco)//给gltf加载器增加解压功能

    // 环境贴图
    this.rgbeLoader = new RGBELoader()
    this.rgbeLoader.load('./envMap.hdr', (envMap) => {
      // 作为环境贴图
      this.scene.environment = envMap
      envMap.mapping = THREE.EquirectangularReflectionMapping
    })

    // 创建一个相机控件对象
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.controls.target.set(0, 0, 0)
    this.controls.update()


    if (logPosTargetBool) {
      this.controls.addEventListener('change', () => {
        // console.log(this.camera.position);
        // console.log(this.controls.target);
        this.renderer.render(this.scene, this.camera)//执行一个渲染操作,类比相机拍照咔
      })

    }


    // 平行光
    this.directionalLight = new THREE.DirectionalLight(0xffffff, 1.0)
    this.directionalLight.position.set(100, 100, 100)
    this.scene.add(this.directionalLight)


    if (helperBool) {

      this.helper = new Helper(this.scene, this.directionalLight)
      this.gui = this.helper.gui
    }



    // 渲染循环
    this.renderer.setAnimationLoop(() => {
      if (helperBool) this.helper.stats.update()


      this.renderer.render(this.scene, this.camera)
    })



    // onresize事件会在窗口被调整大小时发生
    window.onresize = () => {
      const width = window.innerWidth
      const height = window.innerHeight
      this.camera.aspect = width / height;//全屏情况下:设置观察范围长宽比aspect为窗口宽高比
      this.renderer.setSize(width, height);//重置渲染器输出画布canvas尺寸
      this.renderer.render(this.scene, this.camera);
      this.camera.updateProjectionMatrix();//相机属性发生变化,需要执行updateProjectionMatrix()方法更新
    }
  }
}

3.新建Helper.js

import * as THREE from 'three'
// 引入stats性能监视器
import Stats from "three/addons/libs/stats.module.js"
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js"
export default class Helper {
  constructor(scene, directionalLight) {
    scene.add(new THREE.AxesHelper(150))
    this.stats = new Stats()
    this.stats.setMode(0)//修改渲染模式,默认为0
    document.body.appendChild(this.stats.domElement);
    this.gui = new GUI()
    this.gui.domElement.style.right = '0px'
    this.gui.domElement.style.width = '500px'



    // 平行光
    const dirFolder = this.gui.addFolder('平行光')
    dirFolder.close()
    // directionalLight.intensity = 2.0
    dirFolder.add(directionalLight, 'intensity', 0, 10).name('光照强度')


    const R = 100
    dirFolder.add({ angle: 45 }, 'angle', 0, 360).onChange(function (v) {
      const rad = THREE.MathUtils.degToRad(v)//角度转弧度
      directionalLight.position.x = R * Math.cos(rad)
      directionalLight.position.z = R * Math.sin(rad)
    }).name('旋转角度')

    dirFolder.add({ angle: 45 }, 'angle', 0, 89).onChange(function (v) {
      const rad = THREE.MathUtils.degToRad(v)//角度转弧度
      directionalLight.position.y = R * Math.tan(rad)

    }).name('照射角度')
  }
}

4.新建twin.js

import CreateTwin from "../twin/CreateTwin";
const twin = new CreateTwin({
  logPosTargetBool: false,
  helperBool: true//是否显示辅助工具

})

export default twin
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值