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

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

Поделиться

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

Джек АллигаторПостоялецwww23 сен. 20174:05#0
talk_thumbnail | Сделал мегатекстуры

Что я нарыл за пару дней гугления и изучения сабжа:

0.
https://silverspaceship.com/src/svt/ - исходные коды, презентация и видео презентации, пару документов от id software с описанием быстрого декодирования текстур
https://www.youtube.com/watch?v=MejJL87yNgI его видео

1. Много разных названий по сути одного и того же: clipmaps, megatextures, virtual textures, sparse virtual textures.
Притом я так и не понял, в чём разница между клипмапами и всем остальным, вроде идея та же =\
Разреженные текстуры - новый термин из расширения opengl, а по сути ничего нового.

2.
- главная идея в аналогии с виртуальной памятью пк. только если там всё прозрачно для пользователя, то тут надо самому делать всю грязную работу.

ud1
Идея как у обычной виртуальной памяти. Любое 32 битное приложение может адресовать 4 Гб памяти. Но далеко не всем приложениям эти 4 Гб нужны, а реально используются скажем несколько мегабайт. Приложение адресует память с помощью 32 битного указателя, указывающий в какой-то регион виртуальной памяти. Чтоб отобразить этот указатель на физический регион памяти делается хитрая вещь, указатель бъется на две части, одна из них является номером страницы виртуальной памяти, а другая смещением в этой странице. После чего зная номер виртуальной страницы из специальной таблицы находится местоположение физической страницы памяти. Зная где находится физическая страница памяти и смещение в ней уже можно считывать/записывать значения. Примерно так.

В мегатекстурах примерно тоже самое. Есть виртуальная текстура больших размеров, скажем 64k*64k. И есть физическая текстура, уже доступных железу размеров, скажем 4k*4k. Все объекты адресуют виртуальную текстуру, чтоб по виртуальным текстурным координатам получить физические производится аналогичные преобразования. Виртуальная текстура бъется на страницы, скажем по 32*32 текселя, и есть еще одна текстура - таблица отображающая координаты виртуальной страницы в реальные.
Но тут возникает куча проблем связанных с фильтрацией текстур и еще надо знать заранее какие страницы из виртуальной текстуры нам нужны, чтоб их заранее загрузить. Access violation здесь к счастью не грозит, но на части объектов тестуры будут отсутствовать.
Virtual Texturing - what is it?

- делим крупную текстуру на кучу мелких одинакового размера всех мипов и подгружаем по мере необходимости.
- текстурные координаты - глобальные. другими словами, каждая вершина меша имеет уникальные виртуальные текстурные координаты
- по этим координатам необходимо определить уровень mip и индексы кусочков мегатекстуры.
на старом железе это делалось вручную, имея таблицу соответствий/текстуру переадресации, на новом - автоматически, через расширение GL_ARB_sparse_texture
- в любом случае, кусками придется управлять вручную, загружая необходимые и выгружая те, что не нужны для рендеринга кадра
почти что ручное управление памятью ГПУ, но с сохранением условностей что данные представляют собой текстуры
- если вообще все меши в сцене текстурируются мегатекстурой, то можно сразу выделить максимум памяти ГПУ под кэш, потому как все текстуры будут проходить через этот кэш
вроде как в новом doom так и сделали

+ Показать

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

Завтра попробую применить это на практике.
Хотя, не смотря на простоту идеи, всё ещё остается некоторая каша в голове.

Правка: 23 сен. 2017 12:51

slava_mibМодераторwww23 сен. 20178:21#1
> 1. Много разных названий по сути одного и того же: clipmaps, megatextures, virtual textures, sparse virtual textures.
Не совсем одно и тоже, дьявол в деталях ;-)

> Притом я так и не понял, в чём разница между клипмапами и всем остальным, вроде идея та же =\
Клипмапы - это фактически аналог мип-мапы (ну, если совсем на пальцах объяснять) для ландшафта. Остальное - оно больше сосредоточено на том, что бы текстурить что угодно, как угодно, в каких угодно количествах, любой формы и при этом подтягивать с диска и хранить в памяти/видеопамяти только нужное. Клипмапы чуть-чуть не так действуют - ибо они скорее далёкий предок остальных перечисленных техник ;-)

MisanthropeПостоялецwww23 сен. 201711:51#2
Джек Аллигатор
> задержка в подгрузке заметна на глаз(особенно в rage)
не то слово
Demiurg-HGПостоялецwww24 сен. 201713:49#5
Делал мегатекстуру в своем домашнем проекте.
Очень, очень, очень, ОЧЕНЬ много проблем и подводных камней.

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

Могу ответить на многие вопросы по реализации.

Правка: 24 сен. 2017 13:51

Panzerschrek[CN]Участникwww24 сен. 201714:18#6
Demiurg-HG
На твоём видео заметна мутность текстур при первом появлении затекстурированной области перед камерой. Такая же фигня наблюдалась в RAGE.
ИМХО это фатальный недостаток такого рода некоторых реализаций мегатекстур.
slava_mibМодераторwww24 сен. 201714:55#7
> некоторых
Panzerschrek[CN], некоторых?
Demiurg-HGПостоялецwww24 сен. 201715:03#8
Panzerschrek[CN]
> ИМХО это фатальный недостаток такого рода некоторых реализаций мегатекстур.
Решением этой проблемы могут быть:
1. Анализ сцены и предварительное кэширование тайлов (я полагаю, так в новом Doom сделано).
2. Здесь на видео для демонстрации загружается 60 страниц в секунду, в реальности можно грузить на порядок больше.
3. Есть реализации (Frostbite) где текстуры для terrain'а генерируются на GPU сразу после получения feedback buffer'а.

slava_mib
> некоторых?
См. выше.

Преимущества мегатекстуры очевидны:
— Мегатекстура решает проблему бесшовного стриминга текстур.
— Мегатекстура реально стримит только то, что надо.
— Мегатекстура занимает фиксированный объем памяти GPU и CPU.

Джек АллигаторПостоялецwww24 сен. 201715:25#9
Demiurg-HG
> Могу ответить на многие вопросы по реализации.
Было бы неплохо.

> Очень, очень, очень, ОЧЕНЬ много проблем и подводных камней.
Заметил пока только трудности с фильтрацией, если нужно сэмплить пиксель на границе двух кусков.
К примеру, на этой картинке
talk_thumbnail | Сделал мегатекстуры
будут проблемы между 7 и 8 кусками.
Впрочем, мне не нужна фильтрация.

Panzerschrek[CN]
> ИМХО это фатальный недостаток такого рода некоторых реализаций мегатекстур.
У меня планета, камера вращается вокруг неё по сферическим координатам и зумится по направлению к центру.
Предполагаю, зная вертикальный/горизонтальный углы поворота и зум, не составит труда подгружать нужные куски заранее.
Хочу вообще без рендера в текстуру обойтись.


Итак, вопросы.
1. Вся работа с виртуальной текстурой ограничивается подгрузкой кусков в кэш и обновлением соответствующих участков таблицы соответствий на ЦПУ? А на ГПУ шейдера делают всегда одно и то же -  конвертируют виртуальные текстурные координаты в реальные текстурные координаты кэша и делают выборку из этого кэша?
2. Мне не очень понятно, как работают функции textureGrad, dFdx, dFdy в glsl. Понятно, что обычная выборка из текстуры сама определяет уровень детализации, а здесь мы это делаем вручную. Непонятно, как именно преобразуются координаты.
В спеках glsl пишут, что эти функции доступны только во фрагментном шейдере. Как тогда узнать высоту для вершины из карты высот в вершинном шейдере?
3. Текстура переадресации не одна, а на каждый мип своя?


Изучал исходники этого товарища: https://silverspaceship.com/src/svt/
Отличные исходники, всё обильно прокомментировано, есть несколько версий шейдеров для понимания что происходит. Но всё равно замудрено как-то.
Вот к примеру:

+ Показать


Потому решил разбить задачу на несколько шагов и каждый шаг в отдельности разобрать.
Для начала без подгрузки кусков, пусть всё сразу будет на ГПУ.
Содержание кэша:

+ капитан барбосса и его мипы

Допустим, изначально текстура переадресации заполнена так:

// pagetable
let mut pt = Vec::new();
pt.push(vec2(0.0,0.0));pt.push(vec2(1.0,0.0));pt.push(vec2(2.0,0.0));pt.push(vec2(3.0,0.0));
pt.push(vec2(0.0,1.0));pt.push(vec2(1.0,1.0));pt.push(vec2(2.0,1.0));pt.push(vec2(3.0,1.0));
pt.push(vec2(0.0,2.0));pt.push(vec2(1.0,2.0));pt.push(vec2(2.0,2.0));pt.push(vec2(3.0,2.0));
pt.push(vec2(0.0,3.0));pt.push(vec2(1.0,3.0));pt.push(vec2(2.0,3.0));pt.push(vec2(3.0,3.0));
То есть, просто отображаем все куски максимальной деталлизации.

+ шейдер

Но что-то пошло не так
Снимок экрана от 2017-09-24 15:14:11 | Сделал мегатекстуры

Просьба обойтись без фейспалмов :D До меня может туго доходит, но эту технологию обязательно осилю!

Правка: 24 сен. 2017 15:26

Джек АллигаторПостоялецwww24 сен. 201715:54#10
Если выводить только координаты кусков, то всё корректно.
#version 450

in vec2 v_texc;
out vec4 out_color;

layout(location = 3) uniform sampler2D tex;
layout(location = 4) uniform sampler2D page_tex;

void main(){

  vec2 a = texture(page_tex, v_texc).xy;
  vec2 i = floor(a+0.5)/3;
  out_color = vec4(i,0,1);

}
+ Показать
Demiurg-HGПостоялецwww24 сен. 201715:59#11
Джек Аллигатор
> + капитан барбосса и его мипы
> У меня планета
Будет Барборг или Свиборосса?

Джек Аллигатор
> Вся работа с виртуальной текстурой ограничивается подгрузкой кусков в кэш и
> обновлением соответствующих участков таблицы соответствий на ЦПУ? А на ГПУ
> шейдера делают всегда одно и то же -  конвертируют виртуальные текстурные
> координаты в реальные текстурные координаты кэша и делают выборку из этого
> кэша?
В целом да. Кадр по шагам.
1. Рисуем сцену, в отдельный RT пишем необходимые нам текстурные координаты и мипы (или сразу адреса тайлов и их мипы).
2. Читаем отдельный RT на CPU и получаем список всех текстурных координат и мипов (из них получаем список необходимых нам тайлов), делаем на нем ditinct, т.е. убираем дубликаты.
3. Строим полные мип-чейны: т.е. если у нас есть страница с заданными координатами и мипом, то нам также нужны и все страницы с меньшей детализацией, которые содержат запрашиваемую страницу.
4. Опять делаем distinct на списке требуемых тайлов, сортируем его по уровню детализации, т.о. тайлы с меньшей детализацией имеют больший приоритет.
5. Если тайлов больше чем может вместить физическая текстура, выкидываем тайлы с наибольшей детализацией.
6. Отправляем список тайлов в очередь загрузки, которую обслуживает отдельный тред.
7. Из очереди загруженных тайлов получаем свежие тайлы и копируем их в физическую текстуру, обновляем текстуру переадресации.

Важный момент, надо заранее определить для себя сколько всего будет мипов, у меня в реализации их 6.

Джек Аллигатор
> 3. Текстура переадресации не одна, а на каждый мип своя?
Текстура одна, в ней несколько мипов.

Джек Аллигатор
> Мне не очень понятно, как работают функции textureGrad, dFdx, dFdy в glsl.
Весьма специфически, у каждого вендора по-разному.

> Понятно, что обычная выборка из текстуры сама определяет уровень детализации, а
> здесь мы это делаем вручную. Непонятно, как именно преобразуются координаты.
Поэтому у меня есть специальная текстура размером 64x64 (2^6), в которой 6 мипов, в каждом мипе записан номер мипа.
Из нее я делаю выборку и получаю точный мип уровень, соответствующий особенностям реализации сэмплера на GPU.

Panzerschrek[CN]Участникwww24 сен. 201716:04#12
Джек Аллигатор
> Заметил пока только трудности с фильтрацией
Надо добавлять границу к тайлам шириной в несколько пикселей, тогда такой проблемы не будет.

> У меня планета, камера вращается вокруг неё по сферическим координатам и
> зумится по направлению к центру.
Это хорошо, что проблем удастся избежать.

Джек АллигаторПостоялецwww24 сен. 201716:08#13
Demiurg-HG
Спасибо за ответы!

> Будет Барборг или Свиборосса?
Пусть для начала на плоскости будет, зачем усложнять?

> Весьма специфически, у каждого вендора по-разному.
Разве?
http://docs.gl/sl4/dFdx
http://docs.gl/sl4/textureGrad
Переформулирую вопрос.
Что такое "explicit texture coordinate gradiends"?

0xc0deПостоялецwww24 сен. 201716:09#14
Джек Аллигатор
> Заметил пока только трудности с фильтрацией, если нужно сэмплить пиксель на
> границе двух кусков.

Для каждого тайла генерят бордеры во время построения SVT.

> 1. Вся работа с виртуальной текстурой ограничивается подгрузкой кусков в кэш и
> обновлением соответствующих участков таблицы соответствий на ЦПУ? А на ГПУ
> шейдера делают всегда одно и то же -  конвертируют виртуальные текстурные
> координаты в реальные текстурные координаты кэша и делают выборку из этого
> кэша?

Да.

> Как тогда узнать высоту для вершины из карты высот в вершинном шейдере?

Для террейна SVT не подходит. Только для текстурирования. Максимум - микрорельеф, который вычитывается из самого детального лода.

> 3. Текстура переадресации не одна, а на каждый мип своя?

Зависит от реализации. У меня была одна текстура переадресации с количеством мип-уровней равному количеству лодов в SVT.

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

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

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

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