图形学虎书阅读笔记 P1-P12
2024-03-19
我阅读了虎书的第一章(P1-P12),提取了一些重要的部分作为笔记:
笔记
计算机图形学有许多广泛的应用领域:建模,渲染,动画,UI/UX, 虚拟现实,可视化,图像处理,3D扫描,计算摄影。
应用范围也很广泛:游戏,卡通,视觉特效,动画,CAD/CAM(计算机辅助设计/计算机辅助制造) 、模拟、医学扫描,信息可视化,诸如此类。
一个程序如果想要使用绘图库,就必须与图像API进行交互。图像API可以被分为:
可视化用户UI端输入
可视化输出
图像API有两种范例:
集成API, 例如java, 由java处理绘图功能。大多数情况下这是便携的。
图形程序库,例如OpenGL, DX, 与某种语言(例如C++)绑定,与UI相互独立,且并不一定是跨平台的。你依赖某个图形库编写的应用程序不一定是跨平台的。
图像管线 (Graphics Pipeline)
处理三角形之间的遮挡关系可以用z-buffer来处理。这差不多算是蛮力。
使用4D坐标空间(3个几何坐标+1个齐次坐标)似乎能更好的处理视图。后续笔记会更深入进行描述。
绘图速度受到三角形顶点数量的影响。因此,我们会想办法减少屏幕上需要绘制的三角形的数量,从而换取更高的性能(因为用户更在意流畅而非更好的画面)。
数学问题
几乎绝大多数现代计算机都遵循IEEE浮点规范(1985)。这个规范定义了许多很有用的行为。
在这个规范里,有些行为对我们很有用:
Infinity: \infin 大于任何有效数字
Minus Infinity: -\infin 小于任何有效数字
Not a number: NaN 返回未定义的结果,例如0/0.
IEEE的规范还设置了一些非常有用的,涉及到无穷的除法行为的定义:
另外,还有一些有用的东西:
总而言之:
任何有效值都大于-\infin,小于+\infin
负无穷小于正无穷
Nan的定义是:
任何包含NaN的表达式,结果都一定是NaN
任何包含NaN的表达式一定是False
还有些有用的东西:对于任何正实数a, 以下规则成立:
有了上述定义,你就可以避免许多问题。像是在许多有限制的编程语言里,0不能作为除数,你需要额外的代码用于判断。但是在IEEE的规定里,你就可以很方便的获得INF,简化你的工作。
效率
一般来说,优化图形学相关的代码包含以下步骤:
直截了当编写代码,别管什么狗屁优化
以优化模式编译
随便用什么调试器来查看性能瓶颈
看看局部的数据结构,看看有没有提高性能的办法。如果可能的话,让数据结构的大小和你使用架构的缓存大小(cache/page size)相匹配。
如果找到瓶颈了,查看生成的汇编代码。尝试重写源码解决你找到的问题。
其中,第一点最为重要。你最好不要尝试上来就优化代码,大多数情况下只会让你的代码变得更糟糕。
数据类型
vector2: 2D向量,包含xy分量。包含向量加减、点积叉积、标量乘除。
vector3:与2d类似。
hvector:4维齐次向量。
rgb:和vec3类似。不过用于表示颜色
transform: 4*4矩阵,表示变换。包含矩阵乘法、以及将其应用于位置、方向、表面法向向量的方法。
image:2D RGB矩阵, 包含输出方法。
调试
调试图形学程序有些麻烦:但我对虎书上内容的总结就是:
直接打印。 没错,将每一个步骤(你需要关注的部分)打印到屏幕上。这一般是图像。你可以给图像赋予显眼的颜色。例如你可以把每个像素的UV作为RGB的R、G通道,输出到屏幕上。这样会得到一张红色、绿色、黑色渐变的奇怪图像。
在图形学编程里,问题大多出在代码逻辑上。你需要用上述方法找到哪个步骤出了问题。代码一定能跑通(要是代码有问题,那你首先编译就不能通过),但是结果达不到预期的话,就在可能会出问题的地方,将那里的中间变量用图像的形式输出出来吧。
你也可以用调试器,但是那大概会很麻烦吧。