Pull to refresh

Comments 26

Механика интересная, но стоило бы границы теней делать более размытыми. Так же что-то мне подсказывает, что при быстром передвижении все на экране будет мелькать. Я бы сделал задержку перед убиранием тени. image Так же такие случаи неплохо было бы тоже обрабатывать. Красным — курсор
Ситуация как Вы обозначили решается элементарно, уменьшением радиуса тени на 0.5px, для деревьев это имеет смысл. Для непрозрачных стен, наоборот, радиус слегка увеличен, что бы не было просветов между блоками, исправим.
По поводу размытости теней: пробовал два варианта:
1) Размытие теневого слоя
2) Разделение тени на две, где вторая чуть меньшего радиуса
Оба эффекта не зацепили, а падение производительности было внушительным.
Может стоит все-таки использовать видеокарту? Накладывать на края градиент альфа канала непроизводительно?
Думал о порте на видеокарту. Тогда, думается, проще заменить тайлы 3D объектами и сделать тень на плоскость, земли. Хотя эффект уже будет совершенно другим.
«а падение производительности было внушительным»
Думаю для Roguelike можно скрыть падение производительности, заранее посчитав тени для позиций на смежных клетках (т.к. игрок двигается по целым клеткам), и делать плавный переход между уже готовыми картинками. Большую часть реального времени мир статичен, и если он выглядит хорошо, то этого, пожалуй, достаточно.
Ничего не скажу за алгоритм, но выглядит симпатишно. В рогуль с такими тенями я б поиграл.
По поводу производительности:

Можно попробовать считать «затененность» для объектов от 1 до, например, 5. Где 1 — легкое затенение, а 5 — полное и не накладывать тени для объектов, у которых «затененность» больше или равна 5.
Если я правильно понял, вы предлагаете предварительно рассчитать освещённость каждого объекта, а затем прорисовывать тень только для тех тайлов, что не затенены? Расчётов будет больше, но за счёт уменьшения прорисовки при большом количестве объектов может быть выигрыш. Как вариант можно попробовать.

Единственный момент, как считать затенённость: по центральному значению, среднему для границ тайла? Вижу один недостаток, возможна ситуация когда на один тайл падает две тёмных тени, и остаётся узкая область не затенённости, которая не отбросит тень.

Есть такая штука — 1D shadow mapping, не знаю будет ли быстрой будучи реализованной на процессоре.

А какая функция используется для наложения теней одна на другую — просто альфа-смешивание с чёрным?
Да простое альфа-смешивание, с чёрным. Можно использовать и другие цвета для придания эффекта, например фиолетовые нотки — туман, или жёлтый-оранжевый — солнечный день.
Это не очень «реалистично» :).
Обычно в основе реалистичности лежит какая-то модель, приближённая к реальности, ну например:
— деревья перекрывают (k) половину освещённости
— соответственно два дерева перекроют k*k, три k*k*k и т.д. (получается не альфа смешивание, а просто умножение на коэффициент «тени»)
— рассчитанный коэффициент пересчитывается для гамма-кодированных значений цвета и уже по нему делается альфа-смешивание.
Ну какой-то такой «реализм» :)

Пикселизированная равнина выглядит интересно, а вот тени в подземелье очень резкие. Выглядит не очень.

Если будет интересно, то вот:
image
image

Чистый рэйкастинг. С большим количеством геометрии(> 2000) работает отлично
Можно не останавливать луч при контакте с поверхностью, а лишь «ослаблять» его ярокость в зависимости от пройденного «внутри» поверхности пути (как в тумане, луч вошёл в тучку :) )
Тогда тени будут мягче. Картинка темновата, вне контакта с препятствиями яркость можно не менять. Думаю что для плотного леса должно хорошо смотреться, т.к. будет видно что все деревья как-то участвуют в построении тени, а не только первый ряд, который всё перекрыл
Увы, у меня не было задачи корректно это рендерить.
Я год как занимаюсь физ. движком.
По производительности он уже шустрее Box2D.

P.S. не сразу понял, что вы веткой промахнулись…
Вы меня заинтересовали, попробую реализовать рейкастинг с прозрачностью для деревьев, и без прозрачности для стен.

На тему механики. Посмотрите игру NOX. Все придумано до нас.

В ноксе прикольные были тени. А про то, что придумано до нас, не мешаешь ещё раз пройти путь предшественников.

Ух ты, на мою статью ссылаются! Спасибо!
А вообще есть пара мыслей.


На скринах видно, что тени накладываются друг на друга и зоны пересечения теней становятся темнее. Это некорректное поведение, т.к источник света только один и точечный. Можно исправить, если рисовать тени в буфер одним цветом, а полупрозрачность теней делать уже после — отрисовывая этот буфер целиком с какой-то прозрачностью.


Мне кажется, что можно не рисовать рисовать дугу в начале тени — так станет проще и не будет видно резких углов, как на последнем скрине. Эта дуга сейчас необходима, иначе тень будет закрывать сам объект частично. Если не менять подход к отрисовке, но хочется убрать эти кружки, возникнет проблема.
Придется отрисовывать объект их тень от самых дальних к игроку до самых ближних. При этом тени объектов будут рисоваться в таком порядке: объект1, тень1, объект2, тень2 и т.д. И тогда нельзя будет поправить наложение теней, про которое я говорил выше. Собственно, стандартная пробема с алгоритмом художника.


Мой совет — попробовать рисовать все на видеокарте. Не знаю, насколько сложно это делать на современном Delphi, возможно есть нужные библиотеки.
Если проект делается ради фана и опыта, можно попробовать переделать его на движок, более удобный для работы с 2d/3d, да тот же Unity3d мой любимый.


Просто все эти вкусные вещи с тенями, освещением и т.д. делаются в разы проще, если можно оперировать ими как 3д/2д объектами на видеокарте, с буфферами, шейдерами, стенсилом и т.д.

По-моему, если два объекта с некоторой прозрачностью перекрывают область видимости, то тени и должны становиться темнее. Собственно, это не совсем честная тень, а скорее способность персонажа замечать объект. Изначально план был в том, что при определённом уровне затенённости просто прятать врага или предмет от взора. А готовые тени сразу использовать в игровой механике, что куда сложнее сделать если рендерить на GPU.

Про подход к прорисовке дуги, тут вы абсолютно правы, тоже приходил к такому выводу. В Дельфях/ Лазаре конечно же есть возможность использовать видеокарту. Приходилось ваять на OpenGL, но тёплый ламповый пиксель на CPU мне куда милее клонированных GPU’шных конвееров.

Да, согласен, что полупрозрачные объекты будут оставлять полутени, которые при наложении дадут более густую тень. Просто сейчас на скринах такие тени отбрасывают непрозрачные объекты, например, деревья. Насколько я вижу, у вас два типа объектов, условно-прозрачные вещи, которые отбрасывают легкую тень и непрозрачные объекты — деревья. Просто сейчас из-за особенностей реализации вы не можете сделать равномерное затенение от непрозрачных объектов, которое бы не выглядело бы странно.


Знаете, на gpu можно делать очень ламповый пиксель :)

Деревья тоже полупрозрачные объекты, но более густые чем предметы. Непрозрачными являются только стены как на последнем изображении.
Повысить производительность можно используя многопоточность. Ну и после двух-трех деревьев — никаких теней не надо, сэкономишь на прозрачности
Да, спасибо за идею. Думал про многопоточность, только хотел делить изображение на сектора рассчитывать в разных потоках, а потом делать слияние результатов.

Сейчас делаю трассировку лучами (ray casting), скорость там много выше но эффект пока не нравиться, возможно по результатам создам отдельный пост.
Выглядит просто ужасно. Такие вот фичи нужны только если ими реализована какая то игровая механика (например монстры прячутся за деревом).
Sign up to leave a comment.

Articles