高级计算机图形学
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
19
顶点着色器
#version 150 in vec4 vPosition; in vec4 vColor; out vec4 color; uniform mat4 model_view; uniform mat4 projection; void main() { gl_Position = projection*model_view*vPosition/vPosition.w; color = vColor; }
25
规范变换
z = x
z=x z = far z = near 原来的裁 剪体 x = 1 变形后 的对象 z=1
x=1
原来的 对象
变换后的 裁剪体
z = 1
26
规范化与隐藏面消除
虽然这里选择的透视矩阵形式上看起来有点儿 任意,但这种选择保证如果在原来的裁剪体内 z1>z2, 那么变换后的点满足z1’>z2’ 因此如果首先应用规范变化,隐藏面消除算法 有效 然而,公式z’ = -(a+b/z)意味着由于规范化导致 距离发生了改变,这可能导致数值问题,特别 是当近距离非常小的时候更是如此
高级计算机图形学
中国科学技术大学计算机学院 黄章进 zhuang@ustc.edu.cn
第三节
投影矩阵
2
基本内容
推导出在标准OpenGL投影中所用的投影 矩阵具体表示 介绍斜投影 介绍投影规范化
3
投影规范化
不想为每种类型的投影设计不同的投影矩 阵,所以把所有的投影转化为具有默认视 景体的正交投影 这种策略可以使我们在流水线中应用标准 变换,并进行有效的裁剪
24
a与b的选取
z’ = -(a+b/z) 如果取 a = (near + far)/(near – far) b = 2 near*far/(near – far) 那么近平面z=-near映射到z = -1 远平面z=-far映射到z = 1 各侧边映射到 x = 1, y = 1 这样,新的裁剪体就是缺省裁剪体
27
OpenGL的透视
Frustum可以定义非对称视景体,但 Perspective不能做到这一点
28
OpenGL透视矩阵
Frustum的规范化
• 错切变换H:把非对称视景棱台变换为对称的 •
•
四棱台,远近平面不变 缩放变换S:把四棱台的侧面变换为x= z和y= z,远近平面不变 透视规范化变换N: x= z变换为x= 1, y= z变换为y= 1,近平面z=-near变换为z=-1, 远平面z=-far变换为z = 1
35
Z缓冲区算法
优点:
void display( void ) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); point4 eye( radius*sin(theta)*cos(phi), radius*sin(theta)*sin(phi), radius*cos(theta), 1.0 ); point4 at( 0.0, 0.0, 0.0, 1.0 ); vec4 up( 0.0, 1.0, 0.0, 0.0 );
(1, 1, 1)
9
正交规范化矩阵
两步
•
近裁剪面z=-near映射到z=-1平面, 远裁剪面z=-far映射到z=1平面
•
把中心移到原点,对应的变换为 T((left+right)/2, (bottom+top)/2, (near+far)/2)) 进行缩放从而使视景体的边长为2 S(2/(right-left), 2/(top bottom), -2/(far-near))
• •
这些变换都是非奇异的 默认值为单位阵(正交视图)
规范化使得不管投影的类型是什么,都是相对 于默认的简单立方体进行裁剪 投影直到最后时刻才进行
•
从而可以尽可能的保留深度信息,这对隐藏面消除是非 常重要的
7
正则视景体
OpenGL缺省的视景体是中心在原点,边长 为2的立方体,相当于调用
Ortho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
20
键盘回调函数
void keyboard( unsigned char key, int x, int y ) { switch( key ) { case 033: // Escape Key case 'q': case 'Q': exit( EXIT_SUCCESS ); break; case 'x': left *= 1.1; right *= 1.1; break; case 'X': left *= 0.9; right *= 0.9; break; case 'y': bottom *= 1.1; top *= 1.1; break; case 'Y': bottom *= 0.9; top *= 0.9; break; case 'z': zNear *= 1.1; zFar *= 1.1; break; case 'Z': zNear *= 0.9; zFar *= 0.9; break; case 'r': radius *= 2.0; break; case 'R': radius *= 0.5; break; case 'o': theta += dr; break; case 'O': theta -= dr; break; case 'p': phi += dr; break; case 'P': phi -= dr; break;
投影矩阵 P = Morth H(, ) 一般情形:P = Morth STH(, )
15
等价性
16
对裁剪体的影响
投影矩阵P = STH把原来的裁剪体变换为 默认的裁剪体
对象 顶视图 远平面 DOP z=1
DOP x = 1
x=1
近平面
裁剪体
变形后的对象
ຫໍສະໝຸດ Baidu
z = 1
17
交互式观察立方体
此时立方体好像发生了错切,然后再进行 正交投影 斜投影 = 错切+正交投影
12
一般的错切
后裁剪面 对象
前裁剪面 投影平面
13
顶视图和侧视图
xp = x + z cot
yp = y + z cot
14
错切矩阵
xy 错切(z值不变)
1 0 H( , ) 0 0 0 cot 0 1 cot 0 0 1 0 0 0 1
0 2 far*near far near 0 0
30
Persective函数投影矩阵
Perspective(fovy, aspect, near, far) 对称性:left = -right, bottom=-top 三角学:top = near * tan(fovy) right = top * aspect
4
投影规范化
把对象进行变形,使得 变形后的对象经正交投 影后得到与原对象的理 想投影一样的视图 扭曲变形由规范化矩阵 来执行
•
设计规范化矩阵,使得视 景体变形为正则视景体
5
流水线
模型-视图 变换
非奇异变换
投影变换
透视除法
4D 3D
裁剪
相对于默认立方体
投影
3D 2D
6
注释
在模型-视图变换和投影变换的过程中,我们 是一直在四维齐次坐标系中的
1
10
最后的投影
令z = 0 这等价于如下的齐次坐标变换
M orth
1 0 0 0
0 0 0 1 0 0 0 0 0 0 0 1
从而在4D中一般的正交投影为P = MorthST
11
斜投影
OpenGL的投影函数不支持一般的平行投 影,例如立方体的如下图示
• Z缓冲区的空间分辨率和颜色缓冲区相同
34
Z缓冲区算法
基本思想:
• •
深度缓冲区的初始深度值对应于 到观察者最远的距离 当光栅化裁剪体内的每个多边形 时,计算出每个片段的深度(到 观察者的距离)
• 如果深度小于Z缓冲区中对应于 •
该片段的深度值,用多边形片段 的颜色来替换颜色缓冲区中的像 素颜色,并更新Z缓冲区中的深 度值 否则,忽略当前多边形的颜色, 考虑下一个片段,进行同样的测 试
彩色立方体位于对象标架的原点 照相机的参考点(at point)位于原点, up方向与y轴正向重合 采用极坐标定位照相机,视点(eye point )坐标为eye = [r sin cos, r sin sin, r cos ]
半径r表示照相机到原点的距离
18
显示回调函数display()
31
为何采取这种方法?
规范化使得只需要一个流水线体系就可以 进行透视投影和正交投影 尽可能位于四维齐次空间中,以便保持隐 藏面消除和明暗处理所需要的三维信息 简化了裁剪的操作
32
隐藏面消除
隐藏面消除算法:删除观察者看不到的表 面。也称为可见面算法:找出可以看到的 表面 对象空间算法:试图对场景中对象的表面 排序,使得按照所排列的顺序来绘制表面 可以得到正确的图像
0 0 2 far near 0
2 0 right left 2 0 P ST top bottom 0 0 0 0
right left right left top bottom top bottom far near far near
mat4 mv = LookAt( eye, at, up ); glUniformMatrix4fv( model_view, 1, GL_TRUE, mv );
mat4 p = Ortho( left, right, bottom, top, zNear, zFar ); glUniformMatrix4fv( projection, 1, GL_TRUE, p ); glDrawArrays( GL_TRIANGLES, 0, NumVertices ); glutSwapBuffers(); }
glutPostRedisplay(); }
21
简单透视
考虑简单透视:COP在原点,投影面在z = -1, 由 平面 x = z, y = z确定的有90度的视角
z = -far (1, 1, 1) (1, 1, 1)
22
透视矩阵
齐次坐标下的简单投影矩阵为
1 0 M 0 0
• 不能很好地与绘制流水线结合,因为对象通过 •
绘制流水线的顺序是任意的 为了正确排序,必须能获取所有对象的信息
33
Z缓冲区算法
图像空间算法可以作为投影过程的一部分 ,试图确定每一条投影线与对象表面形成 的所有交点之间的关系 Z缓冲区算法在光栅化多边形时用深度缓 冲区(Z缓冲区)存储必要的深度信息, 只显示每条投影线上离COP最近的点
P = NSH
29
透视投影矩阵
2near right left 0 P NS H 0 0
0 2near top bottom 0 0
right left right left top bottom top bottom far near far near 1
称这个视景体为正则视景体(canonical view volume)
8
正交规范化
glOrtho(left, right, bottom, top, near, far) 规范化 求出把指定裁剪体转化为默认裁剪体的变换 (right, top, far) (1, 1, 1)
(left, bottom, near)
0 1
0 0 0 1 0 0 1 0 0 0
注意这个矩阵与远裁剪面无关
23
推广
1 0 0 0 0 1 0 0 透视规范化矩阵 N 0 0 a b 0 0 1 0 p=(x,y,z,1) -> (x,y,az+b,-z) 在透视除法后,点(x,y,z,1)变到了 x’ = -x/z, y’ = -y/z, z’ = -(a+b/z) 无论a, b的值是什么,在正交投影后就得到所期 望的点。此时矩阵N非奇异