GPU渲染管线之旅|08 Pixel Shader

2023-05-16

在这一部分中,我们来谈谈像素处理的前半部分:dispatch和实际的像素着色。事实上,这部分是大多数图形开发者在谈到PS stage时所关心的内容。有关alpha blendLate-Z的内容则会下一篇文章中去探讨。后面我们会看到,在硬件的设计上PS stage相对是比较复杂的。这也是像素处理分成两篇来写的原因。在进入这个阶段的时候,从raster或者early-z传入的信息包括:shader的像素坐标(实际上是小的四方块)和相关的覆盖遮罩。三角形的顺序与上层软件应用程序提交的完全相同,和我们在上次中看到的那样。我们在这里需要做的是将线性的,连续的工作流同时分配到数百个着色器单元中,然后等待这些着色器单元返回结果,一旦他们返回结果,我们就将它们再合并到一条线的内存流中。

从上面的描述中可以看到,这是典型的fork/join-parallelism示例。这篇文章我们要探讨的fork这半部分内容,也就是将工作流分配给大量的着色器单元。下一篇在去看join合并阶段(将数百个流合并为一个流)。在进入到PS stage之前对于光栅化还有点内容需要补充一下,因为我刚才说的只有一个四轴流进入的情况并不完全正确。

1. 光栅化:开始即分开

在我看来,我告诉你的在很长一段时间内都是正确的,但是这是一个管道的串行部分,一旦你在一个问题上抛出超过300个着色器单位,管道的串行部分就有成为瓶颈的趋势。

所以GPU的架构们开始使用多光栅的方式;截至到2010年,NVidia使用的是四个光栅化引擎。下图就是Fermi GF100的架构。
nv
AMD则是使用两个光栅化引擎,对于下图中的Tera Scala2,它有两个通用的Shader Engine,而每个Shader Engine都包含有一个光栅化引擎。
amd
从NV的演示文稿中可以看到一些关于保持API顺序要求的注释。特别是,在光栅化/early-Z之前,你需要对Primitive进行排序,就像我上次提到的:在alpha blend之前这样做是行不通的。

光栅化器之间的工作分配是基于我们在early-Z和粗光栅化中看到的tile。帧缓冲区被划分为瓦片大小的区域,每个区域被分配给一个光栅化器。设置完成后,参考三角形的边界框,确定哪些三角形交给哪个光栅化器;大三角形总是会被发送给所有的光栅化器,但是小三角形只会被发送到一个小块,并且只会被发送给拥有它的光栅化器。

这个方案的美妙之处在于,它只需要改变工作分布和粗光栅(遍历瓦片);只看到单个块或四边形(即从层次化Z向下的管道)的所有东西都不需要修改。问题是你现在是根据屏幕位置来划分作业;这可能会导致光栅器之间严重的负载不平衡(想象一下在一个平铺中有几百个小三角形),你真的不能做任何事情。但是好的方面是,所有添加到管道的顺序约束(Z-test/write顺序,blend顺序)都会附加到特定的帧缓冲区位置,所以屏幕空间的细分工作不会破坏API的顺序——如果不是这样,平铺渲染器就不会工作。

2. 再一次分散开

好的,我们得到的不是一个线性的四坐标流加上遮罩,而是在2到4之间。我们仍然需要将它们分配给数百个着色器单位。该是另一个派遣单位的时候了!这首先意味着另一个缓冲。但是我们发送到着色器的批次有多大?这里我再一次用英伟达的数字,仅仅因为他们在公共白皮书中提到了这个数字;AMD可能也在某处声明了这些信息,但我不熟悉他们的术语,所以我不能做一个直接搜索它。无论如何,对于NVidia,分配到着色单元的单位是32个线程,他们称之为“扭曲”。每个四4像素(每个反过来可以作为一个线程处理),所以对于每个阴影批处理我们的问题,我们需要抓住8传入四胞胎的光栅化程序之前我们可以寄出一批着色器单元(我们可以发送更少,以防有一个着色器开关或管道冲洗)。

同时,这也是解释为什么我们处理的是2×2像素的四块而不是单个像素的一个好点。主要原因是衍生品。纹理采样器依赖于纹理坐标的屏幕空间导数来进行mip-map选择和过滤(正如我们在第4部分中看到的);并且,在shader model 3.0及以后版本中,同样的机制以派生指令的形式直接用于像素着色器。在一个四边形中,每个像素在同一四边形中具有一个水平和垂直邻居;这可以用来估计参数在x和y方向上的导数,使用有限差分(它可以归结为几个减法)。这给了你一个非常便宜的方法来得到衍生物,代价是总是不得不在一次阴影组2×2像素。这在大三角形的内部没有问题,但这意味着25-75%的四边形的阴影工作被浪费了。这是因为四边形中的所有像素,甚至是遮罩的像素,都被着色了。这对于为可见的四边形像素生成正确的导数是必要的。不可见但仍然有阴影的像素被称为“辅助像素”。下面是一个小三角形的例子:

在这里插入图片描述

三角形与4个四边形相交,但只在其中3个四边形中产生可见像素。此外,在这3个四边形中,只有一个像素被实际覆盖(每个像素区域的采样点被描绘成黑色的圆圈)——被填充的像素被描绘成红色的。在每个部分覆盖的四边形中剩余的像素是辅助像素,用较浅的颜色绘制。这张图应该清楚地说明,对于小三角形,阴影的像素总数中很大一部分是辅助像素,这引起了一些关于如何合并邻近三角形的四块的研究。然而,尽管这样的优化很聪明,但当前的API规则不允许这样的优化,当前的硬件也不允许这样做。当然,如果HW供应商在某种程度上认为浪费在四轴上的阴影工作是一个严重的问题,这很可能会改变。

3. 属性插值

像素着色器的另一个特色是属性插值——所有其他材质类型,都到目前为止我们看到的(VS)和那些我们还谈论(GS、HS DS, CS)输入之前直接从材质阶段或内存,但是像素着色器有一个额外的插值一步在他们面前。在前面讨论Z时,我已经讨论过一点,它是我们看到的第一个内插属性。

其他插值属性的工作方式大致相同;平面方程是计算在三角形设置(gpu可以选择推迟这个计算,例如,直到知道至少有一个三角形的瓷砖层次z检验通过,但不得关注我们这里),然后在像素阴影,有一个独立的单元,执行属性插值使用像素位置的四胞胎和飞机方程计算。

更新:Marco Salvi指出(在下面的评论中),虽然曾经有专门的插值器,但现在的趋势是让它们返回质心坐标,代入平面方程。实际的计算(每个属性两次乘法)可以在着色器单元中完成。

所有这些都不足为奇,但是还有一些额外的插值类型需要讨论。首先,有“常量”插值器,它在整个原语中都是常量,并从“主要顶点”(在原语设置过程中确定的顶点)获取每个顶点属性的值。硬件要么有一个快速路径,要么只是建立一个相应的平面方程;两种方式都很好。

然后是无透视插值。这通常会建立不同的平面方程;对于基于X的插值,通过将每个顶点的属性值除以相应的w来建立透视校正插值的平面方程,对于质心插值,通过构建三角形边向量来建立平面方程。然而,对于基于X的插值,在不将每个顶点的值除以相应的w的情况下,当建立平面方程时,非透视插值属性的值是最便宜的。

4. “质心”插值是棘手的

接下来,我们有“质心”插值。这是一个标志,不是一个单独的模式;它可以与透视和无透视模式相结合(但不能与恒定插值,因为它将毫无意义)。它的命名也很糟糕,而且除非启用了多重采样,否则它是不操作的。对于多重采样的ob来说,这是一个解决实际问题的有点粗糙的解决方案。问题是,在多采样中,我们在光栅化器的多个采样点上评估三角形的覆盖率,但我们只对每个像素做一次实际的着色。纹理坐标等属性将被插值到像素的中心位置,就好像整个像素都被原语覆盖了一样。这可能会在以下情况下导致问题:
在这里插入图片描述
这里,我们有一个被原语部分覆盖的像素;四个小圆描述了4个采样点(这是默认的4x MSAA模式),而中间的大圆描述了像素中心。注意,大圆在原语之外,任何“插值”的值实际上都是线性外推;例如,如果应用程序使用纹理地图集,这就是一个问题。根据三角形的大小,像素中心的值可能会非常远。质心采样解决了这个问题。最初的解释是,GPU获取原语覆盖的所有样本,计算它们的质心,并在那个位置采样(因此名字)。通常,这只是一个概念模型,gpu可以自由地做不同的事情,只要他们为采样选择的点在原语之内。

如果您认为硬件不太可能真正计数所覆盖的样本,那么将它们相加,然后除以计数,然后加入俱乐部。下面是实际发生的情况:

如果所有的采样点都覆盖了原语,那么就像往常一样在像素中心(即所有合理的采样模式的所有采样位置的质心)进行插值。
如果不是所有的样例点都覆盖这个三角形,硬件会选择其中的一个样例点,并在那里进行计算。所有被覆盖的样本点(根据定义)都在原语内,因此可以工作。

这种选择过去是任意的(即留给硬件);我相信DX11现在已经确切地规定了它是如何完成的,但这更多的是在不同的硬件之间获得一致的结果,而不是API用户真正关心的事情。如上所述,这有点奇怪。对于部分覆盖像素的四轴飞行器,它还会搞砸导数计算——真倒霉。我能说的是,它可能是工业强度的胶带,但它仍然是胶带。

最后(DX11中的新特性!)有一个“拉模型”属性插值。常规的属性插值是在像素着色器开始之前自动完成的;拉模插值添加了实际的指令,做插值到像素着色器。这允许着色器计算它自己的位置来采样值,或者只在一些分支中插入属性,而不在其他分支中。它可以归结为像素着色器能够发送额外的请求到插值单元,而着色器正在运行。

5. 实际的着色器体

再一次,一般的着色器原则在API文档中有很好的解释,所以我不打算讨论单个指令是如何工作的;一般来说,答案是“如你所料”。然而,关于像素着色器的执行还有一些有趣的细节值得讨论。

第一个是:纹理采样!等等,在第4部分中我不是已经花了很长时间在材质采样器上了吗?是的,但那是纹理采样方面的事情-如果你还记得,有一点关于纹理缓存错过是如此频繁,采样器通常被设计为维持至少一次错过主存的请求(16-32像素,记住!)而不会中断。那么多循环,上百个循环。这将是一个巨大的浪费,完美的ALUs,让他们闲置,而所有这些都在进行。

所以着色单元实际上做的是在他们发布了纹理样本之后切换到不同的批处理;然后当批处理发出纹理样本(或完成)时,它切换回先前的批处理并检查纹理样本是否存在。只要每个着色器单位有一些批次,它可以在任何给定的时间工作,这就充分利用了可用的资源。但是,它确实增加了完成单个批的延迟——同样,这是延迟与吞吐量之间的权衡。现在你应该知道哪一方在gpu上获胜了:吞吐量!总是这样。这里需要注意的一点是,同时保持多个批(在NVidia硬件上称为“Warps”,在AMD称为“wavefront”)运行需要更多的寄存器。如果一个着色器需要很多寄存器,一个着色器单元可以保持较少的扭曲;如果有较少的他们,在某些点上你会跑完没有等待纹理结果的可运行批的机会是更高的。如果没有可运行的批,您就不走运了,必须暂停,直到其中一个批获得结果为止。这是很不幸的,但是在这种情况下,硬件资源是有限的——如果内存不足,那么内存就会不足。

另一点我还没有谈到:动态分支着色器(即循环和条件)。在着色单元中,每批处理的所有元素的工作通常是同步进行的。所有“线程”在同一时间运行相同的代码。这意味着ifs有点棘手:如果任何线程想要执行的“那么”分支,如果他们需要,尽管他们中的大多数可能会忽略结果使用一种称为预测的技术,因为他们不想下那里的. .“else”分支也是类似的。如果条件语句在元素之间是连贯的,那么它就很有用;如果条件语句或多或少是随机的,那么它就不那么有用了。最坏情况下,你总是会执行每个if的两个分支。哎哟。循环的工作原理类似——只要至少有一个线程想要继续运行一个循环,那么批处理/Warp/Wavefront中的所有线程都会这样做。

另一个特定的像素着色器是丢弃指令。一个像素着色器可以决定“杀死”当前的像素,这意味着它不会被写入。同样,如果一个批处理中的所有像素都被丢弃,着色单元可以停止并转到另一个批处理;但如果至少有一根线还在,其余的就会被拖走。DX11在这里添加了更多的细粒度控制,通过从像素着色器写入输出的像素覆盖(这总是与原始的三角形/Z-test覆盖进行沙子处理,以确保一个着色器不能写入它的原语之外,为了健康)。这允许着色器放弃个别样本而不是整个像素;例如,它可以用来在着色器中使用自定义的抖动算法来实现Alpha-to-Coverage。

像素着色器也可以写入输出深度(这个特性已经存在了很长一段时间了)。根据我的经验,这是一种很好的方法,可以降低早期Z、分层Z和Z压缩,并且通常可以获得最慢的路径。到目前为止,您已经足够了解这些东西是如何工作的了。😃

像素着色器产生几个输出——一般来说,每个渲染目标有一个4分量的矢量,(目前)最多可以有8个。着色器然后将结果发送到管道,D3D称之为“输出合并”。这是我们下次的话题。

但在我结束之前,还有最后一件事,像素着色器可以做,从D3D11开始:他们可以写无序访问视图(无人机)-这只有计算和像素着色器可以做。一般来说,在计算着色器执行过程中,无人机代替了渲染目标;但与渲染目标不同,着色器可以确定写入自身的位置,并且没有隐含的API顺序保证(因此名称中的“无序访问”部分)。现在,我只会提到这个功能的存在-当我开始计算着色器时,我会更多地谈论它。

更新:在评论中,史蒂夫给了我一个提醒关于正确的AMD术语(的第一个版本后没有“时”的名字,因为我不记得它)也发布了一个链接到这个伟大的演讲Kayvon Fatahalian解释着色器执行在gpu上,有很多更漂亮的图片,我可以打扰)。如果你对着色器核心的工作方式感兴趣,你应该去看看它。

和…就是这样!这次没有太多的警告。如果这里遗漏了什么,那是因为我真的忘记了它,而不是因为我觉得它太神秘或太具体而不能在这里写出来。请随意在评论中指出遗漏之处,我会看看我能做些什么。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GPU渲染管线之旅|08 Pixel Shader 的相关文章

  • CUDA Visual Studio 2010 Express 构建错误

    我正在尝试在 64 位 Windows 7 上使用 Visual Studio 2010 Express 在 Windows 上开始 CUDA 编程 我花了一段时间来设置环境 然后我刚刚编写了我的第一个程序 helloWorld cu 目前
  • 如何在Python中设置像素的alpha值

    我正在尝试编辑image https drive google com file d 0B8JcwRV HVk0OURrcTFJczhmV2RlUGdMOG0ybldYUVRoamtF view usp sharing以一种将所有白色像素转
  • 使用 BufferedImages 获取图像每个像素的颜色

    我试图获取图像的每个像素的每种颜色 我的想法如下 int pixels BufferedImage image image ImageIO read this getClass getResources image png int pixe
  • 使用 GLSL 着色器在同一片段着色器中定义的多个子例程类型无法正常工作

    我正在开发一个使用 GLSL 着色器的程序 我编写了 2 种不同的方法来用 2 种不同的方法计算 ADS 环境光 漫反射 镜面反射 着色 为了正确完成这项工作 我使用子例程来使用一种或另一种方法来计算 ADS 着色 这是片段着色器代码的一部
  • 超出 CreateConstantBufferView 处虚拟地址的末尾

    我正在遵循 使用 DirectX12 进行游戏编程 ch 6 代码 但在 ID3DDevice CreateConstantBufferView 中 我发现 D3D12 错误 D3D12 错误 ID3D12Device CreateCons
  • 无法满足显式设备规范“/device:GPU:0”,因为没有匹配的设备

    我想在我的 Ubuntu 14 04 机器上使用 TensorFlow 0 12 作为 GPU 但是 当将设备分配给节点时 我收到以下错误 InvalidArgumentError see above for traceback Canno
  • 使用 OpenGL 着色器进行数学计算 (C++)

    我有一个矩阵 例如 100x100 尺寸 我需要对每个元素进行计算 matrix i j tt 8 5例如 我有一个巨大的矩阵 我想使用 OpenGL 着色器来实现该算法 我想使用着色器 例如 uniform float val unifo
  • GPU的编程语言有哪些

    我读过一篇文章 指出 GPU 是超级计算的未来 我想知道在GPU上编程使用什么编程语言 OpenCL 是开放式跨平台解决方案 可在 GPU 和 CPU 上运行 另一个是 NVIDIA 为其 GPU 构建的 CUDA HLSL Cg 等少数几
  • 根据 GLSL 中向量的特定分量执行最小-最大的最快方法?

    我需要在我的 GLSL 代码中多次调用这种函数 vec2 minx vec2 a vec2 b if a x lt b x return a else return b 我担心过度分支 有没有办法避免 if else 结构 我建议使用 GL
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • 帧缓冲区和在 opengl 中使用着色器

    我对帧缓冲区有点困惑 我想要做的是使用附加了多个纹理的帧缓冲区 填充每个纹理 然后使用着色器组合 混合 所有纹理以创建新的输出 听起来很容易 是的 我也是这么想的 但我不明白 如何将当前绑定的纹理传递给着色器 您需要的是将纹理放入特定的槽中
  • CUDA Thrust 的多 GPU 使用

    我想使用我的两张显卡通过 CUDA Thrust 进行计算 我有两张显卡 在单卡上运行对于两张卡都适用 即使我在 std vector 中存储两个 device vector 也是如此 如果我同时使用两张卡 循环中的第一个周期将起作用并且不
  • UnimplementedError:图形执行错误:在张量流上运行 nn

    我一直遇到这个错误 我不知道为什么 特别是因为我完全遵循某人的代码并且该人在运行此错误时没有错误 img shape 128 128 3 load pretrained model base model tf keras applicati
  • 设备内存刷新cuda

    我正在运行一个 C 程序 其中调用了两次 cuda 主机函数 我想清理这两个调用之间的设备内存 有没有办法可以刷新 GPU 设备内存 我使用的是计算能力为2 0的Tesla M2050 如果你只想将内存归零 那么cudaMemset可能是最
  • 如何计算正切和副法线?

    谈谈OpenGL着色语言 GLSL 中的凹凸贴图 镜面高光之类的东西 I have 顶点数组 例如 0 2 0 5 0 1 0 2 0 4 0 5 法线数组 例如 0 0 0 0 1 0 0 0 1 0 0 0 世界空间中点光源的位置 例如
  • Windows Azure 虚拟机配备什么类型的显卡?

    我正在考虑在 Windows Azure 虚拟机上运行一些图形密集型程序 但不确定它们有什么样的硬件 所有虚拟机都具有相同的 GPU 吗 您对此有何体验 Azure 虚拟机中的 GPU 可能非常基本 并且很可能不具备执行密集图形操作所需的处
  • 无法编译cuda_ndarray.cu:libcublas.so.7.5:无法打开共享对象文件

    我正在尝试在 aws 实例中导入 theano 库以使用 GPU 我已经使用 boto 编写了一个 python 脚本来自动执行 aws 设置 该脚本本质上会从我的本地计算机对实例执行 ssh 然后启动一个 bash 脚本 其中我执行 py
  • 如何在 OpenGL 中绘制镜像某些东西的镜子?

    根据我的理解 要在 OpenGL 中进行镜像 您基本上需要绘制场景 然后将所有内容翻转并再次绘制 只是使其通过镜子可见 从而在镜子中创建完美翻转的图像 但我看到的问题是 执行此操作时 唯一可以看到其他镜子的镜子是在前一个镜子之后渲染的镜子
  • 我怎样才能将图像逐像素绘制到jframe

    我是java的初学者 直到今天我尝试做我自己认为的事情 所以这一天就在这里 我已经将图像的所有像素排列为 RGB 我想单击一个按钮并制作逐像素创建的类似动画的图像 这就是我所做的 但不起作用 import java awt BorderLa
  • 需要 TensorFlow 依赖项。如何在 Windows 上运行 TensorFlow

    我有兴趣让 TensorFlow 在 Windows 上运行 但目前我意识到这是不可能的 因为某些依赖项无法在 Windows 上使用 例如巴泽尔 之所以出现这种需求 是因为据我目前了解 从 TensorFlow 访问 GPU 的唯一方法是

随机推荐

  • 18张含金量最高的大数据证书

    这年头从事数据行业很不赖 用人需求量之大达到创记录的水平 xff0c 薪资也水涨船高 几乎任何数据认证都会让你的薪资涨一涨 本文介绍了哪几大数据认证可以让你稳赚丰厚薪水 顶级数据技能拿顶薪 你是不是在想 xff1a 为获得那下一份数据认证付
  • XML解析——Java中XML的四种解析方式

    XML是一种通用的数据交换格式 它的平台无关性 语言无关性 系统无关性 给数据集成与交互带来了极大的方便 XML在不同的语言环境中解析方式都是一样的 只不过实现的语法不同而已 XML的解析方式分为四种 xff1a 1 DOM解析 xff1b
  • JVM调优总结 -Xms -Xmx -Xmn -Xss

    Xms 是指设定程序启动时占用内存大小 一般来讲 xff0c 大点 xff0c 程序会启动的快一点 xff0c 但是也可能会导致机器暂时间变慢 Xmx 是指设定程序运行期间最大可占用的内存大小 如果程序运行需要占用更多的内存 xff0c 超
  • Spring Boot 传参方式

    最近在搞Spring Boot的项目 xff0c 把传参方式总结一下 网上也参考一些文章 xff0c 总结的很不错 xff0c 这里借鉴一下 注解 64 RequestParam 这个注解用来绑定单个请求数据 xff0c 既可以是url中的
  • Java BigDecimal开方

    前言 一般开平方使用的是Math中的静态方法Math sqrt double a xff0c 涉及到金融计算的时候 xff0c Math sqrt double a 精度就不够了 金融领域的计算 xff0c 用的都是BigDecimal类型
  • c实现set集合

    集合有点编程语言会带有 xff0c 有的没有 但是我想redis的集合set你一定听说过或者用过 下面咱们用链表来实现set 相信有了前面的基础我们可以很容易的实现set集合 需要引入我的链表的list c和list h 头文件 span
  • Spring Boot 集成RabbitMQ

    RabbitMQ is an open source multi protocol messaging broker 前言 参照官方Messaging with RabbitMQ xff0c 记录在实战中的一些坑 搭建RabbitMQ服务
  • Java 获取接口所有实现类

    利用Spring的Bean工厂 xff0c 获取接口所有实现类 前言 在学习Spring Boot 集成RabbitMQ时 xff0c 发现定义了好几个bean xff0c 这些bean在什么地方用到呢 xff1f 查看RabbitAdmi
  • Intellij IDEA-SSH executable-Native

    Connecting to gitlab using PuTTY generated SSH key in IDEA 背景 项目开发中 xff0c 使用Gitlab搭建git服务 xff0c 做代码的版本管理 xff0c 一开始是使用htt
  • 近年作品集

    青海省电力局资产盘点机器人 一种基于地图骨架提取和启发式搜索树的路径规划算法 复杂地图 一种基于地图骨架提取和启发式搜索树构建的路径规划 简单地图
  • 【技巧】SQL中修改列名(column)

    问 xff1a 怎么修改Mysql中的表格的某列的列名 xff1f 答 xff1a 比如说我想将seat表中的seatid列名修改为 seat id 1 初状态 xff1a 输入 xff1a select from seat 查看seat
  • 【报错】resultMap认知错误

    数据库改了一个字段的名字 xff0c 后来牵扯到实体类标准化都要改 xff0c 原来以为 xff0c mybatis使用的sql语句都是通过resultMap映射后 xff0c 可以使用后面的property xff0c 因为之前colum
  • Spring框架知识点

    1 Spring概述 1 1 什么是框架 xff1f 框架 xff08 Framework xff09 xff1a 框 xff08 指其约束性 xff09 架 xff08 指其支撑性 xff09 xff0c 在软件设计中指为解决一个开放性问
  • 前端脚手架开发工具包

    文章目录 文件操作fs extrareaddirpevent stream监听文件变化 chokidar 文件匹配glob 远程下载模板代码download git repo 命令行参数解析 minimist轻量级的命令行参数解析引擎 Co
  • 关于联想Y7000P睡眠后无法唤醒问题修复

    这个新的机器是WINDOWS11的 xff0c 症状了自己睡眠后就醒不过来了 xff0c 于是我找到了公众号 xff0c 提示下载一个软件修复驱动 xff0c http tools lenovo com cn tools exeTools
  • GPU渲染管线之旅|05 图元处理、Clip/Cull, 投影和视图变换

    上一篇中我们讨论了关于 纹理和采样 xff0c 这一篇我们回到3D管线的前端 在执行完顶点着色之后 xff0c 就可以实际的渲染东西了 xff0c 对吗 xff1f 暂时还不行 xff0c 因为在我们实际开始光栅化图元之前 xff0c 仍然
  • mac地址的作用

    最近读一本关于linux编程的书籍 xff0c 看到一部分很迷茫 xff0c 忽然不知道mac地址的作用 xff0c 既然已经有了ip地址了要mac地址何用呢 xff1f MAC地址是数据链路层的地址 xff0c 如果mac地址不可直达 直
  • 谈谈OpenCV中的四边形

    首先抛出一个问题 xff0c 给定一系列二维平面上的的点 xff0c 这些点是可以组成一个封闭的二维图形 因为这些点是矩形区域拍摄图像后识别得到的图形的边界点 xff0c 所以我们要抽象出来这个矩形 xff0c 也就是我们要反映出这个矩形
  • GPU渲染管线之旅|07 深度处理、模板处理

    在这一篇中 xff0c 我们来讨论Z pipline的前端部分 简称它为early Z 以及它是在光栅化中怎么起作用的 和上一篇一样 xff0c 本篇也不会按实际的管道顺序进行讨论 xff1b 我将首先描述基础算法 xff0c 然后再补充管
  • GPU渲染管线之旅|08 Pixel Shader

    在这一部分中 xff0c 我们来谈谈像素处理的前半部分 dispatch和实际的像素着色 事实上 xff0c 这部分是大多数图形开发者在谈到PS stage时所关心的内容 有关alpha blend和Late Z的内容则会下一篇文章中去探讨