简介:本资源是山东大学计算机图形学课程期末复习精要整理,面向该校及相关高校计算机、数字媒体等专业本科生,聚焦核心考点与易混淆概念,助力高效备考与知识体系梳理。内容覆盖图形绘制流水线(顶点处理、裁剪与图元组装、光栅化、片元处理)、双缓冲机制原理与代码实现、投影变换与gluLookAt函数参数解析、全局/局部光照模型对比、光线跟踪基本思想、合成照相机模型、边缘函数与分层光栅化、齐次栅格化优势、走样问题及抗锯齿方案(超采样/多重采样)等关键模块,并附Z-Buffer算法、渲染方程与Phong光照模型等延伸要点。资源为1个6.87MB的Word文档(.docx),结构清晰、术语准确、公式与伪代码兼备,便于打印复习与重点标注。目前已有2313人学习下载,是兼顾理论深度与应试实用性的高质量期末复习笔记。
1. 计算机图形学到底是什么:不是“画图软件”,而是让屏幕“凭空造物”的数学引擎
你有没有想过,为什么打开一个三维游戏,角色能转头、光影会流动、远处的山会变小、近处的树叶子还带反光?这些画面不是提前录好的视频,也不是靠手动画出来的每一帧——它们是电脑在你按下“运行”那一秒,从零开始,用数学公式“算出来”的。
打个比方:计算机图形学(Computer Graphics)就像一位精通几何、光学和线性代数的“数字建筑师”。它不直接搬砖砌墙,而是先写一套严密的施工说明书:告诉机器——“这个球体中心在哪儿、半径多大、表面是磨砂还是镜面、头顶有几盏灯、每盏灯发什么颜色、光线碰到球后怎么弹、弹到你眼睛里时亮度剩多少……”然后,机器照着这份说明书,一像素一像素地推演、计算、填色,最终拼出你看到的画面。
这不是 Photoshop 里的滤镜,也不是 PPT 里的动画路径;它是现代所有三维视觉体验的底层逻辑——从手机地图的倾斜视角,到电影《阿凡达》里的潘多拉森林,再到你期末考卷上那道“写出 gluLookAt 参数含义”的题,全靠这套体系支撑。山东大学这门课考的,从来不是你会不会调 API,而是你能不能看懂这张“施工说明书”里每个符号、每步变换、每次插值背后的物理意义和数学必然性。搞懂它,你就不再只是调用glutSwapBuffers()的人,而是能一眼看出“为什么这里闪屏”“为什么高光跑偏了”“为什么远处纹理糊成一片”的人——这才是期末复习真正要抢回的“认知主权”。
2. 图形绘制流水线:一张图看懂画面是怎么被“算”出来的
图形绘制流水线(Graphics Pipeline),是计算机图形学最核心的骨架。它不是某段代码,而是一套标准化的、分阶段执行的计算流程——就像汽车装配线:底盘进来,依次经过焊接、喷漆、装发动机、质检,最后开出厂门。画面也一样:一个三维模型进来,经过顶点处理、裁剪、光栅化、片元处理,最终变成你屏幕上的一帧像素。理解它,等于拿到了整门课的“路线图”。
2.1 为什么必须分阶段?——并行性与职责分离的硬需求
早期显卡没有流水线,所有计算挤在一块儿做:先算完所有顶点位置,再统一裁剪,再一起光栅化……结果是 CPU 等 GPU、GPU 等内存、内存等显存,效率极低。现代流水线强制“分段作业”,带来两个不可替代的好处:
第一,并行加速。顶点处理模块可以同时处理成百上千个顶点(因为彼此独立),光栅化模块可以同时测试多个像素是否在三角形内,片元处理模块能并发计算不同片元的颜色——就像十条流水线同时拧螺丝,速度翻十倍。
第二,硬件专用化。GPU 芯片上,顶点处理器(Vertex Shader Core)专精矩阵乘法,光栅化单元(Rasterizer Unit)专精边缘函数求解,片元处理器(Fragment Shader Core)专精颜色混合与深度比较。如果混在一起,芯片设计会臃肿低效,功耗飙升。
提示:考试常考“为什么顶点处理是彼此独立的?”答案就藏在这里——每个顶点的坐标变换只依赖自身原始坐标和变换矩阵,不读取也不修改其他顶点数据,天然适合并行。
2.2 四大阶段拆解:从“点”到“像素”的完整旅程
我们以一个最简单的三角形为例,走一遍经典流水线(Classic Graphics Pipeline):
| 阶段 | 输入 | 核心任务 | 输出 | 关键技术点 |
|---|---|---|---|---|
| 顶点处理(Vertex Processing) | 一组顶点(含位置、法向量、纹理坐标) | 对每个顶点执行模型变换(Model)、视图变换(View)、投影变换(Projection),即 MVP 矩阵连乘;同时计算顶点颜色、光照初值 | 变换后的齐次裁剪坐标(x,y,z,w)及附属属性(如颜色、纹理坐标) | glLoadIdentity()清空当前矩阵;gluLookAt()构建 View 矩阵;glOrtho()或glFrustum()构建 Projection 矩阵 |
| 裁剪与图元组装(Clipping & Primitive Assembly) | 变换后的顶点流 | 将顶点按顺序组装成图元(如三角形、线段);对每个图元执行裁剪——剔除完全在视见体(Viewing Frustum)外的部分,对穿过边界的图元进行分割(如把一半在内一半在外的三角形切成两个小三角形) | 裁剪后、位于规范立方体(-1~1)内的图元集合 | 裁剪目的不是“省事”,而是避免后续计算出现除零、无穷大等退化(degeneracy)错误;gluLookAt后必须确保物体在视见体内,否则直接消失 |
| 光栅化(Rasterization) | 裁剪后的图元(如三角形) | 判断屏幕上哪些像素(或片元)被该图元覆盖;为每个被覆盖的片元生成初始属性(位置、重心坐标、深度 z、纹理坐标等) | 一组片元(Fragment),每个携带(x,y,z, color, texCoord, ...) | 核心算法是边缘函数(Edge Function):对三角形三条边分别计算E(x,y) = ax+by+c,若三点同号则在内部;glEnable(GL_DEPTH_TEST)开启深度测试的前提是光栅化输出了 z 值 |
| 片元处理(Fragment Processing) | 光栅化生成的片元流 | 对每个片元执行光照计算(Phong/Gouraud)、纹理采样(mipmap)、Alpha 混合、深度测试(Z-Buffer)、模板测试等;决定该片元是否写入帧缓冲区(Frame Buffer) | 更新后的像素颜色与深度值 | 片元 ≠ 像素!一个像素可能被多个片元覆盖(如多重采样),最终颜色是多次片元处理的结果;glutSwapBuffers()交换的正是帧缓冲区内容 |
2.3 流水线不是黑匣子:一个真实代码片段说明各阶段如何衔接
// OpenGL 旧版固定管线示例(对应山东大学PPT风格) void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清空颜色+深度缓冲 // 【顶点处理】阶段启动:设置变换矩阵 glLoadIdentity(); // 重置模型视图矩阵 gluLookAt(0,0,5, 0,0,0, 0,1,0); // View矩阵:相机在(0,0,5),看向原点,上方向Y轴 glOrtho(-2,2,-2,2,-1,1); // Projection矩阵:正交投影,视见体x∈[-2,2], y∈[-2,2], z∈[-1,1] // 【图元组装】阶段:定义三角形三个顶点 glBegin(GL_TRIANGLES); glVertex3f(-1.0, -1.0, 0.0); // 顶点1 glVertex3f( 1.0, -1.0, 0.0); // 顶点2 glVertex3f( 0.0, 1.0, 0.0); // 顶点3 glEnd(); // 此刻,OpenGL驱动已将这三个顶点送入顶点处理器 → 裁剪器 → 光栅化器 → 片元处理器 glutSwapBuffers(); // 【输出】:交换前后缓冲,显示本帧 }这段代码看似简单,但背后是完整的四阶段流水线在运转:gluLookAt和glOrtho构建了顶点处理所需的矩阵;glBegin/glEnd触发图元组装;glVertex3f提供原始顶点;glutSwapBuffers完成最终呈现。考试中让你“写出 gluLookAt 三个参数组的物理含义”,就是在考你是否看清了 View 矩阵这一环在流水线中的确切位置和作用。
2.4 流水线的“默认状态”:为什么需要归一化视见体(Normalization)
你可能疑惑:为什么glOrtho设定的是[-2,2]这种任意范围,而裁剪却总在[-1,1]的规范立方体内进行?答案就是视见体归一化(Normalization)。
它的本质,是流水线设计者的一个绝妙妥协:让所有投影(正交、透视)最终都映射到同一个标准空间(Canonical View Volume),这样后续的裁剪、光栅化、深度测试模块就可以用同一套硬件电路、同一段固件代码来处理,无需为每种投影写不同逻辑。
- 对正交投影,归一化是线性缩放平移;
- 对透视投影,归一化通过齐次坐标的 w 分量实现(
z' = z/w),把金字塔形视见体“压扁”成规范立方体。
这就是为什么gluLookAt后必须接glOrtho或glFrustum——前者提供 View 矩阵,后者提供 Projection 矩阵,二者相乘得到最终的 MVP,才能把世界坐标正确“塞进”那个-1~1的标准盒子。没这一步,顶点坐标就无法被裁剪器识别,整个流水线会在第二阶段就卡死。
3. 双缓冲、Z-Buffer、走样:那些让画面“稳、准、真”的关键机制
如果流水线是造车的骨架,那么双缓冲、Z-Buffer、抗走样技术,就是让这辆车开得稳、不撞墙、看起来像真车的三大底盘系统。它们不直接参与“画什么”,但决定了“画得有多好”。山东大学期末考反复出现的glutInitDisplayMode(GLUT_DOUBLE)、glEnable(GL_DEPTH_TEST)、glEnable(GL_MULTISAMPLE),全指向这三个机制。
3.1 双缓冲:消灭屏幕撕裂的“时间错位”问题
想象一下:你正在看一段 60 帧/秒的动画。单缓冲模式下,显卡一边往同一块内存(帧缓冲区)里写下一帧画面,显示器一边从这块内存里读取当前画面显示。问题来了——当显示器读到一半(比如刚读完上半屏),显卡恰好把下半屏改成了新帧内容,结果屏幕上半是旧帧、下半是新帧,出现一道明显的“撕裂线”。这就是屏幕撕裂(Screen Tearing)。
双缓冲(Double Buffering)用“空间换时间”完美解决:它准备两块独立的帧缓冲区——前台缓冲区(Front Buffer)专供显示器读取显示,后台缓冲区(Back Buffer)专供 GPU 渲染写入。GPU 总是在后台缓冲区画下一帧,画完立刻执行glutSwapBuffers(),原子性地交换前后台指针(不是复制数据!)。此时显示器无缝切换到新画好的后台缓冲区作为新的前台,而 GPU 立刻在刚腾空的旧前台(现后台)上开始画再下一帧。
注意:
glutInitDisplayMode(GLUT_DOUBLE)必须在glutCreateWindow()之前调用,否则窗口创建时未申请双缓冲内存,glutSwapBuffers()会无效。这是山东大学实验课常见翻车点。
3.2 Z-Buffer:解决“谁在前面”的深度战争
没有深度测试,3D 世界就是一张叠在一起的幻灯片——近处的茶杯会永远盖住远处的桌子,哪怕你绕到桌子后面。Z-Buffer(深度缓冲区)就是这场“深度战争”的裁判。
它是一块与帧缓冲区同样大小的内存,每个像素位置存储一个z值(即该像素对应物体表面到相机的距离)。渲染每个片元时,GPU 执行两步原子操作:
- 比较:将当前片元的
z值与 Z-Buffer 中对应位置的z值比较; - 更新:若当前
z更小(即更靠近相机),则用当前片元颜色更新帧缓冲区该像素,并用当前z值更新 Z-Buffer;否则丢弃该片元。
// 伪代码:Z-Buffer核心逻辑 for each fragment F at pixel (x,y): z_current = F.z; // 当前片元深度 z_buffer = zBuffer[x][y]; // Z-Buffer中该像素历史深度 if (z_current < z_buffer) { // 更近才可见 frameBuffer[x][y] = F.color; // 更新颜色 zBuffer[x][y] = z_current; // 更新深度 }这个算法简洁到极致,却解决了隐藏面消除(Hidden Surface Removal)这一根本难题。考试中问“Z-Buffer 算法为何能正确处理相互遮挡的复杂模型?”,答案就是:它不依赖图元绘制顺序,每个片元独立决策,天然支持任意拓扑关系。
3.3 走样(Aliasing):数字世界的“阶梯效应”与它的三重解药
走样,是离散采样(像素网格)与连续世界(真实光线)碰撞时必然产生的“数字伤疤”。它有三种典型表现:
- 几何走样:斜线呈现锯齿状(“楼梯效应”);
- 纹理走样:远处地板纹理闪烁、摩尔纹;
- 运动走样:旋转的风扇叶片忽隐忽现。
根本原因在于:奈奎斯特采样定理被违反——当场景中细节变化频率超过像素采样率(即每英寸线对数 > 1/2 像素间距),高频信息就会“折叠”成低频假象。
解决方案不是提高分辨率(成本太高),而是在采样前主动模糊(预滤波)或在采样后智能融合(后滤波):
| 方法 | 原理 | 代价 | 山东大学考点 |
|---|---|---|---|
| 超级采样(Supersampling, SSAA) | 以 4x 分辨率(如 3840×2160)渲染,再降采样(box filter)到 1920×1080 | 显存+计算量 ×4,GPU 负载爆炸 | 常考概念辨析:“SSAA 与 MSAA 本质区别?”答:SSAA 对每个子像素都执行完整片元着色,MSAA 只对每个子像素做深度/模板测试,着色只算一次/像素 |
| 多重采样(Multisampling, MSAA) | 每个像素划分为 4 或 8 个子样本(sub-sample),共享同一套纹理坐标和颜色计算,但独立记录深度/模板值;最终颜色是覆盖子样本的加权平均 | 平衡效果与性能,现代 GPU 硬件原生支持 | glEnable(GL_MULTISAMPLE)是启用开关;glutInitDisplayMode(GLUT_MULTISAMPLE)是初始化前提 |
| 各向异性过滤(Anisotropic Filtering, AF) | 专治纹理走样:当纹理平面与视线夹角极大(如地面)时,传统双线性滤波会拉伸模糊;AF 根据纹理坐标梯度(dudx, dudy)动态选择长方形采样区域,保持清晰 | 显存带宽略增,但效果显著 | PPT 中mipmap原理题必延伸至此;glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f)是典型调用 |
提示:考试若问“为什么开启 MSAA 后帧率下降不如 SSAA 明显?”,答案直指核心——MSAA 省去了重复的片元着色(Shading)计算,只增加了深度/模板的子样本存储与混合开销。
4. 光照模型与渲染:从“亮一块”到“像真光”的进化之路
如果说流水线是骨架,缓冲机制是底盘,那么光照模型就是赋予画面灵魂的“光之语法”。山东大学期末考中,“Phong 模型三部分”、“Gouraud vs Phong 着色区别”、“全局光照为何慢”这些题,都在考察你是否理解:光不是均匀洒下的,而是遵循物理定律,在物体表面发生反射、折射、散射的复杂过程。
4.1 局部光照:快速但“近视”的光照快照
局部光照(Local Illumination)模型只考虑光源→物体表面→观察者这一条直射路径,忽略环境光二次反射、物体间互反射等全局效应。它快、可控、易于硬件实现,是实时渲染的基石。
Phong 光照模型:三合一的经验公式
Phong 模型将物体表面反射光分解为三部分,每部分用独立公式计算,再线性叠加:
I_{\text{total}} = I_{\text{ambient}} + I_{\text{diffuse}} + I_{\text{specular}}- 环境光(Ambient):模拟全局漫反射底色。
I_a = K_a * I_{a,\text{light}}K_a是材质环境反射系数(0~1),I_{a,\text{light}}是环境光强度。它让背光面不纯黑,但无方向性。 - 漫反射(Diffuse):服从 Lambert 定律,亮度与入射光和表面法向夹角余弦成正比。
I_d = K_d * I_{d,\text{light}} * \max(0, \mathbf{N} \cdot \mathbf{L})K_d是漫反射系数,L是光源到点的单位向量,N是表面法向量。这是“哑光塑料感”的来源。 - 镜面反射(Specular):模拟光滑表面高光。
I_s = K_s * I_{s,\text{light}} * (\max(0, \mathbf{R} \cdot \mathbf{V}))^nR是L关于N的反射向量,V是视线向量,n是高光指数(越大越尖锐)。这是“金属/陶瓷感”的关键。
注意:考试常混淆
R和V。牢记R是光“怎么弹出去”,V是眼“往哪看”,只有两者方向一致时(R·V ≈ 1),才看到强高光。
Gouraud vs Phong 着色:插值对象决定画质天花板
二者都是为多边形网格着色,但插值粒度天差地别:
| 特性 | Gouraud 着色 | Phong 着色 |
|---|---|---|
| 插值对象 | 顶点颜色(I_{\text{vertex}}) | 顶点法向量(N_{\text{vertex}}) |
| 插值方式 | 在三角形内双线性插值顶点颜色 | 先插值边上的法向量,再插值面上的法向量 |
| 着色时机 | 顶点处理阶段计算I_v,光栅化后直接插值 | 光栅化后对每个片元F插值得到N_F,再在片元处理阶段用N_F计算I_F |
| 效果 | 高光呈多边形轮廓,曲面显“棱角”,计算快 | 高光圆润自然,曲面平滑,但需为每个片元重算光照,开销大 |
// OpenGL中启用方式(固定管线) glShadeModel(GL_SMOOTH); // 启用插值(默认) // Gouraud:glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE); // Phong:需用可编程管线(Shader)实现,固定管线无法原生支持考试若问“为什么 Phong 着色能产生正确高光而 Gouraud 不能?”,答案就是:高光位置由R·V决定,而R依赖于精确的表面法向N;Gouraud 只插值颜色,丢失了N的空间变化,导致高光被“抹平”在三角形上。
4.2 全局光照:追求真实的“物理级”渲染
全局光照(Global Illumination, GI)试图模拟光在场景中无限次反弹的真实行为:阳光照到白墙,白墙又把光漫反射到红沙发,红沙发再反射微弱红光到天花板……这种间接照明让画面拥有真实的空间感和色彩渗透。
渲染方程(Rendering Equation):GI 的终极数学表达
Kajiya 在 1986 年提出的渲染方程,是 GI 的理论基石:
L_o(\mathbf{x}, \omega_o) = L_e(\mathbf{x}, \omega_o) + \int_{\Omega} f_r(\mathbf{x}, \omega_i, \omega_o) \, L_i(\mathbf{x}, \omega_i) \, (\mathbf{n} \cdot \omega_i) \, d\omega_iL_o:从点x沿方向ω_o出射的辐射亮度;L_e:点x自发光亮度;- 积分项:所有入射方向
ω_i的贡献,由 BRDFf_r(双向反射分布函数)加权; (n·ω_i):Lambert 余弦因子,表征入射光有效面积。
这个方程之所以“难求解”,是因为:
- 无限递归:
L_i本身又是另一点的L_o,需递归追踪; - 高维积分:积分域
Ω是半球,需对所有方向采样; - BRDF 复杂:真实材质 BRDF(如 Cook-Torrance)含多个参数,解析解不存在。
因此,实时渲染放弃精确求解,转而用光线追踪(Ray Tracing)或辐射度(Radiosity)近似。而山东大学考纲中提到的“光线追踪”,正是沿着ω_o反向发射光线,递归求交、采样光源、累加贡献的蒙特卡洛方法——它效果惊艳,但每像素需发射数十至数百条光线,远超 60FPS 实时要求,故仅用于电影离线渲染。
提示:考试若问“为什么光线追踪不适合交互应用?”,不要只答“慢”,要指出本质:它违背了实时渲染的‘确定性帧率’约束。一帧耗时从 16ms(60FPS)飙升至数秒,用户交互(如鼠标移动)会严重卡顿。
4.3 BRDF:描述材质“个性”的物理身份证
BRDF(Bidirectional Reflectance Distribution Function)是材质的“光学指纹”,定义了:给定入射光方向ω_i和出射观察方向ω_o,表面在点x处将多少比例的入射光反射到ω_o。
- 理想漫反射(Lambertian)BRDF:
f_r = \frac{\rho}{\pi},ρ即漫反射率K_d,是常数。它假设光向所有方向均匀散射,符合粗糙表面(粉笔、哑光漆)。 - Phong BRDF(经验模型):
f_r \propto (\mathbf{R} \cdot \mathbf{V})^n,虽不严格物理,但高效模拟镜面高光。 - Cook-Torrance BRDF(物理模型):将反射分解为镜面(Microfacet)+ 漫反射(Diffuse)+ 几何遮蔽(Geometry)三部分,参数多但真实。
考试中“BRDF 的物理意义”题,核心答点就是:它是一个关于方向的函数,满足能量守恒(反射光 ≤ 入射光)和亥姆霍兹互易性(f_r(ω_i,ω_o) = f_r(ω_o,ω_i))。记住这两条,就能判断一个自编 BRDF 是否合理。
5. 易混概念辨析:终结那些让你考场犹豫的“好像都对”
计算机图形学里,太多术语长得像、功能近、英文缩写还撞车。山东大学期末卷上,一个选项写错字母,整道题就丢分。下面这 5 组,是历年考生血泪踩坑最多、老师最爱设陷阱的易混点。我们不讲定义,只说怎么一眼分清、为什么容易混、考试怎么防坑。
5.1 片元(Fragment) vs 像素(Pixel):不是同义词,是“候选人”与“正式员工”的关系
- 易混点:教材常写“光栅化生成片元”,代码里又操作
glDrawPixels,学生误以为片元=像素。 - 为什么混:中文翻译都带“片”字,且一个片元最终常对应一个像素颜色。
- 怎么区分:
- 像素(Pixel):帧缓冲区(Frame Buffer)中的一个存储单元,有固定位置
(x,y)和颜色值。它是最终显示在屏幕上的“成品”。 - 片元(Fragment):光栅化器为潜在覆盖某个像素而生成的临时计算单元,携带
(x,y,z, color, texCoord, ...)等属性。它可能被深度测试(Z-Buffer)淘汰,也可能被 Alpha 混合(Blending)修改,甚至被多重采样(MSAA)拆成多个子片元。
✅ 考场速记:“片元是应聘者,像素是录用者”。一个像素位置,可能经历多个片元的竞争(深度测试)、合作(MSAA)、淘汰(模板测试),最终只有一个(或加权平均)胜出成为像素。
- 像素(Pixel):帧缓冲区(Frame Buffer)中的一个存储单元,有固定位置
5.2 正交投影(Orthographic) vs 透视投影(Perspective):不是“平行”vs“汇聚”,是“距离无关”vs“距离敏感”
- 易混点:看到“正交线平行”“透视线汇聚”,就认为区别只在视觉效果。
- 为什么混:PPT 图常只画线框,忽略核心数学差异。
- 怎么区分:
- 正交投影:不改变物体相对大小。
z坐标只用于深度测试,不影响x,y。公式本质是线性映射:x' = x, y' = y, z' = z(经归一化后)。适用于 CAD、UI、等距游戏。 - 透视投影:模拟人眼,近大远小。
x',y'坐标被z缩放:x' = x/z, y' = y/z(齐次坐标下w=z)。z不仅管深度,还直接扭曲x,y。
✅ 考场速记:看
glFrustum()和glOrtho()的参数。glFrustum(l,r,b,t,n,f)中n,f是近远裁剪面z值,但l,r,b,t会随z变化(因l/z等);glOrtho(l,r,b,t,n,f)中l,r,b,t是绝对坐标,与z无关。 - 正交投影:不改变物体相对大小。
5.3 Gouraud 着色 vs Phong 着色:不是“快”vs“慢”,是“插值颜色”vs“插值法向”
- 易混点:知道 Gouraud 快、Phong 慢,但选错“哪个插值什么”。
- 为什么混:名字都带“Phong”,且都用于三角形着色。
- 怎么区分:
- Gouraud:在顶点计算完整光照
I_v,然后在三角形内插值I_v得到像素颜色。 - Phong:在顶点计算法向
N_v,然后在三角形内插值N_v得到片元法向N_f,最后在每个片元用N_f计算光照I_f。
✅ 考场速记:“Gouraud 插颜色,Phong 插法向”。题目若说“高光在三角形内部出现”,一定是 Phong;若说“高光被限制在顶点附近”,则是 Gouraud。
- Gouraud:在顶点计算完整光照
5.4 模型变换(Model) vs 视图变换(View):不是“物体动”vs“相机动”,是“坐标系换”vs“视角换”
- 易混点:
glTranslatef(1,0,0)是物体右移,gluLookAt(1,0,0,...)是相机左移,效果一样,学生困惑“为何要分两个变换”。 - 为什么混:数学上等价,但概念层级不同。
- 怎么区分:
- 模型变换:将物体从自身局部坐标系(Object Space)变换到世界坐标系(World Space)。描述“物体在世界中怎么摆”。
- 视图变换:将世界坐标系中的所有物体,变换到相机坐标系(Camera Space / Eye Space)。描述“从相机视角看,世界是什么样”。
✅ 考场速记:“模型变换是物体搬家,视图变换是相机搬家”。
gluLookAt(ex,ey,ez,...)的ex,ey,ez是相机在世界坐标中的位置,不是相机自身坐标!所以它属于视图变换,而非模型变换。
5.5 齐次坐标(Homogeneous) vs 普通三维坐标(Cartesian):不是“多一个数”,是“为变换而生”的数学工具
- 易混点:
(x,y,z,1)和(x,y,z)看起来就差一个1,学生不理解为何要引入。 - 为什么混:教科书常从代数角度讲“方便矩阵表示”,忽略几何本质。
- 怎么区分:
- 普通三维坐标:只能表示平移以外的变换(旋转、缩放、剪切),因为平移
x'=x+tx无法写成3×3矩阵乘法。 - 齐次坐标:
[x,y,z,w]表示点,当w≠0时,对应笛卡尔坐标(x/w,y/w,z/w);w=0时表示无穷远点(方向向量)。关键价值:用4×4矩阵统一表示所有仿射变换,包括平移([x,y,z,1] × [T] = [x',y',z',1])。
✅ 考场速记:“齐次坐标是给平移发的‘入场券’”。没有它,
glTranslatef就无法融入 MVP 矩阵连乘;gluLookAt生成的 View 矩阵,其最后一行[0,0,0,1]正是为了保证w坐标不变,维持点的性质。 - 普通三维坐标:只能表示平移以外的变换(旋转、缩放、剪切),因为平移
6. 什么时候用、什么时候别用:一份来自山东大学考场的实战边界指南
复习到最后,知识不是堆在脑子里的名词,而是能帮你在考场上快速决策的肌肉记忆。我整理了山东大学近年期末卷的 7 类高频题型,结合你手头这份复习资料,告诉你:每个知识点在什么情境下必考、什么条件下绝对不考、遇到陌生题如何用已有知识推导。这不是押题,而是建立你的“考点雷达”。
6.1 流水线阶段题:抓住“输入-输出-职责”铁三角
这类题常以“以下操作属于哪个阶段?”或“某步骤缺失会导致什么现象?”形式出现。
- 必考情境:给出
gluLookAt、glVertex3f、glutSwapBuffers等函数,问所属阶段。 - 解题口诀:“顶点进,像素出;中间裁剪光栅化”。
- 凡涉及
glVertex*、glNormal*、glColor*等设置顶点属性 →顶点处理; - 凡涉及
glBegin(GL_TRIANGLES)、glEnd()→图元组装; - 凡涉及
glEnable(GL_DEPTH_TEST)、glBlendFunc→片元处理; glutSwapBuffers()是输出控制,不属于流水线内部阶段,但考频极高。
- 凡涉及
- 避坑提醒:
glClear()清空缓冲区,是渲染前准备,不属于任何流水线阶段;glPushMatrix()/glPopMatrix()是矩阵栈管理,服务于顶点处理,但本身不是阶段。
6.2 矩阵与变换题:死磕gluLookAt三组参数的物理坐标系
gluLookAt(ex,ey,ez, cx,cy,cz, ux,uy,uz)是山东大学的“送分题”也是“夺命题”。
- 必考情境:给出相机位置、目标点、上方向,让你写出参数;或给出参数,问相机朝向。
- 解题核心:所有坐标都是世界坐标系(World Space)下的值。
ex,ey,ez:相机在世界中的坐标(不是相机自己的原点!);cx,cy,cz:相机镜头对准的世界中某点(如(0,0,0));
本文还有配套的精品资源,点击获取