Я хотел бы реализовать выбор цвета в DirectX 12. Итак, в основном я пытаюсь выполнить рендеринг для двух целей рендеринга одновременно. Первая цель рендеринга должна содержать нормальный рендеринг, а вторая должна содержать objectID.
Я думаю, что для рендеринга до двух целей рендеринга все, что вам нужно сделать, это установить их с помощью OMSetRenderTargets.
Вопрос 1: Как указать, какой шейдер или объект состояния конвейера следует использовать для конкретной цели рендеринга? Например, как вы говорите, что render_target_0 должен отображаться с помощью shader_0, render_target_1 должен отображаться с помощью shader_1?
вопрос 2: Как вы читаете пиксель из буфера кадра после его рендеринга? Это как в DirectX 11 с использованием CopySubresourceRegion, а затем Map? Вам нужно использовать кучу для чтения? Вам нужно использовать ресурсный барьер или забор или какой-то примитив синхронизации, чтобы избежать одновременного использования ресурсов буфера кадров процессором и графическим процессором?
Я попробовал поискать ответы, но не очень далеко, потому что DirectX 12 довольно новый, и пока не так много примеров, учебных пособий или проектов с открытым исходным кодом для DirectX 12.
Заранее благодарны за Вашу помощь.
Дополнительные специальные бонусные баллы за примеры кода.
Так как я не получил никакого ответа о переполнении стека, я сделал кросс-пост на gamedev.net и получил хороший ответ: http://www.gamedev.net/topic/674529-d3d12-color-picking-questions/
Для тех, кто найдет это в будущем, я просто скопирую ответ red75prime с форумов GameDev здесь.
red75prime ответ:
Вопрос 1 не относится к D3D12. Используйте один пиксельный шейдер с несколькими выходами. Рендеринг в несколько текстур за один проход в DirectX 11
Вопросы 2. Да всем.
псевдокод:
ID3D12GraphicsCommandList *gl = ...;
ID3D12CommandQueue *gqueue = ...;
ID3D12Resource *render_target, *read_back_texture;
...
// Draw scene
gl->DrawInstanced(...);
// Make ready for copy
gl->ResourceBarrier(render_target, RENDER_TARGET, COPY_SOURCE);
//gl->ResourceBarrier(read_back_texture, GENERIC_READ, COPY_DEST);
// Copy
gl->CopyTextureRegion(...);
// Make render_target ready for Present(), read_back_texture for Map()
gl->ResourceBarrier(render_target, COPY_SOURCE, PRESENT);
//gl->ResourceBarrier(read_back_texture, COPY_DEST, GENERIC_READ);
gl->Close(); // It's easy to forget
gqueue->ExecuteCommandLists(gl);
// Instruct GPU to signal when command list is done.
gqueue->Signal(fence, ...);
// Wait until GPU completes drawing
// It's inefficient. It doesn't allow GPU and CPU work in parallel.
// It's here just to make example simple.
wait_for_fence(fence, ...);
// Also, you can map texture once and store pointer to mapped data.
read_back_texture->Map(...);
// Read texture data
...
read_back_texture->Unmap();
РЕДАКТИРОВАТЬ: я добавил «gl-> Close ()» к коду.
EDIT2: переходы между состояниями для read_back_texture не нужны. Ресурсы в куче для чтения всегда должны иметь состояние COPY_DEST.
Других решений пока нет …