本文主要是介绍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
这篇关于DirectX 11 Particle System With StreamOut的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!