Комментарии 39
Какие тёмные получились блоки. Это так специально сцена построена? Потому как вижу, что кусты освещены нормально.
Да, те объекты, что отбрасывают тени, свет не пропускают (только грани освещаются за счёт того, что я на пару пикселей увеличивал лучи от источников света), на них действует только общее освещение. Над этим я в процессе раздумий как бы это по адекватнее сделать, не костылями. Если брать рёбра объектов, что тыльной стороной повёрнуты, эта проблема решается на ура, но появляется проблема обтрасывания теней на соседние блоки. Вобщем, надо определиться, какую из этих двух проблем решить менее ресурсоёмко и допилить.
На вскидку:
1. Отрисовать блоки в стенсил буфер
2. Отрисовать в карту глубины только тыльные грани со стенсилтестом (расширив эти грани на 1 пиксель относительно блока). Таким образом грани, находящиеся на соседних блоках не пройдут стенсил тест.
Красота.
Так и просится вместо Марио что-нибудь темное и фентезийное, в духе Baldur's Gate…
Это то, что сейчас я разрабатываю в свободное от работы время, в задумках нечто подобное Митбою и Гаю, с обилием смертей и нервов. Марио здесь просто ради примера, первая раскадровка анимации персонажа, что попалась в гугле, а потом уже и тестовый уровень набросал в таком же концепте. Концепта главгероя у меня пока нет, как здесь недавно отметили — быть дизайнером и писать код проще и красивее результат, чем быть программистом и рисовать, а рисую я совсем неочень =)
Используете какой-либо готовый движок и редактор или все самописное?
Всё самописное, кроме таких «низкоуровневых» библиотек, как pcre, jpeglib, lua, pnglib и zlib. Часть кода нагло позаимствовал из исходников DooM 3 — мат. библиотека, очень уж она мне понравилась, а возиться с векторами/матрицами самому уже не интересно, слишком много велосипедного кода. Думаю в будущем перевести на SDL для линукс-совместимости. В принципе, можно и самому, по сути вынести создание окна и обработку событий.
А, если не секрет, поделитесь, чем эта библиотека лучше glm? Или вы glm не рассматривали?
До сего момента не сталкивался с ней, надо будет посмотреть. Вообще, по большей части из-за того, что реализовано там всё максимально просто и по минимуму (для 2D мне этого с лихвой), а так же присутствуют такие штуки, как Sqrt16, Sin16, LengthFast и т.п. для более быстрых расчетов с потерей точности. Ну и сам Джон Кармак приложил к этому делу руки =)
А в 2D сейчас реально имеет смысл жертвовать точностью? Мне кажется, потери производительности тут основные не в арифметике с глобальными матрицами… Хотя это надо в конкретном случае рассматривать.

Мне glm нравится тем, что она по синтаксису максимально близка к GLSL.
Невероятно, все один в один как у меня. Я тоже сейчас разрабатываю игру в стиле митбоя с обилием смертей и нервов. То, что у вас в профиле [О себе] один в один про меня, за исключением того, что я не веб-программист. И судя по некоторым фразам из статьи вы с геймдева, как и я
Просмотр «Indie Game: The Movie», думаю, многих инди-разработчиков вдохновил =) На геймдеве я есть, но как просто читатель, т.к. большинство вопросов решаются либо своей головой, либо чтением спецификаций, либо гуглом.
Я посмотрел видео, и вот прям захотелось поиграть в такого Марио, без обилия смертей и нервов.
Может реализуете, если уже есть почти готовый вариант? Можно пару новых инструментов дать Марио: фонарик, осветительная ракета и т.п. Из пейзажев просится наверху ночной (с луной и звёздами — посветлее), а в подземелье и так темно, там можно какие-нибудь катокомбы нарисовать.
А что за редактор вы в видео используете для манипуляций над объектами мира? Самописный?
Самописный на Lua, благо в 5.2 есть неплохое подобие объектной модели (хотя, грубо говоря, это просто синтакический сахар) и довольно удобно реализуется GUI.
Мне кажется вы вдохнули новую жизнь в Марио, а бы с удовольствием поиграл на темных сценах!
Лет так 10 назад, когда еще писал игрушки, подобным образом делал туман войны в простенькой стратегии.
Слишком четкая граница свет-тень, хотелось бы помягче.
Свет от Марио как-то странно смотрится, область видимости можно сделать проникающим светом с затуханием.
Тень от источника света слишком темная, она должна быть намного светлее.
В остальном круто :)
Саня, не придирайся это поправить несложно, больше волнует — почему монетки не собираются!
Описанная техника все-таки называется Shadow Mapping. Тогда как упомянутый Deferred Shading (рус. отложенное освещение) — это нечто совсем иное.
Deferred Shading — это техника реализации освещения (shading), позволяющая отделить геометрическую сложность сцены от количества источников света. Подробности тут
Более того, в статье скорее смесь Shadow Mapping и Shadow Volumes (aka Stencil Shadows), поскольку в итоге явно рисуются освещенные области в виде геометрии.
НЛО прилетело и опубликовало эту надпись здесь
Мне кажется что чем фигуры строить и рисовать по лампочке за отдельный проход, проще:
— отрисовать diffuse в текстуру на весь экран
— рисовать квад на весь экран
— передавать в шейдер массив источников, массив этих 2D-shadowmap-ов
— для каждой лампочки считать попадает ли в тень каждой лампы данный пиксель (я так понимаю для этого надо найти угол между источником, посмотреть по нему в текстуру, и сравнить с расстоянием до источника)
— сложить, помножить по вкусу
— взять diffuse и помножить тоже по вкусу

В общем-то так примерно 3D-игрушки и работают. Если не нужно всякие эффекты поверх картинки — можно вообще это сделать в один проход, рисуя не квад, а чисто спрайты через этот шейдер.
Красивая реализация.
У меня возникла мысль: а что если помимо обычного освещения в 2D еще и реализовать raytracing?
От себя добавлю, что для пущего визуального эффекта «открытых пространств», стоит отрисовывать тени с учетом геометрии уровня.
А то меня смущает тень от персонажа, падающая на фон (хотя я не знаю специфики, может быть там просто очень пыльно и туман?).
Думаю, я неудачно выбрал фон, смотрелось бы лучше если бы это было, например, подземелье, и свет от игрока освещал фоновые стены. А для открытых пространств фон, наверное, рисовать вообще без учета освещения и понапускать «тумана» в некоторых местах для видимости лучей, в общем, есть над чем подумать.
Использовать будем одну из самых распространённых технологий — deferred shading, портировав её в 2D.

Суть deffered shading-а — построение geometry buffer-а, в котором каждый пиксель описывает геометрию сцены, и потом кучей источников света освещается. Так что общего с deffered shading-ом в статье ничего нет.

В части 1.2 вы предлагате читать из шадоумапы на цпу? Т.е. ждать на ЦПУ когда ГПУ отрисует шадоумапу? А зачем вообще вам понадобился вертексный каркас? Почему нельзя в шейдере проверять затенен пиксель или нет, как в классической шадоумапе? Алсо если хочется волюмных теней — то быстрее будет построить волюмы без всяких рендеров прямо на цпу.
Буфер глубины заполняется на CPU, по нему строится каркас, поэтому ничего ждать не надо. Из видеопамяти читать вроде как плохой тон. Думаю, как здесь уже предложили, попробовать не строить каркас, а передавать сгенерированные буферы глубины в шейдеры и там всё рассчитывать. А с деферред-шейдингом да, накосячил, прошу прощения.
Тогда тем более не нужно никакого буфера гулбины. Реализуем любое дерево (loose quadtree/bounding volume hierarchy например). Складываем все блоки в него. Для каждого лайта выбираем блоки, до которых он может дотянуться и рейтрейсим в вершины этих блоков. Получаем набор лучей, которые сортируем по углу и собираем в тот самый trinagle fan. Это быстрее чем софтварный рендер в шадоумапу, никаких оптимизаций как вы в пункте 4 описали — не нужно, а на выходе получается даже оптимальнее, чем у вас в пункте 4.
Здесь есть одно но — у меня в планах сделать некоторые игровые элементы, зависящие от освещённости, как, например, датчики, реагирующие на свет и тому подобное, поэтому вообще всё на GPU перенести не получится.
Я выше как раз описал как софтварно делать и проще, и оптимальнее.

Проверка же датчика, реагирующего на свет — должна делаться не так. Я уже подозреваю, что вы собираетесь делать проверку датчика в каждом треугольнике меша от каждого источника света. По факту вам нужно все ровно наоборот. Вам нужно от датчика пустить луч к источнику света. Если луч достигает источника — то датчик реагирует.
Так что в любом случае самый оптимальный вариант — это дерево и рейкастинг без всяких там софтварных шадоумапов.
У него же кубики там. Чтобы посмотреть по каким кубикам проходит прямая, подойдет любой алгоритм рисования отрезка.

Для движущихся объектов еще может быть имеет смысл строить деревья, если их много.
Проверить освещённость в текущей реализации не сложно просто «суммировав» нужные значения из уже сформированных буферов глубины, тем самым точно узнав коэффициент освещённости. А строить тени аналитически я не взялся, отбросил эту мысль почти сразу, весьма геморно это для динамических уровней с тысячами тайлов в пределах экрана (это в демке просто марио-стайл с парой десятков тайлов).
Полностью аналитически форму тени будет непросто построить, хотя бы из-за движущихся объектов, и изменения уровня налету (выбивание блоков а-ля марио, например).

Можно попробовать заюзать stencil buffer а-ля doom 3, но что-то мне кажется что тут уже shadowmaps лучше будут.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.