WebGL тур по Сонячній системі: Марс, частина 2

28

Від автора: у першій статті я показав вам основи threeJS, зокрема налаштування камери і інтеграцію WebGL сцени з контентом на веб-сторінці. У цьому уроці ми спозиционируем камеру в 3D просторі, направимо її на об’єкт, а сам об’єкт подсветим. Але спершу необхідно зрозуміти природу 3D простору. Ця стаття є прямим продовженням попередньої статті. Далі вам знадобляться знання і код з попередньої статті.

Навігація в просторі

Зі шкільного курсу ви повинні знати координатну площину Х і Х У. по горизонталі, по вертикалі. За допомогою точок на осях ви можете задати координати будь-якого елементу в позитивному 2D просторі. Для від’ємних значень необхідно розширити осі вліво і вниз:

WebGL тур по солнечной системе: Марс

Точка 0 0 – перетин осей або точка початку координат.

Щоб розташувати елемент в 3D просторі необхідно додати третю вісь, перпендикулярну двом іншим. Третя вісь йде в бік глядача і від нього. Вісь Z можна візуалізувати за допомогою невеликого нахилу:

WebGL тур по солнечной системе: Марс

Зверніть увагу на те, що позитивна сторона осі Z йде від нас, а від’ємна до нас.

Тепер положення будь-якої точки в просторі можна визначити за допомогою перетину трьох значень: Х, У і Z:

Подання чисел не має значення: це можуть бути міліметри, фути або навіть світлові роки. Важливо як вони ставляться один до одного: 2х – подвійне відстань від 1х.

Камера, створена в попередньому уроці, за замовчуванням розташована в центрі координат. Необхідно зрушити камеру з центру:

camera.position.set(1380, 0, 0);

У сцені міститься той світ, який ми створимо всі об’єкти і елементи. Створюється сцена наступним рядком коду:

scene = new THREE.Scene();

Сцена автоматично поміщається в точку 0 0 0. В цій же точці буде розташовуватися наш центральний об’єкт – Марс. Наша камера повинна дивитися на цю точку:

camera.lookAt(scene.position);

Для позиціонування камери можна використовувати ті ж значення Х або Z, будь вони позитивні або негативні. Ефект буде той же, так як камера буде дивитися в центральну точку.

Хай буде світло

Зараз наша сцена нескінченна і чорна: будь-який об’єкт в ній буде не видно, так як немає джерела світла. Давайте це виправимо:

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:

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);

Цей код, розміщений на веб-сторінку з кодом вище і кодом з першої частини, покаже вам картинку, яку можна подивитися на початку статті. Тут багато чого можна додати, а код потрібно пояснювати, що я зроблю в третій частині.