利用elementplus和threejs创建3D预览窗口,在创建后场景多出一块空白(如图)怎么回事?

新手上路,请多包涵

这是我的代码

<template>
  <div class="STLViewer">
    <el-dialog title="3D预览" v-model="newDialogVisible" style="height: 710px" @close="closeModel" @open="open()">
      <div id="container" v-if="newDialogVisible" style="width: 96.2%; height: 300px;"></div>
      <el-button class="btn" type="primary" @click="closeModel">确认</el-button>
    </el-dialog>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js'

var scene, mesh;

export default {
  name: 'STLViewer',
  data() {
    return {
      publicPath: process.env.BASE_URL,
      // mesh: null,
      camera: null,
      // scene: null,
      renderer: null,
      controls: null,
      newDialogVisible: false
    }
  },
  methods: {
    // 初始化
    init() {
      this.createScene() // 创建场景
      this.loadSTL() // 加载STL模型
      this.createLight() // 创建光源
      this.createCamera() // 创建相机
      this.createRender() // 创建渲染器
      this.createControls() // 创建控件对象
      this.render() // 渲染
    },
    // 创建场景
    createScene() {
      scene = new THREE.Scene()
    },
    // 加载STL模型
    loadSTL() {
      const THIS = this
      const loader = new STLLoader()
      loader.load(
        `${THIS.publicPath}models/gear.stl`,
        geometry => {
          // 创建材质
          const material = new THREE.MeshLambertMaterial({ color: 0x7777ff })
          mesh = new THREE.Mesh(geometry, material)
          // mesh.rotation.x = -0.5 * Math.PI
          mesh.scale.set(0.6, 0.6, 0.6)
          scene.add(mesh)
        }
      )
    },
    // 创建光源
    createLight() {
      // 环境光
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光
      scene.add(ambientLight) // 将环境光添加到场景

      const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯
      spotLight.position.set(150, 150, 150)
      spotLight.castShadow = true
      scene.add(spotLight)
    },
    // 创建相机
    createCamera() {
      const element = document.getElementById('container')
      const width = element.clientWidth // 窗口宽度
      const height = element.clientHeight // 窗口高度
      const k = width / height // 窗口宽高比
      // PerspectiveCamera( fov, aspect, near, far )
      this.camera = new THREE.PerspectiveCamera(35, k, 0.1, 1000)
      this.camera.position.set(200, 250, 150) // 设置相机位置

      this.camera.lookAt(new THREE.Vector3(10, 40, 0)) // 设置相机方向
      scene.add(this.camera)
    },
    // 创建渲染器
    createRender() {
      const element = document.getElementById('container')
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, powerPreference: "high-performance" })
      this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
      this.renderer.shadowMap.enabled = true // 显示阴影
      this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
      this.renderer.setClearColor(0x3f3f3f, 1) // 设置背景颜色
      element.appendChild(this.renderer.domElement)
    },
    render() {
      if (mesh) {
        // mesh.rotation.z += 0.006
      }
      this.renderer.render(scene, this.camera)
      requestAnimationFrame(this.render)
    },
    // 创建控件对象
    createControls() {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    },
    open(){
      this.$nextTick(()=>{
        this.init();
      })
    },
    closeModel(){
      // 释放模型资源
      scene.clear();
      mesh.clear();
      this.newDialogVisible = false;
    },
  }
}
</script>
<style>
#container {
  position: absolute;
  width: 100%;
  height: 100%;
}
.btn {
  position: relative;
  top:610px;
  margin-left: 46.5%;
}
</style>

有什么解决办法吗?我希望上面那段空白去掉

阅读 770
2 个回答

检查一下css吧

新手上路,请多包涵

首先,你的这个问题可能是你的透视相机参数配置问题。
THREE.PerspectiveCamera构建了一个视锥,超出这个视锥空间的部分是不会渲染的,像你上面截图中出现的模型像是被整齐的抹去了一块,可能的原始是你的模型部分正好超出了你视锥的范围,导致超出视锥范围的模型不渲染。
[1]视锥参考链接

解决方案:

  1. 修改透视相机参数;
  2. 修改模型的原点位置,移动模型位置到视锥范围内;
推荐问题
logo
Microsoft
子站问答
访问
宣传栏