使用顶点缓冲区实例化,如何动态更改单独的实例位置? [英] Using vertex buffer instancing, how to dynamically change separate instance position?

查看:200
本文介绍了使用顶点缓冲区实例化,如何动态更改单独的实例位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to draw million cubes. Cubes has the same vertex array, but may have different scale/position/rotation. Important: they may change their position dynamically, after vertex buffer creation. Some of them should be connected by the line. So I also need to draw lines.

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

Currently I deal with the instancing using constant buffer:

VertexShader.hlsl

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地址并在那里复制结构对象:

In D3D initialization I create one constant buffer resource, get the GPU address and copy there structure object:

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

然后我按照需要的方式填充cbNPerObject.world,并在UpdatePipeline()中使用添加的多维数据集数进行一次调用DrawIndexedInstanced().

Then I fill cbNPerObject.world the way I need and in the UpdatePipeline() make one call DrawIndexedInstanced() with number of cubes I added.

一切正常,除了一件事-恒定的缓冲区大小限制. float4x4 world[4000]的最大大小为4096,但我需要数百万.以4096大小的常量缓冲区的形式创建块-似乎并不酷.因此,我决定使用另一种实例化方法-使用顶点缓冲区.

All works good, except one thing - constant buffer size restriction. float4x4 world[4000] can be maxim 4096 sized, but I need millions. Create chunks in form of constant buffers with 4096 size - seems not cool. So I decided to use another method of instancing - use vertex buffer.

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

I don’t understand how can I dynamically transform my instances when I use vertex buffer, because to change vertex buffer I have to change vertexBufferView which also seems incorrect. As far as I understand for instancing by this way I need to create instance buffer and store it together with vertex buffer or what, Im confused

推荐答案

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

You need to use an instance buffer; effectively storing the positions in a new vertex buffer which you map into memory and modify before submitting. Inside the vertex shader you then have access to the instance position for the thing you are currently drawing.

这里有一个很好的解释: https://www.braynzarsoft.net/viewtutorial/q16390-用索引原语实例化33个

There's a good explanation of it here: https://www.braynzarsoft.net/viewtutorial/q16390-33-instancing-with-indexed-primitives

此示例基于DX11,但原理相同.

This example is based on DX11, but the principle is the same.

有人在这里将方法转换为DX12: https://gamedev.stackexchange.com/questions/163077/dx12-passing-an-实例缓冲区

Somebody converted the approach to DX12 here: https://gamedev.stackexchange.com/questions/163077/dx12-passing-an-instance-buffer

这篇关于使用顶点缓冲区实例化,如何动态更改单独的实例位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆