18 мая 2011
В конце последнего обновления я сказал, что собираюсь оставить прозрачность пока в покое и вернуться к ней позже. Я солгал... Я просто не мог оставить её в покое.
В последней части я подумал, что у меня есть хорошее решение для прозрачности - техника "экранной двери". Оказалось, что я внедрил ее неправильно и даже не заметил, что она не работает. Причина в том, что этот конкретный ландшафт Minecraft не делает ничего сложного. У нас всего три прозрачных блока - вода, стекло и листья. Вода в основном лежит ровно над землей и не нуждается в сортировке. Стекло в основном затуманивает другие стеклянные или непрозрачные вещи, и его не нужно сортировать. А листья появляются в пучке вокруг дерева и ошибки сортировки не очень заметны.
Когда я правильно реализовал прозрачность двери, она выглядела довольно плохо, и я понял, что она просто не достаточно хороша. Я хотел перейти к более глобальному построению мира, но вопрос все еще ворчал на меня. В конце концов, я хочу позволить пользователям создавать свои собственные блоки с собственными текстурами. Что, если я просто не смогу реализовать это из-за времени, необходимого для корректного рендеринга прозрачных данных?
Это видео - кошмар, который меня преследует. Посмотрите его в 480p, чтобы увидеть истинный ужас сглаживания!
Читатель Саймон Бакэн предложил прозрачность "Quake 2-style", где полутонирование происходит не на поверхности визуализируемого объекта, а во "view-пространстве". Это предотвращает наложение псевдонимов (в основном) и сверкание при движении. Это выглядит лучше, и я пытался сказать себе, что это достаточно хорошо. Вот видео. Если сфокусировать взгляд на шуме полутонового рисунка, то можно увидеть, что он движется вместе с экраном, а не с миром.
Сортируем реже
Флориан дал мне большой список вещей, которые нужно попробовать в отношении прозрачности. Некоторые из них представляли собой один и тот же разумный совет - если сортировка стоит слишком дорого, то сортируйте реже. Например:
- Распределите сортировку по нескольким кадрам. Глаз не заметит, если вещи на короткое время окажутся в неправильном порядке.
- Сначала сортируйте близлежащие объекты, а удаленные оставляйте на потом. Ошибки на расстоянии будут не так заметны.
- Сортируйте только тогда, когда нужно сортировать - когда глаз движется и меняет перспективу на кусочек сцены.
Если бы мы рисовали на сцене произвольные треугольники, то потенциально любое изменение положения глаз могло бы изменить порядок сортировки. Но все эти сцены - кубы, и они лучше себя ведут. Оказывается, есть быстрый тест на то, нужно ли нам сортировать кусок после хода.
Если подумать, какие кубы находятся ближе всего к глазу в начальной и конечной позиции, то можно увидеть, что только при переходе глаза между двумя разными рядами кубов нам нужно отсортировать. Офф-концы - это особый случай - если глаз движется в одну сторону кубика, это не влияет на порядок сортировки. Мы делаем этот тест в x, y и z, и если ни один из них не требует повторной сортировки, мы оставляем кусок в покое.
На практике это дает несколько странный результат. При перемещении одного блока все куски к горизонту в тех же X, Y или Z, что и глаз, повторно сортируются, в то время как куски к боковым сторонам остаются неизменными. Так как ландшафт в основном горизонтальный, то при вертикальном перемещении вы получаете действительно большие размеры (целую плоскость кусков).
Я добавил код, чтобы сохранить список "сортируемых" кусочков. В процессе визуализации он тестирует каждый кусочек и добавляет его в этот список. На каждом фрейме мы сортируем некоторое количество кусочков из списка. В конце концов, это будет контролироваться некоторой оценкой того, сколько процессорного времени я могу себе позволить. Сейчас это опция "sortCount".
Этот простой алгоритм выполняет все три оптимизации, которые я перечислил выше. Сортировка выполняется по несколько кусков за раз, от ближнего до дальнего, и только при движении.
Это видео показывает создаваемый и обрабатываемый список сортировки. Кусочки отрисовываются красным цветом, когда тест сортировки говорит, что их может понадобиться отсортировать.
Видео было снято со скоростью 30 кадров в секунду с 2 отсортированными кусочками на кадр. В демо, я получаю больше похоже на 90 кадров в секунду и сортирую по 10 кусочков за раз, так что вы не можете увидеть, что происходит на самом деле. Кроме того, я даже не проверяю кусочки без прозрачных кубиков. Мне было трудно даже сказать, делает ли он сортировки (потому что так мало сортировки требуется на этом пейзаже), поэтому я добавил кучу плавающих коробок с прозрачными сторонами.
Это видео показывает конечный результат. На моих машинах, я еще не поймал его с некорректной областью. Частота смены кадров нормальная, даже на моих более медленных машинах с Linux. Попробуйте и дайте мне знать. На данный момент я удалил сводку точек на расстоянии, поэтому опции "summarDistance" и "detailDistance" не дают никакого эффекта.
Я доволен этим, так что теперь я могу вернуться к построению мира!
Построй свой собственный пейзаж
В исходном коде появился новый проект под названием BuildWorld. Это бекенд кода извлечения из Minecraft, который позволит вам создать свой собственный ландшафт. Вам понадобятся инструменты программирования, чтобы перекомпилировать код, но в остальном навыков программирования немного. В файле Source/BuildWorld/BuildWorld.cpp найдите процедуру createWorld. Вы можете написать что-нибудь простое:
// add a terrain from noise for (int x = 0; x < WORLD_XSIZE; x++) { for (int z = 0; z < WORLD_ZSIZE; z++) { double value = (noise(x*DENSITY, z*DENSITY) - noiseMin)/noiseRange; int height = 5+(int) (MAXHEIGHT * value); height = max(0, min(WORLD_YSIZE-1, height)); for (int y = 0; y < height; y++) { WORLD_CELL(x, y, z) = 1; // stone } } }
Вы устанавливаете байты в большом массиве (1024 на 128 на 1024). Установите любой шаблон блоков, который вам нравится. Цифры для различных типов блоков можно найти в docs/blocks/mcblocks.xml в демонстрационной версии Crafty. Программа BuildWorld создаст этот массив и установит все видимые флаги, а затем запишет огромный каталог блоков для использования в Crafty. Если вы хотите мир поменьше, вы можете изменить его размер в файле BuildWorld.cpp. Просто убедитесь, что ваши размеры кратны 32.
Создайте каталог "newworld", в который он будет записывать чанки. Запустите его, и он создаст ландшафт, как показано на рисунке 2:
Отредактируйте файл options.xml в Crafty, чтобы установить "worlddir" вместо "newworld", и вы сможете отобразить свой мир.
Демо
Демо-версия 20 будет использовать те же файлы мира, что и части 19 и 15. Скачайте The Part 19 Demo World. Распакуйте ее в тот же каталог, что и демо. Каталог "world" должен быть рядом с "docs" и "options.xml". Или вы можете отредактировать атрибут "worldDir" в "options.xml", чтобы указать на него.
Для Windows, качайте The Part 20 Demo - Windows.
Для Linux, качайте The Part 20 Demo - Linux.
Исходники
Качайте The Part 20 Source, или идите на https://github.com/mgoodfel/SeaOfMemes гитхаб.
- Войдите или зарегистрируйтесь, чтобы оставлять комментарии