Импорт файла Blender obj с помощью mtl в ThreeJS - PullRequest
0 голосов
/ 18 января 2020

Я пытаюсь импортировать объектный файл, который я создал в Blender, в Three JS. Мой проект Blender выглядит следующим образом: image

Я экспортировал его в сигнал, для импорта в Three JS Я использовал 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-сервер для загрузки 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

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 18 января 2020

Кажется, что ваша сцена имеет около 7'000'000 вершин, что не мало, но слишком много.
В Blender попытайтесь выполнить экспорт в несколько более мелких объектов. Например, каждый отдельно, улица, дерево, один из домов и т. Д. c. С помощью этого метода вы можете приблизиться к пределу вашей сцены.

Также попробуйте дублировать несколько объектов в вашей сцене в коде вместо того, чтобы делать это в Blender!

(В 3D-приложениях реального времени Вы всегда должны стараться использовать оптимальные 3D-модели (геометрия, топология) и не слишком большие модели с несколькими миллионами вершин)

...