hlsl - 如何将几何着色器与输出流结合使用?

标签 hlsl directx-11 geometry-shader

似乎这个功能的记录非常少。在 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 创建

而不是 CreateGeometryShader

您需要设置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/

相关文章:

c++ - 多个对象,不同的行为

c++ - 几何着色器计算的线在相机移动时消失

opengl - GLSL 几何着色器替换 glLineWidth

c++ - 硬编码 HLSL 着色器

directx - 在顶点着色器中采样纹理?

c++ - createInputLayout 返回 false

directx - 以编程方式创建 directx 11 纹理,三种不同方法的优缺点

c++ - HLSL:SV_Position,为什么/如何从 float3 到 float4?

directx - 如何使用 SlimDX 设置 HLSL 统一变量的值?