Используя создание экземпляров буфера вершин, как динамически изменить положение отдельного экземпляра? - PullRequest
0 голосов
/ 01 апреля 2020

Мне нужно нарисовать миллион кубов. Кубы имеют одинаковый массив вершин, но могут иметь разный масштаб / положение / вращение. Важно: они могут динамически менять свою позицию после создания буфера вершин. Некоторые из них должны быть связаны линией. Поэтому мне также нужно рисовать линии.

В настоящее время я имею дело с инстансингом, используя постоянный буфер:

VertexShader.hlsl

struct VS_INPUT
{
float4 pos: POSITION;
float4 colour: COLOUR;
uint InstanceID: SV_InstanceID;
}
cbuffer ConstantBuffer : register(b0)
{
float4x4 view;
float4x4 proj;
float4x4 world[4000];
}

В инициализации D3D я создаю один постоянный буфер ресурс, получить адрес GPU и скопировать туда структуру объекта:

struct ConstantBufferObject
{
XMFLOAT4X4 view;
XMFLOAT4X4 proj;
XMFLOAT4X4 world[4000];
}cbNPerObject;
...
memcpy(cbvGPUAddress[i],& cbNPerObject,sizeof(cbNPerObject));

Затем я заполняю cbNPerObject.world так, как мне нужно, и в UpdatePipeline() совершаю один вызов DrawIndexedInstanced() с количеством добавленных кубов.

Все работает хорошо, за исключением одного - ограничение постоянного размера буфера. float4x4 world[4000] может быть размером 4096, но мне нужны миллионы. Создавать куски в виде постоянных буферов размером 4096 - кажется, не круто. Поэтому я решил использовать другой метод инстансинга - использовать буфер вершин.

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

1 Ответ

0 голосов
/ 02 апреля 2020

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

Здесь есть хорошее объяснение: https://www.braynzarsoft.net/viewtutorial/q16390-33-instancing-with-indexed-primitives

Это Пример основан на DX11, но принцип тот же.

Кто-то преобразовал подход к DX12 здесь: https://gamedev.stackexchange.com/questions/163077/dx12-passing-an-instance-buffer

...