Стилизация рендеринга “нарисованного” мира

Разработка игр | |

В этой статье будет небольшой разбор того, как в этом демо (загрузить его можно отсюда) был создан эффект, при котором виртуальное окружение выглядит так, будто его разукрасили масляными красками.

Вот видео:

paint543

paint554

Эффект нарисованности не был запланированным. Была идея показать природную сцену определённого типа и мало времени. Стало ясно: пытаться делать реалистично даст либо очень посредственную картинку (ввиду Unity и сложности моделирования растительности для игр), либо год мучений в надежде догнать Crysis (да и тот, на взгляд не привыкшего к графике игр человека, вряд ли выглядит совершенно; картонно-крестовидные плоскости листвы и меня до сих пор коробят). В общем, это был не вариант.

Главное – сохранить правильное ощущение, атмосферу, не испоганив её ограничениями графики. Очень хотелось избежать синтетичности и компьютерности (это же природная сцена всё-таки).

Таким образом, я должен был создать что-то, с одной стороны, очень сложное, а с другой, не требующее большой вычислительной мощности (чтоб не спалить компьютеры тех, кто решит установить мою демку). Но что именно? Интуиция прошептала: «Нужно все запечь!» И тут в памяти всплыли 3D-сканы природных пейзажей. Там все цвета расположены как нужно, а освещение отфильтровано, «просчитано» в реальном времени и уже «впечено» в окружение, благодаря чему эти 3D-сканы выглядят довольно убедительно даже с плохой геометрией (или даже будучи просто облаком точек). К несчастью, на тот момент время года было не тем, что мне было нужно, поэтому поупражняться в фотограмметрии не получилось.

Но что если «просканировать» реалистичную офлайн-сцену? Мне вспомнилась программа Vue – с ее помощью специалисты по генерации экстерьеров и кинематографических 3D-сцен создают виртуальные природные пейзажи. Я понятия не имел, что из этого выйдет, но все же решил попробовать.

Я взял одну из сцен-болванок, отрендерил ее с разных углов и поместил результат в Agisoft Photoscan, чтобы воссоздать приблизительную геометрию вместе с «запеченным» в эту сцену освещением. И… увы, результат себя не оправдал. Причины – сложная растительность и эффект сглаживания. И тут меня осенило. Что, по сути, делает Agisoft? Он создает карту глубины, а затем размещает на разных глубинах облака точек. Ну, так я же могу сгенерировать карту глубины прямо в Vue, зачем лезть в Agisoft?

Таким образом, зная техники отложенного просчета и преобразования глубины в позицию, я мог взять сцены из Vue и сделать из них облака точек. Впрочем, сделать это было не так-то просто. У глубин в Vue не очень удобная кодировка, но, к счастью, я нашел решение и этой проблемы.

И из этого:

paintprocess1

Немного пошаманив с MaxScript, я получил это:

paintprocess2

Т.е. у нас получилась объемная текстурированная сетка.

Самое трудное позади, нужно лишь повторять этот процесс, пока в сцене не останется дырок. Теперь, наконец, можно поиграться с шейдерами! :)

dasxc

paint11s

Здесь каждый отображаемый пиксель ведет себя как квадратный полигон, а в качестве текстуры у него используется один из таких мазков:

daubs

Почти готово. При просчете был баг, из-за которого на некоторых полигонах была лишь часть мазка. Но это выглядело даже лучше, поэтому я не стал ничего фиксить. Это не баг, а фича! :)

Размер полигонов, разумеется, зависит от глубины, т.е. чем ближе расстояние, тем больше полигон. Было очень важно не смешивать вместе большие и маленькие полигоны, поэтому я очень осторожно выбирал углы обзора.

Тестовый образец выглядел на отлично, поэтому я решил, что пора приступить вот к этой сцене:

pond_v2

Я сделал ее сам. Дом, забор и окружающий пейзаж были созданы с нуля. Растения были добавлены из уже существующих наборов. Я объединил это все в одной композиции, причем растений пришлось отрендерить очень много – так, чтобы они покрывали всю площадь сцены:

sdf5

Некоторые картинки пришлось подфотошопить – чтобы избавиться от темных пятен и добавить цветов:

pond_300_fill

Этих темных пятен пришлось подправить очень много, потому что у меня возникли проблемы с созданием правильного освещения. Но в итоге я все же заставил картинку выглядеть лучше. Финальная сцена – это смесь разных подходов, потому что у меня не было времени заново рендерить все с разными настройками. Ну, и выглядело это посимпатичней.

Вот пара ранних скриншотов:

paint3

paint5

К этому моменту я уже подправил направление мазков – это было важно, поскольку мазки, направленные в одну сторону, выглядели неестественно. Сначала я попытался сделать это через процедурную генерацию (похожим образом из карты высот генерируется карта нормалей), но безуспешно. То есть мне хотелось, чтобы одни мазки лежали одним образом, а другие – другим. К примеру, мне нужно было, чтобы на траве были вертикальные мазки, а на заборе – мазки, повторяющие форму забора. И когда у меня не получилось сделать это через процедурную генерацию, я решил сделать дополнительные текстуры, вручную прорисовав в них нужное направление мазков. В финальной версии у мазков, которые находятся близко к камере, используются текстуры, нарисованные вручную, а у мазков, которые далеко – текстуры, сделанные процедурной генерацией. Вот пара примеров:

pond4_dir_hi3

По правде говоря, разукрашивать векторы разными цветами в фотошопе – это не самая лучшая идея, но это самый быстрый метод, до которого я смог додуматься.

Но разница очевидна. Слева – мазки, смотрящие в одном направлении, справа – в разных:

paintprocess3

Таким образом мы и подходим к финальной картинке. В концовке я решил немного оторваться и воспользоваться тем, что всё состоит из маленьких квадов, заставив их крутиться, разлетаться и собираться по всякому. Вся анимация частиц задана в шейдере.

Домик в конце пришлось практически полностью рисовать кистями в фотошопе, т.к. фотографичная версия слишком выбивалась из общего стиля.

Такие вот дела. Записал всё это, чтобы хотя бы самому не забыть, что и как делал.

Бонус: Недавно меня спрашивали, как заделать дыры между полигонами. Очень просто – базовую геометрию нужно сделать очень примитивной:

paintprocess4

Автор Mr F, оригинал найдете по ссылке, Rendering painted world in JG

Владимир FrostBite Хохлов frostbite@progamer.ru

Поделиться

Обсудить