【问题标题】:Loading and using an HLSL shader?加载和使用 HLSL 着色器?
【发布时间】:2011-09-12 04:51:38
【问题描述】:

我一直在寻找所有我能找到的所有关于编写着色器的教程。他们都没有向我展示如何将它们合并到我的场景中。

所以本质上:

给定一个 hlsl 着色器,如果我有一个名为 drawTexturedQuad() 的函数,并且我希望将着色器应用于结果,我该怎么做呢?

谢谢

【问题讨论】:

    标签: c++ c direct3d hlsl


    【解决方案1】:

    ID3DXEffect 提供Begin()BeginPass() 方法。在此期间只需致电drawQuad()。任何有关着色器的基本教程都应该显示这样的示例。

    只是一个附加说明-如果有疑问,请询问MSDN

    【讨论】:

      【解决方案2】:

      这个问题的答案出奇地复杂,并且随着 GPU 硬件变得越来越强大而变得越来越困难。 D3DX FX 系统是所有需要完成的工作的一个示例,因此使用它是让事情在短期内正常使用的一个很好的步骤。

      着色器是代码,但它们位于 CPU 之外的另一台机器上,因此需要对它们的所有数据进行编组。固定部分:基本渲染状态,如深度状态、模板状态、混合模式、绘图命令;非常容易实现。困难的部分是为可编程部分搭建桥梁:着色器、缓冲区、采样器和纹理。

      索引缓冲区可以正常工作,因为在渲染未索引几何体的情况下,您只能有一个,或者没有。

      顶点缓冲区或多或少相当容易处理,因为可以对硬件进行编程以按程序读取顶点缓冲区。您的顶点缓冲区只需要提供至少与顶点着色器想要访问的信息一样多的信息。修改着色器的顶点输入,或需要同时编辑两侧的顶点格式,因此相当容易使用。

      采样器和纹理是下一个“更容易”挂钩的难点:它们有一个变量名和一个相当严格的类型。例如,在编译着色器“foo”时,纹理“myNormalMap”被分配纹理槽 3。您需要(通过反射 API)查找纹理被分配的槽,并将引擎认为“myNormalMap”的纹理设置为在运行时到插槽 3,当然也使用 API 来确定是否首先需要纹理。这就是着色器变量命名约定开始变得重要的地方,因此可以使多个着色器与相同的 C++ 代码兼容。

      常量缓冲区(或 D3D9 中的原始着色器常量)要复杂得多,尤其是在 Unreal 等引擎中可以找到的可编程着色器框架中。任何给定着色器使用的常量都是完整列表的子集,但 C++ 端通常必须像需要所有这些常量一样编写。反射 API 不仅需要确定着色器中实际引用了哪些变量,还需要确定它们的位置。这在 D3D10 和更新版本中变得更易于管理,因为 cbuffer 是结构体并且比 D3D9 系统流动性差,后者受到寄存器数量的严重限制,但它也增加了还需要使用反射 API 来确定 cbuffer 顺序的步骤绑定(以及哪些 cbuffers 本身也被引用)。

      最终有一种设计可以让这一切发挥作用:

      创建一个驱动特定着色器原型的类。对于这个类暴露给着色器的每个变量(无论是纹理、常量缓冲区等),在反射信息中查找它是否被使用,找出它的位置,然后设置它。保持这种快速、灵活和可扩展性都是一项艰巨的挑战。

      【讨论】:

      • "但它还增加了还需要使用反射 API 来确定 cbuffer 绑定顺序(以及哪些 cbuffer 本身也被引用)的步骤。" - 为什么不只使用相关的缓冲区偏移量,例如,如果您已加载 ShaderResourceView,请使用相关的 t0、t1 等,它们按照您将资源设置到着色器的顺序进行引用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-09
      • 2014-06-29
      相关资源
      最近更新 更多