前言:最近用vue+threre.js实现3d页面的时候,发现导入obj模型时模型在页面中显示不出来的问题。也纠结了好几天,换了好几种方式去试,到底是模型有问题还是代码有问题?真是个令人头痛的问题啊!
一、关于obj模型存放的目录
- 这里我用的vue是4.x版本的。
- 在vue中存放obj模型必须要放在静态资源(static)文件下,否则会出错。
- 由于4.x版本的vue没有static这个文件夹,但是他的静态资源文件夹是叫
public
,这样我在public下面创建一个文件夹叫static,再在static文件夹下存放的我的obj模型文件以及mtl文件。 - 文件目录如下:
二、关于obj模型的导入
直接上代码吧:
<template>
<div id="academy">
</div>
</template>
<script>
import * as THREE from "three";
import {
OBJLoader,MTLLoader} from "three-obj-mtl-loader";
const OrbitControls = require('three-orbit-controls')(THREE);
export default {
name:'academy',
data(){
return{
}
},
methods: {
/**加载模型 */
loadPlant() {
let that = this;
let objLoader = new OBJLoader();
let mtlLoader = new MTLLoader();
mtlLoader.load("/static/academic/bluegrayhome.mtl", function(materials) {
// materials.preload();
objLoader.setMaterials(materials);
objLoader.load(
"/static/academic/bluegrayhome.obj",
function(obj) {
obj.position.set(0, 0,0);
obj.scale.set(0.01, 0.01, 0.01);
that.scene.add(obj);
},
// called while loading is progressing
function(xhr) {
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},
// called when loading has errors
function(error) {
console.log("An error happened");
}
);
});
},
},
mounted() {
this.loadPlant();
}
}
</script>
这里关于相机,场景等初始化的内容没有放上去。
在导入obj之前还要 npm install three-obj-mtl-loader
,并在组件中引入。
三、关于obj模型显示不出来的问题
敲黑板,这个问题真的是!!!!!一言难尽!!!
在我的这里obj模型已经是加载出来了,但就是在页面中显示不出来,也就是我看不到它!!!!
那这是为什么呢?为什么显示不出来呢?于是我又发现控制台中报了warnings,起初我以为是这个warning的问题,可后来经过多种方法的调试发现并不是这个问题。
于是乎我又开始崩溃了,怎么就是看不到呢?后来我又以为是模型太大的问题,但其实并不是。一次偶然我向页面中添加了轨道控制器,使场景可以旋转起来,然后我就发现!!!!!原来我的模型一直都在,只是它在我看不到的地方!!也就是我的相机根本照不到我的物体,所以我什么也看不到。(不要问我为什么起初没考虑这个问题,其实我也考虑过是不是相机位置的问题,我还进行了调试,但还是没用,直到我添加了控制器,一转才发现问题的所在)。
控制器的代码如下:
// 初始化控制器
initOrbitControls(){
let controls = new OrbitControls(this.camera,this.renderer.domElement);
controls.enableDamping = true;
controls.enableZoom = true;
controls.autoRotate = false;
controls.autoRotateSpeed = 3;
controls.enablePan = true;
controls.enableKeys = true;
controls.keyPanSpeed = 7;
controls.keys = {
LEFT:37,
UP:38,
RIGHT:39,
BOTTOM:40
}
this.controls =controls;
},
只需要把这个函数写在methods方法里就可以了,然后再去调用它。
只要一转就可以看到模型了。
四、总结
如果obj模型出不来可以看看:
- 是不是没有把模型放在静态目录下
- 是不是相机没有照到物体
- 是不是引用的路径有问题
- 场景和相机是否已经加载出来了
其实问题有很多,关键在于怎么去发现问题的所在,是在不行的话就多试试咯。加个控制器再加个坐标轴。
完整代码如下:
<template>
<div id="academy">
</div>
</template>
<script>
import * as THREE from "three";
import {
OBJLoader,MTLLoader} from "three-obj-mtl-loader";
const OrbitControls = require('three-orbit-controls')(THREE);
export default {
name:'academy',
data(){
return{
scene:'',
light:'',
camera:'',
renderer:'',
}
},
methods: {
/**初始化 */
initScene() {
this.scene = new THREE.Scene();
const ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
this.scene.add(ambientLight);
var axesHelper = new THREE.AxesHelper(15);
this.scene.add(axesHelper);
},
initCamera() {
const aspect = window.innerWidth / innerHeight; //宽高可根据实际项目要求更改 如果是窗口高度改为innerHeight
this.camera = new THREE.PerspectiveCamera(45, aspect, 1, 1000);
this.camera.position.set(15, 25, 20);
this.camera.lookAt(new THREE.Vector3(0, 0, 0)); // 让相机指向原点
const pointLight = new THREE.PointLight(0xffffff,1,100);
pointLight.position.set(0,0,20100);
this.scene.add(pointLight);
this.scene.add(this.camera);
},
initRenderer() {
this.renderer = new THREE.WebGLRenderer({
antialias: true, alpha: true });
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, innerHeight);
this.container = document.getElementById("academy");
this.container.appendChild(this.renderer.domElement);
},
// 初始化控制器
initOrbitControls(){
let controls = new OrbitControls(this.camera,this.renderer.domElement);
controls.enableDamping = true;
controls.enableZoom = true;
controls.autoRotate = false;
controls.autoRotateSpeed = 3;
controls.enablePan = true;
controls.enableKeys = true;
controls.keyPanSpeed = 7;
controls.keys = {
LEFT:37,
UP:38,
RIGHT:39,
BOTTOM:40
}
this.controls =controls;
},
animate() {
this.renderer.render(this.scene, this.camera);
this.requestId = requestAnimationFrame(this.animate);
},
init() {
this.group = new THREE.Group();
this.initScene();
this.initCamera();
this.initRenderer();
this.initOrbitControls();
},
/**加载模型 */
loadPlant() {
let that = this;
let objLoader = new OBJLoader();
let mtlLoader = new MTLLoader();
mtlLoader.load("/static/academic/bluegrayhome.mtl", function(materials) {
// materials.preload();
objLoader.setMaterials(materials);
objLoader.load(
"/static/academic/bluegrayhome.obj",
function(obj) {
obj.position.set(0, 0,0);
obj.scale.set(0.01, 0.01, 0.01);
that.scene.add(obj);
},
// called while loading is progressing
function(xhr) {
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},
// called when loading has errors
function(error) {
console.log("An error happened");
}
);
});
},
loadPlant2() {
let that = this;
let objLoader = new OBJLoader();
let mtlLoader = new MTLLoader();
mtlLoader.load("/static/academic/绿树2.mtl", function(materials) {
// materials.preload();
objLoader.setMaterials(materials);
objLoader.load(
"/static/academic/绿树2.obj",
function(obj) {
obj.position.set(0, 0,0);
obj.scale.set(0.01, 0.01, 0.01);
that.scene.add(obj);
},
// called while loading is progressing
function(xhr) {
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},
// called when loading has errors
function(error) {
console.log("An error happened");
}
);
});
},
loadPlant3() {
let that = this;
let objLoader = new OBJLoader();
let mtlLoader = new MTLLoader();
mtlLoader.load("/static/academic/绿树1.mtl", function(materials) {
// materials.preload();
objLoader.setMaterials(materials);
objLoader.load(
"/static/academic/绿树1.obj",
function(obj) {
obj.position.set(10, 10,0);
obj.scale.set(0.01, 0.01, 0.01);
that.scene.add(obj);
},
// called while loading is progressing
function(xhr) {
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},
// called when loading has errors
function(error) {
console.log("An error happened");
}
);
});
},
},
mounted() {
this.init();
this.loadPlant();
this.loadPlant2();
this.loadPlant3();
this.animate();
document.getElementsByTagName("canvas")[0].style.verticalAlign = "bottom"; //解决canvas底部留白问题
// window.addEventListener("click", this.clickModel, false);
// window.addEventListener("resize", this.onResize, false);
},
}
</script>
<style scoped>
#academy{
height: 600px;
}
</style>