Статьи

Строим Землю с помощью WebGL и JavaScript

Из всех предоставленных нам HTML5 и связанных API-интерфейсов WebGL , пожалуй, самый интересный. С его помощью мы можем создавать потрясающие трехмерные среды прямо в наших браузерах, и в этой статье я расскажу вам, как именно это сделать.

В частности, мы собираемся создать модель планеты Земля, вокруг которой мы можем вращаться, как сумасшедший, и с помощью которой мы можем удивить наших коллег-разработчиков … ну, по крайней мере, немного.

Прежде чем мы начнем

Для этого урока мы будем использовать фантастический плагин three.js WebGL . Это немного похоже на jQuery для WebGL в том смысле, что в нем абстрагируется много уродства, присущего нативному API. Проще говоря, three.js делает нашу жизнь намного проще.

Мы можем включить его, как любой обычный скрипт в наш HTML-документ, например:

<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r63/three.min.js"></script> 

Здесь мы использовали CDN, но вы могли бы использовать локальную версию. Затем нам нужно убедиться, что WebGL есть что рендерить. Здесь у нас есть некоторая гибкость: мы можем использовать обычный div или canvas для рендеринга непосредственно в HTML, в противном случае мы можем создать и добавить холст позже, используя JavaScript. Мы пойдем с первым методом, чтобы сделать вещи немного проще:

 <body> <div id="container"></div> <script src="earth.js"></script> </body> 

После добавления ссылки на файл JavaScript наш HTML более или менее готов.

Настройка

Three.js сам по себе имеет тенденцию настраивать вещи так же, как настоящая 3D-программа для рабочего стола. У нас есть сцена, в которой вещи живут, камера для их просмотра, некоторое освещение, средство визуализации для рендеринга вещей и, конечно, сами 3D-объекты. Список может показаться немного сложным, но все они могут принимать форму переменных в нашем earth.js JavaScript earth.js .

 var scene, camera, light, renderer, earthObject; var WIDTH = window.innerWidth - 30, HEIGHT = window.innerHeight - 30; var angle = 45, aspect = WIDTH / HEIGHT, near = 0.1, far = 3000; 

Здесь определены некоторые другие переменные, а именно, константы WIDTH и HEIGHT, чтобы получить ширину и высоту для нашего рендерера, и группу переменных, которые мы будем использовать позже, чтобы установить положение нашей камеры.

Все это элементы, которые являются общими для почти каждого 3D-проекта, независимо от платформы или среды, поэтому привыкните к этим парням, слоняющимся поблизости. С Three.js мы можем реализовать их довольно легко, и мы увидим, как они вписываются в наш проект через мгновение.

Окружение

Для начала нам нужно взять наши новые переменные и настроить их так, чтобы наша модель Земля выглядела потрясающе.

Мы можем начать с настройки всего, что будет обрабатывать эту среду:

 var container = document.getElementById('container'); camera = new THREE.PerspectiveCamera(angle, aspect, near, far); camera.position.set(0, 0, 0); scene = new THREE.Scene(); light = new THREE.SpotLight(0xFFFFFF, 1, 0, Math.PI / 2, 1); light.position.set(4000, 4000, 1500); light.target.position.set (1000, 3800, 1000); 

Вот описание того, что происходит в коде выше:

  • Мы берем ссылку на наш контейнер в нашем HTML
  • Мы настроили нашу камеру, используя переменные, которые мы объявили ранее (для получения дополнительной информации о том, как камеры работают в 3D, проверьте это ).
  • Мы устанавливаем положение камеры с помощью position.set , который принимает аргумент для каждого измерения (x, y и z). Как вы уже догадались, мы будем использовать эту камеру, чтобы указывать на наши трехмерные объекты, которые в данном случае — наша Земля.
  • Далее мы настраиваем наш свет. Без этого у нас был бы только черный экран при рендеринге всего, поэтому нам нужно довольно тщательно его настроить. SpotLight объект Three.js принимает более или менее те же аргументы, что и наша камера, но добавляет цвет в шестнадцатеричном значении в качестве первого аргумента, за которым следуют остальные.
  • Наконец, мы настроили наш рендер. Еще одна важная часть головоломки, рендерер фактически отображает созданную нами сцену на экране; опять же, без этого мы не увидели бы ничего, кроме тьмы космоса. Мы даем ему сглаживание (для некоторых поверхностей с гладкой задницей) и добавляем его как элемент DOM в наш оригинальный контейнер.

Теперь нам нужно начать строить саму Землю, придерживаясь сетки:

 var earthGeo = new THREE.SphereGeometry (30, 40, 400), earthMat = new THREE.MeshPhongMaterial(); var earthMesh = new THREE.Mesh(earthGeo, earthMat); earthMesh.position.set(-100, 0, 0); earthMesh.rotation.y=5; scene.add(earthMesh); 

Здесь мы создаем сетку, которая похожа на объект, который мы оденем, чтобы он выглядел как Земля, и дадим ему некоторую геометрию и материал, или текстуру, чтобы покрыть ее. Мы также правильно позиционируем его и добавляем в нашу сцену, как и в случае с другими объектами.

Вы можете увидеть пример нашей настройки ниже. Здесь есть некоторый дополнительный код для обработки рендеринга (к которому мы скоро вернемся), но пока он выглядит хорошо!

Голубая планета

Теперь самое интересное — снимать кожу с этого парня. Сначала мы будем использовать диффузную карту, которая придаст нам вид Земли, и которую вы можете добавить следующим образом:

 // diffuse map earthMat.map = THREE.ImageUtils.loadTexture('images/earthmap1k.jpg'); 

Если вам нужна хорошая текстура для использования здесь, вы можете попробовать ее или найти в Google приличную диффузную карту Земли. Все с хорошим разрешением хорошо.

Теперь это выглядит не так уж плохо, но мы можем сделать это лучше, введя небольшую топографию здесь. На Земле есть несколько довольно высоких гор, и чтобы убедиться, что остальная часть Солнечной системы знает это, нам нужно использовать карту рельефа . В 3D карты рельефа — это черно-белые изображения с интенсивностью белого, указывающей высоту «рельефа» (или, в нашем случае, наших гор).

 // bump map earthMat.bumpMap = THREE.ImageUtils.loadTexture('images/elev_bump_16ka.jpg'); earthMat.bumpScale = 8; 

С этим мы более или менее там. Опять же, поиск в «Google Bump Map» даст вам множество вариантов, но если вы не хотите охотиться, вы можете найти хороший вариант здесь . Если мы запустим приведенный выше код (с кодом рендеринга ранее), мы получим это:

Покрутите!

Все, что осталось сейчас, это дать нашей Земле некоторое вращение. Для этого нам понадобятся две новые функции, которые мы можем вызвать render() и animate() .

 function animate() { requestAnimationFrame(animate); render(); } 

Наша функция animate() не слишком сложна. Он вызывает себя постоянно, используя requestAnimationFrame() и каждый раз, когда это происходит, он вызывает нашу функцию render() . Давайте перейдем к функции render() следующим образом:

 function render() { var clock = new THREE.Clock(), delta = clock.getDelta(); earthMesh.rotation.y += rotationSpeed * delta; renderer.render(scene, camera); } 

Вот где все происходит. Каждый раз, когда getDelta() метод render() , он немного вращает нашу Землю по оси Y (здесь вы можете выбрать любую величину для поворота; в этом случае мы используем встроенные часы с getDelta() , но ты не обязан). Затем он очищает наш рендер, необходимый шаг, чтобы избежать уродливости рендера, и рендерит нашу сцену (со всем в ней) и нашу камеру.

До конца

Конечно, есть некоторые хитрости, которые мы можем добавить, чтобы сделать нашу Землю еще лучше. OrbitControls.js — это сценарий, который даст некоторую управляемую мышью способность вращения нашей Земли, и добавление поля звезд на нашем фоне или облаков в нашей стратосфере также не слишком сложно. Если вы действительно любите наказания, вы даже можете добавить атмосферу на свою планету, используя шейдеры WebGL.

Вы можете увидеть пример с кодом некоторых из этих дополнений в финальной демонстрации CodePen:

Обязательно кликайте по странице и прокручивайте колесико мыши, чтобы увидеть специальные эффекты (удерживайте нажатой клавишу «Shift», чтобы заставить колесико мыши работать на этой странице, или используйте полную демонстрационную страницу ).

Вывод

WebGL и three.js могут быть сложными, потому что они требуют от нас время от времени думать немного как 3D-художник, используя такие вещи, как сцены, рендеры и камеры, чтобы выполнить свою работу.

Но результат выглядит впечатляюще и, если вы преданны, может привести к некоторым интересным возможностям с 3D в браузере. Оставайтесь с этим, и вы сможете осуществить некоторые удивительные подвиги в кратчайшие сроки.