想象你走进一家汽车工厂:传送带上没有一辆完整的汽车,只有满地编号的螺栓和钢板。工人按部就班做四件事——先给每颗螺栓定好空间位置,再把它们焊接成车身框架,接着盖上一张网格纸逐格扫描轮廓,最后在每个格子里喷漆贴花。四道工序走完,一辆“汽车”驶下生产线。你屏幕上每一帧 3D 画面,正是这样被“造”出来的:一堆三维坐标点,经过四个车间变成彩色像素。这条生产线在计算机图形学里叫图形渲染管线(Graphics Rendering Pipeline)。本文带你走进四个车间,看清顶点、几何、光栅化、像素这四个阶段各自发生了什么,以及当画面卡顿时,到底该找哪个车间“算账”。

岗位关联

渲染管线是图形学的工业地基。无论做游戏引擎、3D 应用、数字孪生还是 AR/VR,你的调试与性能优化能力,都取决于对这条流水线每一道工序的直觉。

目录
  1. 可视化演示
  2. 管线总览:一座汽车工厂的四道工序
  3. 顶点处理:给每颗螺栓定好位置
  4. 几何处理:把散件焊接成车架
  5. 光栅化:盖网格纸,逐格扫描
  6. 像素处理:喷漆、贴花与质检
  7. 性能与优化:最慢的工位决定车速
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示图形渲染管线的核心机制,通过采集/分析/决策/反馈四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

图形渲染管线:渲染管线 渲染管线的整体架构与阶段划分 顶点处理阶段与坐标空间变换 核心机制可视化 图形渲染管线整体架构与关键组件

管线总览:一座汽车工厂的四道工序

想象你走进一家汽车工厂:传送带上没有一辆完整的汽车,只有满地编号的螺栓和钢板。工人按部就班做四件事——先给每颗螺栓定好空间位置,再把它们焊接成车身框架,接着盖上一张网格纸逐格扫描轮廓,最后在每个格子里喷漆贴花。四道工序走完,一辆“汽车”驶下生产线。你屏幕上每一帧 3D 画面,正是这样被“造”出来的。

这条生产线叫渲染管线(Rendering Pipeline)。输入是 CPU 准备好的顶点数据——每个顶点的位置、颜色、法线、贴图坐标;输出是屏幕上的一帧像素。GPU 把流水线拆成四个阶段:顶点处理、几何处理、光栅化、像素处理。数据在阶段之间单向流动,就像零件在传送带上只能前进不能后退。GPU 内部有数千个并行单元,可以同时给一万颗“螺栓”定位,而不是排队等一个机械臂。

流水线的魅力在于四道工序同时开工:不同零件在不同工位并行加工。但也正因如此,任何一个工位掉链子,整条线就会卡壳——这正是后面要讲的“瓶颈”。

顶点→装配图元→光栅化片元→着色/测试像素\text{顶点} \xrightarrow{\text{装配}} \text{图元} \xrightarrow{\text{光栅化}} \text{片元} \xrightarrow{\text{着色/测试}} \text{像素}
这条链就是流水线的“物料清单”:螺栓变成车架,车架变成半成品格子,半成品变成成品。
  1. 顶点(Vertex)三维坐标点加上各种属性,是流水线的原材料,相当于一颗颗螺栓。
    v=(x,y,z)+(颜色,法线,UV)v = (x, y, z) + (\text{颜色}, \text{法线}, \text{UV})
  2. 图元(Primitive)顶点按顺序装配成三角形等基本形状,相当于焊接成车架。
    △(v0,v1,v2)\triangle(v_0, v_1, v_2)
  3. 片元(Fragment)三角形被光栅化成候选像素格子,每个格子带着深度和插值属性,是待喷漆的半成品。
    f=(xscreen,yscreen,z,属性)f = (x_{screen}, y_{screen}, z, \text{属性})
  4. 像素(Pixel)通过深度测试与混合后真正写入屏幕的最终颜色,是下线成品。
    p=(x,y,color)p = (x, y, color)

顶点处理:给每颗螺栓定好位置

走进一号车间,工人正处理满地的“螺栓”——每个顶点就是一颗螺栓,带着自己的铭牌:位置坐标、法线方向、颜色、贴图坐标。光有螺栓不算车,必须先把每颗螺栓在空间里的位置和姿态定准。这个阶段叫顶点处理(Vertex Processing),由 GPU 里的顶点着色器(Vertex Shader)完成。它是“逐顶点执行”的程序:场景里有一百万个顶点,它就并行执行一百万次。

顶点着色器最重要的活是坐标变换——把顶点从“模型自己的小坐标”搬进“整个世界”,再搬到“相机眼睛里”,最后变成屏幕坐标。这条变换链叫 MVP:M 模型矩阵负责摆放、旋转、缩放;V 视图矩阵把世界坐标换成以相机为原点的视角;P 投影矩阵把三维场景压进裁剪空间,并通过“除以 w”的透视除法实现近大远小。

透视除法是“近大远小”的数学根源:离相机越远,齐次坐标里的 w 越大,坐标被压得越小。之后经过视口变换,NDC 坐标(范围 -1 到 1)被映射成屏幕像素坐标。一号车间交出的工件,是每个顶点在相机视野里的准确位置——下一站,它们要被焊接成三角形。

vclip=Mproj×Mview×Mmodel×vlocalv_{clip} = M_{proj} \times M_{view} \times M_{model} \times v_{local}
从右往左读:顶点先被模型矩阵摆放进世界,再被视图矩阵搬到相机眼前,最后被投影矩阵压成裁剪空间坐标。这就是“把一颗螺母放到相机看得见的位置”的数学描述。
  1. 局部坐标 \(v_{local}\)顶点在模型自带坐标系里的原始位置,相当于螺栓出厂时零件盒里的坐标。
    vlocal=(xlocal,ylocal,zlocal,1)Tv_{local} = (x_{local}, y_{local}, z_{local}, 1)^T
  2. 模型矩阵 \(M_{model}\)完成摆放、旋转、缩放,把模型从局部坐标搬到世界坐标。
    vworld=Mmodel×vlocalv_{world} = M_{model} \times v_{local}
  3. 视图矩阵 \(M_{view}\)以相机为原点重新描述世界,相当于把整个场景搬到相机坐标系。
    vview=Mview×vworldv_{view} = M_{view} \times v_{world}
  4. 投影矩阵 \(M_{proj}\)透视或正交投影,把三维场景压入裁剪空间,得到齐次坐标。
    vclip=Mproj×vviewv_{clip} = M_{proj} \times v_{view}

几何处理:把散件焊接成车架

二号车间的机械臂把三颗螺栓组成一组,焊成一个三角形——这就是图元(Primitive)。三角形是 3D 渲染的基本积木:任何曲面、任何模型,最后都会拆成密密麻麻的小三角形再拼回原样。焊接之前,车间先做两件“偷懒”的事,它们是几何处理(Geometry Processing)的拿手好戏。

第一件是视锥裁剪(Frustum Culling):相机能看见的范围是一个四棱锥(视锥),完全在视锥外的三角形直接扔进废料桶;被视锥边界切到的三角形,则按交点切出新三角形。第二件是背面剔除(Back-Face Culling):三角形分正面和背面,背面朝相机、你根本看不见的面直接丢弃——这一下能省掉大约一半的三角形。此外还有曲面细分(Tessellation):当客户要求车轮更圆润时,机械臂把大三角形敲成更多小块,让曲面更光滑。

经过二号车间的筛选与整形,只有“面朝相机、在视野内”的三角形能进入下一站。被淘汰的三角形越多,后面的车间越轻松——废料桶里装的都是白省下来的工作量。

n⃗=(v1−v0)×(v2−v0)\vec{n} = (v_1 - v_0) \times (v_2 - v_0)
叉积像“用两条边向量拧出一个垂直于平面的法线”。法线朝相机还是背相机,决定了这个三角形要不要被剔除。
  1. 边向量从顶点 \(v_0\) 出发的两条边,分别指向 \(v_1\) 和 \(v_2\)。
    e1⃗=v1−v0,e2⃗=v2−v0\vec{e_1} = v_1 - v_0,\quad \vec{e_2} = v_2 - v_0
  2. 叉积运算两个边向量做叉积,得到垂直于三角形平面的法向量。
    n⃗=e1⃗×e2⃗\vec{n} = \vec{e_1} \times \vec{e_2}
  3. 符号判朝向在相机坐标系中看法线 \(z\) 分量的符号,背向相机则整个三角形不可见,立即剔除。
    nz<0⇒culln_z < 0 \Rightarrow \text{cull}

光栅化:盖网格纸,逐格扫描

三号车间没有机械臂,只有一张网格纸和一支笔。工人把三角形轮廓描到网格纸上,一格一格检查:这一格的中心到底在不在三角形里面?在,就涂一格;不在,就跳过。全部检查完,一个连续光滑的三角形就变成了一幅由小方格组成的“点阵画”——这就是光栅化(Rasterization)。

计算机里的“网格纸”就是屏幕像素阵列。光栅化第一步是屏幕映射:把 NDC 坐标换算到像素坐标。第二步是覆盖判定:对三角形外接矩形范围内的像素,逐个用边函数(Edge Function)判断像素中心在三角形的哪一侧——完全不用检查整张屏幕。只判定“在不在”还不够,喷漆时还得知道每个格子的深度和颜色怎么渐变。这就要靠重心插值:用重心坐标把三个顶点的属性线性混合到每个像素,画面才能从“硬边”变成“平滑渐变”。若想让边缘不出现锯齿,还能用多重采样抗锯齿(MSAA),对像素内多个子采样点取平均。

三号车间输出的不再是三角形,而是成百上千个片元——每个片元是一张待喷漆的格子,上面标好了深度、渐变比例和贴图坐标,等着四号车间来上色。

Ei(p)=(px−vi,x)(vi+1,y−vi,y)−(py−vi,y)(vi+1,x−vi,x)E_i(p) = (p_x - v_{i,x})(v_{i+1,y} - v_{i,y}) - (p_y - v_{i,y})(v_{i+1,x} - v_{i,x})
像素点的属性可以看作三个顶点属性的“加权平均”:权重越大,说明离哪个顶点越近,属性越偏向谁。深度、颜色、贴图坐标都靠这一招在三角形内部平滑过渡。
  1. 重心坐标权重用三个小三角形的面积比算出 \(\lambda_0, \lambda_1, \lambda_2\),它们都是 0 到 1 之间的数。
    λi=SiStotal\lambda_i = \frac{S_i}{S_{total}}
  2. 属性加权颜色、深度、UV 都按同一组权重做线性组合。
    colorp=λ0color0+λ1color1+λ2color2color_p = \lambda_0 color_0 + \lambda_1 color_1 + \lambda_2 color_2
  3. 归一化约束三个权重加起来恰好等于 1,保证插值结果不会飘出三角形。
    λ0+λ1+λ2=1\lambda_0 + \lambda_1 + \lambda_2 = 1

像素处理:喷漆、贴花与质检

四号车间是最后一道工序,也是画面“质感”的来源。工人拿到每个片元的配料单——深度、UV、插值颜色——开始喷漆:先按 UV 坐标从纹理图上取色(贴花纹),再用光照模型计算明暗,最后还要过两道“质检”。

第一道质检是深度测试(Depth Test)。想想排队买票:同一个屏幕位置上,可能前后站着两个三角形。谁离相机更近,谁就“插队”显示在前;被挡住的片元直接丢弃。深度缓冲(Z-Buffer)就是记录每个像素当前最近深度的本子:新片元只有在深度更近时才能覆盖旧的。没有它,后面的物体会错误地盖住前面的。第二道质检是混合(Blending):玻璃、烟雾、粒子这些半透明物体,喷上去的漆必须和底下的颜色按透明度混合,而不是直接覆盖。全部测试通过的片元被写入帧缓冲,最终组成一整帧画面——你屏幕上看到的彩色三角形。

全部格子喷完漆、通过质检,汽车终于驶下流水线。这辆“汽车”其实就是画面上成百上千万个像素——它们加起来,就是你看到的整个 3D 世界。

Cout=αsrc⋅Csrc+(1−αsrc)⋅CdstC_{out} = \alpha_{src} \cdot C_{src} + (1 - \alpha_{src}) \cdot C_{dst}
半透明玻璃后面放一束花,你看到的是“花的颜色 × 透光率 + 玻璃颜色 × 不透明度”。\(\alpha\) 就是玻璃的“不透光度”。
  1. 源颜色 \(C_{src}\)新片元的颜色(比如玻璃),它的不透明度用 \(\alpha_{src}\) 表示。
    Csrc=(rsrc,gsrc,bsrc),0≤αsrc≤1C_{src} = (r_{src}, g_{src}, b_{src}),\quad 0 \leq \alpha_{src} \leq 1
  2. 目标颜色 \(C_{dst}\)帧缓冲中已经存在的颜色(比如后面的花)。
    Cdst=(rdst,gdst,bdst)C_{dst} = (r_{dst}, g_{dst}, b_{dst})
  3. 线性混合按不透明度加权相加,得到最终输出色。
    Cout=α⋅Csrc+(1−α)⋅CdstC_{out} = \alpha \cdot C_{src} + (1-\alpha) \cdot C_{dst}

性能与优化:最慢的工位决定车速

工厂有条铁律:流水线的速度由最慢的工位决定。哪怕其他三个车间一秒处理一亿次,只要有一个车间一分钟只处理一个,整条线就被拖垮——这个最慢工位,就是瓶颈(Bottleneck)。

性能分析的第一步是定位瓶颈在哪个阶段,而不是盲目优化。用 Profiler 测出每个阶段的耗时,就能看出是顶点处理太慢(顶点数爆炸),还是像素处理太慢(过度绘制 Overdraw,比如半透明粒子层层叠加,同一像素被涂了几十遍),或是 CPU 侧绘制调用(Draw Call)太多,GPU 一直在排队等指令。常见的优化手段包括:批量渲染(Batching)——把大量小物体合并成一次绘制调用;层级简化(LOD)——远处的模型用更少面数;视锥剔除与遮挡剔除——从一开始就不把不可见物体送进管线;还有纹理的 Mipmap 层级——远处物体用小纹理减少带宽。所有招数都指向同一件事:把工件在入场前就减重,让最慢的车间也能喘过气。

下次游戏卡顿,别急着怪显卡。拿出工厂思维先问一句:卡在哪号车间?是 CPU 喂料太慢,还是像素喷涂过载?找到最慢的工位,优化才算真正开始。

tframe≥max⁡(t顶点,t几何,t光栅,t像素),FPS=1tframet_{frame} \geq \max(t_{顶点}, t_{几何}, t_{光栅}, t_{像素}),\quad FPS = \frac{1}{t_{frame}}
一帧的耗时不可能低于最慢阶段的耗时,就像一串珍珠项链的串线时间不可能短于最慢那颗珠子打孔的时间。帧率就是一帧耗时的倒数。
  1. 各阶段耗时分别测出顶点、几何、光栅、像素四个车间的平均处理时间。
    t1=t顶点, t2=t几何, t3=t光栅, t4=t像素t_1 = t_{顶点},\ t_2 = t_{几何},\ t_3 = t_{光栅},\ t_4 = t_{像素}
  2. 取最大值整体帧耗时至少等于四个阶段的最大值,即瓶颈阶段。
    tframe=max⁡(t1,t2,t3,t4)t_{frame} = \max(t_1, t_2, t_3, t_4)
  3. 帧率换算一秒钟除以单帧耗时得到帧率。瓶颈每快一分,帧率就实打实涨一分。
    FPS=1tframeFPS = \frac{1}{t_{frame}}

AI 应用场景

场景1:开放世界游戏的“视锥筛选”

阶段:几何处理与性能优化

解决的问题:开放世界场景常有几百万个三角形,若全部送进光栅化,GPU 会被大量不可见三角形拖垮。传统做法是“全画再说”,导致帧率低下、发热严重。

具体案例:某开放世界项目用视锥裁剪 + 遮挡查询,先过滤掉相机看不见的 80% 三角形;再对远景建筑启用 LOD 低模,绘制调用从 1.2 万次降到 800 次,主机端帧率从 35 提升到 60。

场景2:移动端粒子特效的过度绘制治理

阶段:像素处理与瓶颈定位

解决的问题:手机 GPU 带宽有限,爆炸粒子、火焰等半透明特效层层叠加,同一像素被着色几十次,像素阶段成为瓶颈,画面卡顿、手机发烫。

具体案例:用 Profiler 定位到像素阶段耗时占 70%,于是降低粒子纹理分辨率、启用 Mipmap 并改用开销更低的抗锯齿方案,把过度绘制系数从 5.2 压到 1.8,帧率从 28 提升到 55。

场景3:BIM 数字孪生的批量渲染

阶段:顶点处理与渲染管线总览

解决的问题:大型 BIM 模型包含数十万个构件,每个构件一次绘制调用,CPU 被 Draw Call 打爆,GPU 却大量闲置。

具体案例:把同类构件合并成静态网格批次,用实例化(Instancing)一次绘制所有相同螺栓,并在几何阶段剔除不可见楼层,漫游视角帧率从 12 提升到 50。

Python 演示

python42 行
"""极简软件光栅化器: 两个三角形输出为 80x40 字符画布""" W, H = 80, 40  def edge(p, a, b):    # 边函数: 返回点 p 在边 ab 的哪一侧(符号距离)    return (p[0] - a[0]) * (b[1] - a[1]) - (p[1] - a[1]) * (b[0] - a[0])  def inside(p, tri):    # 三条边同号 => 点在三角形内部    d1 = edge(p, tri[0], tri[1])    d2 = edge(p, tri[1], tri[2])    d3 = edge(p, tri[2], tri[0])    has_neg = (d1 < 0) or (d2 < 0) or (d3 < 0)    has_pos = (d1 > 0) or (d2 > 0) or (d3 > 0)    return not (has_neg and has_pos)  def rasterize(canvas, tri, ch):    # 只扫描三角形包围盒, 不做全屏遍历    xs = [v[0] for v in tri]    ys = [v[1] for v in tri]    for y in range(max(0, min(ys)), min(H, max(ys) + 1)):        for x in range(max(0, min(xs)), min(W, max(xs) + 1)):            if inside((x, y), tri):                canvas[y][x] = ch  def main():    canvas = [[' '] * W for _ in range(H)]    # 前面的三角形, 用 # 表示    rasterize(canvas, [(20, 5), (48, 32), (6, 34)], '#')    # 后面的三角形, 用 * 表示, 重叠处后画者覆盖    rasterize(canvas, [(52, 8), (74, 30), (38, 36)], '*')    for row in canvas:        print(''.join(row))  if __name__ == '__main__':    main()
目的:把正文讲的“边函数覆盖判定 + 包围盒光栅化”浓缩成 40 行可运行程序,在终端输出两个三角形的 ASCII 像素图,直观还原三号车间“逐格扫描”的过程。
  1. def edge(p, a, b):实现正文的边函数,返回像素点相对一条边的符号侧。
  2. has_neg` 与 `has_pos三边同号判定,等价于“像素中心被三条边夹住”。
  3. range(max(0, min(ys)), min(H, max(ys) + 1))只遍历三角形外接矩形,跟 GPU 光栅化的包围盒优化一脉相承。
  4. rasterize(canvas, tri, ch)一个三角形一个形状字符,重复调用即可绘制多个图形。
  5. if __name__ == '__main__':提供独立可运行的入口,直接 python 执行即可。

常见误区

误区光栅化不就是把三角形涂上颜色吗?顶点给了颜色,光栅化阶段直接把它填满就行了。

正解光栅化只做“网格扫描判定”——判断像素中心是否在三角形内,并插值出深度、UV 等属性。真正的着色(纹理、光照、明暗)是四号车间像素处理阶段的事。工厂里三号车间只负责“制版”,“喷漆”在四号车间;混为一谈就分不清哪里出了性能问题。

为何常见:最终画面上三角形看起来确实“被填了色”,初学阶段很难把“覆盖判定”和“着色计算”这两件事拆开。

误区顶点变换不就是平移、旋转、缩放嘛,投影就是把 z 轴压扁,没什么特别的。

正解透视投影的关键在最后一步——每个裁剪坐标除以自己的 w 分量。离相机越远,w 越大,坐标被压得越小,这才产生“近大远小”的透视感。没有这一步,画面就像工程图一样毫无纵深;而 w 恰恰是平移和投影用齐次坐标表达时才出现的。

为何常见:平移旋转缩放是学变换时的第一直觉,而齐次坐标里的 w 除法藏在矩阵乘法之后,不亲手算一遍很难体会到它的分量。

误区背面剔除听着很危险,开着开着我的模型是不是就被削掉一半了?

正解背面剔除依据三角形绕序(顶点排列方向)叉积出的法线朝向,只去掉背对相机的面。只要模型是封闭的(比如球壳),背面的面本来就被正面挡着,剔掉它们画面毫无损失,反而省一半三角形。它会出问题,通常是因为模型法线翻转或开了单面材质——那是数据问题,不是剔除的错。

为何常见:名字里带“剔除”,听起来像暴力删减;其实它删的是“反正看不见”的部分,相当于工厂把背对镜头的零件提前扔进废料桶。

误区游戏一卡就是显卡垃圾,砸钱换更贵的 GPU 就完事了。

正解帧耗时 = 四个阶段的最大值。很多场景瓶颈根本不在 GPU:可能是 CPU 侧 Draw Call 太多、GPU 排队等指令;可能是几何阶段裁剪过慢;也可能是像素阶段过度绘制。用 Profiler 先定位瓶颈再优化,才能把钱花在刀刃上——否则换了顶级显卡,光照还是逐个像素算、粒子还是叠十层,照样卡。

为何常见:显卡是“运行游戏”最直观的记忆点,人们容易忽略渲染是 CPU 与 GPU 接力完成的流水线。

面试题

Q1. 渲染管线四大阶段的正确顺序是?

单选题 · easy

  • A.顶点几何光栅像素← 正确答案
  • B.光栅顶点像素几何
  • C.像素光栅几何顶点
  • D.顶点像素光栅几何

答案:A。渲染管线像汽车流水线,顺序固定:顶点处理(摆位)、几何处理(焊接)、光栅化(网格扫描)、像素处理(喷漆)。光栅化不可能排在顶点之前,因为它需要三角形,而三角形要前面的阶段装配出来;像素处理作为上色质检必然是最后一站。

Q2. 顶点着色器的主要职责是?

单选题 · easy

  • A.变换顶点世界坐标
  • B.变换顶点裁剪坐标← 正确答案
  • C.计算片元光照颜色
  • D.剔除视锥外物体

答案:B。顶点着色器像一号车间的机械臂,逐个处理顶点,核心工作是通过 MVP 矩阵完成坐标变换链,最终把顶点送到裁剪空间。计算片元颜色属于像素处理阶段,剔除视锥外物体属于几何处理阶段。B 比 A 更完整,因为世界坐标只是中间态。

Q3. 透视投影产生“近大远小”的关键步骤是?

单选题 · mid

  • A.用模型矩阵放大顶点
  • B.用视图矩阵平移相机
  • C.裁剪坐标除以 w 分量← 正确答案
  • D.视口变换时像素缩放

答案:C。近大远小的数学根源是透视除法:投影矩阵把深度信息写进 w,顶点坐标除以 w 后,远处物体被压得越小。模型矩阵只负责摆放,视图矩阵只换视角,视口变换只是像素网格换算,三者都不产生透视效果。

Q4. 背面剔除的判断依据是?

单选题 · mid

  • A.绕序叉积的法线朝向← 正确答案
  • B.三角形离相机的距离
  • C.三角形顶点的颜色
  • D.三角形在屏幕的面积

答案:A。背面剔除看三角形绕序(顶点排列方向)叉积出的法线朝向:在相机坐标系中法线背对相机,说明这是看不见的背面,直接丢弃。距离、颜色、面积跟“是否面向相机”毫无关系,凭它们判断会误删可见面。

Q5. 光栅化阶段的核心任务是?

单选题 · mid

  • A.采样纹理计算光照
  • B.把顶点装配成图元
  • C.覆盖判定与属性插值← 正确答案
  • D.把片元写入帧缓冲

答案:C。光栅化就是三号车间的网格扫描:用边函数判定像素中心是否被三角形覆盖,再用重心插值算出每个像素的深度、颜色、UV。光照和纹理采样在像素处理阶段;顶点装图元在几何阶段;写帧缓冲是像素处理最后一步。

Q6. 深度测试的直接作用是?

单选题 · hard

  • A.让透明物体正确混合← 正确答案
  • B.让近处片元遮挡远处
  • C.降低几何阶段面数
  • D.加快纹理采样速度

答案:A。深度测试模拟排队买票:同一屏幕位置来了多个片元,深度最小(离相机最近)的才被写入颜色缓冲,其余丢弃,从而保证近处遮挡远处、场景前后关系正确。混合管透明效果,面数靠几何优化,纹理速度与带宽相关,都不是深度测试的职责。

Q7. 帧率与帧耗时的关系是?

单选题 · easy

  • A.帧耗时取倒数得帧率
  • B.帧耗时乘二得帧率
  • C.帧耗时加六十得帧率
  • D.帧耗时的平方得帧率← 正确答案

答案:D。帧率就是一秒能画多少帧,帧耗时越短帧率越高,二者互相取倒数,即 FPS = 1 / t_frame。乘二、加六十、平方这些关系都违背了时间单位的基本定义,属于张冠李戴。

Q8. 现代 GPU 中哪些阶段可编程?

多选题 · mid

  • A.顶点着色器阶段← 正确答案
  • B.像素着色器阶段← 正确答案
  • C.光栅化覆盖判定
  • D.深度测试与混合

答案:AB。现代 GPU 提供两个可编程阶段——顶点着色器和像素(片元)着色器,开发者可以写自定义着色器程序。光栅化的覆盖判定与深度测试+混合是固定功能单元,由硬件电路完成,不可编程,只能配置参数。

Q9. 像素处理阶段包含哪些操作?

多选题 · hard

  • A.纹理采样← 正确答案
  • B.光照着色← 正确答案
  • C.重心插值
  • D.背面剔除

答案:AB。像素处理阶段做三件事:纹理采样(贴花纹)、光照着色(算明暗)、深度测试与混合(质检交付)。重心插值是光栅化阶段完成属性传递的手段;背面剔除是几何处理阶段的工作,两者都不发生在像素阶段。

Q10. 下列哪些能有效提升渲染性能?

多选题 · extreme

  • A.合并批次减少绘制调用← 正确答案
  • B.使用 LOD 简化远模型← 正确答案
  • C.视锥加遮挡剔除← 正确答案
  • D.提高场景纹理分辨率

答案:ABC。合并批次减少 Draw Call 能缓解 CPU 瓶颈;LOD 简化远处面数;视锥与遮挡剔除从源头减少三角形数量——三者都直接降低某个阶段的耗时。提高纹理分辨率只会加重像素处理与带宽压力,通常适得其反,属于反向优化。