Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Волгоградец

Рейтинг: 5.00. Голосов: 2.

Изометрическая сортировка. Новый подход.

Запись от Волгоградец размещена 25.01.2013 в 17:50
Обновил(-а) Волгоградец 06.02.2013 в 16:51

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

ВАЖНО! Это не stage3D. Я собирал под 10-й плеер. Использовался PixelBender.

Итак, что не так с общепринятыми алгоритмами? Вот вам две картинки - два спрайта.

Название: pic1.png
Просмотров: 4278

Размер: 2.8 Кб

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

TrueIso.swf   (30.6 Кб)


Управление: мышка - выбор фигуры. WASD и стрелки - перемещение в xy-плоскости. SHIFT + W/S/Up/Down - перемещение вдоль оси z.

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

Теперь главный вопрос - зачем это нужно? Собственно, не нужно ). Я даже думаю, что у этой идеи нет продолжения. Мне, как программисту и игроделу было интересно реализовать новый подход. Попутно я познакомился с парой новых алгоритмов.

P.S.: сначала я хотел написать подробное описание алгоритма с картинками. Но решил не торопиться - дело это трудоемкое, а я ленивый. Если вдруг вам покажется это интересным, я напишу.

Upd.: Мне удалось победить рваные края. Выкладываю краткое описание алгоритма и исходники.

TrueIso2.swf   (66.6 Кб)


Весь мир и все объекты я представляю в виде AABB, т.е. обычных кубиков, которые могут менять только свои x, y, z. Основа алгоритма - это использование картинок, представляющих собой глубину объекта в конкретном пикселе. Глубина - это значение от 0 (самая дальняя точка) до 1 (ближайшая точка к наблюдателю). Использую т.н. oblique projection - это когда все линии остаются параллельными при проекции. Имея мир со значением глубины 0..1 и объект также с глубиной 0..1, легко перевести глубину из локальных координат в глобальные:

Нажмите на изображение для увеличения
Название: pic2.png
Просмотров: 429
Размер:	7.9 Кб
ID:	334

Как выглядят карты глубин? Вот, например, карта для красного забора:

Название: pic3.png
Просмотров: 1671

Размер: 8.8 Кб

Странная правда? Объясню, почему она такая пестрая. В первой версии программы я использовал один канал из карты для хранения глубины. Т.е. из RGBA я юзал только R. Это 1 байт, 8 битов, целые значения от 0 до 255 (напомню, что я привожу значения к диапазону 0..1). И с этим связана проблема неточности. Помните рваные края в местах пересечений объектов? Представьте, что у нас объект, у которого физическая глубина 1000 пикселов. А мы имеем только возможность записывать данные от 0 до 255, что и вызывает проблемы. Как это побороть? Хранить величину не в одном канале, а в нескольких - чем больше, тем лучше. В связи с тем, что флэш использует цвета с предумноженной альфой (premultiplied alpha) и связанных с этим переводах значений цвета при передаче в пиксельбендер и обратно, я выбрал 3 канала для хранения глубины - RGB. A всегда равна 1. Поиск в гугле быстро дал готовое решения для запекания float в 24 бита и я сгенерировал новые карты.

Теперь сам алгоритм:
1. Берется текстура с черной заливкой, что символизирует глубину 0.
2. С помощью бленд-фильтра (blendShader) корректируется общая карта глубины - для каждого объекта смотрится значение в буфере - если глубина объекта больше глубины в буфере, записывается цвет глубины объекта. Если меньше, значит текущий пиксел находится позади и оставляем так как есть. Благодаря бленду, не нужно следить за положением объектов в дисплей листе.
3. Для всех объектов устанавливаю фильтр, где сравнивается значение глубины в каждом пикселе со значением из буфера, который мы получили в пункте 2. Если они примерно равны, то показываю пиксель основной картинки. Если нет, просто ставлю альфу у этого пикселя равной 0.

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

Теперь о плюсах и минусах.

Плюсы:
1. Не нужно заморачиваться с положением объектов в дисплей листе. Шейдеры сделаю свое дело и картинка будет выглядеть корректно.

Минусы:
1. Ооооочень медленная работа шейдеров. В демке в каждом кадре идет расчет для каждого объекта. При 10 штуках начинаются тормоза.
2. Где брать карты глубин? Нигде. Рисовать самим. Я написал класс-утилиту, которая по входным треугольникам строит карту. Для примитивных форм все достатотчно просто, но для сложной формы правильную карту сделать будет непросто.
3. Можно использовать только целые координаты x, y, z. Иначе будут артефакты.
4. Нельзя правильно отобразить полупрозрачные объекты.

Как видите, минусов больше, чем плюсов. Поэтому я прячу разработку подальше в ящик ).

Исходник: TrueIso2.zip

P.S.: доступно также на английском языке ссылка
Вложения
Тип файла: swf TrueIso.swf (30.6 Кб, 1173 просмотров)
Тип файла: swf TrueIso2.swf (66.6 Кб, 998 просмотров)
Всего комментариев 10

Комментарии

Старый 25.01.2013 18:30 expl вне форума
expl
Намучившись с сортировкой параллелограммов (учитывая, что в общем случае задача всегда решается только если все они стоят на одной плоскости) тоже подумывал о таком "z-буфере"

Рваные края - не страшно - в большинстве случаев объекты не будут пересекаться.
Тогда я даже не попытался, т.к. был уверен - что производительности для этого z-буфера не хватит.

Чисто ради любопытства, что с производительностью на саомом деле - сколько объектов в реальном времени держит?
Старый 25.01.2013 18:50 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
Хех, если честно, не пробовал. Но пиксельбендер достаточно шустрый. И если учесть, что половину расчетов нужно производить только если реально есть пересечения, то думаю производительность будет не плохая. Вобщем поле для оптимизации есть.
Старый 25.01.2013 20:17 iflamberg вне форума
iflamberg
 
Аватар для iflamberg
Нет сейчас времени код смотреть. Я наблюдаю артефакты. Если двигать параллелепипед, то на диагонали верхней грани периодически появляются белые точки. Если зависнуть параллелепипедом над "стенами", то под ним белая полоска. Ну и на пересечении стен не ровная линия среза, а какая-то "жеваная", ошибки округления?

Не знаю. Я для своего изо-движка просто "слямзил" решение из as3isolib и для параллелепипедов, в том числе, на разной высоте, там все отлично работало.

А так, круто конечно же, что уж там.
Старый 26.01.2013 00:10 Jewelz вне форума
Jewelz
 
Аватар для Jewelz
а можно код посмотреть? если на паблик не охота выкладывать, то в личку? =) спасибо
Старый 26.01.2013 02:43 expl вне форума
expl
Цитата:
Не знаю. Я для своего изо-движка просто "слямзил" решение из as3isolib и для параллелепипедов, в том числе, на разной высоте, там все отлично работало.
У меня не работало(всмысле работало с багами). Там даже на их сайте приводится картинка, которую вприципе не отсортируешь не порезав один прямоугольник на куски. А самый прикол - что as3isolib даже кучу других случаев правильно не обрабатывает (это не гон на либу, т.к. я не знаю, где это реализовано, а своя "правильная" реализация оказалась недостаточно быстой).

В бою приходилось использовать один из 2-х вариантов:
- миримся с нечастыми глюками и надеемся что в большинстве случаев сработает правильно подход as3isolib с "как-бы правильной" сортировкой параллелепипедов.
- забиваем на параллелепипеды - сортируем по одному только расстоянию от экрана, пытаясь удачно подобрать точку привязки (последнее время использовался, потому что результаты предсказуемы и, как оказалось, при определённых условиях можно и параллелепипеды использовать)
Обновил(-а) expl 26.01.2013 в 02:54
Старый 26.01.2013 13:21 derhab вне форума
derhab
 
Аватар для derhab
Цитата:
P.S.: сначала я хотел написать подробное описание алгоритма с картинками. Но решил не торопиться - дело это трудоемкое, а я ленивый. Если вдруг вам покажется это интересным, я напишу.
Да, очень интересно
Старый 06.02.2013 16:53 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
Обновил пост. Добавил новую демку, краткое описание, исходники.
Старый 06.02.2013 17:37 iflamberg вне форума
iflamberg
 
Аватар для iflamberg
Все очень круто.
Старый 06.02.2013 23:34 gloomyBrain вне форума
gloomyBrain
 
Аватар для gloomyBrain
Хром, мак, релизный 11.5 плеер. Одни артефакты.
Старый 07.02.2013 00:37 TanaTiX вне форума
TanaTiX
 
Аватар для TanaTiX
Уволок в мемориз, спасибо.
 

 


Часовой пояс GMT +4, время: 13:50.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.