Глава за кольором і освітленню була б неповною без обговорення тіней. Додавання тіні до сцен може істотно підвищити їх реалізм і візуальну ефективність.
На рис 5.38 і 5.39 показані два освітлених куба. Хоча обидва варіанти пофарбовані, куб з тінню більш переконливий, ніж куб без неї.
Що таке тінь?
Концептуально малювання тіні є досить простим. Тінь виходить тоді, коли об'єкт закриває світло від джерела світла і не дає йому потрапити на інший об'єкт або поверхню, розташовану за об'єктом, що створює тінь. Область поверхні затемненого об'єкта, на яку наклався контур затеняющего об'єкта, здається темною. Тінь можна створити програмними засобами, спроектувавши вихідний об'єкт на площину поверхні, що містить об'єкт. Потім об'єкт малюється чорним (або іншим темним кольором), можливо, частково прозорим
Існує безліч методів і алгоритмів малювання тіней (в тому числі досить складні). Оскільки книга присвячена переважно програмного інтерфейсу OpenGL, ми сподіваємося, що, опанувавши програмним засобом, ви знайдете час вивчити літературу, запропоновану в додатку А, в тому числі що стосується математичного апарату, який є основою запрограмованого підходу. У главі 18, "Текстура глибини і тіні", розглянуто кілька засобів прямої підтримки створення тіней в OpenGL; в цьому розділі досить продемонструвати один з найпростіших методів, добре працює при накладенні тіней на плоску поверхню (таку, як земля). Процес подібного проектування ілюструється на рис. 5.40.
Для накладення проекції об'єкта на іншу поверхню використовуються нетривіальні дії з матрицями, яких ми торкнулися в попередньому розділі. Зараз ми спробуємо звести процес до максимально простим концепціям і діям.
Код накладення проекції
Отже, потрібно так "сплюснути" спроектовану матрицю спостереження моделі, щоб всі представлені в ній об'єкти малювалися в двомірному вигляді. Незалежно від орієнтації об'єкта він сплющується на площину, в якій лежить його тінь. Ще слід врахувати два параметри: відстань до джерела світла і напрям його випромінювання. Напрямок променів джерела світла визначає форму тіні і впливає на її розмір. Якщо ви коли-небудь бачили свою тінь раннім або пізнім ранком, то знаєте, наскільки довгою і викривленої вона може бути в залежності від положення Сонця.
Наведена в лістингу 5.8 функція gltMakeShadowMatrix з бібліотеки glTools приймає в якості аргументів три точки площини, на якій ви ж-гавкаєте бачити тінь (ці три точки не повинні лежати на одній прямій), положення джерела світла і покажчик на матрицю перетворення, яку будує ця функція . Ми не будемо заглиблюватися в нетрі лінійної алгебри, але вам слід знати, що ця функція виводить коефіцієнти рівняння площині, на якій буде розташовуватися тінь, і з їх допомогою, враховуючи положення джерела світла, будує матрицю перетворення. Якщо цю матрицю помножити на поточну матрицю спостереження моде- чи, все намальовані згодом об'єкти будуть спроектовані на цю площину.
приклад тіні
Щоб продемонструвати використання функції, наведеної в лістингу 5 8, підвісимо літак в повітрі над землею Джерело світла буде поміщений вище і трохи лівіше літака За допомогою клавіш зі стрілками літак можна обертати, при цьому на землі буде відповідним чином змінюватися його тінь Результат виконання відповідної програми SHADOW показаний на рис 5 41
У коді, наведеному в лістингу 5 9, показано, як була створена матриця проекції тіні Зверніть увагу, що ми створили матрицю один раз в функції SetupRC і записали її в глобальній змінно !!
У лістингу 5 10 наводиться код візуалізації системи "літачок з тінню" Спочатку ми малюємо землю Потім зображуємо літачок (як завжди), відновлюємо матрицю спостереження моделі і множимо її на матрицю тіні Так ми отримуємо шукану матрицю відкидання тіні. Після цього знову малюємо літак. (Ми модифікували код, і тепер він приймає мітку, що повідомляє функції DrawJet проводити кольорову або чорно-білу візуалізацію) Відновивши ще раз матрицю спостереження моделі, малюємо невелику жовту сферу, аппроксимирующую положе- ня джерела світла Зверніть увагу на те, що перед малюванням площині під літачком ми відключили перевірку глибини Даний прямокутник лежить в тій же площині, в якій намальована тінь, і ми повинні гарантувати, що тінь малюється. Ми ще не обговорювали, що станеться, якщо малювати два об'єкти або площині в одному місці. Втім, ми розглядали перевірку глибини як засіб, що дозволяє визначити порядок малювання об'єктів. Якщо два об'єкти займають одне і те ж місце, як правило показується тільки остання намальована фігура Іноді, втім, через слабке дозволу значень по глибині виникає повна плутанина - на екрані упереміш відображаються пікселі, що належать різним об'єктам (z-fighting)
Повертаючись до світу сфер
Останній приклад занадто великий, щоб повністю приводити його вихідний код У попередньому розділі ми розглядали програму SPHEREWORLD, що створює тривимірний населений світ з анімацією і рухом камери. У цьому розділі ми знову повертаємося до світу сфер і додаємо до "жителям" (тору і сферам) джерела світла і властивості матеріалів. Крім того, за допомогою технології накладення тіней на площину ми створюємо тіні на землі! Як уже зазначалося, час від часу ми будемо повертатися до цього прикладу, додаючи до нього вивчені функції OpenGL На рис. 5.42, наприклад, показаний результат виконання програми SPHEREWORLD з урахуванням матеріалу, вивченого в цьому розділі.