【问题标题】:What does a pixel shader actually do?像素着色器实际上是做什么的?
【发布时间】:2012-06-25 16:52:16
【问题描述】:

我对图形编程比较陌生,而且我刚刚阅读了一些书籍并且一直在浏览教程,所以如果这似乎是一个愚蠢的问题,请原谅我。

我已经掌握了 Directx11 的基础知识并开始运行,现在我想找点乐子。所以很自然地,我一直在大量阅读着色器管道,我已经着迷了。编写一段简单、微小的代码,它必须足够高效,以每 60 秒运行数万次而不浪费资源,这让我急于掌握这个概念,然后再继续下去,可能会弄得一团糟东西的。我遇到的问题是掌握像素着色器实际在做什么。

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

但我没有像素着色器。我得到的是顶点着色器的输出是像素着色器的输入。那么这不就是将多边形顶点的二维坐标交给像素着色器吗?我所理解的是像素着色器接收单个像素并对它们执行计算以确定颜色和照明等内容。但如果这是真的,那么哪些像素呢?整个屏幕还是仅位于转换后的二维多边形内的像素?

还是我完全误解了什么?

【问题讨论】:

    标签: pixel-shader direct3d11


    【解决方案1】:

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

    在此之后,生成并裁剪图元(三角形或三角形的倍数)(在 Direct3D 11 中,由于变换反馈、几何着色器、曲面细分等等,它实际上要复杂一些……但不管它是什么,最后你有三角形)。

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

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

    它采用插值的顶点属性,并可选择读取统一值或纹理,并产生一个输出(它也可以可选择地产生多个输出)。像素着色器的此输出引用一个片段,然后被丢弃(例如由于深度测试)或与帧缓冲区混合。 通常,同一像素着色器的许多实例会同时并行运行。这是因为像这样运行 GPU 会更高效、更节能。一个像素着色器不知道同时运行的任何其他像素着色器。
    像素着色器通常在一组中运行(也称为“扭曲”或“波前”),并且一组中的所有像素着色器同时执行完全相同的指令(在不同的数据上)。同样,这允许构建更强大的芯片,消耗更少的能源,更便宜。




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

    【讨论】:

    • 好的,我想我现在明白了。因为我是一个视觉学习者,所以我制作了一张我认为你所描述的图表,所以如果我遗漏了什么,请告诉我。 postimage.org/image/9oy2nroqr
    • 一个错误:后顶点着色器坐标不是像素坐标,而是标准化。对于 Direct3D,这意味着它们介于 0.0 和 1.0 之间(在 OpenGL 中为 -1.0 和 1.0)。起初这不是很直观,因为屏幕通常不是方形的,但它“可以正常工作”(不用担心,您无需做任何特别的事情!)并且硬件在此进行计算(例如剪辑)效率更高空间。其余的看起来不错(几何着色器、镶嵌和裁剪被称为“发生在两者之间的东西”)。
    • 啊,我更喜欢归一化坐标,因为无论您选择的屏幕分辨率如何,一切都在同一比例上(opengl 似乎有点奇怪,-1 到 1)。那么几何着色器和曲面细分阶段发生在两者之间?我会认为它们首先出现,因为新顶点可以被输入顶点着色器并转换为屏幕坐标。自动创建的新顶点是二维的吗?
    • 哎呀,我刚刚意识到我正在迅速将这个问题变成一个小型问题论坛,而且我已经花费了你足够多的时间。我想我已经很好地掌握了像素着色器运行,所以我应该很好。谢谢您的帮助!现在去玩玩吧:P
    • here(或here OpenGL 4.x 等效,更好的图像,名称略有不同但相同)。出于几个实用效率的原因,顶点着色器之后运行细分是有意义的(例如,您如何在不知道的情况下知道细分多少?补丁覆盖的屏幕区域?)。您不会简单地将每个三重顶点细分成一千个三角形。你可以根据他们实际覆盖的屏幕区域来做。
    【解决方案2】:

    您对像素着色器的理解是正确的,因为它“接收单个像素并对其执行计算以确定颜色和照明等内容。”

    着色器接收的像素是在转换后的 2d 多边形(具体为三角形)的光栅化过程中计算的单个像素。因此,顶点着色器处理三角形的 3 个点,而像素着色器处理“填充”三角形的像素,一次一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-11
      • 2010-11-26
      • 2015-06-23
      • 2017-12-26
      • 2016-10-19
      • 1970-01-01
      相关资源
      最近更新 更多