c++ - 使用顶点缓冲区实例化,如何动态改变单独的实例位置?
问题描述
我需要画一百万个立方体。立方体具有相同的顶点数组,但可能具有不同的比例/位置/旋转。重要提示:在创建顶点缓冲区后,它们可能会动态更改其位置。其中一些应该通过线路连接。所以我还需要画线。
目前我使用常量缓冲区处理实例化:
顶点着色器.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
这似乎也不正确。据我了解以这种方式进行实例化,我需要创建实例缓冲区并将其与顶点缓冲区或什么一起存储,我很困惑
解决方案
您需要使用实例缓冲区;有效地将位置存储在新的顶点缓冲区中,您可以将其映射到内存中并在提交之前进行修改。在顶点着色器中,您可以访问当前正在绘制的事物的实例位置。
这里有一个很好的解释: https ://www.braynzarsoft.net/viewtutorial/q16390-33-instancing-with-indexed-primitives
这个例子是基于DX11,但是原理是一样的。
有人在这里将方法转换为 DX12: https ://gamedev.stackexchange.com/questions/163077/dx12-passing-an-instance-buffer
推荐阅读
- c# - 为什么 Point[] 在 winforms 集合编辑器中不能正常工作(通过 PropertyGrid)?
- c - 在 C 中寻址多维数组
- javascript - 如何使用正则表达式将内容包装在某个 html 标记内而不影响任何 html 标记
- asp.net-web-api - 我无法使用 umbraco 项目在 WebAPI 中使用 Get 方法
- c# - 与测试证书一起使用,但在使用生产证书时,我得到“请求被中止:无法创建 SSL/TLS 安全通道。”
- android - 使用支持库 27.1.1,当我开始一项活动时,我的应用程序冻结
- r - tsne 去除降维过程中的case
- sql - 将一行记录显示到多列
- unity3d - 为什么我会收到以下上传错误,我该如何解决?
- macos - libusb 在 Cocoa App 上返回零设备