Темы проектов
Этот раздел будет постепенно пополняться.
Во всех проектах, если не сказано иного, требуется реализовать какую-либо схему управления наблюдателем: либо хождение по поверхности, либо «свободную камеру», либо камеру с фиксированной точкой фокуса.
Фрактальная мельница
Пирамида. Из верхушки перпендикулярно высоте пирамиды идёт ось. На оси — вращающиеся лопасти (в количестве не менее 3 штук). На конце каждой лопасти — такая же пирамида с лопастями, только меньше. И так далее.
Должна быть возможность рисовать до четырёх уровней таких пирамид (общим числом не менее \(1+3+9+27=40\)).
Рекомендации:
- для каждого объекта хранить его ориентацию относительно того объекта, к которому он прикреплён
- ориентацию хранить либо матрицей (что несколько сложнее для отладки, но может требовать чуть-чуть меньше вычислений), либо кватернионом (тензором, составленным из \(e, e_{12}, e_{13}, e_{23}\)) и вектором сдвига
За текстуры, землю, небо, освещение и тени — отдельные бонусы.
Также отдельный бонус за освоение drawArraysInstanced
.
Бассейн
Комната. Половина пола на одном уровне, половина — на другом. В той части, которая ниже уровнем, налита вода, отражающая и преломляющая свет. На воде должна быть рябь. На стенах комнаты — какие-нибудь текстуры (например, стандартная керамическая плитка).
Рекомендации:
- рябь на воде не обязательно должна быть реалистичной; можно использовать, например, шум Перлина
- отражение и преломление можно реализовать визуализацией на пару текстур: при визуализации оба экрана можно расположить в плоскости воды, а камеру — недалеко под/над водой
- правильное направление отражённого/преломлённого луча можно отыскать
тремя-четырьмя шагами бинарного поиска (постарайтесь
обойтись без
if
) — см. иллюстрацию
За металлическую лестницу, спускающуюся в бассейн, и тени — отдельные бонусы.
Бинпоиск:
«Рекламный щит»
Рекламным щитом (billboard) называют плоское изображение, всегда обращённое к камере.
Требуется реализовать комнату, по которой летают несколько (не менее двух) идеальных сфер. Естественно, идеальную сферу нельзя собрать из треугольников. Зато можно визуализировать на плоской поверхности.
Соответственно, поверхности, на которых визуализируются сферы, должны быть всегда обращены к камере.
Рекомендации:
- в этом проекте эффектнее всего будет свободная камера, позволяющая переместиться в любую точку комнаты и выбрать произвольный ракурс
- траектории сфер стоит выбрать так, чтобы они не подлетали слишком близко друг к другу — потеряется весь эффект
За текстурирование и тени — отдельные бонусы.
Тени
Тут всего лишь требуется реализовать несколько предметов, летающих по комнате, и отбрасывающих тени.
Рекомендации:
- за основу можно взять программу, которую предлагалось реализовать в соответствующем разделе
- в качестве предметов можно взять просто кубы или что-нибудь настолько же примитивное
За текстурирование и визуализацию источников света техникой рекламных щитов или же каким-нибудь полноэкранным фильтром — отдельные бонусы.
Трассировка лучей
В точности то же, что и в прошлом проекте, но только тени нужно определять не при помощи теневых карт, а при помощи трассировки лучей: провести отрезок от освещаемой точки до источника света и проверить, не пересекается ли он с каким-либо из треугольников геометрии.
Также можно добавить примитивное глобальное освещение, учитывающее освещение не только источниками света напрямую, а светом, рассеянным и/или отражённым с других поверхностей.
Для этого достаточно выпустить из точки, цвет которой мы рассчитываем, несколько лучей в случайных направлениях (лучше их захардкодить, а не реализовывать в шейдерах генератор псевдослучайных чисел), а уже для пересечений этих лучей с геометрией рассчитать освещённость непосредственно источником света. Затем полученные освещённости, домноженные на косинусы соответствующих углов и делённые на вторую степень длин соответствующих отрезков, осреднить (сложить и поделить на количество лучей).
Рекомендации:
- не стоит использовать слишком сложную геометрию — достаточно пары кубов, летающих по комнате
- треугольники кубов можно передавать как в текстуре (но её придется
каждый кадр изменять методом
texSubImage2D
), так и генерировать во фрагментном шейдере, передавая в него лишь положения кубов - можно и положения кубов генерировать во фрагментном шейдере; но с текстурой координат треугольников итоговый код будет заметно проще
За текстурирование и визуализацию источников света — отдельные бонусы.
Комната с зеркалом
Комната, в которой на стене висит зеркало. Можно прямоугольной формы, а можно — и более интересной.
Ключевой момент — наблюдателя нужно визуализировать. Например, кубом с натянутой на него текстурой лица.
Также в комнате нужно расположить несколько предметов, которые можно увидеть из зеркала. Естественно, всё это должно быть освещено.
Рекомендации:
- проще всего банально нарисовать всю сцену два раза: одну — реальную и одну — мнимую, симметричную реальной относительно плоскости зеркала
- не забудьте отразить нормали в мнимой сцене
- также не забудьте отразить все источники света, освещающие зеркало
- как альтернатива, можно нарисовать сцену в текстуру с точки зрения «мнимого» наблюдателя, расположенного симметрично реальному относительно плоскости зеркала — такой подход может дать размытое изображение вблизи зеркала; также необходимо будет следить за тем, чтобы экран, на который рисуется сцена с точки зрения «мнимого» наблюдателя, соответствовал по форме таковому для реального наблюдателя
За реализацию бликов на зеркале от источника света, текстурирование, использующее нормальные карты, и участок комнаты, находящийся за зеркалом — отдельные бонусы.
Изометрический тетрис
Реализовать трёхмерную графику для какой-нибудь двумерной игры (например, тетриса, но можно выбрать и что-нибудь другое).
Рекомендации:
- игру нужно выбирать с простыми правилами — их нужно реализовать достаточно полноценно
- возможно, для некоторых игр более приятно будет выглядеть не центральная, а параллельная проекция
- отдельные объекты игры (например — кубики в тетрисе) должны быть визуально отличимы друг от друга (в том же тетрисе соседние кубики не должны сливаться в единый прямоугольник)
За реализацию управления мышкой (например, выделение фигур или клеток в шахматах или же — трёхмерных пунктов главного меню) — отдельный бонус. Также полагается бонус за возможность управления камерой.
Лабиринт
Реализовать достаточно большой лабиринт с возможностью перемещения по нему. Стены должны быть текстурированы, причём — несколькими различными текстурами.
Рекомендации:
- лабиринт можно как захардкодить, так и сгенерировать случайным образом
- придётся реализовать какой-нибудь формат хранения лабиринта
- можно, например, хранить только кубические блоки стен (как в Minecraft)
- или же можно хранить отрезки стен, совокуплённые с номером текстуры и коэффициентами, определяющими сдвиг и растяжение текстуры (как в Doom)
За реализацию дверей с возможностью их открывания/закрывания — отдельный бонус. Импорт первого уровня из Wolfenstein 3D также даёт отдельный бонус.
Меташары
Марширующие кубы. Это как квадраты, но только кубы.
Таблицы можно взять отсюда.
За расчёт поля нормалей к гладким (а не кусочно-треугольным) изоповерхностям — отдельный бонус. За освещение и тени — также отдельный бонус.