像素着色器实际上做了什么?

Fat*_*sis 8 pixel-shader direct3d11

我对图形编程比较陌生,而且我刚读过一些书籍并且一直在扫描教程,所以请原谅我这是否是一个愚蠢的问题.

我已经掌握了directx11的基础知识,现在我想要玩得开心.所以很自然地我一直在深入阅读着色器管道,我已经着迷了.编写一个简单,微不足道的代码片段的想法必须足够有效,每60秒运行数万次而不浪费资源,这让我急于掌握这个概念,然后再继续并可能弄得一团糟东西的.我遇到的问题是掌握像素着色器实际上在做什么.

顶点着色器很容易理解,您可以在一个统一的数据结构中组织一个对象的顶点,这些数据结构与它的信息相关,比如位置和纹理坐标,然后将每个顶点传递到着色器,通过变换矩阵从3d转换为2d .只要我理解它,我就可以找出如何编码它.

但我没有像素着色器.我得到的是顶点着色器的输出是像素着色器的输入.那么只是将像素着色器交给多边形顶点的2d坐标吗?我所了解的是,像素着色器接收单个像素并对其进行计算以确定颜色和光照等事物.但如果那是真的,那么哪个像素呢?整个屏幕还是只是位于变换的2d多边形内的像素?

或者我完全误解了什么?

Dam*_*mon 10

顶点着色器很容易理解,您可以在一个统一的数据结构中组织一个对象的顶点,这些数据结构与它的信息相关,比如位置和纹理坐标,然后将每个顶点传递到着色器,通过变换矩阵从3d转换为2d .

在此之后,生成并剪切基元(三角形或三角形的三角形)(在Direct3D 11中,由于变换反馈,几何着色器,细分,你的名字,它实际上有点复杂......但不管它是什么,在结束你有三角形).

现在,片段被"生成",即单个三角形被划分为具有规则网格的小单元格,顶点着色器的输出属性根据每个网格单元与三个顶点的相对位置进行插值,并设置"任务"每个小网格单元格.这些单元中的每一个都是"片段"(如果使用多重采样,则对于一个像素1可以存在若干片段).

最后,在所有这些"任务"上执行一个小程序,这是像素着色器(或片段着色器).

它采用插值顶点属性,并可选择读取均匀值或纹理,并生成一个输出(它也可以选择性地生成多个输出).像素着色器的这个输出指的是一个片段,然后被丢弃(例如由于深度测试)或者与帧缓冲器混合.通常,同一像素着色器的许多实例同时并行运行.这是因为像这样运行GPU的效率更高,功效更高.一个像素着色器不知道同时运行的任何其他像素着色器.
像素着色器通常在组中运行(也称为"warp"或"wavefront"),并且一个组内的所有像素着色器同时执行完全相同的指令(在不同的数据上).同样,这允许构建更强大的芯片,用户使用更少的能源,并且更便宜.




1请注意,在这种情况下,片段着色器仍然只为每个"单元格" 运行一次.多重采样仅根据(更高分辨率)深度测试确定它是否将计算值存储在较高分辨率的额外"时隙"(子样本)之一中.对于屏幕上的大多数像素,所有子样本都是相同的.然而,在边缘上,只有一些子样本将被特写几何体填充,而一些子样本将保持其值远离更远的"背景"几何体.当多重采样图像被解析(即,转换为"正常"图像)时,图形卡会生成这些子样本的"混合"(在最简单的情况下,只是算术平均值),这会产生除边缘以外的所有内容与往常一样,边缘被"平滑".

  • 见[这里](http://i.msdn.microsoft.com/dynimg/IC340510.jpg)(或[这里](http://www.lighthouse3d.com/wp-content/uploads/2011/03/pipeline4 .png)对于OpenGL 4.x等效,更好的图像,略有不同的名称,但同样的事情).为几个_practical_和_efficiency_原因运行tesselation _after_顶点着色器是有意义的(例如,如果不知道补丁所覆盖的屏幕区域,你将如何知道多少次?).你不是简单地将每个三重顶点都镶嵌成千个三角形.你根据他们实际覆盖的屏幕面积来做到这一点. (2认同)