Статья о том как художник/дизайнер бодался с системой рисования линий для игры и сделал ее :)
Кому будет интересна статья? Наверно всем, но не бывалым прогерам так как тут ничего нового для них нет. Читателя ждет МНОООГО видео, картинок и обьяснений "на пальцах".
Немного модного арта для затравки (который получился попутно и случайно в процессе тестов рисовалки):
В общем надоело смотреть на то как лазерный луч в нашей инди-игре не оставляет на стенах ничего. Абсолютно ничего. Пробовал trail добавлять, но он же исчезает. И смотрится trail так себе... Даже бомжам стыдно показывать.
Итак, поехали. Нужно было сделать систему рисования линий для игры. Линия должна рисоваться от лазерного луча на любой поверхности. Стал делать свою систему потому, что на AssetStore ничего такого нет. Есть одна система, но она:
1) рисование на каждом обьекте (static/dynamic) приводит к тому, что обьект вырывается из батчинга и создает +1 drawCall.
2) система рисует только точки. Ну типа как в Splatoon. Можно рисовать пятна, но не линии.
Очевидно, это мне не подходит, так что go делать что-то свое.
Это далеко неконечный вариант так как линии здесь не рисуются, рисуются "точки". За счет медленного движения мышки кисть рисуется часто и след выглядит как линия:
В сети можно найти кусочки кода и даже проекты, которые позволяют рисовать следы на какой-то одной модели.
Требования к системе такие:
- линии должны рисоваться на статических обьектах, но не всех. Динамические обьекты должны не давать рисовать линию на полигонах, которые ЗА ними.
- работает максимально быстро
- работает на любом железе на котором работает Unity
- число линий неограничего
- число цветов линий - неограничено
- рисовать можно не только линии
Задача эта для меня новая, никогда такого еще не делал, пришлось повозиться.
Как рисуются линии в комп-графике? Есть модель и игрок проводит по модели лучем. На модели должен остаться след. Нужно найти в каком месте рисовать этот след.
1) очевидно, полигоны, которые смотрят ОТ начала рисования линии не будут содержать на себе след. Потому, что это полигоны с противоположной стороны модели. Их можно отбраковать.
2) есть полигоны, которые смотрят на игрока и которые попали в область рисования линии. На них предположительно будет след от линии.
Ну вот, для наглядности:
Красная точка - начало луча. Синие линии - это сектор в котором луч повернулся. Стрелка показывает направление поворота (хотя это неневажно).
В итоге у нас есть треугольник, которым рассекли модель. Полигоны, которые повернуты от игрока (backfaced) сразу тупо отбросились и я их не сек плоскостью в кторой орудует луч.
Есть некоторые полигоны, которые повернуты к нам, но, которые не дожны рисовать на себе линию так как они перекрыты другими полигонами. Например, это полигоны в центре картинки. Для отбраковки таких линий, я запилил алгоритм отбраковки, который отсеивает их.
Вот фото работы этого алгоритма:
Красные линии - это то, что будет рисовать линию на модели. Желтые - это то, что отсечено.
Цифры и прочее - это для себя. Вообще пришлось сделать стенд и на нем все отлаживать. Стенд поддерживает подргузку линий из файла. если в игре что-то крякнется, приходится запускать отладчик, который подгружает в себя все логи и тестирует состояние игры на момент поломки. Удобно, всем советую искать баги невручную :) ну а потом, когда баг выявлен, ищешь что нагнулось в алгоритме.
Здесь просто тесты алгоритма, смотрел как работает:
В сцене может быть несколько "рисователей". Вот видео. где одновременно рисуется больше одного пятна за 1 раз. Кстати, тут видно, что нужно рисовать именно линии, а не пятна. Иначе между точками есть пробелы.
Здесь видно (подсвечиваю) полигоны на модели и какие полигоны секутся лучем (рисуют линию):
Здесь наглядно видно как работает рисование линий:
Удалось сечь обьект и рисовать на нем линию. Здорово!
Осталось сделат самую малость: найти обьекты, которые будут рисовать на себе линии.Вот водишь ты лучем в пространстве и нужно знать с чем луч пересечется. Для этого есть Оctree & BVH. Первый хорош для статики, второй для динамических обьектов. Спасибо GameDev.ru (а именно крутым парням foxes и kkolyan за подсказки).
Внедряем деревянные структуры, печем, запускаем. Работает!
Это не конечный вариант, но все же. Вот как смотрится след в действии:
Спасибо за внимание. На данный момент я занимаюсь больше артом и даже на такие беглые статьи не хватает времени.
Кому интересно, вот ссылки на меня. Здесь я выкладываю некоторые результаты по игре. Пока больше скетчами делюсь. Позже больше видео начну выкладывать ;) Подписывайтесь, это сильно стимулирует работать :)
https://twitter.com/CGAleksey
https://www.instagram.com/cgaleksey/