繁体   English   中英

加载和使用 HLSL 着色器?

[英]Loading and using an HLSL shader?

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

所以本质上:

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

谢谢

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

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

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

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

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

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

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

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

最后,有一种设计可以使一切正常工作:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM