← к содержанию

Урок 8. Материалы, текстуры и прозрачность

Предыдущие два урока касались библиотеки DDD лишь косвенно, тут же мы снова к ней полноценно возвращаемся. Ровно-серая модель обезьянки конечно, хорошо показывает её форму, но нам, естественно, хотелось бы её как-нибудь раскрасить. Класс Объект, который мы создавали ближе к концу 5-го урока, является небольшим контейнером, содержащим меш (его мы передаём одним из аргументов в конструкторе) и материал этого объекта (как несложно догадаться, его класс называется Материал). Материал по-молчанию (непрозрачный белого цвета) создаётся сразу вместе с экземпляром класса Объект. В любой момент мы можем у него запросить доступ к этому материалу и изменить его так, как нам требуется.

  1. Давайте добавим в нашу сцену новый объект. Откройте модуль scena.d и допишите в конце следующее:

    auto меш2 = менеджер.получить_меш("Цилиндр"); 
    auto место2 = менеджер.начальное_место.создать_ребёнка("Место объекта2", 
                                                   Вектор3(0, 0, 1),
                                                   Кватернион.НОЛЬ);
    if (!(меш2 is null)) {
        auto объект2 = new Объект("объект2", меш2);
        место1.присоединить_объект(объект2);
    }

Всё тоже самое мы проделывали в 5 уроке, чтобы вывести на экран Сюзанну, так что эти строки не должны вызывать вопросов.

  1. Если сейчас запустить наше приложение, то мы увидим, что цилиндр полностью закрыл вид на обезьянку. Теперь изменим материал этого цилиндра (вставьте эту строку внутри if-условия):

        объект2.получить_материал.задать_диффузный_цвет([0.8, 0.3, 0.3, 0.3]); 

Т.к. альфу-компоненту этого цвета мы присвоили равной 0.3, то цилиндр должен стать прозрачным. Возможно, вам повезло, и обезьянку через розовый якобы прозрачный цилиндр видно (в случае, если обезьянка была отрисована раньше цилиндра), но это будет происходить далеко не всегда. Вот мой скриншот:


  1. Работа с прозрачностью в OpenGL – довольно болезненная тема, и в простых движках она обычно не решается идеально. В DDD выбран такой подход: сначала отрисовываются все непрозрачные объекты, затем прозрачные. В идеале при отрисовке прозрачных объектов тоже требуется соблюдать очерёдность (разделить их на отдельные треугольники и выводить начиная от дальних к ближним), но это не было реализовано. Поэтому в своих сценах старайтесь не злоупотреблять прозрачностью и не допускать ситуаций, когда прозрачные объекты на экране накладываются друг на друга. Итак, в нашем случае, нам надо определить для DDD материал цилиндра как «имеющий прозрачность», тогда он будет визуализироваться после обезьянки, и сцена будет отрисована правильно. Вставьте эту строку сразу после строки добавления материала:

объект2.получить_материал.задать_присутствие_прозрачности(true);


Теперь сцена не должна зависеть от случайностей порядка визуализации:

  1. Добавим нашему цилиндру дополнительную бликовую составляющую цвета:

        объект2.получить_материал.задать_бликовый_цвет([0.9, 0.9, 0.9, 1]);
        объект2.получить_материал.задать_степень_блика(20);

У меня получилось такое изображение:


  1. Теперь раскрасим нашу Сюзанну. Добавьте внутрь if-условия, относящегося к переменной меш1 такую строку:

объект1.получить_материал.задать_диффузную_текстуру(менеджер.получить_текстуру("Сюзанна"));

К сожалению, отображение текстуры сквозь прозрачность (в данном случае на встроенном Intel-видео) тоже далеко от идеала:


  1. Уберём теперь цилиндр и посмотрим незамутнённым взглядом на нашу текстурированную обезьянку. Для этого закомментируйте строку, в которой объект с мешем цилиндра (объект2) присоединяется к своему Месту:

        //место2.присоединить_объект(объект2);

Вот результат:


Таким образом, вы теперь можете накладывать материалы и текстуры на свои модели. К сожалению, некоторые иллюстрации к этому уроку показывают, что с визуализацией прозрачности в DDD далеко не всё в порядке, но в небольших количествах её вполне возможно применять.