RTR4读书笔记 Chapter3 The Graphics Processing Unit

3.1 平行数据架构(Data-Parallel Architectures)

GPU针对吞吐量(throughput)进行了优化,吞吐量定义为可以处理数据的最大速率。 但是,这种快速处理具有成本。 由于专用于高速缓存存储器和控制逻辑的芯片面积较小,因此每个着色器内核的等待时间通常比CPU处理器遇到的等待时间高得多。
通过切换到另一个片段使GPU保持忙碌来减少延迟。 GPU通过将指令执行逻辑与数据分离开来,称为单指令,多数据(SIMD)
if和loop在GPU中会影响效率的原因:

  • GPU中的warp(一些执行同一个shader program的线程)运行时若遇到if,若一些线程选择了其中一个分支,会导致选择另一个分支的线程空闲,而导致效率低下。

3.2 GPU管线概述(GPU Pipeline Overview)

绿色阶段是完全可编程的,虚线表示可选阶段,黄色阶段是可配置的,但不能编程。
具体在第二章已有阐述

3.3 可编程的着色阶段(The Programmable Shader Stage)

现代的着色器程序使用统一的着色器设计。
这意味着与顶点,像素,几何和曲面细分相关的着色器共享一个通用的编程模型。在内部,它们具有相同的指令集体系结构(instruction set architecture ISA)

draw call调用图形API来绘制一组基元,从而使图形管道执行并运行其着色器。
每个可编程着色器阶段都有两种类型的输入:统一输入,其值在整个绘制调用期间保持恒定(但可以在绘制调用之间更改),以及变化的输入,即来自三角形顶点或栅格化的数据。
例如,像素着色器可以将光源的颜色提供为统一的值,并且三角形表面的位置每像素变化。
纹理是一种特殊的均匀输入,它曾经一直是应用于表面的彩色图像,但是现在可以认为是任何大型数据数组。

3.4 可编程的着色与API的演变(The Evolution of Programmable Shading and APIs)

一些API和图形硬件发布的时间线

3.5 顶点着色器(The Vertex Shader)

从数学上讲,每个三角形都有一个定义好的表面法线,直接使用三角形的法线进行着色似乎更有意义。
但是,在渲染时,三角形网格通常用于表示基础曲面,而顶点法线通常用于表示该曲面的方向,而不是三角形网格本身的方向。
在右侧,中间顶点已被复制并指定了两个法线,表示褶皱。

顶点着色器既不能创建也不能破坏顶点,并且一个顶点生成的结果不能传递到另一顶点。
由于每个顶点都是独立处理的,因此可以将GPU上任意数量的着色器处理器并行应用于传入的顶点流。

顶点着色器主要功能:

  1. 生成物体,通过仅创建一次网格并使其由顶点着色器变形来生成对象;
  2. 使用蒙皮和变形技术对角色的身体和面部进行动画处理;
  3. 程序变形,例如,旗帜飘动,布料或水的运动;
  4. 生成粒子,通过将退化的(无区域)网格发送到管道中,并根据需要为它们分配一个区域来创建粒子,从而通过使用整个帧框的内容作为纹理来实现镜头变形、热雾、水波纹、页面卷曲和其他效果;
  5. 地形高度,使用纹理图来添加地形高度。

3.6 曲面细分阶段(The Tessellation Stage)

优点:

  • 节省内存
  • 曲面描述通常比提供相应的三角形更紧凑。
  • 防止CPU和GPU之间的总线成为动画角色或形状不断变化的对象的瓶颈。
API 1st step 2nd step 3rd step
DirectX hull shader tessellator domain shader
OpenGL tessellation control shader primitive generator tessellation evalution shader

The tessellation stage

3.7 几何着色器(Geometry Shader)

几何着色器可以将图元转换为其他图元,例如,可以通过让每个三角形创建线边,将三角形网格转换为线框视图(Wireframe View,不知道是什么)。或者,可以将这些线替换为面向观察者的四边形,从而使线框渲染的边缘更厚。

  • 有效地创建级联阴影图以生成高质量的阴影。
  • 从点数据创建可变大小的粒子
  • 沿着轮廓拉伸fins(同样不知道是什么)进行毛发渲染以及找到对象边缘。

3.8 流式输出(Stream Output)

在通过顶点着色器(以及可选的细分和几何着色器)处理了顶点之后,除了可以将其发送到光栅化阶段,也可以输出到流中(即有序数组)。实际上,光栅化可以完全关闭,然后将管道纯粹用作非图形流处理器。
这种类型的操作可用于模拟由于水或其他颗粒效应而产生的结果。

3.9 像素着色器(The Pixel Shader)

关于延迟渲染

最初,像素着色器只能输出到合并阶段,以进行最终显示。 随着时间的推移,像素着色器可以执行的指令数量已大大增加。 这种增加产生了multiple render targets(MRT)的想法:
除了将像素着色器程序的结果仅发送到颜色和z-buffer外,还可以为每个片段生成多个值集并将其保存到不同的buffer中,每个buffer称为渲染目标(Render Target)。 渲染目标通常具有相同的x和y尺寸;某些API允许使用不同的大小,但渲染区域将是其中的最小尺寸。某些体系结构要求渲染目标的位深度相同,甚至可能具有相同的数据格式。 取决于GPU,可用的渲染目标数是四个或八个
即使有这些限制,MRT功能还是更有效地执行渲染算法的有力辅助。 一个pass可以在一个目标中生成彩色图像,在另一个目标中生成对象标识,在第三个目标中生成世界空间距离,这种能力还产生了另一种类型的渲染管线,称为延迟渲染,其中可见性和阴影是在单独的pass中完成。 第一遍存储有关对象在每个像素处的位置和材质的数据。 然后,连续的pass可以有效地施加照明和其他效果。

关于差值计算

像素着色器无法知道或影响相邻像素结果的规则是有例外的。
一种是像素着色器可以在梯度或微分信息的计算过程中立即访问相邻片段的信息(尽管是间接的)。
像素着色器具有沿插入屏幕轴每个像素的任何插值值变化的量。
这样的值可用于各种计算和纹理访问。
这些梯度对于诸如纹理过滤之类的操作尤其重要,在该操作中,我们想知道多少图像覆盖一个像素。
所有现代GPU均通过以2为一组的片段(称为aquad)处理片段来实现此功能。
关于差值计算

3.10 合并阶段(The Merging Stage)

合并阶段是将(在像素着色器中生成的)各个片段的深度和颜色与帧缓冲区进行合并的阶段。
DirectX将此阶段称为输出合并(output merger);OpenGL将其称为“按样本操作”(per-sample operations)。

为了提高效率,在像素着色器前对图元进行可见性检测——early-z。但像素着色器具有更改片段的z深度或完全丢弃片段的能力,若在像素着色器中发现有其中一种操作,early-z便无法使用,导致效率降低。

*合并阶段保证了绘制顺序是排序后的。

3.11 计算着色器(The Compute Shader)

在DirectX 11中引入了计算着色器,它是GPU计算的一种形式,因为它是未锁定在图形管线中某个位置的着色器。它由图形API调用,与渲染过程紧密相关。它与顶点,像素和其他着色器一起使用。

与其他着色器一样,它是着色器,因为它具有一组输入数据,并且可以访问buffers(例如纹理)进行输入和输出。
计算着色器的一个重要优点是它们可以访问在GPU上生成的数据。
从GPU向CPU发送数据会产生延迟,因此如果可以将处理和结果保留在GPU上,则可以提高性能。
在后期处理中,以某种方式修改了渲染的图像,这是计算着色器的常见用法。

发布了4 篇原创文章 · 获赞 0 · 访问量 175

猜你喜欢

转载自blog.csdn.net/weixin_44422550/article/details/104445152
今日推荐