Сегодня мы продолжаем наши уроки WebGL для тех, кто изучает его и хочет расширить свои знания. В сегодняшнем уроке мы рассмотрим процесс загрузки готовых трехмерных объектов. Существует множество веб-сайтов, на которых вы можете загрузить эти модели, и, кроме того, если у вас есть редактор трехмерных объектов (например, 3D Max, Maya или даже Blender), вы можете создавать свои собственные модели. Существует также множество форматов файлов трехмерных объектов, таких как obj, collada (dae), obj, mtl, stl, vrml и так далее. Большинство из них могут быть загружены в ваши сцены three.js с помощью специальных загрузчиков. И сегодня мы рассмотрим, как загружать трехмерные модели, используя различные загрузчики.
Live Demo 1
Live Demo 2
Live Demo 3
Live Demo 4
OBJ
Чтобы загрузить объектные файлы (.obj), мы можем использовать OBJLoader.js. Использовать эту библиотеку довольно просто, но, прежде всего, нам нужно присоединить библиотеку (в разделе, где мы связываем все другие необходимые скрипты):
<script src="js/three.min.js"></script> <script src="js/OBJLoader.js"></script> <script src="js/THREEx.WindowResize.js"></script> <script src="js/OrbitControls.js"></script> <script src="js/stats.min.js"></script> <script src="js/script1.js"></script>
Теперь давайте подготовим общий скелет (из всех наших демонстраций):
var lesson6 = { scene: null, camera: null, renderer: null, container: null, controls: null, clock: null, stats: null, init: function() { // Initialization // create main scene this.scene = new THREE.Scene(); this.scene.fog = new THREE.FogExp2(0xcce0ff, 0.0003); var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; // prepare camera var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 2000; this.camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR); this.scene.add(this.camera); this.camera.position.set(0, 100, 300); this.camera.lookAt(new THREE.Vector3(0,0,0)); // prepare renderer this.renderer = new THREE.WebGLRenderer({ antialias:true }); this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); this.renderer.setClearColor(this.scene.fog.color); this.renderer.shadowMapEnabled = true; this.renderer.shadowMapSoft = true; // prepare container this.container = document.createElement('div'); document.body.appendChild(this.container); this.container.appendChild(this.renderer.domElement); // events THREEx.WindowResize(this.renderer, this.camera); // prepare controls (OrbitControls) this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement); this.controls.target = new THREE.Vector3(0, 0, 0); this.controls.maxDistance = 2000; // prepare clock this.clock = new THREE.Clock(); // prepare stats this.stats = new Stats(); this.stats.domElement.style.position = 'absolute'; this.stats.domElement.style.left = '50px'; this.stats.domElement.style.bottom = '50px'; this.stats.domElement.style.zIndex = 1; this.container.appendChild( this.stats.domElement ); // add spot light var spLight = new THREE.SpotLight(0xffffff, 1.75, 2000, Math.PI / 3); spLight.castShadow = true; spLight.position.set(-100, 300, -50); this.scene.add(spLight); // add simple ground var ground = new THREE.Mesh( new THREE.PlaneGeometry(200, 200, 10, 10), new THREE.MeshLambertMaterial({color:0x999999}) ); ground.receiveShadow = true; ground.position.set(0, 0, 0); ground.rotation.x = -Math.PI / 2; this.scene.add(ground); // load a model this.loadModel(); }, loadModel: function() { ...... } }; // Animate the scene function animate() { requestAnimationFrame(animate); render(); update(); } // Update controls and stats function update() { lesson6.controls.update(lesson6.clock.getDelta()); lesson6.stats.update(); } // Render the scene function render() { if (lesson6.renderer) { lesson6.renderer.render(lesson6.scene, lesson6.camera); } } // Initialize lesson on page load function initializeLesson() { lesson6.init(); animate(); } if (window.addEventListener) window.addEventListener('load', initializeLesson, false); else if (window.attachEvent) window.attachEvent('onload', initializeLesson); else window.onload = initializeLesson;
Этот код создает пустую сцену с камерой, статистикой управления рендерингом и освещением. Обратите внимание на пустую функцию «loadModel» — мы будем размещать здесь разные коды для загрузки моделей разных форматов. Наш первый формат — «obj». Посмотрите на следующую реализацию:
// prepare loader and load the model var oLoader = new THREE.OBJLoader(); oLoader.load('models/chair.obj', function(object, materials) { // var material = new THREE.MeshFaceMaterial(materials); var material2 = new THREE.MeshLambertMaterial({ color: 0xa65e00 }); object.traverse( function(child) { if (child instanceof THREE.Mesh) { // apply custom material child.material = material2; // enable casting shadows child.castShadow = true; child.receiveShadow = true; } }); object.position.x = 0; object.position.y = 0; object.position.z = 0; object.scale.set(1, 1, 1); lesson6.scene.add(object); });
Сначала мы создали новый экземпляр THREE.OBJLoader, а затем — загружаем файл модели ‘chair.obj’. Чтобы применить пользовательский материал, мы просмотрели его дочерние элементы и применили подготовленный материал2 (THREE.MeshLambertMaterial). Мы также применили отбрасывание и получение теней. В конце — мы устанавливаем положение объекта и устанавливаем значение масштаба.
MTL
Короче говоря, это дополнение к ранее описанному формату OBJ. Потому что MTL — это файл, который описывает материалы файла OBJ. Для загрузки файлов OBJ с поддержкой MTL мы можем использовать другой загрузчик: OBJMTLLoader. Чтобы его использовать, не забудьте включить необходимые библиотеки:
<script src="js/MTLLoader.js"></script> <script src="js/OBJMTLLoader.js"></script>
Теперь добавьте следующий код в нашу функцию loadModel:
// prepare loader and load the model var oLoader = new THREE.OBJMTLLoader(); oLoader.load('models/castle.obj', 'models/castle.mtl', function(object) { object.position.x = -200; object.position.y = 0; object.position.z = 100; object.scale.set(0.1, 0.1, 0.1); lesson6.scene.add(object); });
Как видите, функция загрузки принимает больше параметров — мы можем указать наш файл ‘mtl’ материалами. Этот метод позволяет нам загружать модель (obj) с текстурами!
DAE
Файлы Collada (dae) также популярны среди 3d дизайнеров. Этот формат также поддерживает текстуры. Чтобы загрузить этот формат, мы можем использовать другой загрузчик: ColladaLoader. Чтобы использовать его, не забудьте включить необходимые библиотеки:
<script src="js/ColladaLoader.js"></script>
Теперь добавьте следующий код в нашу функцию loadModel:
// prepare loader and load the model var oLoader = new THREE.ColladaLoader(); oLoader.load('models/mlc.dae', function(collada) { var object = collada.scene; var skin = collada.skins[0]; object.rotation.x = -Math.PI / 2; object.rotation.z = Math.PI / 2; object.position.x = -50; object.position.y = -100; object.position.z = 0; object.scale.set(0.025, 0.025, 0.025); object.updateMatrix(); lesson6.scene.add(object); });
JSON
Этот формат изначально поддерживается Three.js. Он также поддерживает пользовательские материалы (с текстурами), которые описаны в файле json. Чтобы загрузить этот формат, мы можем использовать другой загрузчик: JSONLoader:
// prepare loader and load the model var oLoader = new THREE.JSONLoader(); oLoader.load('models/palm.js', function(geometry, materials) { // get original materials var material = new THREE.MeshFaceMaterial(materials); var mesh = new THREE.Mesh(geometry, material); mesh.position.x = -50; mesh.position.y = -80; mesh.position.z = 0; mesh.scale.set(10, 10, 10); lesson6.scene.add(mesh); });
Live Demo 1
Live Demo 2
Live Demo 3
Live Demo 4