似乎这个功能的记录非常少。在 DirectX SDK 的几何着色器教程中,没有使用 CreateGeometryShaderWithStreamOutput 的示例,也没有任何线程解释它的基础知识。在 msdn 中,他们说要使用哪些函数创建它,而不是如何以及它的用途。有没有人成功使用过它,您可以分享一个小示例或教程的链接吗?它的用途是什么?性能是否良好?到目前为止据我了解,它用于基于 GPU 的视锥体剔除?
最佳答案
您可以在 DirectX SDK 中找到 2 个示例(在 directX 10 部分)
- 管道GS
- 粒子GS
您还可以检查 NVidia 示例: http://developer.download.nvidia.com/SDK/10/direct3d/samples.html
Rain 和 Metaballs 正在使用流输出
所有这些示例都在 dx10 上,但它们相当容易移植到 dx11(只需替换一些位)。
它有很多用途(非详尽列表):
- 动态粒子
- 模型预处理(蒙皮、置换、镶嵌)。因此,您可以在模型上应用一次位移,然后将位移后的模型重新绑定(bind)到多个 channel (阴影贴图/ Material ...)
- 模型导出:在着色器中生成一些几何体,将流输出内容返回到 CPU 中并导出为 3D 模型。
如果您想使用原始管道而不是流输出,则需要执行以下操作(这是来自 Microsoft Stream Output documentation 的摘要)
FX 框架在底层执行相同的操作。
您的几何着色器必须使用 CreateGeometryShaderWithStreamOutput 创建
您需要设置D3D11_SO_DECLARATION_ENTRY以匹配您的几何着色器输出布局(这与输入汇编器的工作方式相同)
接下来确保您的缓冲区是通过流输出访问创建的:
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.BindFlags = otherBindFlags | D3D11_BIND_STREAM_OUTPUT;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
bufferDesc.CPUAccessFlags = 0;
请注意,otherBindFlags 不能同时为 D3D11_BIND_UNORDERED_ACCESS(但允许着色器 View 和原始 View )。
最后,在执行绘制之前,将流输出缓冲区分配为 SOSetTargets :
UINT offset[1] = 0;
ID3D11Buffer* m_pBuffer (your buffer created before)
deviceContext->SOSetTargets( 1, &m_pBuffer, offset );
完成绘制调用后,不要忘记使用以下方法进行清理:
UINT offset[1] = 0;
ID3D11Buffer* pNullBuffer = 0;
deviceContext->SOSetTargets( 1, &pNullBuffer, offset );
关于hlsl - 如何将几何着色器与输出流结合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12606556/