DirectX 11 Particle System With StreamOut

编写DirectX 11 应用程序时,我们通常是将数据发送到GPU,然后在GPU中对数据进行计算,处理,渲染出图像

但当我们需要从GPU中获得数据该怎么办,SteamOut,顾名思义,可以将GPU中的数据流输出到CPU中


在设计粒子系统时,我们需要做的三件事情是:

一:初始化粒子

二:更新粒子

三:渲染粒子

通常而言,一、二都是在CPU中完成,三由GPU完成

但是由于我们有StreamOut,我们可以将粒子的更新也由GPU完成,充分利用GPU的计算能力

将更新后的粒子通过StreamOut输出到CPU中


那么现在我们考虑这么几个问题,StreamOut输出的数据存放在哪里,如何实现StreamOut

下面对其进行讲解:

StreamOut输出的数据是输出到ID3D11Buffer中,就如同VertexBuffer一样,将其储存在Buffer中

则StreamOut输出的数据的缓存StreamOutBuffer , 与VertexBuffer的顶点格式是相同的


粒子系统中我们通常的做法是:

先使用StreamOut对粒子进行更新,将更新后的粒子存储于Buffer1中,然后再经更新后的粒子绘制出来,并作为下一帧的输入缓存

由于同一个缓存不能同时绑定两个阶段,则此时我们需要两个缓存,一个用于接收StreamOut更新后的粒子,一个用于绘制,并作为下一帧的输入缓存

即:

IA Input : Buffer2

StreamOut ------> Buffer1

Buffer1    swap data    Buffer2    // 交换Buffer1和Buffer2中的数据,则此时Buffer2中保存是更新后的粒子数据    

Render with Buffer2                    // 由于此时保存的是更新后的粒子数据,因为渲染的结果是更新后的场景  , 并且在下一帧这些的粒子作为输入被再次更新


在这里我们介绍一下SOSetTarget

void SOSetTargets(
  [in]  UINT NumBuffers,
  [in]  ID3D11Buffer *const *ppSOTargets,
  [in]  const UINT *pOffsets
);

该函数设置StreamOut输出数据的目标缓存,传入一个缓存数组,NumBuffers表示该数组中缓存的个数,pOffsets表示各缓存在缓存数组中的索引偏移量

如:

UINT offset = 0;
ID3D11Buffer* mParticleSystemStreamOutVertexBuffer = NULL;

//Init mParticleSystemStreamOutVertexBuffer
...

deviceContext->SOSetTargets( 1 , &mParticleSystemStreamOutVertexBuffer , &offset );

将缓存从StreamOut阶段解绑,只需将空缓存数组绑定到SO阶段,即可解绑,如下:

UINT offset = 0;

ID3D11Buffer* BufferArray[1] = { 0 };
deviceContext->SOSetTargets( 1 , BufferArray , &offset );


更新粒子可以通过GeometryShader来完成

该粒子系统使用两种技术:

一:通过StreamOut更新粒子,不渲染

二:渲染粒子


这里需要介绍一个函数:

HRESULT CreateGeometryShaderWithStreamOutput(
  [in]   const void *pShaderBytecode,
  [in]   SIZE_T BytecodeLength,
  [in]   const D3D11_SO_DECLARATION_ENTRY *pSODeclaration,
  [in]   UINT NumEntries,
  [in]   const UINT *pBufferStrides,
  [in]   UINT NumStrides,
  [in]   UINT RasterizedStream,
  [in]   ID3D11ClassLin
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值