
Трехмерная стратежка - 4
Дорогие друзяки, фичекрип не остановить!
Временно забил болт на игровую логику (праздники же, можно и расслабиться) и колбасил новые фичи рендера.
Под катом новости.

Демка тут: megaswf.com/serve/94374/ (Space — включить дебаг)
1. Тени
Больше недели потратил на реализацию теней.
Проекционные текстуры и честные шэдоумапы отбросил сразу, даже не стал мудрить с ними, хотя может и зря.
После этого остались 2 варианта. Оба попробовал:
1.1. Честные стенсильные тени.
Об этом можно почитать тут: www.gamedev.ru/code/articles/?id=4201
+ все честно и красиво, попиксельно и с самозатенением
— жрет филлрейт, нужно держать отдельный буфер для стенсила и переводить его в картинку
1.2. Фейковые проекционные тени.
Проекция геометрии на плоскость.
+ относительно быстро
— это фейк
Оба варианта рендерились в отдельную битмапу половинного разрешения (филлрейт в 4 раза меньше), чуть-чуть блурились и накладывались поверх основной картинки с блендингом.
У такого подхода (с отдельной битмапой) следующие недостатки:
— Надо чистить кусок памяти (забивать нулями) перед рендерингом
— Для стенсила надо делать еще один проход, чтобы стенсил перевести в цвет
— Надо перебрасывать из памяти в битмапу, через SetPixels()
— Наличие полноэкранной картинки поверх основной сразу отжирает 4-5 fps
— Неправильно смешивается с лайтмапами (хотя всем пофиг, конечно)
— (Самое главное) Никак не избавиться от лишнего затенения частиц! То есть, марин стреляет, а сквозь вспышку от выстрелов видна тень от ствола. Ужасно выглядит.
В итоге, остановился на «ручном рендеринге» проекционных теней с полным разрешением в общую картинку. Что интересно, по сравнению с рендерингом таких же теней в отдельную картинку половинного разрешения, скорость возросла.
Обидно, что нет теней на стенках, но я специально сделал вектор света почти вертикальным (75 градусов), так что этого почти не заметно.
2. Occlusion culling. Мегафича :)
Толковые пацаны (см. www.umbrasoftware.com/ ) на таких штуках рубят нехилое бабло. Их технология лицензирована в третьей версии Unity, между прочим.
Разумеется, у меня все попроще, но принцип тот же.
Сама идея простая: Если объект (или часть) за стенкой (или любым другим «большим» объектом), то рисовать его не нужно, все равно через z-буфер не пролезет.
Рассказываю как сделано у меня:
2.1 Определяем окклюдеры (в препроцессе).
Окклюдером может быть любой выпуклый объект. Можно и невыпуклый, но тогда будет глючить. Окклюдерами есть смысл назначать только большие объекты, чтобы не тратить время на лишние проверки.
2.2 Проецируем все вершины окклюдера на экран.
2.3 Собираем из этих вершин выпуклую оболочку. Почитать можно тут algolist.manual.ru/maths/geom/convhull/
2.4 Для каждого меша определяем список окклюдеров, которые его потенциально заслоняют.
Тут, кстати, не все так просто. Как определить, что объект находится за препятствием, а не перед ним?
Толковые пацаны из большого геймдева строят «бесконечную» пирамиду из лицевых граней препятствия и ребер оболочки, которой и проверяют объекты. Увы, это не так быстро, как хотелось бы. Пришлось делать по другому.
Я вспомнил, как быстро определить, пересекает ли отрезок экран или нет. Алгоритм Коэна-Сазерленда. algolist.manual.ru/graphics/clip_seg.php

Предположив, что «окно» это AABB окклюдера, концы отрезка это позиция камеры и объекта соответственно, я получил быстрый метод определения «потенциальных заслонений».
Кстати, есть расширение алгоритма Коэна-Сазерленда для трехмерного пространства, но в моем случае хватает двухмерного.
2.5 Если окклюдер потенциально может заслонить объект — продолжаем. После проекции меша (без рендеринга) у меня есть его AABB на экране. Находим площадь пересечения выпуклой оболочки окклюдера и AABB меша. Варианты:
2.5.1 Площадь пересечения равна 0, значит пересечения не было и объект виден.
2.5.2 Площадь пересечения равна площади AABB, значит объект полностью закрыт и рендерить его не надо.
2.5.3 Площадь пересечения меньше площади AABB, значит скрыта только часть объекта, надо отсекать треугольники.
2.6 Растеризуем окклюдер в «интервальный» буфер. Для каждого экранного Y пишем левую и правые координаты окклюдера.Надеюсь тут понятно.
2.7 Для каждой вершины треугольника определяем, попадает она в интервал или нет. Если все 3 вершины внутри интервалов, значит весь треугольник скрыт и рисовать его не нужно.
Самое плохое, что окклюдинг для моей геометрии нифига не помогает. Тут практически все на экране и скрывать особо нечего.
Так что, наверное, оставлю только пообъектный куллинг для теней. Или может стенки повыше надо сделать.
Не знаю, думаю.
Еще подсветил немного текстуры, стало получше, по моему.
Вроде все.
Временно забил болт на игровую логику (праздники же, можно и расслабиться) и колбасил новые фичи рендера.
Под катом новости.

Демка тут: megaswf.com/serve/94374/ (Space — включить дебаг)
1. Тени
Больше недели потратил на реализацию теней.
Проекционные текстуры и честные шэдоумапы отбросил сразу, даже не стал мудрить с ними, хотя может и зря.
После этого остались 2 варианта. Оба попробовал:
1.1. Честные стенсильные тени.
Об этом можно почитать тут: www.gamedev.ru/code/articles/?id=4201
+ все честно и красиво, попиксельно и с самозатенением
— жрет филлрейт, нужно держать отдельный буфер для стенсила и переводить его в картинку
1.2. Фейковые проекционные тени.
Проекция геометрии на плоскость.
+ относительно быстро
— это фейк
Оба варианта рендерились в отдельную битмапу половинного разрешения (филлрейт в 4 раза меньше), чуть-чуть блурились и накладывались поверх основной картинки с блендингом.
У такого подхода (с отдельной битмапой) следующие недостатки:
— Надо чистить кусок памяти (забивать нулями) перед рендерингом
— Для стенсила надо делать еще один проход, чтобы стенсил перевести в цвет
— Надо перебрасывать из памяти в битмапу, через SetPixels()
— Наличие полноэкранной картинки поверх основной сразу отжирает 4-5 fps
— Неправильно смешивается с лайтмапами (хотя всем пофиг, конечно)
— (Самое главное) Никак не избавиться от лишнего затенения частиц! То есть, марин стреляет, а сквозь вспышку от выстрелов видна тень от ствола. Ужасно выглядит.
В итоге, остановился на «ручном рендеринге» проекционных теней с полным разрешением в общую картинку. Что интересно, по сравнению с рендерингом таких же теней в отдельную картинку половинного разрешения, скорость возросла.
Обидно, что нет теней на стенках, но я специально сделал вектор света почти вертикальным (75 градусов), так что этого почти не заметно.
2. Occlusion culling. Мегафича :)
Толковые пацаны (см. www.umbrasoftware.com/ ) на таких штуках рубят нехилое бабло. Их технология лицензирована в третьей версии Unity, между прочим.
Разумеется, у меня все попроще, но принцип тот же.
Сама идея простая: Если объект (или часть) за стенкой (или любым другим «большим» объектом), то рисовать его не нужно, все равно через z-буфер не пролезет.
Рассказываю как сделано у меня:
2.1 Определяем окклюдеры (в препроцессе).
Окклюдером может быть любой выпуклый объект. Можно и невыпуклый, но тогда будет глючить. Окклюдерами есть смысл назначать только большие объекты, чтобы не тратить время на лишние проверки.
2.2 Проецируем все вершины окклюдера на экран.
2.3 Собираем из этих вершин выпуклую оболочку. Почитать можно тут algolist.manual.ru/maths/geom/convhull/
2.4 Для каждого меша определяем список окклюдеров, которые его потенциально заслоняют.
Тут, кстати, не все так просто. Как определить, что объект находится за препятствием, а не перед ним?
Толковые пацаны из большого геймдева строят «бесконечную» пирамиду из лицевых граней препятствия и ребер оболочки, которой и проверяют объекты. Увы, это не так быстро, как хотелось бы. Пришлось делать по другому.
Я вспомнил, как быстро определить, пересекает ли отрезок экран или нет. Алгоритм Коэна-Сазерленда. algolist.manual.ru/graphics/clip_seg.php

Предположив, что «окно» это AABB окклюдера, концы отрезка это позиция камеры и объекта соответственно, я получил быстрый метод определения «потенциальных заслонений».
Кстати, есть расширение алгоритма Коэна-Сазерленда для трехмерного пространства, но в моем случае хватает двухмерного.
2.5 Если окклюдер потенциально может заслонить объект — продолжаем. После проекции меша (без рендеринга) у меня есть его AABB на экране. Находим площадь пересечения выпуклой оболочки окклюдера и AABB меша. Варианты:
2.5.1 Площадь пересечения равна 0, значит пересечения не было и объект виден.
2.5.2 Площадь пересечения равна площади AABB, значит объект полностью закрыт и рендерить его не надо.
2.5.3 Площадь пересечения меньше площади AABB, значит скрыта только часть объекта, надо отсекать треугольники.
2.6 Растеризуем окклюдер в «интервальный» буфер. Для каждого экранного Y пишем левую и правые координаты окклюдера.
2.7 Для каждой вершины треугольника определяем, попадает она в интервал или нет. Если все 3 вершины внутри интервалов, значит весь треугольник скрыт и рисовать его не нужно.
Самое плохое, что окклюдинг для моей геометрии нифига не помогает. Тут практически все на экране и скрывать особо нечего.
Так что, наверное, оставлю только пообъектный куллинг для теней. Или может стенки повыше надо сделать.
Не знаю, думаю.
Еще подсветил немного текстуры, стало получше, по моему.
Вроде все.
- +8
- ryzed
Комментарии (33)
Очень будет интересно посмотреть что получится в итоге.
Соглашусь с ув.тов.darkvam — нужна игра! В топку стенсилово проекционные механизмы — помоему тени тут вообще мало что решают. На таком уровне графики в старых игрушках тени были кружочками под ногами персонажей и всё. И не мешало! Зато представь сколько ты будешь сейчас париться с геймплеем. Какбе продумать структуру для треугольников и рендерер организовать красиво это здорово, но геймплей он же других жертв требует. В стратежке гемор, я бы уточнил — МЕГАГЕМОР с подбором характеристик под карактеров, пушки, итемы и пр.пр.много пр. ЛИБО ты можешь найти такого же оптимиста как ты, только с креном в сторону ИИ! Пока ты будешь АО запекать, он приделает нейросети зеленым ящерицам. Ну и еще биг квесчен — зачем тут 3д? Например такая идея — забить на топ даун камеру и организовать управление от первых лиц. Т.е. игрок будет видеть только то что видят его подопечные, ну разумеется головой можно будет вертеть. Т.е. обана, за углом уже не понятно есть кто или нет. И вообще многие фишки добавляются. Например вместо одного этажа уровень будет из пяти… Вопщем игровой аспект пока прячется за трёхмерным окклюдером — нехорошо есть это!
А так всё круто :D Плюсанул.
Баланс и уровни частично сопру из Incubation :)
Уровни там очень круто сделаны, жаль, что эту игру почти забыли.
3д — потому что «бесплатная» анимация, ну, и вообще, хочется мне сделать 3д.
От первого лица не получится, потому что текстуры вблизи страшны, как моя жизнь.
Делай то что нравится — получай удовольствие от копания с 3d.
Тут никто не может знать во что это все выльется.
PS: для меня твои посты стали пинками в стиле «Иди работай уже, тут люди 3д уже делают, а ты...»
Имхо лучше просто кружочки по челобунами + мягкие качественно посчитанные тени в лайтмапе.
Я по другому не умею.
Блурить в фотошопе ну его нафиг.
Еще непонятно, что делать с тенями от дверей/других объектов в случае кружочков.
Можно как я уже говорил отдельно просчитать AO, отдельно лайтмапы, а потом смешать всё в фотошопе, добавив контрастность для АO. Будет выглядеть очень атмосферно.
Ты ведь этот направленный источник не собираешься в релизе оставить, ведь правда? :)
а теней от дверей и не надо делать, просто освещать как и динамические объекты. (я так понял на двери у тебя лайтмапы не кладутся)
Ладно, идею понял, буду пробовать.
Мне бы научиться в максе работать, поднапрячь художественные способности и еще придумать, чтобы всё это освещение не тормозило в игре.
Буду ковырять.
Когда будет готов хоть один уровень — тогда буду думать про аутсорс.
Удачи! ;)
Во-первых знания и умения пригодятся.
Во-вторых ни одна технология мгновенно не вытесняет другую (вспомните сколько двд вытесняли сд, когда блюрей пророчил смерть двд и какова еще ситуация). Ну выйдет через год Молехилл, пока обкатается, протестится, застабилится пройдет еще года-два. Пока его начнут применять.