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

Dynamic vertex pulling в Direct3D11 (комментарии)

Страницы: 1 2 3 Следующая »
#0
0:07, 22 янв 2015

Dynamic vertex pulling в Direct3D11 (комментарии)

Это сообщение сгенерировано автоматически.

#1
0:10, 22 янв 2015

Вий
> с виду они как раз совершенно одинаковые!
+1
Инстансинг какой то

#2
0:55, 22 янв 2015

Внимательнее читать надо :)

Вий
> а в чем уникальность кубиков?
Каждый кубик создаётся как отдельный меш. В данный момент там действительно одинаковые кубики, но это не один кубик, нарисованный 16 тысяч раз, а 16 тысяч кубиков, нарисованных 16 тысяч раз.
Код из примера:

for (int i = 0; i < kNumMeshes; ++i) { // create a lot of 'unique' meshes
    cubeVertexBuffers[i] = sgfx::createBuffer(sgfx::BufferType::Vertex, cubeVertices, sizeof(CommonVertex) * verticesSize, sizeof(CommonVertex));
    cubeIndexBuffers[i]  = sgfx::createBuffer(sgfx::BufferType::Index, cubeIndices, sizeof(uint32_t) * indicesSize, sizeof(uint32_t));
}

На днях выложу скриншот, где не кубики, а густой разнообразный лес с травой и кустами :)

#3
1:45, 22 янв 2015

bazhenovc
> Код из примера:
А где он? в репозитории его нет

Я вот что хочу спросить - а это чудо нормально отсекается по фрустуму? если 16 тысяч деревьев, то не все же они видимы.

#4
7:22, 22 янв 2015

1. DrawInstanced надо вызывать с максимальным количеством вершин, которое есть в буфере команд.
  Это необходимо потому, что вызов отрисовки у нас 1, и если у мешей разное количество вершин или индексов — это нужно как-то учитывать. Я предпочитаю всегда рисовать наибольшее количество вершин, а лишние отсекать, отправляя их за clipping plane.
  Таким образом появляется много дополнительной ненужной нагрузки на вершинный шейдер, поэтому надо следить за тем, чтобы разница между минимальным и максимальным vertex count была в разумных пределах (500—600 вершин). Нужно помнить, что эта разница равна количеству «мусорных» вершин на каждый инстанс, и она растёт со скоростью геометрической прогрессии в квадрате. Следите за художниками!

Открыл в надежде почитать, как это сделать без мусорных вершин, так как это и есть самый серьезный недостаток данного способа. Жопа будет когда будет куча маленьких ростков в далеке, с минимальным LOD, и одно большое дерево с максимальным LOD.
А вообще этот способ был доступен с тех пор, как появились текстуры в вершинных шейдерах. Складываем в текстуру, обращаемся по индексу. Так что DX11 или OpenGL 4.0 не обязателен.
Да и пример слабоват.

1. 4 базовых вида деревьев,
2. 3 стадии роста для каждого дерева (росток, деревце, большое дерево),
3. 3 стадии здоровья для каждой стадии роста дерева(здоровое, больное, умирающее),
4. 5 уровней детализации (LOD) для каждой стадии здоровья каждой стадии роста каждого дерева (включая импостеры).

180 батчей в пике. Не такой уж и оверхед для CPU. В особенности если хранить все в одном вертекс буфере, чтобы биндить лишь однажды.

В общем CPU то мы разгрузим, а вот GPU ушатаем кешмиссами и мусорными вершинами (которых будет львиная доля)

#5
9:28, 22 янв 2015

Да это же Mantle API ! :) Наверное , скоро будет и SDK от bazhenovc-ча

#6
11:11, 22 янв 2015

war_zes
> Я вот что хочу спросить - а это чудо нормально отсекается по фрустуму? если 16
> тысяч деревьев, то не все же они видимы.
Да, отсекается нормально и вкручивается в существующие движки очень прозрачно.

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

MrShoor
> Открыл в надежде почитать, как это сделать без мусорных вершин, так как это и
> есть самый серьезный недостаток данного способа.
В OpenGL есть MultiDrawIndirect, там можно без мусорных вершин сделать. У NVidia даже пример есть: http://docs.nvidia.com/gameworks/content/gameworkslibrary/graphic… ectsample.htm

> Жопа будет когда будет куча маленьких ростков в далеке, с минимальным LOD, и одно большое дерево с максимальным LOD.
Я большие деревья на этапе загрузки разбиваю на маленькие куски, чтобы совпадало с минимальным лодом. Импостеры рисуются отдельно обычным инстансингом.

> А вообще этот способ был доступен с тех пор, как появились текстуры в вершинных шейдерах. Складываем в текстуру, обращаемся по индексу. Так что DX11 или OpenGL 4.0 не обязателен.
В один пиксель текстуры помещается один float4, а формат вершины обычно подразумевает ещё и нормаль и прочую разный хлам. У нас вертех дерева занимает 64 байта(48 байт полезных, 16 байт паддинг), если хранить всё в текстуре - надо было бы делать несколько выборок, против одной выборки из StructuredBuffer.

> Да и пример слабоват.
Да, я знаю, я скоро пример получше выложу.

> В общем CPU то мы разгрузим, а вот GPU ушатаем кешмиссами и мусорными вершинами (которых будет львиная доля)
Ну я и не спорю, более того - это и было основной целью, разгрузить CPU любой ценой :) Ну и при правильном подходе мусорные вершины не будут серьёзной проблемой.

#7
12:35, 22 янв 2015

bazhenovc
> В OpenGL есть MultiDrawIndirect, там можно без мусорных вершин сделать. У NVidia даже пример есть: http://docs.nvidia.com/gameworks/content/gameworkslibrary/graphic… ectsample.htm
Дык так и надо было разгружать CPU, а не вот таким вот велосипедом.

> В один пиксель текстуры помещается один float4, а формат вершины обычно
> подразумевает ещё и нормаль и прочую разный хлам. У нас вертех дерева занимает
> 64 байта(48 байт полезных, 16 байт паддинг), если хранить всё в текстуре - надо
> было бы делать несколько выборок, против одной выборки из StructuredBuffer.
Существенной разницы не будет. Все 3-4 выборки лягут в кеш. Я уже давно так гоняю материалы и трансформации.

Вий
> А тогда опиши этот самый правильный подход при котором мусорные вершины не
> будут серьезной проблемой!
А что там описывать то? Правильный подход - Indirect буфера. Описано в документации к DX и OGL

#8
12:39, 22 янв 2015

MrShoor
> Дык так и надо было разгружать CPU, а не вот таким вот велосипедом.
Нам надо поддерживать D3D10-железки, где нет ни индиректа, ни 4-го OpenGL :)
Да и шипать проект на OpenGL я бы не рискнул, по крайней мере в ближайшие года 3.

> Существенной разницы не будет. Все 3-4 выборки лягут в кеш. Я уже давно так гоняю материалы и трансформации.
На самом деле там не всё так радужно из-за постоянного рандомного доступа к памяти.

> А что там описывать то? Правильный подход - Indirect буфера. Описано в документации к DX и OGL
Всё так, но в D3D10 feature level DrawIndirect отсутствует в каком-либо виде.

Помимо этого D3D11 не умеет MultiDrawIndirect, а в свете того, что DX12 будет только на Win10 - с DX11 мы не расстанемся ещё очень долго.

#9
13:26, 22 янв 2015

bazhenovc
Все это здорово. Но эта техника, больше на костыль похожа. Вроде и интересно , но и как то не то.

Какой смысл в этом будет, когда выйдет Mantle API SDK и Directx 12 ?
К весне-лету по слухам будет Mantle API SDK, а Directx 12 будет в конце 2015.

Мало того что Mantle API и Directx 12 прекрасно побеждают разгрузку CPU, так еще имеют новые техники рендера и большую гибкость.


Если мне не веришь то посмотри свои sdk по Mantle API  и Directx 12, о которых ты успел всем тут на форуме растрезвонить, что они у тебя есть.

#10
13:38, 22 янв 2015

ronniko
> Все это здорово. Но эта техника, больше на костыль похожа. Вроде и интересно ,
> но и как то не то.
Это и есть костыль ;)

> Какой смысл в этом будет, когда выйдет Mantle API SDK и Directx 12 ?
Не будет никакого, но только тогда, когда мы сможем полностью отказаться от D3D11, что случится не скоро.
Эта техника специально предназначена как некий переходный вариант между D3D11 и D3D12, не стоит относится к ней как к чему-то революционному или универсальному.

> Если мне не веришь
Почему это не верю?:)

#11
13:51, 22 янв 2015

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

> На самом деле там не всё так радужно из-за постоянного рандомного доступа к памяти.
Ты сейчас о чем? Позиция/нормаль/ит.п. должны лежать рядом в текстуре. А если между вертексами, так со Structured буфер ровно то же самое, рандомный доступ.

> Помимо этого D3D11 не умеет MultiDrawIndirect
Да ну, правда?

#12
13:53, 22 янв 2015

ronniko
>Какой смысл в этом будет, когда выйдет Mantle API SDK и Directx 12 ?
>К весне-лету по слухам будет Mantle API SDK, а Directx 12 будет в конце 2015.
Mantle SDK работает только на AMD, а DX12 - только на Windows 10.
А что делать людям, которые сидят на nvidia + windows 7-8? А это, между прочим, крупнейший сегмент
рынка на данный момент (и, возможно, еще на много много лет). Да и перспективы Win10 весьма туманны, если микры опять нафакапят
с чем-нить, то никто не будет на неё переходить и dx12 вообще останется за бортом.

Как видишь, это не панацея.

> Мало того что Mantle API и Directx 12 прекрасно побеждают разгрузку CPU, так еще имеют новые техники рендера и большую гибкость.
Да ты кэп. Спасибо хоть картинки больше не пихаешь в каждое свое сообщение.

#13
14:02, 22 янв 2015

Mephisto std

А что делать людям, которые сидят на nvidia + windows 7-8?

Если так задавать вопрос.
То я точно так же могу задать такой же вопрос тебе  Mephisto std.
А что делать людям которые сидят на Directx 9 ? И которые юзают даже Windows XP.
Там Directx 10 и 11 нет.

#14
14:15, 22 янв 2015

MrShoor
> Да ну, правда?
Ты не видишь разницы между DrawIndirect и MultiDrawIndirect?

Просто DrawIndirect:

const DrawArraysIndirectCommand  *cmd  = (const DrawArraysIndirectCommand  *)indirect;
DrawInstanced(mode,  cmd->first,  cmd->count,  cmd->instanceCount, cmd->baseInstance);

MultiDrawIndirect:

for (int n = 0; n < drawcount; n++) {
    const DrawArraysIndirectCommand  *cmd;
    if (stride != 0) {
        cmd = (const DrawArraysIndirectCommand  *)((uintptr)indirect + n * stride);
    } else {
        cmd = (const DrawArraysIndirectCommand  *)indirect + n;
    }
 
    DrawInstanced(mode,  cmd->first,  cmd->count,  cmd->instanceCount, cmd->baseInstance);
}

Мусорные вершины можно убрать только использовав MultiDrawIndirect, которого в D3D11 нет, есть только обычный DrawIndirect.

Для справки:
https://www.opengl.org/wiki/GLAPI/glDrawArraysIndirect
https://www.opengl.org/wiki/GLAPI/glMultiDrawArraysIndirect

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.