可见面判别

Download Report

Transcript 可见面判别

课程内容进展
综述
‘图形学’和‘图形系统’
建模
曲线曲面 实体造型
观察
观察流水线 裁剪
显示
可见面判别
其它
UI 动画 ……
光照 面绘制
坐标系统
基本图元
几何变换
第八讲 可见面判别算法
引子——可见面判别
(Visible-surface detection, Culling)

作用:在绘制时消除场景中不可见的线和面,获
得真实感的绘制。 深度关系



线:近亮、远暗/不显示/虚线显示/不同颜色显示
面:屏幕象素仅包含前向面的颜色
场合1:对象指定位置视图投影到显示设备
 3D

to 2D产生二义型
场合2:复杂场景
 3D物体本身的遮挡;
 复杂场景中物体相互之间的遮挡;
两大类可见面判别方法

物空间算法 object-space
 对象级别——直接对物体几何模型进行处理,将场景
中的各物体和物体上的各个组成部件进行比较和判别

像空间算法 Image-space
 象素级别——对物体的投影结果进行处理,在投影平
面上对每个像素判断其可见性(所属可见面)
提高效率:深度排序、连贯性
基本方法:后向面判别 物空间
N
VN>0
V
N
VN=0
V
N
VN<0
V
可见面判别算法的细分

后向面判断:通常可用来消除一半左右的隐藏面
 完全适用:凸多面体(前向面可见,后向面不可见)
 不足之处:凹多面体或者其它复杂三维对象或者多对
象场景中,前向面也会部分被其它面遮挡

可见面判别算法分类
1. 深度缓存 像空间
2. A缓存 像空间
3. 扫描线 像空间
4. 深度排序 物空间
5. BSP树 物空间
6. 区域细分 像空间 + 物空间完成深度排序
7. 八叉树 物空间
8. 光线投射 物空间
像空间
1.深度缓存算法 depth-buffer method

在投影面上按每一象素位置,比较场景中所有面的深度


深度缓存
刷新缓存
y
x
存储投影面上各象素对应的深度值
存储投影面上各象素的属性值
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z
-
-
10
-
-
-
-
-
-
-
-
-
-
-
-
-
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9












9
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9











9
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9










8
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8









8
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8








8
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8
8








1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8
8



18




1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8
8



18
17



1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8
8



18
17
15


1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8
20


18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8
20
20

18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8
20
20

18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
4
9
8
8
8
20
20

18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
4
6
8
8
8
20
20

18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
4
6
7
8
8
20
20

18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
4
6
7
8
8
20
20

18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
4
6
7
8
8
20
20

18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
4
6
7
8
8
11
20

18
17
15
14

depth-Buffer最终结果
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
4
6
7
8
8
11
20

18
y
17
15
14

x
depth-Buffer算法简述
假设,深度规范为0-1,且投影平面在深度为0处
① 初始化所有单元
depthBuff(x,y)=1.0
(最深)
frameBuff(x,y)=背景色
② 逐个处理场景中每一表面上每一点,深度为z
如 z<depth(x,y) 则
depthBuff(x,y)=z,
·各表面以任意次序处理
·每一表面可用扫描线法转换
framBuff(x,y)=Surfcolor(x,y)
单个面扫描转换中的z值计算
垂直边:(x,y-1)
像空间
2. A缓存算法


是深度缓存算法的扩充
每个象素对应一个表面链表
d

Surf1

Surf2

Surf3
深度域
y
 RGB强度分量
 表面标识名
 透明度
 其他表面绘制参数
因此,A缓存算法可
以处理透明表面

x
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z


10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9 17
9
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9 17
9 18
8
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9 17
9 18
8 18
8
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9 17
9 18
8 18
8 19
8



18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9 17
9 18
8 18
8 19
8



18
17
15
14

19
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9 17
9 18
8 18
8 19
8 19
20


18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9 17
9 18
8 18
8 19
8
20
20

18
17
15
14

19
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
9 17
9 18
8 18
8 19
8
20
20

18
17
15
14

19
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
4 9 17
9 18
8 18
8 19
8
20
20

18
17
15
14

19
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
4 9 17
6 9 18
8 18
8 19
8
20
20

18
17
15
14

19
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
4 9 17
6 9 18
7 8 18
8 19
8
20
20

18
17
15
14

19
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
4 9 17
6 9 18
7 8 18
8 8 19
8
20
20

18
17
15
14

19
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
4 9 17
6 9 18
7 8 18
8 8 19
8 9 19
20
20

18
17
15
14

1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
4 9 17
6 9 18
7 8 18
8 8 19
8 9 19
1120
20

18
17
15
14

a-Buffer最终结果
1 2 3 4 5 6 7 8 9 10
12 14
16 18 20 22
z

17
10 17
4 9 17
6 9 18
7 8 18
8 8 19
8 9 19
1120
20

y
18
17
15
14

x
像空间
3.扫描线算法 scan-line method

沿各扫描线计算并比较面片深度值
 判断交点之间部分的可见性,将可见象素点置入刷新缓存
扫描时建立面的 On/Off 标志
平面参数计算判断重叠面的可见性
ON
ON
ON
Off
ON
ON
ON
Off
Off
Off
Off
Off
像空间
扫描线算法(续)

表面相互贯穿或循环遮挡时,需先通过切割来消除循
环遮挡,再应用该算法
物空间
4.深度排序算法(画家算法)
depth-sorting method
画家算法

将表面按各自深
度的最深值排序

从深度最大的表
面开始,逐个扫
描转换
画家算法(续)



两个面S和S’,且 S深度> S’深度
但它们深度上有重叠
如果以下条件都不满足,则需重
新排序




投影无重叠
投影的包围矩形无重迭 次序任意
相对于观察位置,S完全位于S’之后
相对于观察位置, S’完全位于S之前
S的所有顶点
S’的所有顶点
都在S’的后面
都在S的前面
S,S’,S’’
S,S’
S’’,S’,S
S’,S
S’,S’’,S
物空间
5. BSP树算法—画家算法的一个例子


分割场景对象的时候,相对于视点,判断各表面是位
于分割平面的前还是后。
类似于画家算法:右左遍历BSP树,逐个扫描转换
像空间 + 物空间完成深度排序
6.区域细分算法 area-subdivision method

将投影平面不断细分为更小的矩形,直到满足
终止条件,将该矩形内象素置入刷新缓存。

表面与投影平面的子矩形区域的关系
包围表面

重迭表面
内含表面
分离表面
对于一个子区域,分割终止条件有几种情况:



所有表面均为它的分离表面
只有一个重迭 or 内含 or 包围表面
有一遮挡了其它所有表面的包围表面(各表面进行深度排序)
物空间
7.八叉树算法

由前往后(0,1…7)将八叉树结点映射到
观察表面
 仅当刷新缓存中相应的象素为空时才置值
5
4
0
1
2
7
3
物空间
8.光线投射算法 ray casting



做由观察平面上每一象素进入场景的射线(由视
点、观察方向、投影方法决定),求之与所有对象
的交点,离观察平面最近的交点置入刷新缓存,
其所在面即为可见面。
对于曲面、球面场景效率高。
是深度缓存算法的变形。
象素
可见面判别方法小结
应用相关,结合使用,硬件实现,并行处理










--------------------------分布广,深度重叠少:
画家算法,BSP
深度重叠多,分布范围小:扫描线,区域细分
--------------------------几千个面以下:画家算法,BSP,扫描线
几千个面以上:深度缓存,八叉树
--------------------------深度缓存:处理时间与面的数量无关
BSP:从不同观察参考点生成多个视图
八叉树,光线投射:含曲面的场景
曲面的可见性判断


光线投射或八叉树算法
曲面的层位线显示:一组表示曲面形状的曲线
曲面的层位线显示及其可见性判断


曲面的xy平面投影图:y = f(x,z)
选定z的范围,设定z
y
Ymax
f(x0,z0+ z)
f(x0,z0+ 2z)
Ymin
f(x1,z0+ 2z)
f(x1,z0+ z) Ymax
f(x0,z0)
f(x1,z0) Ymin
x0
x1
x
OpenGL显示三维模型
GLfloat ctrlPts[8][3] = {
{ 10.0,
100.0, 0.0}, { 10.0, 200.0, 0.0},
{110.0, 200.0, 0.0}, {110.0, 100.0,
0.0}, { 10.0, 100.0, 100.0}, { 10.0,
200.0, 100.0}, {110.0, 200.0, 100.0},
{110.0, 100.0, 100.0}};
void myinit(void)
{ glClearColor (0.0, 0.0, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW); }
void display()
{
glClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
glRotatef(15, 0.0f, 1.0f, 0.0f);
glRotatef(15, 1.0f, 0.0f, 0.0f);
glPolygonMode(GL_FRONT_AND_BACK,
GL_FILL/GL_LINE);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
。。。。。 给出每个面4个点
glEnd(); 。。。。。。。
glPolygonMode(GL_FRONT_AND_BACK,
GL_FILL);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1,1);
glColor3f(0.0, 0.0, 0.0);//背景色
glBegin(GL_POLYGON);。。。
glEnd();。。重复画所有面
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT/GL_BACK);
glPopMatrix ();
glFlush();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
glEnable(GL_CULL_FACE);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glCullFace(GL_BACK);
glCullFace(GL_FRONT);
或者glCullFace(GL_BACK);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glBegin(GL_POLYGON); 。。。(底面未画)
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glBegin(GL_POLYGON);
。。。。。 给出每个面4个点
glEnd(); 。。。。。。。
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1,1);
glColor3f(0.0, 0.0, 0.0);//背景色
glBegin(GL_POLYGON);。。。
glEnd();。。重复画所有面
}
注意:Stitching & z-fighting
void display()
{
glClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT);
glPushMatrix ();
glEnable(GL_CULL_FACE);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glCullFace(GL_FRONT);
glCullFace(GL_BACK);
或者glCullFace(GL_BACK);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glBegin(GL_POLYGON); 。。。。。
}
第8讲小结

各可见面判别算法在物空间或像空间分别
进行何种工作。
 如何处理表面
 如何置刷新缓存的值