首页 > 解决方案 > 使用顶点缓冲区实例化,如何动态改变单独的实例位置?

问题描述

我需要画一百万个立方体。立方体具有相同的顶点数组,但可能具有不同的比例/位置/旋转。重要提示:在创建顶点缓冲区后,它们可能会动态更改其位置。其中一些应该通过线路连接。所以我还需要画线。

目前我使用常量缓冲区处理实例化:

顶点着色器.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]可以是 maxim 4096 大小,但我需要数百万。以 4096 大小的常量缓冲区的形式创建块 - 似乎并不酷。所以我决定使用另一种实例化方法——使用顶点缓冲区。

我不明白如何在使用顶点缓冲区时动态转换我的实例,因为要更改顶点缓冲区,我必须更改vertexBufferView这似乎也不正确。据我了解以这种方式进行实例化,我需要创建实例缓冲区并将其与顶点缓冲区或什么一起存储,我很困惑

标签: c++directxdirectx-12geometry-instancing

解决方案


您需要使用实例缓冲区;有效地将位置存储在新的顶点缓冲区中,您可以将其映射到内存中并在提交之前进行修改。在顶点着色器中,您可以访问当前正在绘制的事物的实例位置。

这里有一个很好的解释: https ://www.braynzarsoft.net/viewtutorial/q16390-33-instancing-with-indexed-primitives

这个例子是基于DX11,但是原理是一样的。

有人在这里将方法转换为 DX12: https ://gamedev.stackexchange.com/questions/163077/dx12-passing-an-instance-buffer


推荐阅读