table {
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
}
1、在表示图片时,1位和8位深的帧缓冲分别只能显示2种和256种颜色。全彩色系统允许使用多少位?
在全彩色系统中,每个像素有24位或更多位。
2、在计算机图形学中,像球体这样的物体通常由平面多边形构成的简单物体(多面体)来近似。利用经线和纬线,定义一组近似以原点为中心的球体的简单多边形。能否仅使用四边形或仅使用三角形?
可以使用四边形和三角形来近似球体。考虑两条相邻的纬线和两条相邻的经线,它们在每个半球的四个位置相交,可用这些点在该区域用四边形近似球体,在 WebGL 中可用两个三角形渲染该四边形;也可使用单个三角形条带来近似两条相邻纬线之间的球体。
但在两极处,由于所有经线汇聚,不能使用条带,可使用两个三角形扇,一个在每个极点。
因此,可以仅使用三角形来近似球体,也可结合四边形和三角形来近似球体。
3、另一种近似球体的方法从正四面体开始,该正四面体由四个三角形构成。假设它以原点为中心且有一个顶点在y轴上,求其顶点坐标。基于对正四面体各面进行细分,推导一个能得到越来越接近单位球体近似的算法。
正四面体顶点坐标为:
(0, 0, 1)
(0, 2√2/3, -1/3)
(-√6/3, -√2/3, -1/3)
(√6/3, -√2/3, -1/3)
算法如下:
初始化
:
指定四个顶点:
javascript
var va = vec4(0.0, 0.0, -1.0, 1);
var vb = vec4(0.0, 0.942809, 0.333333, 1);
var vc = vec4(-0.816497, -0.471405, 0.333333, 1);
var vd = vec4(0.816497, -0.471405, 0.333333, 1);
调用
tetrahedron(va, vb, vc, vd, numTimesToSubdivide)
开始递归。
递归细分
:
在
tetrahedron
函数中调用
divideTriangle
函数对四个面进行细分。
细分三角形
:
在
divideTriangle
函数里,若
count > 0
,计算各边中点:
javascript
ab = normalize(mix(a, b, 0.5), true);
ac = normalize(mix(a, c, 0.5), true);
bc = normalize(mix(b, c, 0.5), true);
并递归调用
divideTriangle
函数继续细分。
归一化
:
将各边中点归一化,使其位于单位圆上。
4、考虑二维空间中点相对于圆形裁剪窗口的裁剪。证明仅需该点的坐标以及圆的圆心和半径,就能确定该点是否被裁剪或完全被裁剪掉。
在二维空间中,对于一个圆形裁剪窗口,设其圆心坐标为 $(x₀, y₀)$,半径为 $r$,点的坐标为 $(x, y)$。
根据两点间距离公式,点 $(x, y)$ 到圆心 $(x₀, y₀)$ 的距离:
d=(x−x₀)2+(y−y₀)2−−−−−−−−−−−−−−−−−√d=(x−x₀)2+(y−y₀)2
若 $d leq r$,则点在圆内,不会被裁剪;
若 $d > r$,则点在圆外,会被裁剪掉。
因此,仅需该点的坐标以及圆的圆心和半径,就能确定该点是否被裁剪或完全被裁剪掉。
5、对于一条线段,证明相对于裁剪矩形顶部的裁剪可以独立于相对于其他边的裁剪进行。利用这一结果证明裁剪器可以实现为四个更简单裁剪器的流水线。
裁剪窗口与裁剪器的工作原理
我们可以将裁剪窗口视为由四条无限直线相交确定的对象,这四条直线分别决定了窗口的顶部、底部、右侧和左侧。
以裁剪线段顶部为例,可将此操作视为一个黑盒,其输入和输出是顶点对,参数为
ymax
。若存在交点,可得出交点坐标,裁剪器会返回三种顶点对之一。
同理,裁剪底部、右侧和左侧时,可使用相同方程,必要时交换 x 和 y 的角色并代入窗口各边的值。
因此,相对于裁剪矩形顶部的裁剪可以独立于其他边进行。
基于此,可将裁剪器细分为四个更简单的裁剪器组成的流水线,每个裁剪器负责裁剪一条边,从而实现裁剪功能。
6、像游戏中使用的空间球,通常利用球内的压力传感器来测量用户施加的力。这类输入设备应用于哪些场景?
这类输入设备可用于三维图形中定位和定向相机,也用于虚拟现实和机器人应用中,还可用于需要更多自由度的场景,如数据手套可感知人体各部位运动以提供更多输入信号,任天堂的Wii等设备也采用了类似的位置和方向感应技术。此外,运动捕捉系统也利用大量计算能力驱动相关设备。
7、所有透视视图的特点是大小会缩小。当物体离观察者更远时,它们的图像会变小。经典透视视图是如何工作的?
在经典透视视图中,观察者相对于投影平面呈对称分布,且位于投影中心的垂线上。投影平面上的窗口和投影中心所确定的棱锥是对称或正棱锥,这种对称性源于人眼观看时视网膜与晶状体的固定关系,或标准相机中底片与镜头的固定关系,以及大多数实际情况中的类似固定关系。
经典透视视图通常分为一点、二点和三点透视,区别在于物体的三个主方向中有多少个与投影平面平行。
三点透视
:三个主方向的平行线都会汇聚到有限的消失点。
二点透视
:若一个主方向与投影平面平行,则只有两个主方向的线会汇聚。
一点透视
:两个主方向与投影平面平行,只有一个消失点。
8、说明隐藏面去除算法或可见面算法是如何工作的。
隐藏面去除算法可分为两类:
对象空间算法
:
尝试对场景中对象的表面进行排序,按特定顺序渲染表面以得到正确图像。例如,对于立方体,先渲染背面,再用正面覆盖。但该算法在对象以任意顺序通过管线的架构中效果不佳。
图像空间算法
:
遵循视图和光线投射模型,从投影中心发出穿过像素的光线,与多边形所在平面相交,确定光线穿过的多边形,找到离投影中心最近的交点,用该点处多边形的颜色为像素着色。对于 $ n imes m $ 的显示器,此操作需进行 $ nmk $ 次,复杂度为 $ O(k) $。
9、说明为什么将原始多边形在表面上的投影称为阴影多边形。
假设阴影落在可由方程 $ y = 0 $ 描述的平面上,阴影不仅是一个平面多边形,而且是原始多边形在该表面上的投影,所以将原始多边形在表面上的投影称为
阴影多边形
。
10、比较并对比仰角(elevation)和方位角(azimuth)。
仰角是星星相对于观察者所在平面上方的角度,通过定义观察者所在点的法线并以此法线定义平面来确定,无论观察者是否实际站在平面上都可定义该角度。
方位角是从该平面中的一个轴到观察者与星星连线在该平面上投影的角度。
11、投影归一化的用途是什么?
投影归一化的用途包括:
将所有投影转换为正交投影,方法是先对物体进行扭曲,使扭曲物体的正交投影与原始物体的期望投影相同;
能设计归一化矩阵,将视体扭曲为规范视体;
可让同一管线实现平行和透视投影;
还能简化裁剪过程,因为规范视体的边与坐标轴对齐。
12、当我们构建三维图形模型时,可能会失望地看到图像看起来扁平,无法展现模型的三维特性。请举一个体现这种缺陷的例子,并描述一种克服这种局限性的方法。
例子:
在假设每个表面以单一颜色呈现给观察者的情况下,球体的正交投影是一个颜色均匀的圆形,立方体看起来像一个扁平的六边形。
克服方法:
开发光源和常见光 – 材料相互作用的单独模型,添加阴影到快速流水线图形架构中,使用局部照明模型计算表面上一点的阴影,还可考虑使用光线追踪和辐射度等方法处理全局照明效果。
13、当我们为一个模型分别开发光源和光与材料相互作用的模型时,目标是为快速流水线图形架构添加着色效果,此时只开发局部光照模型。请解释局部光照模型相对于全局光照模型支持这些特性的特点。
局部光照模型允许我们独立于场景中的任何其他表面,计算要分配给表面上某一点的阴影。其计算仅取决于分配给表面的材料属性、表面的局部几何形状以及光源的位置和属性。
而全局光照模型不具备这种独立性,计算时需考虑场景中其他表面的影响,不利于在快速流水线图形架构中使用。
14、Phong模型支持哪些不同类型的材料 – 光相互作用?
Phong模型支持三种类型的材料-光相互作用,分别是:
环境光(ambient)
漫反射(diffuse)
镜面反射(specular)
15、说明当面朝向光源时,我们对漫反射贡献所做的更改。
当面朝向光源时,漫反射项仅在面朝向光源(即点积为非负)时才有意义,因此必须将计算修改为:
var d = Math.max(dot(normal, lightPosition), 0.0);
16、比较局部光照模型和全局光照模型的原理。说明全局光照模型为克服局部光照模型的局限性所采用的不同渲染策略。
局部光照模型与全局光照模型
局部光照模型在计算表面某点的颜色时,独立于场景中的其他表面,仅依赖于表面的材质属性、局部几何形状以及光源的位置和属性。
例如在渲染一组球体时:
每个球体独立着色;
所有球体在观察者看来相同;
无法处理阴影、反射和光线遮挡等全局效果。
全局光照模型则考虑场景中所有物体之间的光照相互作用,能处理阴影、反射和光线遮挡等现象。
为克服局部光照模型的局限性,全局光照模型采用了
光线追踪
和
辐射度
两种渲染策略:
光线追踪
:从合成相机模型出发,对于每一条投射到多边形的光线,在确定该点是否被一个或多个光源照亮后再进行处理。
17、纹理映射如何使用图像(或纹理)来影响片段的颜色?
纹理映射的基本步骤
纹理映射通过三个基本步骤使用图像(或纹理)影响片段颜色。
步骤一:加载纹理图像
在应用程序中形成纹理图像并将其放置在GPU的纹理内存中。
步骤二:分配纹理坐标
为每个片段分配纹理坐标,纹理坐标可作为额外的顶点属性与顶点关联,由光栅化器在多边形上对顶点处的纹理坐标进行插值得到,也可在着色器中生成。
步骤三:应用纹理
将纹理应用于每个片段,通过片段着色器中的纹理采样函数(如
texture2D
)根据纹理坐标从纹理中获取颜色值,输出到片段颜色中。还可通过片段着色器对采样得到的颜色进行修改,如改变灰度、替换灰度为颜色或进行卷积等操作,从而进一步影响片段的颜色。
18、在电影和电视中,我们会看到抖动对象的较暗副本,即运动模糊效果。是什么导致了这种效果?请解释你的答案。
如果对一个对象进行抖动并多次渲染,同时保持其他对象的位置不变,就会在最终图像中得到该抖动对象的较暗副本,从而产生运动模糊效果。
若对象沿着路径移动而非随机抖动,我们能看到对象的轨迹,这种效果类似于用长曝光时间拍摄移动对象的照片。
还可以调整对象的α值,使对象的最终位置具有更高的不透明度或营造出速度差异的感觉。
19、我们可以尝试通过简单地绘制点并让人类视觉系统将这些点合并成形状来显示采样数据。如果数据接近奈奎斯特极限,为什么这种技术是危险的?
当数据接近奈奎斯特极限时,可能违反奈奎斯特准则,导致采样的副本重叠,出现混叠现象。
一旦混叠发生,无法区分原数据中该频率的信息和采样过程置于该频率的信息,会出现可见的拍频或莫尔条纹图案等明显混叠效果,使显示出现可见错误。
20、为什么在纹理采样中线性滤波比点采样是更好的选择?
点采样是使用最接近光栅化器输出的纹理坐标的纹理元素的值,这最容易出现明显的走样错误。
而线性滤波是对由点采样确定的纹理元素邻域内的一组纹理元素进行加权平均,能得到更平滑的值,减少走样,所以是更好的选择。
21、展示如何通过渲染到纹理来创建新的纹理映射,然后通过另一次渲染到纹理使用新的纹理映射来确定下一个纹理映射,从而实现将后缓冲区交换到前缓冲区类型的数据传输。
可以通过在一对帧缓冲对象(FBOs)之间切换(乒乓操作)来实现这种技术。
以一个简单的例子说明,先将场景渲染到纹理以创建纹理图像,此步骤仅用于建立初始条件,后续渲染无需使用该程序对象。
接着,将一个矩形(两个三角形)渲染到新纹理,应用第一次渲染创建的纹理来确定片段颜色。
片段着色器通过对片段四个相邻纹理颜色求平均来扩散第一个纹理的值。
在代码实现中,使用一个标志位来指示使用哪组缓冲区。
开始渲染时,根据标志位绑定纹理对象并设置帧缓冲纹理。
渲染矩形后,解绑 FBO 并交换纹理,将新创建的图像作为新纹理映射进行正常渲染到标准帧缓冲。
最后交换纹理并重复该过程。
22、比较简单纹理映射和凹凸映射。
纹理映射与凹凸映射
纹理映射
使用图像(或纹理)来影响片段的颜色。可通过以下方式指定纹理:
固定图案
程序纹理生成方法
数字化图像
纹理映射通过在光滑表面绘制图案来增加细节,从而增强表面的视觉效果。
凹凸映射
则是在着色过程中扰动法向量,使表面看起来有形状上的微小变化,例如橙子表面的凸起。它通过改变表面的法线来模拟复杂表面的外观,而无需实际创建复杂的几何结构。
23、使用指点设备在显示屏上选择对象的过程是什么?
有至少四种处理该问题的方法:
选择法
:
调整裁剪区域和视口,跟踪小裁剪区域中哪些图元被渲染到光标附近区域,这些图元的名称会进入命中列表供用户程序后续查看。但基于着色器的 OpenGL 版本已弃用此方法。
射线法
:
从投影中心通过鼠标在投影平面上的位置生成一条射线,检查该射线与哪些对象相交,相交的最近对象即为所选对象。此方法适用于光线追踪渲染器,也可在流水线架构中实现,但有性能损失。
边界框法
:
使用(轴对齐)边界框或范围来表示感兴趣的对象,应用程序维护一个简单的数据结构来关联对象和边界框,即可在应用程序内进行近似选择。
额外颜色缓冲区法
:
使用一个不显示的额外颜色缓冲区和额外渲染,将对象以不同颜色渲染到该缓冲区,应用程序员可通过更改颜色来确定对象内容。
24、根据关节角度,找出简单机器人上任意点位置的方程。能否根据上臂尖端的位置确定关节角度?请解释你的答案。
可以使用层次建模方法确定位置的数值或找到显式方程来根据关节角度给出模型中任意期望点集的位置。
若 $ heta$ 是关节角度数组,$p$ 是模型中顶点数组,运动学模型形式为:
p=f(θ)p=f(θ)
对于能否根据上臂尖端位置确定关节角度,答案是
不一定
。
模型有三个自由度,即三个可指定的角度。虽然每组角度对应上臂尖端的唯一位置,但反之不成立。
给定上臂尖端的期望位置:
可能没有能使尖端处于该位置的角度组;
可能有一组角度能达到指定位置;
也可能有多个角度组能使尖端处于期望位置。
25、构造实体几何(CSG)是如何解决对象多边形表示法的弱点的?
以下是将给定文本内容调整为
Markdown
格式的结果:
假设从一组原子实体几何元素(如平行六面体、圆柱体和球体)开始,这些对象的属性包括表面属性(如颜色或反射率)和体积属性(如大小和密度)。
在描述此类对象的场景时,考虑构成每个对象的空间点,即:
每个对象是一组点。
可使用集合代数从这些实体基元形成新对象。
CSG 建模
使用三种集合运算:
并集
交集
集合差
通过这些运算和操作,能够解决以下问题:
多边形表示法只能描述三维对象表面
在 CAD 应用中难以利用图形对象体积属性
显示存在歧义等问题
26、是否可以通过后序中序遍历使用二叉空间分割树(BSP树)来绘制多边形?
可以。可以使用后序中序遍历(即先遍历右子树,接着是根节点,最后是左子树)来绘制多边形。
27、展示如何向场景图中添加光照属性。
可以通过以下代码向场景图中添加光照属性:
myLight = new Light();
myScene.add(myLight);
其中,先创建一个光照对象
myLight
,然后将其添加到场景
myScene
中。
28、找出描述n个粒子系统动力学所需的常微分方程组。
已知加速度是速度的导数,速度是位置的导数,我们可以将粒子的牛顿第二定律写成六个耦合的一阶微分方程:
p˙i=vi,v˙i=1mifi(t)p˙i=vi,v˙i=1mifi(t)
因此,$ n $ 个粒子系统的动力学由一组 $ 6n $ 个耦合的常微分方程控制。
29、我们可以将一个可能用于搜索的二叉树描述为一个包含指向其子节点指针的节点列表。请用 C++ 编写一个数据结构来实现这样的二叉搜索树,并编写一个函数来遍历显示这些节点。
以下是实现该功能的 C++ 代码示例:
#include <iostream>
// 定义二叉树节点的数据结构
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
// 中序遍历函数,可按从小到大顺序输出节点值
void inorderTraversal(TreeNode* root) {
if (root == nullptr) return;
inorderTraversal(root->left);
std::cout << root->val << " ";
inorderTraversal(root->right);
}
int main() {
// 构建一个简单的二叉搜索树示例
TreeNode* root = new TreeNode(4);
root->left = new TreeNode(2);
root->right = new TreeNode(5);
root->left->left = new TreeNode(1);
root->left->right = new TreeNode(3);
// 调用中序遍历函数显示节点
inorderTraversal(root);
std::cout << std::endl;
return 0;
}
以上代码定义了二叉树节点的数据结构
TreeNode
,并实现了中序遍历函数
inorderTraversal
来显示节点。在
main
函数中构建了一个简单的二叉搜索树并调用遍历函数输出节点值。
30、请列举两种群聚算法的示例
一是让粒子朝远离所有粒子质心的方向移动,二是让每个粒子朝特定位置的粒子移动
31、在人物模型中添加程序噪声,使模型在静止时每个关节都有轻微的运动。
在人物模型的关节位置添加少量噪声可以为模型带来真实感,可通过在噪声生成器中添加非线性操作(如取绝对值)来生成用于模拟流动中湍流的序列。程序噪声可用于创建纹理映射、模拟流体模型中的湍流行为、动画中的真实运动以及模糊物体(如云)等,以此实现人物模型关节的轻微运动效果。
32、考虑显式方程 y = mx + h。它描述了哪些类型的几何图形?
该方程描述的几何图形是直线。
33、曲线参数形式的优点有哪些?
曲线参数形式的优点包括:
在二维和三维中形式相同,二维情况下只需去掉z的方程
可将点 $ p(u) $ 的轨迹可视化为 $ u $ 变化时绘制的曲线
其导数可视为曲线绘制的速度,且指向曲线的切线方向
在计算机图形学中是最灵活和健壮的形式
34、找出曲线平滑性的标准。
曲线平滑性通常根据沿曲线的导数来定义。一般来说,一阶导数连续的曲线比一阶导数有间断点的曲线更平滑,更高阶导数连续的曲线平滑性更高。
对于多项式曲线
p(u)=∑k=0nckukp(u)=∑k=0nckuk
所有导数都存在且可解析计算,唯一可能出现连续性问题的地方是连接点。
35、假设你使用一组样条曲线来描述动画中物体随时间移动的路径。在这种情况下,你如何注意到G1连续性和C1连续性之间的差异?
对于C1连续性,要求两段曲线在连接点处的所有三个参数方程及其一阶导数都匹配;而G1连续性只要求两段曲线在连接点处的导数成比例,即切线方向相同,但切线的大小可能不同。
在动画路径中,若使用G1连续性的曲线,虽然在连接点处切线连续,但切线比例常数的值(即连接点两侧切线的相对大小)会影响曲线,导致曲线外观不同。并且在动画等应用中,G1连续性可能不足,因为仅切线方向相同但大小不同的曲线组合可能使物体运动路径在连接处不够平滑自然,而C1连续性的曲线能保证在连接点处更平滑过渡,物体运动路径会更自然流畅。
36、贝塞尔曲线控制点的凸包有什么意义?
贝塞尔多项式是凸和,其必位于四个控制点的凸包内。虽不插值所有控制点,但不会离它们很远。
这两个特性结合控制点数据,便于用户交互式处理贝塞尔曲线:
用户可输入四个控制点定义初始曲线;
再通过操作点来控制形状。
此外,贝塞尔曲线的凸包还具有
变差缩减特性
,即曲线细分后新多项式的凸包位于原曲线凸包内。
37、埃尔米特几何矩阵的意义是什么?
埃尔米特几何矩阵 $ M_H $ 用于求解多项式系数 $ c $,即
c=MHqc=MHq
其中 $ q $ 为数据矩阵。通过它可得到埃尔米特多项式
p(u)=uTMHqp(u)=uTMHq
使曲线段在连接点处的插值值和导数共享,保证所得函数及其一阶导数在所有段上连续。
38、非均匀有理B样条(NURBS)曲线的意义是什么?对B样条曲线或曲面应用仿射变换会发生什么?
NURBS曲线保留了三维B样条的所有属性,如凸包和连续性属性,还具有另外两个在计算机图形学和CAD中特别重要的属性:
1. 一是其构造中嵌入的透视分割确保了NURBS曲线在透视视图中能被正确处理;
2. 二是二次曲面是二次NURBS曲线的特殊情况,因此可以使用NURBS曲线这一单一建模方法处理最广泛使用的曲线和曲面。
对B样条曲线或曲面应用仿射变换,会得到与从变换后的控制点导出的B样条相同的函数。
39、对贝塞尔曲线进行递归细分的渲染方法有什么意义?
该方法基于凸包的使用,无需对多项式进行显式求值。可以将曲线分成两个独立的多项式,每个多项式在原区间的一半上有效。
此外,细分方法具有可适应性,在渲染的某些时刻可能仅需对一侧进行细分,并且由于曲线的渲染可在流水线的光栅化阶段进行,显示器的有限分辨率限制了凸包的细分次数。
40、基于多边形可由单个平面内一组相交直线描述的思想,设计一个测试点是否在凸多边形内的方法。
将点与凸多边形各边所在直线进行判断,可通过计算点与各边的位置关系来确定。
射线法
:
假设从该点出发向某一方向作射线,计算射线与多边形各边的交点情况。
若射线与多边形的边相交
奇数次
,则点在多边形内;
若相交
偶数次
,则点在多边形外。
向量叉积法
(适用于凸多边形):
对于凸多边形的每条边,计算该边向量与从边的起点到待判断点的向量的叉积。
若所有叉积的
符号相同
,则点在多边形内;
若存在
不同符号
,则点在多边形外。
41、假设你有一个代数函数,其中最高项是x的i次方乘以y的j次方乘以z的k次方。那么,求解射线与该函数所定义的曲面的交点时,需要求解的多项式的次数是多少?
i + j + k