Как вы используете Geometry Shader с выходным потоком?

Похоже, что эта функция очень плохо документирована. В туториалах по шейдерам геометрии в DirectX SDK нет примера использования CreateGeometryShaderWithStreamOutput и нигде нет потоков, объясняющих основы этого. В msdn написано, какие функции использовать для его создания , но не как и для чего он используется. Есть ли кто-нибудь, кто успешно его использовал, можете ли вы поделиться небольшим примером или ссылкой на учебник для него? Для чего он используется и хорош ли он с точки зрения производительности? Насколько я понял , он используется для отбраковки усеченной пирамиды на основе графического процессора?


person user1700893    schedule 26.09.2012    source источник


Ответы (1)


Вы можете найти 2 примера в DirectX SDK (в разделе DirectX 10)

  • ТрубыGS
  • ЧастицыGS

Вы также можете ознакомиться с примерами NVidia: http://developer.download.nvidia.com/SDK/10/direct3d/samples.html

Rain и Metaballs используют поток

Все эти семплы на dx10, но их довольно легко портировать на dx11 (всего несколько битов для замены).

Для него существует несколько применений (неполный список):

  • Динамические частицы
  • Предварительная обработка модели (скининг, смещение, тесселяция). Таким образом, вы можете применить смещение к своей модели один раз, а затем повторно привязать смещенную модель к нескольким проходам (карта теней/материал...)
  • Экспорт модели: сгенерируйте некоторую геометрию в шейдере, верните поток вывода обратно в процессор и экспортируйте в виде 3D-модели.

Если вы хотите использовать необработанный конвейер вместо потокового вывода, вам необходимо выполнить следующее (это сводка из Microsoft Stream Output документация)

FX Framework делает то же самое под капотом.

Ваш шейдер Geometry должен быть создан с помощью CreateGeometryShaderWithStreamOutput

вместо CreateGeometryShader

Вам необходимо установить D3D11_SO_DECLARATION_ENTRY, чтобы соответствовать макету вывода вашего геометрического шейдера (это работает так же, как входной ассемблер)

Затем убедитесь, что ваш буфер создан с доступом к потоковому выводу:

D3D11_BUFFER_DESC bufferDesc;
bufferDesc.BindFlags = otherBindFlags | D3D11_BIND_STREAM_OUTPUT;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.CPUAccessFlags = 0;

Обратите внимание, что другие флаги BindFlags не могут быть D3D11_BIND_UNORDERED_ACCESS в то же время (хотя Shader View и Raw Views разрешены).

Наконец, прежде чем выполнять отрисовку, назначьте буфер вывода потока с помощью SOSetTargets:

UINT offset[1] = 0;
ID3D11Buffer* m_pBuffer (your buffer created before)
deviceContext->SOSetTargets( 1, &m_pBuffer, offset );

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

UINT offset[1] = 0;
ID3D11Buffer* pNullBuffer = 0;
deviceContext->SOSetTargets( 1, &pNullBuffer, offset );
person mrvux    schedule 27.09.2012
comment
Эти два примера Microsoft DX10 не используют API CreateGeometryShaderWithStreamOutput. Хотя они используют потоки вывода, они делают это в эффектах FX, а не в коде C++. - person Soonts; 03.04.2017
comment
Образцы nVidia делают то же самое. - person Soonts; 03.04.2017
comment
В моем случае проблема заключалась в том, что MSDN говорит «возможные значения включают: POSITION», но выдает E_INVALIDARG из API CreateGeometryShaderWithStreamOutput. Вместо этого «SV_Position» работал нормально. - person Soonts; 06.04.2017