Реалистические и эффективные погодные эффекты: дождь и снег

Реалистические и эффективные погодные эффекты: дождь и снег

Жюстен Стокер

Введение

Во многих играх погодные эффекты являются второстепенными, или им уделяется мало внимания. Делая исследование для проекта, я понял, что существует очень мало информации о том, как создавать погодные явления, такие, как дождь или снег. Эта статья демонстрирует эффективный и визуально привлекательный подход моделирования выпадающих осадков. Перед введением этого метода я начну с готовых кратких примеров двух других методов и их недостатков.

Метод 1: Текстурирование экрана

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

Проблемы:

Для 2D игры это хороший и недорогой выбор. Однако одна проблема заключается в том, что необходимо позаботиться, чтобы текстуры были наложены верно, даже правильно наложенные текстуры могут легко привести к повторяющихся шаблонам. В 3D игре легко заметить, что результат такого подхода будет выглядеть дешевым. Существуют некоторые усовершенствованные варианты этого метода. Здесь представлена презентация об эффектах дождя: http://ati.amd.com/developer/gdc/2006/GDC06-Advanced_D3D_Tutorial_Day-Tatarchuk-Rain.pdf

Метод 2: Системы частиц

Системы частиц очень популярны и могут создать множество интересных эффектов. Частица представляет собой простой текстурированный объект в 3D пространстве (например, точечный спрайт), который имеет ограниченный срок действия. Каждая частица обычно произведена источником (ствол пистолета, предельная высота неба и т.д.), имеет воздействие сил (гравитации, ветра) и затем заканчиваются через некоторое заданное время.

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

Проблемы:

Решение, где создавать погодные частицы, может быть немного сложным. Один из подходов создает частицы на всех открытых частях карты, это очень неэффективно, и игра, происходящая вне помещения, быстро заполнит память, хранящую все частицы. Лучший подход, весьма распространенный в современных играх, производит частицы вокруг камеры. Проблема, которая возникает при этом, напоминает мультфильмы, где дождевое облако следует за персонажем, но тратит секунду, чтобы догнать движущийся персонаж. Если ваша камера проносится через мир, не будет никаких капель дождя или снежинок, появляющихся в течение секунды или двух!

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

Другой подход

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

Движение частиц

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

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

Это уравнение будет сохранять высоту нашей частицы в пределах (0, высота] при t> = y0. Первоначальные значения вне нашего диапазона можно избежать, используя (высота + (y0 + t * velocity.y)% высота)% высота, но t должно быть достаточно большим. Это экономит дополнительные операции со всеми частицами. С этой функцией, все, что мы должны сделать — подставить начальные положения частиц и обновить параметр времени; каждая частица будет падать, пока не достигнет 0, затем «сброс» к максимальной высоте.

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

Добавление горизонтального перемещения

Чтобы сместить наши частицы по горизонтали, мы будем использовать тот же подход, что и для их падения. Мы изменяем предыдущее уравнение, учитывая начало координат. Наши ветровые эффекты обеспечиваются velocity.x и velocity.z, и когда конкретный компонент скорости является положительным, существует упрощенная версия уравнения. В приведенном уравнении показано, как вычислить x-координату частицы:

То же самое сделано для z-координаты, и предыдущее уравнение используется для y-координаты. Наши частицы будут падать и двигаться по горизонтали, оставаясь при этом внутри области.

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

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

Погода

До этого момента, я объяснил, как создать область, которая содержит снег или дождь. Мы могли бы применить миллион частиц, чтобы охватить весь наш мир, но я уже говорил, почему это не осуществимо. Как мы тогда покроем нашу карту частицами? Скажем, наша камера может видеть частицы до определенного расстояния, d, и наша погодная область имеет ширину и высоту 2d.

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

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

Эта проблема все еще существует вне центра, как показано на четвертом изображении.

Если мы определим область, которая содержит камеру как текущую область, мы будем иметь три других смежных области. Цель заключается в том, чтобы наши смежные области всегда были расположены таким образом, чтобы камера никогда не показывала пробел, мы можем видеть пробел только, когда камера пересекает центр текущей области!

Конечно, если мы пересекаем линию центра, мы также больше не видим частиц в области противоположной движению камеры, потому что они расположены дальше на d единиц. В приведенном выше примере частицы в двух нижних областях находятся слишком далеко, чтобы их увидеть. Это имело бы место даже в том случае, если бы камера находилась наверху в центре текущей области. Это ключ к методу: при пересечении центра текущей области, две из четырех областей могут быть незаметно перемещены, так как их частицы не видны. Вы можете всегда расположить три смежных области таким образом, чтобы скрыть любые потенциальные пробелы. Камера может быть в одной из четырех возможных конфигураций относительно центра текущей области:

Теперь, когда мы знаем, когда мы должны переместить определенные области, мы должны выяснить, какие из них необходимо переместить. Есть только два возможных способа переместить области: горизонтально или вертикально. Заметим, что если камера покидает текущую область, не пересекая центр, переход не является необходимым; вместо этого мы должны заменить текущую область на ту, в которой находится камера.

Здесь представлен алгоритм обновления нашей области:

  1. Проверить, переместилась ли камера в X или Z направлениях

    1. Проверить, покинула ли камера текущую область

    1. Проверить каждую границу текущей области
      1. Если камера покинула текущую область, заменить текущую область на область, в которой находится камера
      2. Обновить состояние камеры, находящейся выше или ниже центра текущей области
    1. Проверить, пересекла ли камера центр текущей области
      1. Обновить состояние камеры, находящейся выше или ниже центра текущей области
      2. Переместить области, которые являются слишком далекими, чтобы их увидеть

Выполнение

Вы можете найти код, чтобы посмотреть, как это работает в приведенном примере, с комментариями к важным классам. Эти основные классы находятся внутри папки «погода», и основное расположение классов выглядит следующим образом:

Weather.cs – основной класс, который содержит все погодные области, обновляет и изменяет области, и передает вызовы каждой области.

WeatherRegion.cs описывает область, которая имеет погодный эффект, связанный с ней.

WeatherEffect.cs – абстрактный класс, который описывает такие эффекты, как дождь или снег.

Rain.cs и Snow.cs являются типами погодных эффектов.

HLSL шейдер файлы — Rain.fx и Snow.fx, и они оба осуществляют движение частиц, описанное ранее.

Расширение концепции

Большинство приложений имеют своего рода предельную высоту, поэтому мы проверяем движение лишь в Х или Z направлениях. Если вы хотите убрать это ограничение, используйте 8 погодных областей — еще 4, которые находятся в верхней части, показаны здесь. Тогда все, что вам нужно сделать, это проверить изменения в Y-координате положения камеры и выполнить сдвиг оси Y.

Реклама
Запись опубликована в рубрике Uncategorized. Добавьте в закладки постоянную ссылку.

Добавить комментарий

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

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s