将带有 mtl 的 Blender obj 文件导入 ThreeJS
Importing Blender obj file with mtl to ThreeJS
我正在尝试将我在 Blender 中创建的对象文件导入 ThreeJS。我的搅拌机项目如下所示:
image
我将它导出为波形,为了导入 ThreeJS 我使用了 MTLLoader 和 OBJLoader,这是我的代码:
<script>
var container;
var camera, controls, scene, renderer, dragControls;
var lighting, ambient, keyLight, fillLight, backLight;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var keyboard = {};
var floor;
var objects = [];
var meshes = [];
var cameraParams = {speed: 0.1, turnSpeed: Math.PI * 0.5};
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2(1, 1), INTERSECTED;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(0, 7, 25);
scene = new THREE.Scene();
ambient = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambient);
keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
keyLight.position.set(-100, 0, 100);
fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
fillLight.position.set(100, 0, 100);
backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
scene.add(keyLight);
scene.add(fillLight);
scene.add(backLight);
// load model
loadMesh('road', function(obj){
obj.position.y = 0;
obj.scale.x = 1;
obj.scale.y = 1;
obj.scale.z = 1;
addMesh(obj);
});
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color('hsl(0, 0%, 10%)'));
container.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;
dragControls = new THREE.DragControls(objects, camera, renderer.domElement);
dragControls.addEventListener('dragstart', function (event) {
event.object.material.emissive.set(0xaaaaaa);
controls.enabled = false;
});
dragControls.addEventListener('dragend', function (event) {
event.object.material.emissive.set(0x000000);
controls.enabled = true;
});
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('keydown', keyDownEvent, false);
window.addEventListener('keyup', keyUpEvent, false);
window.addEventListener('mousemove', onMouseMove, false);
}
function addMesh(mesh) {
meshes.push(mesh);
scene.add(mesh);
}
function loadMesh(name, callback) {
var objLoader = new THREE.OBJLoader();
var matLoader = new THREE.MTLLoader();
matLoader.setPath('assets/');
matLoader.load('ROAD2.mtl', function(materials) {
materials.preload();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('ROAD2.obj', function (obj) {
callback(obj);
});
});
}
function onWindowResize() {
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function keyDownEvent(event) {
keyboard[event.keyCode] = true;
}
function keyUpEvent(event) {
keyboard[event.keyCode] = false;
}
function onMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function animate() {
requestAnimationFrame(animate);
if (keyboard[37]) { // left arrow key
camera.rotation.y += cameraParams.turnSpeed;
}
if (keyboard[39]) { // right arrow key
camera.rotation.y -= cameraParams.turnSpeed;
}
controls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
我的 Blender 场景很少在我的浏览器中加载,即使加载,也没有任何纹理。大多数情况下,我的选项卡在加载任何内容之前就崩溃了,因为它占用了我所有的内存(使用 Firefox 和 http-server 加载 html)。我不知道问题是什么,在 Google 上找不到任何东西,大多数示例都是关于一个具有材质和纹理的对象。
如果它很重要,我的文件层次结构如下所示:
index.html
js/
DragControls1.js
MTLLoader.js
OBJLoader.js
OrbitControls.js
three.js
assets/
ROAD2.mtl
ROAD2.obj
cottage_textures.png
road_texture.png
如有任何帮助,我们将不胜感激。
看来你的场景有大约7'000'000个顶点,这不是一点而是太多了。
在 Blender 中,尝试在几个较小的对象中进行导出。例如每一个单独的,街道,一棵树,其中一所房子等。
使用此方法,您可以接近场景的极限。
此外,尝试在代码中复制场景中的多个对象,而不是在 Blender 中进行!
(在实时 3D 应用程序中,您应该始终尝试使用最佳 3D 模型(几何、拓扑)而不是具有数百万个顶点的超大模型)
我正在尝试将我在 Blender 中创建的对象文件导入 ThreeJS。我的搅拌机项目如下所示: image
我将它导出为波形,为了导入 ThreeJS 我使用了 MTLLoader 和 OBJLoader,这是我的代码:
<script>
var container;
var camera, controls, scene, renderer, dragControls;
var lighting, ambient, keyLight, fillLight, backLight;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var keyboard = {};
var floor;
var objects = [];
var meshes = [];
var cameraParams = {speed: 0.1, turnSpeed: Math.PI * 0.5};
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2(1, 1), INTERSECTED;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(0, 7, 25);
scene = new THREE.Scene();
ambient = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambient);
keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
keyLight.position.set(-100, 0, 100);
fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
fillLight.position.set(100, 0, 100);
backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
scene.add(keyLight);
scene.add(fillLight);
scene.add(backLight);
// load model
loadMesh('road', function(obj){
obj.position.y = 0;
obj.scale.x = 1;
obj.scale.y = 1;
obj.scale.z = 1;
addMesh(obj);
});
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(new THREE.Color('hsl(0, 0%, 10%)'));
container.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;
dragControls = new THREE.DragControls(objects, camera, renderer.domElement);
dragControls.addEventListener('dragstart', function (event) {
event.object.material.emissive.set(0xaaaaaa);
controls.enabled = false;
});
dragControls.addEventListener('dragend', function (event) {
event.object.material.emissive.set(0x000000);
controls.enabled = true;
});
window.addEventListener('resize', onWindowResize, false);
window.addEventListener('keydown', keyDownEvent, false);
window.addEventListener('keyup', keyUpEvent, false);
window.addEventListener('mousemove', onMouseMove, false);
}
function addMesh(mesh) {
meshes.push(mesh);
scene.add(mesh);
}
function loadMesh(name, callback) {
var objLoader = new THREE.OBJLoader();
var matLoader = new THREE.MTLLoader();
matLoader.setPath('assets/');
matLoader.load('ROAD2.mtl', function(materials) {
materials.preload();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('ROAD2.obj', function (obj) {
callback(obj);
});
});
}
function onWindowResize() {
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function keyDownEvent(event) {
keyboard[event.keyCode] = true;
}
function keyUpEvent(event) {
keyboard[event.keyCode] = false;
}
function onMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function animate() {
requestAnimationFrame(animate);
if (keyboard[37]) { // left arrow key
camera.rotation.y += cameraParams.turnSpeed;
}
if (keyboard[39]) { // right arrow key
camera.rotation.y -= cameraParams.turnSpeed;
}
controls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
我的 Blender 场景很少在我的浏览器中加载,即使加载,也没有任何纹理。大多数情况下,我的选项卡在加载任何内容之前就崩溃了,因为它占用了我所有的内存(使用 Firefox 和 http-server 加载 html)。我不知道问题是什么,在 Google 上找不到任何东西,大多数示例都是关于一个具有材质和纹理的对象。 如果它很重要,我的文件层次结构如下所示:
index.html
js/
DragControls1.js
MTLLoader.js
OBJLoader.js
OrbitControls.js
three.js
assets/
ROAD2.mtl
ROAD2.obj
cottage_textures.png
road_texture.png
如有任何帮助,我们将不胜感激。
看来你的场景有大约7'000'000个顶点,这不是一点而是太多了。
在 Blender 中,尝试在几个较小的对象中进行导出。例如每一个单独的,街道,一棵树,其中一所房子等。
使用此方法,您可以接近场景的极限。
此外,尝试在代码中复制场景中的多个对象,而不是在 Blender 中进行!
(在实时 3D 应用程序中,您应该始终尝试使用最佳 3D 模型(几何、拓扑)而不是具有数百万个顶点的超大模型)