Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Сделал мегатекстуры (2 стр)

Сделал мегатекстуры (2 стр)

Поделиться

Страницы: 1 2 3 4 5 6 Следующая

Mr FПостоялецwww24 сен. 201719:35#15
Джек Аллигатор
> Мне не очень понятно, как работают функции textureGrad, dFdx, dFdy в glsl.
> Понятно, что обычная выборка из текстуры сама определяет уровень детализации, а
> здесь мы это делаем вручную. Непонятно, как именно преобразуются координаты.
Координаты сами никак не меняются, но оказывается влияние на выбор мипов/анизотропию. Грубо говоря, чтобы выбрать подходящий мип, видюха смотрит, насколько в соседних пикселях отличаются значения UV. Чем больше они отличаются, тем, значит, мельче текстура уменьшена на экране, и тем мельче надо выбрать мип.
Когда ты вычисляешь UV в пиксельном шейдере, особенно когда читаешь в соседних пикселях куски из далёких друг от друга мест атласа, выходит что рядом UV могут очень сильно отличаться, и видюха выберет лоуресный мип - это неправильно.
dFdx/dFdy позволяют измерить насколько сильно изменяется сунутое в них значение в соседних пикселях, а textureGrad принимает посчитанные ими значения и юзает заместо встроенного определения по UV. Так ты можешь обмануть видюху, посчитав мипмаппинг/анизо на основе одних координат, а использовать другие.
Надеюсь, не слишком запутанно объяснил.

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

Правка: 24 сен. 2017 19:37

Джек АллигаторПостоялецwww24 сен. 201719:52#16
Mr F
Спасибо огромное! Многое прояснилось.
Джек АллигаторПостоялецwww2 окт. 20171:51#17
Осилил.
Осталось добить всякие мелочи в устройстве кэша и определиться со следующей проблемой.
Текстуры у меня не квадратные, а 2к1.
Можно сходу приспособить существующий код под новые условия, если размер тайлов тоже сделать 2к1.
А можно пошаманить над кодом и оставить квадратные куски. Но это потом, а пока только первый вариант попробовал.
+ тестовая текстура

Для теста взял реальную текстуру из проекта. (неправильно рассчитанная карта нормалей)
Максимальный мип 8192х4096. Это 4096 тайлов.
Всего 7 мипов. Минимальный 128х64, что соответствует размеру одного куска.
Всего кусков всех мипов 5461.
Таблица переадресации 64х64.

Изображение замечательно и сверхбыстро режется на куски с помощью imagemagick:

convert map.png -crop 128x64 tiles/tile%04d.png
Можно написать скрипт, автоматизирующий создание мипов и их разрезание на части.

Особенности конвейера:
1. Сначала составляется индекс всех частей кэша при помощи двоичной кучи.
При чтении/записи в кэш, в кучу пишется время обновления части. Так можно узнать самый невостребованный элемент кэша и писать туда. Пересортировывать кучу не надо.
2. Есть HashMap, где ключ - координаты таблицы переадресации куска + мип. По ключу получаем адрес куска в кэше. Если ключа в HashMap нет, кэшируем нужный кусок.
Двоичная куча возвращает ключ куска, ранее записанного по тому адресу, этот ключ из HashMap удаляется.
Т.о. по HashMap всегда можно узнать, какие куски есть в кэше и их адрес.
3. Каждый кадр на цпу рендерится таблица индексов кусков. Где какие мипы будут решается сразу на цпу, это избавляет от необходимости делать ненужный крюк через гпу, рендеря индексы кусков в текстуру и подгружая новые куски.
То бишь я вообще обошелся без textureGrad, dFdx, dFdy и прочего шаманства.
4. Подгружаются недостающие куски перед рендером кадра с этими кусками. Пока не вынес это дело в отдельный поток, но даже так, с подгрузкой сотен кусков за кадр фпс проседает незначительно.
5. Рендерится кадр уже стопроцентно со всеми кусками в кэше, никакой подгрузки не видно совсем.
Единственно проблема может быть если в кэше не осталось места - не подгрузятся куски высокой детализации. Но это решается настройкой размера кэша и правильным рассчетом мипов.

+ тестовый результат

"Камера" где-то в области Сибири на текстуре - там самые детализированные куски. По краям изображения, соответственно, самые низкие мипы.
По скриншоту особо не оценить результат - для загрузки на форум пришлось пожать джипегом до состояния мыла, да и тестовая сцена не самая лучшая.

Видос:




Далее ещё поэкспериментирую и перенесу результат на планету.
В связи с чем новый вопрос.
Есть три текстуры, которые планируется замегатекстурить.
Карты нормалей, высот и предрассчитанного эмбиента.
Это 3+1+1=5 каналов ui8.
Где-то в отдаленных участках памяти всплыла информация о том, что карта нормалей ужимается до двух каналов.
Т.о. всё это можно вместить в одну четырехканальную мегатекстуру.
Перспективное дело, или забить и делать две-три разные мегатекстуры?
Пока только это успел найти по теме:
http://www.gamedev.ru/code/forum/?id=121532
http://diaryofagraphicsprogrammer.blogspot.ru/2009/01/partial-der… mal-maps.html



Ещё вопрос - как получившиеся тайлы лучше запаковать, чтобы не было тысяч файлов на харде? Это на ssd пока нет проблем, а на обычном харде должно быть ад.
В каком направлении гуглить?

Правка: 2 окт. 2017 2:43

RanmaПостоялецwww2 окт. 20178:03#18
Джек Аллигатор
> Ещё вопрос - как получившиеся тайлы лучше запаковать, чтобы не было тысяч
> файлов на харде? Это на ssd пока нет проблем, а на обычном харде должно быть
> ад.
> В каком направлении гуглить?

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

0xc0deПостоялецwww2 окт. 20178:37#19
Джек Аллигатор
> Перспективное дело, или забить и делать две-три разные мегатекстуры?

Имхо, лучше одна мегатекстура, но несколько физических кешей

FordPerfectПостоялецwww2 окт. 20178:44#20
Ranma
Этому формату не обязательно быть прямо-таки собственным.
innuendoПостоялецwww2 окт. 201710:51#21
Джек Аллигатор
> 3. Каждый кадр на цпу рендерится таблица индексов кусков. Где какие мипы будут
> решается сразу на цпу, это избавляет от необходимости делать ненужный крюк
> через гпу, рендеря индексы кусков в текстуру и подгружая новые куски.
> То бишь я вообще обошелся без textureGrad, dFdx, dFdy и прочего шаманства.

у тебя частный случай :)

RanmaПостоялецwww2 окт. 201711:04#22
FordPerfect
Можно конечно дамп настоящего FAT32-раздела забубенить, потом маунтить его и читать обычными средствами - читаться будет уже через mmap (можно и NTFS, если желаете получить медаль "Месье истинно знающий толк в извращениях"). Можно сделать TAR, но и там дофига лишних полей, да ещё и длина имени ограничена. А от собственной таблицы много не надо: имя файла, смещение от начала, размер, ну и чтоб по самой таблице поиск быстрый был - можно добавить хеш от имени и по нему таблицу предварительно сортировать.
nonamezeroxПостоялецwww2 окт. 201711:27#23
Daniil PetrovПостоялецwww2 окт. 201712:11#24
Ranma
> Надо запаковать все файлы в один большой файл собственного формата с
> виртуальной файловой таблицей, при старте таблицу прочитать, чтобы знать где
> что лежит, и держать файл открытым. Функции открытия отдельных файлов заменить
> на маппинг (memory-mapped files) по заданному смещению, чтение будет просто
> работой с памятью.
Я вот хочу со временем подключить zlib для подобной канители. Насколько это нормальная затея?
Джек АллигаторПостоялецwww2 окт. 201712:29#25
Ranma
> Надо запаковать все файлы в один большой файл собственного формата с
> виртуальной файловой таблицей, при старте таблицу прочитать, чтобы знать где
> что лежит, и держать файл открытым. Функции открытия отдельных файлов заменить
> на маппинг (memory-mapped files) по заданному смещению, чтение будет просто
> работой с памятью.
С memory-mapped files уже имел дело. Хорошая идея. Спасибо.

0xc0de
> Имхо, лучше одна мегатекстура, но несколько физических кешей
Неужто в один 16к кэш всё не поместится?

innuendo
> у тебя частный случай :)
Что не так?

Daniil Petrov
> Я вот хочу со временем подключить zlib для подобной канители. Насколько это
> нормальная затея?
Присоединяюсь к вопросу.

Mr FПостоялецwww2 окт. 201713:32#26
Daniil Petrov
> Я вот хочу со временем подключить zlib для подобной канители. Насколько это
> нормальная затея?
вроде не самое быстрое, что есть. LZMA вроде быстрее.
вот этот чувак ещё всю жизнь занимается компрессией и пытается (вроде успешно) победить их всех, поищите его компрессоры: http://cbloomrants.blogspot.ru/

я сам сувал тайлы в зип и открывал через это: https://icculus.org/physfs/
идея очень хорошая, легко переключаться между файлами с харда и виртуальной файловой системой из нескольких архивов.
одно но: он не дружит с нелатинскими путями к файлам (хотя может уже починили? это проблема, когда для чего-то юзаешь абсолютные пути, а юзер положил твою прогу в "мои документы"), так что надо переделывать или брать что-то ещё, или не юзать абсолютные пути)

Правка: 2 окт. 2017 13:35

Daniil PetrovПостоялецwww2 окт. 201714:05#27
Mr F
Я вообще намерен все имена держать только в латинице, мне главное нормально работать с архивами, хотя возможно покурить и решение ID Software по работе с их pak-файлами, если опять же есть, чем их паковать.

Правка: 2 окт. 2017 14:12

0xc0deПостоялецwww2 окт. 201714:26#28
Джек Аллигатор
> 0xc0de
> > Имхо, лучше одна мегатекстура, но несколько физических кешей
> Неужто в один 16к кэш всё не поместится?

Один для дифуза, другой для нормалий, и т.д. И тайлы на диске хранить рядышком. Пример, допустим три текстуры:

| page 0 diffuse, page 0 normal, page 0 specular | page 1 diffuse, page 1 normal, page 1 specular | ...

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

0xc0deПостоялецwww2 окт. 201714:27#29
Daniil Petrov
> Я вот хочу со временем подключить zlib для подобной канители. Насколько это
> нормальная затея?

Для мегатекстуры не нужно.

Страницы: 1 2 3 4 5 6 Следующая

/ Форум / Программирование игр / Графика

Тема закрыта.

2001—2017 © GameDev.ru — Разработка игр