От автора: в первой статье я показал вам основы threeJS, в частности настройку камеры и интеграцию WebGL сцены с контентом на веб-странице. В этом уроке мы спозиционируем камеру в 3D пространстве, направим ее на объект, а сам объект подсветим. Но прежде необходимо понять природу 3D пространства. Эта статья является прямым продолжением предыдущей статьи. Далее вам понадобятся знания и код из предыдущей статьи.
Навигация в пространстве
Из школьного курса вы должны знать координатную плоскость Х и У. Х по горизонтали, У по вертикали. С помощью точек на осях вы можете задать координаты любого элемента в положительном 2D пространстве. Для отрицательных значений необходимо расширить оси влево и вниз:
Точка 0 0 – пересечение осей или точка начала координат.
Чтобы расположить элемент в 3D пространстве необходимо добавить третью ось, перпендикулярную двум другим. Третья ось идет в сторону зрителя и от него. Ось Z можно визуализировать с помощью небольшого наклона:
Обратите внимание на то, что положительная сторона оси Z идет от нас, а отрицательная к нам.
Теперь положение любой точки в пространстве можно определить с помощью пересечения трех значений: Х, У и Z:
Представление чисел не имеет значения: это могут быть миллиметры, футы или даже световые годы. Важно как они относятся друг к другу: 2х – двойное расстояние от 1х.
Камера, созданная в предыдущем уроке, по умолчанию расположена в центре координат. Необходимо сдвинуть камеру из центра:
1 |
camera.position.set(1380, 0, 0); |
В сцене содержится тот мир, который мы создадим, все объекты и элементы. Создается сцена следующей строкой кода:
1 |
scene = new THREE.Scene(); |
Сцена автоматически помещается в точку 0 0 0. В этой же точке будет располагаться наш центральный объект – Марс. Наша камера должна смотреть на эту точку:
1 |
camera.lookAt(scene.position); |
Для позиционирования камеры можно использовать те же значения Х или Z, будь они положительные или отрицательные. Эффект будет тот же, так как камера будет смотреть в центральную точку.
Да будет свет
Сейчас наша сцена бесконечна и черна: любой объект в ней будет не виден, так как нет источника света. Давайте это исправим:
1 2 3 |
light = new THREE.PointLight(0xFFFFFF, 2, 5000); light.position.set(2000, 2000, 1500); scene.add(light); |
На данном этапе вы пока что ничего не увидите. Не только потому, что источник света по умолчанию невидим, но мы даже еще не отрисовали сцену.
threeJS поддерживает шесть разных типов света:
PointLight. Свет с позицией, который равномерно излучается во всех направлениях. Точечный свет идеально подходит для симуляции света от звезд или ламп.
DirectionalLight. Свет с направлением, но без «луча» (в отличие от варианта ниже). Подходит для имитации солнечного света с поверхности Земли.
SpotLight. Свет, направленный в определенном направлении с широким «лучом». Похож на театральный прожектор, светящий на сцену.
RectAreaLight. Свет из прямоугольной плоскости: подходит для симуляции света через окно или из люминесцентной панели.
AmbientLight. «Общий» свет со всех направлений. Похож на очень тусклый свет в безлунную ночь. Имеет эффект заполнения сцены оттенком: чем ярче окружающий свет, тем более «вымытой» будет сцена.
HemisphereLight. В 3D приложениях иногда называется skylight. Симулирует свет сверху (небо) и снизу (любые отражения или свет из-под земли). Как окружающий свет, разбитый на две половины.
В будущих статьях я подробно остановлюсь на каждом источнике света. А сейчас рассмотрим точечный свет. Он принимает три аргумента: цвет (hex значение с приставкой 0х), интенсивность и точка падения света.
В реальном мире свет подчиняется закону обратных квадратов: интенсивность света угасает пропорционально обратному квадрату расстояния от источника. Закон срабатывает сразу же, как только фотон вылетел из источника света. В 3D с этим часто возникают проблемы: очень просто создать свет достаточной, по вашему мнению, мощности только, чтобы тот быстро затух и не осветил сцену. Поэтому в 3D у света есть параметр дистанция «спада»: до определенной точки свет не теряет свою интенсивность и только после нее начинает постепенно угасать.
Точно также и с тенями, отбрасываемыми в реальном мире. В 3D с ними тоже возникают проблемы: поэтому тени необязательны. Для точечного источника света тени заданы по умолчанию.
Проще самому поэкспериментировать со значением интенсивности, чтобы увидеть эффект: вы поймете, что слишком высокая интенсивность «гасит» цвета в сцене, как слишком яркая вспышка, расположенная слишком близко к объекту на фотографии.
Безвидна и пуста
Было бы жалко проделать все это и не увидеть результата. Далее я пробегусь по упрощенной версии оставшегося кода. Весь JS код кроме подключения библиотеки threeJS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000), light = new THREE.PointLight(0xFFFFFF, 2, 5000), scene = new THREE.Scene(); light.position.set(2000, 2000, 1500); camera.position.set(1500, 0, 0); camera.lookAt(scene.position); scene.add(light); let marsGeo = new THREE.SphereGeometry (500, 32, 32), marsMaterial = new THREE.MeshPhongMaterial( { color: 0xff6600 } ), marsMesh = new THREE.Mesh(marsGeo, marsMaterial); scene.add(marsMesh); let renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight) marsloc.appendChild(renderer.domElement); renderer.render(scene, camera); |
Этот код, помещенный на веб-страницу с кодом выше и кодом из первой части, покажет вам картинку, которую можно посмотреть в начале статьи. Тут много чего можно добавить, а код нужно объяснять, что я сделаю в третьей части.
Источник: //thenewcode.com/
Редакция: Команда webformyself.