Новости

3D об'єкти в браузері на HTML5

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

Вступ

Одного разу до нас звернувся замовник, який займається продажем мобільних телефонів через інтернет. Для свого магазину він придумав одну цікаву «фішку». Ідея полягала в тому, щоб дозволити користувачеві бачити товар «на повен зріст», щоб легко можна було оцінити габарити товару. Користувач повинен мати можливість повертати пристрій будь-якою стороною і її розміри будуть в точності збігатися з розміром пристрою, якщо його прикласти до екрану. Як визначити розмір пікселя в міліметрах для нас було не настільки цікаво (і ця стаття не про це), набагато цікавішою виявилася можливість плавно повертати пристрій на екрані.

Магазин повинен працювати на всіх сучасних платформах, включаючи смартфони і пристрої від Apple, тому про використання flash або будь-яких інших доповнень до браузерів мови не було, все повинно працювати на чистому HTML5. Перш ніж описувати тернистий шлях від ідеї до реалізації проекту, наведу посилання і пару картинок - результат скрипта, що малює тривимірний об'єкт на HTML5 canvas.

Перш ніж описувати тернистий шлях від ідеї до реалізації проекту, наведу посилання і пару картинок - результат скрипта, що малює тривимірний об'єкт на HTML5 canvas

малюємо об'єкт

Як відомо, полюбився багатьом canvas до сих пір не підтримує 3D. Цей сумний факт говорить нам забути про наявність чарівної функції «намалювати об'єкт» і про підтримку будь-яких апаратних прискорень 3D графіки.

До цього проекту у нас вже був досвід розробки ігор на canvas і багато моментів, що стосуються роботи з динамічної графікою в javascript були добре відомі. Зокрема, була розроблена невелика бібліотека для підтримки циклу відтворення, визначення сцени і розміщення об'єктів для відтворення. Тепер нам потрібно було створити 3D об'єкт, здатний малювати себе під різними кутами.

Тепер нам потрібно було створити 3D об'єкт, здатний малювати себе під різними кутами

Тут нам і знадобилися знання комп'ютерною графікою, отримані під час навчання в університеті (спасибі, дебела В.А.). Ми використовували матриці 4х4 для завдання поворотів і зсувів, перспективну проекцію і визначення яскравості межі на основі кута між вектором нормалі і напрямком до джерела світла. Власне, це все, що було потрібно. Легко і просто, на javascript займає пару сотень рядків і набагато швидше, ніж розбиратися в уже винайдених велосипедах. Після отримання проекції і яскравості межі залишається тільки намалювати і залити полігон стандартними засобами canvas.

Виходячи з поставлених завдань проекту, необхідно мати можливість контролювати розмір пристрою на проекції. Оскільки проекція перспективна, то було вирішено зрушувати об'єкт по осі Z так, щоб його найближча точка була на строго заданій відстані від камери. Тепер якщо для об'єкта задана ширина 200 пікселів, то при погляді спереду на об'єкт розмір проекції буде рівно 200 пікселів в ширину.

Дана реалізація буде працювати у всіх браузерах, що підтримують canvas. Для IE версії нижче 9 ми використовували excanvas, швидкість роботи значно повільніше, що в Chrome або FF, але воно працює!

накладаємо текстури

Побачивши результат нашої роботи, замовник захотів спробувати накладати текстуру на отриманий об'єкт. Ще раз нагадаю, canvas не підтримує 3D перетворень, що стосується і картинок, тому ця ідея здавалася утопічною. Звичайно, можна було ще трохи згадати курс комп'ютерної графіки і реалізувати перетворення зображень прямо на javascript, проте ця процедура була б занадто повільної, щоб показувати об'єкт в реальному часі.

Довгі пошуки відповідного рішення увінчалися успіхом. за засланні був виявлений цікавий підхід до накладання текстур. Пропонується повністю відмовитися від тривимірних перетворень текстури, а використовувати замість них звичайні двовимірні аффінниє перетворення, які доступні для елемента HTML5 canvas.

Щоб це використовувати, кожна грань розбивається на трикутники, для кожної вершини трикутника визначаються відповідні координати текстури. Далі коефіцієнти матриці двовимірного перетворення підбираються таким чином, щоб перевести 3 точки текстури до відповідних 3 точки межі. Таке перетворення є завжди і воно однозначно, якщо тільки 3 точки не лежать в одній прямий. Але в цьому випадку накладати текстуру і не треба.

Зрозуміло, що такий трюк не надто точно відтворює тривимірні перетворення, при збільшенні числа трикутників і зменшенні розміру кожного з них якість картинки поліпшується, але з ним зменшується і швидкість накладення текстури на грань. На картинках нижче представлений результат накладення під кутом при розподілі передній грані на 2, 4, 16, 64 трикутника відповідно.

На картинках нижче представлений результат накладення під кутом при розподілі передній грані на 2, 4, 16, 64 трикутника відповідно

Як бачимо, варіант з розподілом межі на 64 трикутника цілком пристойно виглядає навіть для досить великих граней і складних текстур.

Наведені вище картинки отримані в браузері Chrome, при спробі відкрити в FF нас чекала ложка дьогтю. Виявляється, там видно лінії між трикутниками. Для кого-то це не критично, а ось наш замовник був засмучений, та настільки, що довелося шукати вихід.

Перша проста ідея була використовувати фонову заливку для межі. На прикладі нашого телефону така заливка добре працює на бічних і задньої сторони телефону. На лицьовій стороні неможливо підібрати колір, щоб діагональну лінію в 1px було не видно.

Довелося думати ще. В результаті було вирішено заливати текстурою НЕ вихідні трикутники, а трикутники трохи вище і ширше. На скільки вище? Відповідь на це питання виявилося на стільки не очевидний, що був введений додатковий параметр. Справа в тому, що занадто велика перетин трикутників погіршує якість накладення, стають видні ступінчасті переходи, а надто маленьке перетин не приховує лінії при деяких ракурсах.

В результаті, остання версія обзавелася одразу двома додатковими параметрами (їх можна міняти в верхній частині вікна). Перший відповідає за те, як сильно дробити межі на трикутники. Другий вказує кількість пікселів, на яке буде збільшуватися кожного трикутник при заливці. Для FF в нашому прикладі оптимальний варіант 1, для Chrome краще, звичайно ж, поставити 0 і не використовувати цю фічу.

На жаль, з появою текстурирования довелося також пожертвувати сумісністю з IE <9, тобто excanvas не підтримує кліппірованіе і не виходить вивести текстуру в обмежену область.

Плани на майбутнє

У даній реалізації у нас малюється проста геометрична фігура в 3D на HTML5 canvas, однак нічого не заважає малювати більш складні об'єкти (поточний движок вже це дозволяє). У нас в планах створити повноцінну бібліотеку, яку можна було б застосовувати в інтернет магазинах для демонстрації товару.

Також є перспективи розвитку ігрового спрямування нашої компанії, можливість створювати прості тривимірні ігри, які легко інтегрувати в соціальні мережі і різні мобільні платформи.

Зрозуміло, що можливості браузера обмежені, і з ростом кількості об'єктів і граней на них ми дуже швидко будемо впиратися в продуктивність, а гальмуючий браузер і сіпаються анімація не додає популярності додатком. Попереду нас чекає ще багато оптимізацій і вдосконалень.

Якщо Вас зацікавили результати, описані в даній статті, якщо у Вас є ідеї і пропозиції щодо використання даної технології, не соромтеся писати нам.

Даний проект став викликом для нашої команди, це один з небагатьох проектів, радість від реалізації якого перевершує отриманий прибуток. А отримані знання і розробки ми обов'язково будемо застосовувати в наших подальших проектах.

На скільки вище?

Уважаемые партнеры, если Вас заинтересовала наша продукция, мы готовы с Вами сотрудничать. Вам необходимо заполнить эту форму и отправить нам. Наши менеджеры в оперативном режиме обработают Вашу заявку, свяжутся с Вами и ответят на все интересующее Вас вопросы.

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: