2013-08-08 7 views
3

Я пытаюсь написать код освещения для изометрической игры Java2D, которую я пишу - я нашел несколько алгоритмов, которые я хочу попробовать - один из которых я нашел здесь :Пытается добиться динамического освещения в изогнутой 2D изометрической среде с использованием Java2D

here

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

Если это невозможно, может ли кто-нибудь направить меня к более оптимальному алгоритму с учетом Java2D? Я рассмотрел освещение на одной плите - однако я считаю, что метод drawPolygon не аппаратно ускорен и, следовательно, работает очень медленно.

Я хочу попытаться избежать внутренних зависимостей или требования к повышенным разрешениям в апплете.

Благодаря

ответ

2

Я сделал много исследований, так как я отвечал на этот вопрос - есть тонны альтернатив и JavaFX Намерена (на более поздней версии), чтобы включить свой собственный язык шейдеров для тех, кто заинтересован. Существует также, конечно, LWJGL, который позволит вам загружать ваши собственные шейдеры на GPU.

Однако, если вы застряли в Java2D (как и я), все еще возможно реализовать освещение в изометрической игре, это просто «неудобно», потому что вы не можете выполнить затенение света на уровне пикселя.

Как это выглядит:

Я достигнут (высоко неполированный - после некоторой полировки я могу заверить вас, что будет отлично смотреться) эффектом для литья тени, глубина сортировки световой карты, и применяя освещение без испытывая падение частоты кадров. Вот как это выглядит:

casting shadows and depth sorting the light map

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

Нынешняя реализация диффузного освещения заключается лишь в том, чтобы просто сделать перекрытые области окружающим цветом и сделать не перекрытые области цветом света - очевидно, несмотря на то, что вы применили эффект затухания, когда вы продвинулись дальше от света (эта часть реализации I которые еще не сделали - но, как я сказал, что это относительно легко)

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

существу. , этот эффект достигается за счет использования множества операций в форме Java - рендеринг световой карты ускоряется с помощью VolatileImage.

Когда карта света генерируется, визуализации подпрограммы выполняет следующие действия:

  1. Создает объект Area, который содержит прямоугольник, который охватывает полноту экрана. Эта область будет содержать ваше окружающее освещение .

  2. Затем он повторяет через огни, спрашивая их, что их будет областью света, если бы не было препятствий на пути.

  3. Он принимает этот объект области и ищет мир для актеров \ Tiles , которые содержатся в этой области, что свет будет бросить в.

  4. Для каждой плитки, которые он находит, что затрудняет представление в Лайта литиевая область, он рассчитает разницу в позиции источника света и положениеобструкции (по существу создавая вектор, который указывает AT препятствие от источника света - это направление, в котором вы хотите наложить тень) Этот вектор-указатель (в мире ) необходимо перевести на экранное пространство.

  5. Как только это было сделано, перпендикуляр к этому вектору взят и нормализован. Это, по сути, дает вам линию, на которую вы можете перемещаться вверх или вниз, умножая ее на любую заданную длину, чтобы перемещаться по указанному направлению. Этот вектор равен перпендикулярно направлению, в котором вы хотите наложить тень.

  6. Почти выполнено, вы создаете многоугольник, состоящий из четырех точек. Первые две точки находятся в основании координаты экрана вашей центральной точки обструкции. Чтобы получить первый балл, вы хотите, чтобы переместил ваш перпендикулярный вектор (рассчитанный в 5) на количество на половину высоты вашей плитки [это относительно точное приближение , хотя я думаю, что эта часть алгоритма немного неверна - но он не имеет заметного распада по визуальному эффекту], а затем, конечно, добавьте к этому возникновение препятствий. Чтобы получить секунд, вы делаете то же самое, но вместо этого отправляетесь вниз.

  7. Остальные две точек вычисляются точно таким же образом - только эти пункты должны быть спроецированы наружу в направлении проекции вектора вашей тени, рассчитанном на 4. - Вы можете выбрать любой большой объем, чтобы проецировать наружу - до тех пор, пока он достигнет, по крайней мере, вне зоны заливки света (так что если вы просто хотите сделать это глупо, умножьте свой вектор проекции тени в 10 раз и вы должны быть в безопасности)

  8. От этого многоугольник, который вы только что создали, построить область, а затем вызывать метод «пересекаться» с областью вашего света как первый аргумент - thi s, убедитесь, что ваша область теней не достигает за пределами области, в которой светит ваш свет.

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

  10. Вычитайте из области окружающего освещения, которую вы построили в (1), как , так и в зоне света, и вы не применяете . ХТЫ в тех области, где эффект освещения будет принимать и визуализацию в

Теперь вам нужно объединить вашу световую карту с вашей глубиной буферного мира делают рутинную

Теперь, когда вы оказали вам 're light map, и он содержится внутри изменчивого изображения, вам нужно бросить его в рутину вашего мира и алгоритм сортировки глубины. Поскольку обратный буфер и световая карта являются одновременно изменчивыми, отображение света по всему миру относительно оптимально.

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

В любом случае, как я уже сказал, я не гарантирую, что это самый оптимальный способ - но пока он отлично работает для меня. Приложена световая карта p