使用不同着色器程序的DirectX 11渲染管道

时间:2017-09-26 17:40:08

标签: shader directx-11

我目前正在阅读Direct3D 11的实际渲染和计算。对于具有最小DirectX / OpenGL经验的人,我发现它非常有用,并给了我一些很好的指导。一切都很有意义,而且看起来很简单(尽管很重)。

但是,我目前正在阅读第3章(130多页),我仍然对一件简单事情感到困惑。

着色器程序,例如......如果您希望某些资源使用特定着色器程序,而另一个使用其他着色器程序,该怎么办?或者,每个资源的处理是否相同?这里的资源,引用顶点/索引数据,或者Texture1 / 2/3,或者......如果我有一个我正在渲染的模型,并希望它在管道中使用特定的着色器程序。

显然,必须有某种方法让一些输入沿着不同的路径进行不同的渲染结果。

但到目前为止,我还没有在书中看到它(也许我会再追上100页)。

道歉,如果这个问题已经存在,不太确定如何构建谷歌搜索这样的东西。

编辑:清晰度

假设我有一个名为ShaderA_vs.hlsl的顶点着色器,另一个名为ShaderB_vs.hlsl。现在,我加载了两个对象模型:ModelA和ModelB。我希望ModelA使用ShaderA_vs,而ModelB使用ShaderB_vs

1 个答案:

答案 0 :(得分:1)

GPU着色器编程实际上有两种不同的途径:

可编程渲染

这个模型是在Direct3D 8.1中引入的,它是"变换&基础设施的老式固定功能传统模型的演变。光"部分和"纹理混合级联"。 顶点着色器是一个着色器程序,取代了"变换& Light"和像素着色器已被替换"纹理混合级联"。

要渲染单个对象(点,线或三角形),可以设置一个顶点着色器,每个点运行一次,作为来自顶点缓冲区的原始数据(并且可能由索引缓冲区索引)。然后,硬件光栅化器为在2D屏幕上绘制的对象触摸的每个像素执行像素着色器。对于着色器和相关状态的特定组合,您可以一次绘制一个像素或40亿个三角形。

如果您想要更改任何状态或着色器程序本身的任何方面,则必须提交新的绘图。您可以在每次绘制之间更改部分或全部状态,在某些情况下,您可能需要明确清除某些状态以避免来自调试层的验证警告。

  

整个场景中的高效状态管理是一项挑战,因此请务必避免假设状态,依赖于您未设置的默认状态,并假设状态在Present之间的帧到帧之间保持不变调用

即使在现代的DirectX管道中,硬件镶嵌,几何着色器和每像素物理照明的所有装饰都是同一基本概念的扩展。

对于图形渲染,这通常是一个很好的概念模型,并且很好地映射到过去在旧的T& L + TextureBlending模型中思考的人。它还可以通过多种方式进行扩展,并且可以在关键点非常有效地使用固定功能硬件,从而可以执行一般计算中所需的操作,例如多边形扫描线转换,z缓冲深度剔除和alpha混合。 / p>

<强>计算

人们使用之前的模型用传统的可编程管道做有趣的非图形处理,你根本不关心光栅化或者顶点着色器正在做什么,你只需画一个大矩形整个渲染目标,你在像素着色器中做了很多东西。然后,您将生成的渲染目标视为某种&#39;通用缓冲区&#39;。

这里的问题是,将问题映射到这个&#34;绘图但做其他事情&#34;是一种痛苦。模型,这是我们得到的地方&#34; Compute Shaders&#34; (DirectX调用此DirectCompute)。在此模型中,您根本不使用顶点缓冲区,索引缓冲区,点/线/三角形,光栅化器或纹理混合。您只需运行一个写入缓冲区的着色器。您可以通过Dispatch直接控制着色器的实例数。

顶点着色器,像素着色器,计算着色器等都可以通过查找部分资源(纹理或被视为通用缓冲区),对它们进行计算以及将结果写入其他视频内存来完成相同的操作。由于隐含的输入,着色器的顶级调用不同,但是关于它。

计算着色器可以做的一件事就是其他着色器模型不能通过少量共享内存与其他着色器实例进行(有限的)通信。这打破了您从之前的模型中获得的极其强大的多线程优势,但却使得更容易解决某些问题。这种做法很棘手,不会造成重大停顿,通常需要手动找出所有同步以获得有效结果。

  

我应该提到第三条路径就是CUDA所做的,这是一个系统隐藏所有低级着色器的东西,假装是C.它还在做同样的和&#34;计算&#34;在幕后。