Особливості моделювання світла: Апроксимації Фонга (Phong Shading)

  1. Розглянемо докладніше
  2. Швидке затінення по Фонгу (Fast Phong shading)
  3. Карта тіні для Phong shading
  4. Особливості швидкого затінення по Фонгу
  5. [Читайте на цю тему: затінення Гуро ]

Апроксимації Фонга, або затінення по Фонгу (Phong shading), носять назву по імені свого винахідника - Ву Тонг Фонга (Wu Tong Phong). Цей метод дає більш точні результати при затіненні полігонів в порівнянні з затінюванням Гуро, розглянутим вище. Суть цих апроксимацій полягає у визначенні нормалі до поверхні в кожній вершині полігона і подальшої інтерполяції вектора по всьому полігону поверхні. Далі для кожного пікселя необхідно обчислити значення яскравості, ґрунтуючись на значеннях вектора нормалі.

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

Затінення по Фонгу - це досить популярний метод для реалізації затінення, особливо в програмах, які застосовують non-realtime rendering, наприклад, 3D Studio. Однак, незважаючи на те, що цей метод значно точніше затінення Гуро, він як і раніше не є фізично точним.

Затінення по Фонгу - це логічна реалізація фізичної моделі світу, яку ми розглянули раніше. І якщо ви недостатньо уважно поставилися до неї, поверніться ще раз, т.к без неї деякі аспекти подальшого викладу будуть здаватися незрозумілими. Кожен одиночний піксель має своє власне значення яскравості, ретельно прораховане при використанні інтерпольованого вектора нормалі.

Прорахунок затінення по Фонгу включає в себе:

  • обчислення двох квадратних коренів
  • реалізацію двох операцій ділення
  • чотирьох операцій множення

і це не рахуючи значної кількості операцій додавання на кожен піксель !!! Більш того, вони не є цілочисельними. Порівняйте це з єдиною операцією додавання на піксель при затіненні Гуро і ви зрозумієте, чому цей метод настільки повільний.

Розглянемо докладніше

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

У реальності далеко не всі поверхні мають такі ідеальними властивостями. Найбільш придатними є поверхні, що мають мікроскопічні шорсткості, наприклад, добре відшліфоване дерево. Більшість поверхонь також володіють деякою мірою спектрального відображення. Затінення по Фонгу не поділяє їх між собою. Воно також не враховує той факт, що яскравість обернено пропорційна квадрату відстані від джерела світла.
У реальності далеко не всі поверхні мають такі ідеальними властивостями

Отже, ми маємо полігон. У кожній вершині полігона ми маємо вектор нормалі до поверхні, частиною якої полігон є (v1, v2, v3). Ці вектори інтерполювати по всій площі полігону, подібно до того, як це робилося для затінення Гуро. У затіненні Гуро, однак, ми мали справу тільки з одним значенням -shade (це скалярна величина). Тут же ми оперуємо вектором з трьома значеннями Vx, Vy і Vz (три значення, три координати - визначають положення вектора в просторі).

Отже, візьмемо піксель на цьому полігоні, червона точка (див. Малюнок). Вектор нормалі, що відповідає цьому пікселю на поверхні - n. Світло падає на полігон уздовж вектора l. Кількість світла, відбитого від даного пікселя, є функцією, званої в англійському dot product.

Dot product - це скалярний добуток векторів, що дає в результаті число, що визначає довжину (величину) результуючого вектора. Якщо ми хочемо отримати в якості результату теж вектор, то це вже буде cross product. Але тут ми його не розглядаємо. Скалярний добуток вектора n (x, y, z) і вектора l (x, y, z) може проводитися за будь-який з двох формул:

  • n * l = nxlx + nyly + nzlz (1)
  • n * l = | n | * | l | cosq (2), де q (тетта) - кут між векторами.

Нам більше підходить другий варіант, т.к він оперує з довжинами (величинами) векторів і кутом між ними. Величина нормалі до поверхні дорівнює 1. А величина вектора падаючого світла приводиться до 1 і буде мати значення від 0 до 1. 1 найяскравіший світло.

Все просто.

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

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

Швидке затінення по Фонгу (Fast Phong shading)

Базовий алгоритм затінення по Фонгу вимагає великих обчислювальних ресурсів і тому дуже повільний. Однак ефект від застосування цього затінення дуже привабливий, тому сам алгоритм неодноразово піддавався різним оптимізаціям. Оптимізувати можна тільки базовий, головний алгоритм, і що не скорочуй кількість операцій з фіксованою точкою або скільки не створювати заздалегідь прорахованих таблиць, все одно в додатках реального часу апроксимації по Фонгу є істотним "гальмом".

Один з варіантів спрощення, активно обговорюваний в колах тривимірної графіки, - це спосіб, що полягає в інтерполяції кута між нормаллю і напрямом світла замість базової інтерполяції самого вектора нормалі по всьому полігону. Це відмінна ідея з одним лише мінусом - фактично, вона не дає нічого. По суті, це відтворення затінення Гуро (тому що інтерполюється скалярна величина), і тому і користі від нього мало. (Можливо, цей факт можна оскаржити і потім довго дискутувати, але це думка самого автора статті - Прим. Перекладача)

Однак цей спосіб дав поштовх для розвитку думки в правильному напрямку, і було запропоновано інтерполювати не один лише кут, а відразу два. Це буде дуже нагадувати інтерполяцію вектора. Далі, замість того різання цілого ряду важких обчислень з цими двома кутами, можна розглянути ці кути як відповідність координатам на заздалегідь прорахованою карті (текстурі) затінення.

Це значно спростить завдання прорахунку в реальному часі. І ми можемо забути про незграбному затенении Гуро і насолоджуватися всіма перевагами затінення по Фонгу на нашому звичайному домашньому комп'ютері. Затінення по Фонгу тепер ставати звичайним, лінійним текстуруванням, яке завдяки Майклу Абраш (Michael Abrash) може реалізовуватися дуже і дуже швидко.

Карта тіні для Phong shading

Карта для затінення по Фонгу (Phong Map) являє собою заздалегідь прорахований набір яркостей для всіх можливих нормалей.

Як не дивно, карта тіні - це дуже нескладна текстура. Зручно використовувати текстуру розмірністю 256х256 пікселів. Ось вона. Ви можете її просто взяти і використовувати. Більш того, ви запросто зможете створити свою власну. Наприклад, ви можете застосувати текстуру з яскравими кільцями для додання зовнішнього вигляду хромованого об'єкта.
Як не дивно, карта тіні - це дуже нескладна текстура

Отже, для кожної з вершин підготовленого до візуалізації полігону ви повинні прорахувати координати відповідної позиції на карті затінення. Дивіться на рисунок праворуч. Для цього полігону визначимо два вектора, що знаходяться під прямим кутом один до одного і до нормалі полігону. Назвемо їх V і H. Ці два вектора будуть визначати координати u, v карти затінення (текстури). Згадуємо, що у текстур в 3х мірної графіку своя система координат- (u, v).
Отже, для кожної з вершин підготовленого до візуалізації полігону ви повинні прорахувати координати відповідної позиції на карті затінення

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

Наша мета - отримати координати u і v виходячи з значень V, H, L.

Алгоритм дуже простий. Якщо карта затінення буде розмірністю 256х256 з точним центром, то:

  • u = (V. L) * 128 + 127
  • v = (H. L) * 128 + 127

Прорахуйте це для кожної вершини, а потім "натягніть" карту затінення на полігон - ви отримаєте плавно затінений полігон відповідно до зовнішнього освітлення.

Можна ще більше спростити і прискорити процес обчислень, якщо допустити, що джерело світла знаходиться в тій же точці, де і камера. У цьому випадку ми можемо ігнорувати самі вектори V і H, а замість них використовувати координати x і y, компоненти вектора нормалі. Помножимо на 128 і додамо 127. Все!

Особливості швидкого затінення по Фонгу

Візуальне якість накладення ефекту Phong Shading буде залежати від розмірності текстури (карти) затінення. Це означає, що при обмеженій розмірності відблиски на полігоні можуть бути помітно пікселізірованни. Якщо об'єкт рухається, то цього можна і не помітити зовсім. Якщо ви застосуєте рельєфне текстурування (bump mapping), то ефект буде ледь помітним.

Недоліком даного методу буде також прояв ефекту паразитного джерела світла. Перший буде там, де і повинен бути, а от другий з'явиться з протилежного боку об'єкта.

[Читайте на цю тему: затінення Гуро ]

[Читайте на цю тему: рельєфне тестурірваніе ]


Матеріал для даної статті люб'язно надав Hugo Elias


Мерлин (Merlin)

Сериал Мерлин (Merlin) — это экранизация захватывающей книги о Короле Артуре, по легенде живший во времена магии и волшебства. Телеканал BBC постарался максимально передать атмосферу тех времён — идеально подобранные актеры, десятки сценаристов, работающих над адаптацией истории к кинематографу, потрясающие декорации и дорогостоящие костюмы и платья — всё это увлекает зрителя и позволяет прочувствовать историю былых времён..

Это лишь начало приключений юного Мерлина и принца Артура, чьи судьбы с этого момента будут крепко связаны. Впоследствии один из них станет самым могущественным и известным чародеем, другой — доблестным рыцарем и великим королем Альбиона…

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