Download presentation
Presentation is loading. Please wait.
Published byHandoko Gunardi Modified 6年之前
1
第六章 三维真实感物体显示技术 虚拟现实(Virtual Reality,简称VR)技术是一种逼真的模拟人在自然环境中视觉、听觉、运动等行为的人机界面技术。其目的是:不仅能够在多维空间仿真建模,而且能够帮助人们获取知识和形成新的概念,Mark Green给出了一个简明的虚拟现实应用系统模型,如图6.1所示。
2
第六章 三维真实感物体显示技术
3
第六章 三维真实感物体显示技术 计算包括所有应用中非图形的计算,几何模型包括一个计算中的数据的高级图形表示或者叫科学计算可视化,观察指用户查看应用数据 。行为体是指以同样方式仿真用户的系统中的交互对象,用户对象的仿真有三个方面的研究:几何仿真、物理仿真和行为仿真。其中几何仿真是核心技术,是三维图形学研究热点,也是立体虚拟现实的基础。
4
第六章 三维真实感物体显示技术 本章主题是 : 三维计算机图形学(CG),介绍三维计算机图形学中一些基本方法,基本概念以及基本技巧 。
本章主要内容是: 立体多面体的消隐算法,基本光照模型以及纹理贴图方法等。
5
第六章 三维真实感物体显示技术 要求: 在模仿现实基础上,自己编程实现相应的程序,达到举一反三,从而熟练掌握这些基本方法和基本技巧以及基本概念。
6
6.1 隐藏面和隐藏线的消除 三维计算机图形学方法中,利用计算机处理立体对象,所使用的表示立体对象的模型称为立体模型 。 主要模型有:
(1)线框架结构模型(wire frame model); (2)表面模型(surface model); (3)实体模型(solid model)
7
6.1 隐藏面和隐藏线的消除 线框架结构模型 它是将立体对象用轮廓线和小的元素面描述的模型,这种模型的对象立体数据输入方式简单,容易操作,可以实现描述的快速性,经常被人们使用。但是由于线推表示会出现错误理解。如下图所示。
8
6.1 隐藏面和隐藏线的消除
9
6.1.1 凸多面体的隐藏线消除 凸多面体是由若干个平面围成的物体,这些平面的方程设为:
10
6.1.1 凸多面体的隐藏线消除 平面的法向量n为(ai,bi,ci) 或(-ai,-bi,-ci) 即 -aix-bix-cix=0
也是平面方程。 为了下面讨论方便,规定n的取法满足下列条件:对物体内一点P0(x0,y0,z0)使得 n·(x0,y0,z0)T+di<0, 这样规定的法向量n指向了物体外部。
11
6.1.1 凸多面体的隐藏线消除 视觉与第i个面上一点连线方向为(li,mi,ni)则第i个面为自隐藏面的判断方法是:
12
6.1.1 凸多面体的隐藏线消除 对于任意凸对面体,可先求出所有隐藏面,然后检查每条边,若此边为两隐藏面的交线,则此边是隐藏线,用虚线表示或消除。
13
6.1.2 凹多面体的隐藏线消除 注意到凹多面体的表面也都是多边形,因此,一条边是否为隐藏线的判断实质上是这样一个问题:空间一段线段P1P2和一个多边形π,判断线段是否被多边形遮挡。如果全被遮挡则是隐藏线,若部分遮挡,则求出隐藏部分,以视点为投影中心,把线段与多边形顶点投影到屏幕,将各对应投影点连线的方程与直线联立求解,即可求得线段与多边形投影得交点。
14
6.1.2 凹多面体的隐藏线消除 这样,线段AB投影多边形有两种可能: 1、线段与多边形的任何边都不相交; 2、线段AB与投影多边形有交点。
下面分别讨论:
15
6.1.2 凹多面体的隐藏线消除 1、线段与多边形的任何边都不相交
此时又有两种可能值,即线段AB与投影多边形分离;或线段AB在投影多边形之中。前一种情况,线段完全可见。后一种,空间线段完全可见或完全隐藏。可以通过空间线段中点与视点连线,判断此连线段与空间多边形是否有交点,若没有交点,则空间线可见,若有交点,则空间线段被空间多边形隐藏。
16
6.1.2 凹多面体的隐藏线消除 2、线段AB与投影多边形有交点 此时投影多边形的边把投影线段分割成若干段,如图所示
17
6.1.2 凹多面体的隐藏线消除 每条线段上所有点具有相同的隐藏性,究竟是隐藏的还是可见的需进一步判断是否落在投影多边形内部。若在内部则需要隐藏。 根据上述方法,依次把多边形的边进行对比便得到所有隐藏线 。
18
6.1.3 曲面隐藏线消除 由方程 (5.2) 表示则曲面经常出现在实际应用和科学计算中,在表示这个曲面的线框式立体图中。一般用x=xi和z=zi两簇曲线表示,曲面隐藏线的消除就是对这两簇曲线进行检测判断曲线哪些部分要被遮挡而隐藏的。
19
6.1.3 曲面隐藏线消除 为此先讨论z=zi的一簇曲线的消隐算法。设 i=1,2……n (5.3)
平面z=zn是最靠近视点,于是平面Z=zn上曲线 (5.4) 都是可见的。
20
6.1.3 曲面隐藏线消除 而对于z=zi平面上的曲线y=f(x,zi),在区间x∈[a,b]上只有两种情况是可见的。
f(x,zi)>max f(x,zj) x∈[a,b] f(x, zi)<min f(x, zj) x∈[a,b] 其余线段上应当消隐,如图5.5。
21
6.1.3 曲面隐藏线消除
22
6.2 消除隐藏面 为了让曲面在图形显示器上显示,需要把对应的曲面某点在屏幕某位置决定出来,即把曲面点变换成图像中点,这过程就是光栅化过程,于是有些曲面或曲面一部分会被遮挡住,因此需要解决消除隐藏面的问题。
23
6.2.1 画家算法 画家算法是把对象空间方法与图像空间方法结合在一起来消除隐藏面的方法,其原理是,先把显示窗口设置成背景色,再把物体各个面按其离视点的远近进行排序,离视点远的多边形平面放在表头,离视点近的在表尾,这样得到一个存放深度优先的表,然后按表头到表尾的顺序逐个绘制各个面。由于后显示的面取代先显示的面,而后显示的面离视点更近一些,因此由远及近的绘制各个面,就相当于消除隐藏面。因为这方法与画家作画过程类似,故取名为画家算法。
24
6.2.1 画家算法 这里涉及了一个问题,即多边形究竟如何排序呢? 下面给出一种建立深度优先级表的方法。
25
6.2.1 画家算法 每个多边形有一些顶点,这些顶点有一个Z坐标,取其中Z坐标最小的记为Zmin,于是这个多边形都有这么个Zmin,按Zmin的大小把多边形作为初步排序。设Zmin最小的多边形为P,它暂时成为优先级最低的一个多边形。对其他任意一个多边形Q,研究P与Q的关系。 (1)若Zmax(P)<Zmin(Q),则P不为遮挡Q。 (2)若Zmax(P)>Zmin(Q)而又有Zmin(P)<Zmin(Q),则需要作进一步检查。
26
6.2.1 画家算法 按下面五种情况进行讨论
27
6.2.1 画家算法 P和Q在xoy平面上投影的包围盒在x方向上不相交。 P和Q在xoy平面上投影的包围盒在y方向上不相交。
Q的各顶点均在P的靠近视点的一侧。 五项中有一项成立,则P就不遮挡Q。如果上述五项都不成立,则说Q有部分被P遮挡了。
28
6.2.1 画家算法 多边形的画家算法如下: ①对每个多边形顶点求Zmin。以Zmin为排序关键码,建立相应的深度排序表。
表中第一个多边形是最小的Zmin,记这多边形为P,同时,设视点位于Z轴方向的无穷远处,于是根据坐标系规定,P是离视点最远的多边形。 ②取第二个多边形为Q ③检查Q与P的关系 如果Zmax(P)<Zmin(Q),则P不遮挡Q,将P写入帧缓存。 如果满足上述五个条件之一,则P不遮挡Q,于是P写入帧缓存。
29
6.2.2 Z缓冲算法 Z缓冲算法又称为深度缓冲算法,这是一种简单而且有效的图像空间隐藏面消除的算法,是由Catual于1975年提出的。这主要针对画家算法中,深度排序计算量大,而且排序后还需检查相邻的面,以确保在深度优先级表中前者在前,后者在后,若遇到多边形相交或循环无序时还必须分割多边形等复杂运算而求出的一种新方法,在这个算法中,需要两张表存放相应数据,一张表叫帧缓存,用来存放对应象素的颜色值,另一张叫Z缓存存储器,用来存放对应象素的深度值。如图所示。
30
6.2.2 Z缓冲算法 屏幕 帧缓存 Z缓冲器 每个单元存放对 每个单元存放对
31
6.2.2 Z缓冲算法 Z缓存器中每个单元的值是对应像素点所反映对象的Z坐标值,Z缓冲器中每个单元初值先完成Z的极小值,而帧缓存中对应单元的初值取为背景色,图形消隐的过程实际上就是根据Z缓冲器的情况给帧缓存对应单元填充相应的颜色值。具体讲,Z缓冲器的值与空间一点的Z值进行比较,若Z缓冲器的值大,则不变,即Z缓冲器的值不变,帧缓存的值也不变;若Z缓冲器的值小,则Z缓冲器的值用此Z值表示,同时帧缓存的对应值用空间点对应的多边形的颜色填。 对显示对象的每个面上的每个点都作了上述处理后,便又得到清除了隐藏面的图。
32
6.2.2 Z缓冲算法 Z-buffer算法() { 帧缓存置背景色; Z缓存置为-1;//表示取为最小值 for(每个多边形面)
扫描转换多边形; for(多边形所覆盖的每个象素(x,y)) 计算深度值Z(x,y); if(Z(x,y)>Z缓冲器中(x,y)的值) 把Z(x,y)替换Z缓冲器(x,y)的值; 把多边形在(x,y)处的颜色值存入帧缓存的(x,y)处; }
33
6.2.2 Z缓冲算法 深度缓冲器算法的优点是 ①方法简单,在象素级上由近物代替远物,从面达到消除隐藏面的要求,对于复杂形状也可以实现;
②计算量为线性复杂度O(n),其中n场景中景物表面采样点的树目,所以,对于复杂画面,此方法能较有效的显示出来; ③由于景物表面上的可见点可按任意次序写入Z缓冲器和帧缓存,所以不必首先把多项式面进行排序,省了画家算法中的排序时间。 ④容易推广至空间的自由曲面。事实上只需在上述算法中把多边形面改为自由曲面便可,故对描述一般场景是个有效方法; ⑤由于目前涉及的三维显示都存在运行速度慢的问题,许多实时显示需要硬件实现算法来加速,固而能否易于硬件实现也是衡量一个算法的指标之一,Z缓冲器算法只涉及比较小而易于硬件实现,所以,Z缓冲算法已在计算机图形学中成了一个标准。
34
6.2.2 Z缓冲算法 Z缓冲算法也有许多缺点 ①该算法并没有考虑物体固有的拓扑几何结构
②有一些处理相对而言实现不了,如对透明半透明效果无法实现。
35
6.2.2 Z缓冲算法 多面体消隐的改进z缓存算法: Z_Buffer() { //帧缓存置为背景色; //扫描整个屏幕
For(屏幕上的每个象素(i,j)) 深度缓存变量zb=-1;//置最小值 For(多面体上的每一个多边形) If(象素点i,j在p的投影多边形内P) If(像素点(i,j)在P的投影多边形内) 计算P在i,j点的深度值depth; If(depth>zb) zb=depth; 帧缓存相应位置置p的颜色; } 按帧缓存进行显示;
36
6.2.3 扫描线z-buffer算法 扫描线z缓冲器算法如下: For(各条扫描线) { 将扫描线桢缓存置为背景色;
求出该多边形与当前扫描线的相交区间; For(相交区间内各个象素点) 计算多边形在该处的深度值Z; If(多边形在该处深度值z<Z缓冲器在该处的值) 用多边形在该处的深度值z取代Z缓冲在该处的值; 用多边形的颜色替代帧缓存中相应值; } 用帧缓存显示当前扫描线;
37
6.2.3 扫描线z-buffer算法 由于在处理每条扫描线时,都要判断所有多边形是否与其相交,若相交还要计算相交区间内每个象素点的深度值,所以扫描线z缓冲算法的运算量还是很大的。因此,在实现算法时,还要采用一些方法降低运算量。
38
6.2.3 扫描线z-buffer算法 首先,建立一个多边形的表及一个边的表,这两个表行数是一样的,是窗口的扫描线。
39
6.2.3 扫描线z-buffer算法
40
6.2.3 扫描线z-buffer算法
41
6.2.3 扫描线z-buffer算法 多边形表用于存放多边形信息,存放原则为:对于一个多边形,根据多边形顶点中y坐标最小的y值,以此值确定多边形在多边形表中的位置,其数据结构包括:多边形的编号ID,多边形顶点y坐标的最大值,以及指向存储在多边形表中的同一行的下一多边形的指针。根据多边形编号,可以从定义多边形的数据表中取出多边形平面方程ax+by+cz+d=0的系数a,b,c,d以及多边形的边,顶点坐标和多边形的颜色属性信息。
42
6.2.3 扫描线z-buffer算法 边的表用于存放多边形的边信息,其存放原则为:对于一个多边形的边,根据边的两端点中较大的y值,确定边在表中的位置。多边形的表的数据结构包括:边的两端点中y坐标的最大值。该边在xoy面上的投影和相邻的两条扫描线交点的x坐标值之差△x, y值较小的那个端点的x坐标和z坐标值以及指向存于边表的同一行的下一条边的指针。如下图所示的多边形中,边表的结构
43
6.2.3 扫描线z-buffer算法
44
6.2.4 区间扫描算法 由于扫描线z缓冲器酸法的运算量较大,下面的区间扫描线算法考虑了各个边的拓扑结构关系,运算量就少许多。
45
6.2.4 区间扫描算法 每条扫描线被多边形边界在xoy平面上的投影分割成为一些小区间,从结构上看,这些区间上的象素的显示或隐藏性质应当一样的。因此,只须分析清楚每个区间上的显示与否的属性便可。于是,只要在区间上任意一点处,找出在该处z值最大的面。这个区间上的每个象素就用这个面颜色来显示。克服了扫描线z缓冲器算法在每个象素处计算多边形z值而工作量大的困难,这种区间上计算z值的做法叫区间扫描线算法。
46
6.2.4 区间扫描算法 如下图所示,扫描线l与A、B、C三个投影多边形的边相交形成9个小区间。下面如何确定这些小区间的颜色呢?
47
6.2.4 区间扫描算法 按下列情况进行讨论: 小区间上没有任何多边形,如[d,e]段和扫描线l两头此时用背景色显示该小区间。
当小区间只有一个多边形,如[a,b],[e,d]等,这时用此多边形的颜色便可显示该小区间。 当小区间存在两个或两个以上的多边形,如图中的[f,g],必须通过深度测试判断哪个多边形是可见的,再显示此多边形的颜色。
48
6.2.4 区间扫描算法 如果允许物体表面相互贯穿,那么还必须求出它们在xoz扫描平面上的交点,再进一步细分这些小区间。更进一步作深度判断哪个多边形是可见的。如下图(a)所示,A、B、C三个多边形是在xoy面上投影重叠。于是应当从他们与扫描平面的交线才能看出它们在空间中的相互位置。这时有两种情况,第一种,各多边形与扫描平面的交线互不相交,如下图(b)所示,则不必将小区间细分为更小的区间。第二种,各多边形与xoz扫描平面的交线相交,则需要将小区间进一步细分,如下图(c)中增加一条g点线,同时[c,g],[g,d]中显示不同的多边形。具体如何显示,需要在数据结构中进行处理,以提高交点的计算效率。
49
6.2.4 区间扫描算法
50
6.2.5 Warnock算法 这是一种分而治的算法,既适合于消去隐藏线又适合于隐藏面,其基本思想如下:
首先观察整个窗口区域,如果窗口中只需显示一个多边形面,则可以直接显示出来,此时称窗口为单纯的,否则为非单纯的。例如:窗口内没有可见物体,则直接显示背景或窗口内只有一个多边形面颜色,则就是单纯的。若窗口内有两个多边形或非单纯的时候,则将窗口分为四部分,进一步判断它们是否单纯。不单纯时再细分,直到窗口单纯或窗口不能再分为止。如图5.13所示
51
6.2.5 Warnock算法
52
6.2.5 Warnock算法 这过程可以用一棵四叉树来描述,有很好的效率。即使1024*1024的视图窗口,被细分十次后也成为一个象素面而不能再分。 当然,算法中关键在窗口是否单纯的判断,这就要分析窗口与物体的所有投影后的多边形面之间的关系,如图5.14所示,多边形面与窗口的关系有4种类型:
53
6.2.5 Warnock算法
54
6.2.5 Warnock算法 (a)分离,是指多边形在窗口之外。 (b)内含,是指多边形在窗口之内。
(d)包围,是指多边形把窗口全部包含。
55
6.2.5 Warnock算法 根据这四种情况,Warnock算法描述如下:
步骤一:对每个窗口进行判断,若所有多边形没在某个窗口,则该窗口设为背景色。 步骤二:若窗口内含一个多边形,则窗口中多边形部分着此多边形色,其余部分着背景色。 步骤三:若窗口与一个多边形相交,同步骤二一样。 步骤四:若窗口被一多边形包围,则全部着多边形颜色。 步骤五:若窗口被若干多边形包围,并且所有多边形不交叉,则把距离视点近的多边形颜色给窗口着色。 步骤六:若以上条件都不满足,那么继续细分窗口,并重复上述步骤。 以上几个步骤中,步骤五是关键,要找出包围窗口的多边形中距离视点最近的一个多边形,需要作深度检测,具体实现时,可将面片根据它们距离视点的最小距离先进行深度排序,然后,再取最小深度的多边形的颜色作为窗口颜色。
56
6.3 编程实例 本节主要介绍Visual C++图形程序设计所必须的基础知识。包括画笔和画刷的建立,常用绘图函数及其在应用程序中的使用方法等,后面针对前述算法做一些例子。
57
6.3.1 绘图函数的用法 1)画笔 画笔的颜色确定所画线条颜色,具体画笔创建方法有三种: CPen::CPen()
CPen::CPen(int nPenStyle,int nWidth,COLORREF crColor) CPen::CPen(int nPenStyle,int nWidth,const LOGBRUSH)
58
6.3.1 绘图函数的用法 2)画点函数 画点是通过调用CDC::SetPixel()或CDC::SetPixelv()函数来实现的,原形如下: COLORREF SetPixel(int x,int y,COLORREF crColor) COLORREF SetPixel(Point point,COLORREF crColor) BOOL SetPixelv(int x,int y,COLORREF crColor) BOOL SetPixelv(Point point,COLORREF crColor)
59
6.3.1 绘图函数的用法 3)MoveTo()和LineTo()函数
CPoint MoveTo(int x,int y); CPoint MoveTo(POINT point); BOOL LineTo(int x,int y); BOOL LineTo(POINT point);
60
6.3.2 实现函数立体图 例5.1 采用上面所介绍的消隐算法,实现函数的图形 。程序见书。
61
6.3.2 实现函数立体图
62
6.4光照模型
63
6.4.1颜色模型和颜色应用 1、光和颜色 物体的颜色不仅取决于物体本身,还与光源,周围环境的颜色有关。如,红光照在物体上,使其带有红色成份,红色物体使其附近物体泛红等,不仅如此,物体颜色还与人们感觉心里系统有关。例如有些人看红色的物体时并不产生红色的感觉,这就我们常讲的色盲。
64
6.4.1颜色模型和颜色应用 2、CIE色度图 对自然界的一种颜色c可以表示为:
等号表示两边代表的光看起来完全相同,“+”号表示光的叠加,r、g、b为颜色配对中所需要的RGB三原色光的相对比例量,R、G、B为红、绿、蓝三原色光。
65
6.4.1颜色模型和颜色应用 1931年国际照明委员会CIE给出了任意可见光所需的三原色光的比例曲线,如下图所示。注意到图中对于500μm的光要用R、G、B线性组合表示时,r值应当为负,否则无法表示。这带来一个问题,即对于500μm的光如何用R、G、B实现。因为我们并不存在一种负的光强,即负的rR是不能实现的。因而有一些颜色不能通过将三原色混合起来得到并在CRT上显示。
66
6.4.1颜色模型和颜色应用
67
6.4.1颜色模型和颜色应用 注意: 于是,CIE在1931规定了三种假想的标准原色,x、y、z以便能得到的颜色匹配的比例量全为正。
除了用红、绿、蓝三色混合成一般颜色外, 还可以用补色青、品红、黄来构成三原色,即只要满足下列二条件的三种颜色均可作为原色: 1、任何一种颜色可以用三种颜色混合而成; 2、三种颜色中任意一种颜色不能由其余两种颜色混合而成。
68
6.4.1颜色模型和颜色应用 CIE用XYZ形成一个CIE—XYZ系统,该系统的光颜色匹配函数定义为如下的一个式子:
69
6.4.1颜色模型和颜色应用 对于同一颜色C的CIE_RGB的值(R,G,B)与CIE_XYZ的值可以通过以下形式相互转换:
70
3、常用颜色模型 1)RGB模型 RGB颜色模型是用红(r)、绿(G)、蓝(B)为坐标轴定义的单位方体。如图5.20所示:原点表示黑色,其对角线上点表示灰度色,角点为白色,坐标轴上的立方体顶点表示原色,而其余相对的顶点为补色,在立方体范围内的每个彩色点都可以用三个参数(R,G,B)表示,值在0~1的范围内。这模型对显示器而言是方便的,显示器总是从暗到亮的增强颜色,而对打印机而言却不方便了,打印机总是从亮到暗的增强颜色,故采用下列颜色模型。
71
3、常用颜色模型
72
3、常用颜色模型 2)CMY模型 用青(C)、淡红(M)、和黄(Y)3种原色所定义的一种颜色模型叫CMY模型,除了原点是白色,对角线顶点为黑色以外,CMY的坐标空间与RGB的完全相同。它是减色系统,故有利于打印机实现。
73
3、常用颜色模型 RGB模型和CMY模型的原色是互补色。因此,它们的转换是很方便的。
74
4、 OpenGL颜色 OpenGL颜色模型实际上有两种 (1)RGB(RGBA)模式; (2)颜色表模式。
75
4、 OpenGL颜色 1)RGBA模式下的颜色函数 函数glColor*()用来设置当前待绘制几何对象的颜色。
Void glColor3{b s i f d ub us ui}(TYPE r,TYPE g,TYPE b); Void glColor4{b s i f d ub us ui}{TYPE r,TYPE g,TYPE b,TYPE a}; Void glColor3{b s i f d ub us ui} v(TYPE*v); Void glColor4{b s i f d ub us ui} v(TYPE *v); 参数*v是包含RGBA颜色数值的指针,r、g、b分别表示红、绿、蓝三种颜色组合,参数a即是表示融合度的数值。{}内是可选数据类型,相应的数据范围如下表所示:
76
4、 OpenGL颜色 表5.1 参数类型列表 前 缀 类 型 对应C变量 b 8-bit int signed int s
表5.1 参数类型列表 前 缀 类 型 对应C变量 b 8-bit int signed int s 16-bit int short i 32-bit int long F float d 64-bit int double ub 8-bit unsigned int unsigned char us 16-bit unsigned int unsigned short ui 32-bit unsigned int unsigned long
77
4、 OpenGL颜色 注意: 2)颜色索引模式下的颜色函数 该模式下使用的函数为:
void glIndex{s i f d} (TYPE c); void glIndex{s i f d}v (TYPE *c); 这些函数用于从颜色索引表中选取颜色,当前颜色索引值存于c中。 注意: 当索引值发生变化后,相应像素点的颜色会发生变化的; 其次,索引表可由用户自己定义; 第三,RGB模式是OpenGL默认的模式。
78
6.5 简单光照模型 生成具有真实感的图象的重要因素是加入光照效果来进行表现。这种表现光照效果的模型称为明暗模型或称为光照模型。在现实世界中,光照射到物体上,光线可能被吸收、反射、和透射。被物体吸收的部分转化为其它的能量。反射和透射的光则进入我们的视觉系统,我们便看见物体。为此,我们需要了解已知物理形态和光源性质的条件下,计算物体的光照效果的数学模型——光照模型
79
6.5 简单光照模型 从一般情况看,物体在场景中产生的颜色和当前的光源、物体材料有关。由于计算机进行光谱计算和光谱至颜色的转换将耗费很大的时间,因而采用较为简单的处理方式。考虑到许多应用场合中照明光源的颜色和构成物体表面的材料并不关心,因而简单光照模型只考虑物体表面的几何对反射和透射光的影响,即在简单照明模型中,环境假设为由白光照明,且反射光和透射光的颜色可以选定,这样使光照明模型的建立和应用变得十分方便。下面讨论不含透射光的简单照明模型。
80
6.5 简单光照模型 在物体不透明的情况下,物体表面的颜色仅由其反射光决定。反射光有三种类型的分量组成:环境反射、漫反射和镜面反射。环境反射是人射光均匀地从周围环境入射到物体表面后等量地向各个方向反射的光。例如:透射厚厚云层的阳光,室内各物体之间光的多次反射结果也可以视作环境反射光。漫反射分量表示特定光源在景物表面的反射光中那些向空间各方向均匀反射出去的光,而镜面反射光为朝一定方向的反射光。这几种反射光是我们看见物体的关键。下面详细讨论这几种光的计算
81
6.5.1 环境光 不同的物体对环境光有不同的反射属性,记为Ka,若用Ia表示环境光的强度,于是物体某点的反射光强度为:
注意到我们所接受的是Iambien的强度,也就是在图上要用 Iambien表示物体上的点,Ka与物体有关,根据物体而定,Ia由环境光定,其越强自然使Iambien越强,符合我们的习惯。
82
6.5.2 漫反射 漫反射是物体并不光滑形成的,这种不光滑的物体叫漫反射体。如图5.22所示,其特点是反射光是由于表面从各个方向等强度地反射而成,因而从各个视角出发,物体表面呈现相同的亮度,所看到的物体表面某点明暗程度不随观测者的位置变化而变化。漫反射光的强度或某点的明暗程度服从Lambert漫反射模型
83
6.5.2 漫反射 其中 Idiffuse是物体表面某点的漫反射光强,Id为点光源的光强度。 表示物体表面该点对漫反射光的反射属性,K d(0<K<1) 是入射光线与物体表面在该点出法线的夹角。
84
6.5.2 漫反射 这里具体计算 是要注意的,令L是该点到光源的单位向量, N为单位法向量,则:
85
6.5.3镜面反射 其实,光照射到物体上,除了产生漫反射外,还会产生镜面反射,相当于光照射到理想的光滑表面一样,其特点是在光滑表面会产生一块高光区的特亮区域。反射光与人射光满足光的反射定律,镜面反射强度与反射光和视线的夹角相关。
86
6.5.3镜面反射 其中,n为物体镜面反射指数,为反射光与视线的夹角
87
6.5.4 phong模型 一个物体在一个场景中,若没有光的照射,我们肯定是看不见的,只有在某种光照下,反射光才能进入我们视觉系统,而光照下物体的反射光有三种类型,也就是说,进入我们视觉系统的反射光有三种类型。因此,物体某点上的反射光的强度应当是三种反射光的迭加。即
88
6.5.4 phong模型 注意到上式中I是光谱量,为避免光谱计算,直接用光栅图形显示器的RGB三基色颜色系统。即写成
89
6.5.4 phong模型 用户可直接指定物体表面环境反射,漫反射和镜面反射光的颜色。也就是说。物体上某一点的颜色可以用上式进行计算而得。
90
6.5.4 phong模型 例5.2 把曲面(x-120)+z40 (20y100)显示出来。 具体做法见教材!
91
6.5.4 phong模型
92
6.6 OpenGL的光照处理 从上面可见,要显示一张简单的曲面所涉及的内容和计算是相当复杂的,若再添加各种场景或增加几个光源,情况更加麻烦。现在OpenGL把相当复杂的工作已集成在相应地函数中,只须对参数的处理便可得到需要的光照模型,方便了我们的使用,下面就介绍如何使用OpenGL进行光照处理。
93
6.6.1光源的定义 光源有许多特性,如颜色、位置、方向等。不同特性的光源,作用在物体上的效果是不一样的。定义一个光源的主要工作就是定义它的各种特性,OpenGL通过光源特性的函数glLight*()来定义光源。 Void glLight{i f}(GLenum light, GLenum pname, TYPE *param); Void glLight{i f}v(GLenum light, GLenum pname, TYPE *param);
94
6.6.1光源的定义 函数定义光源不等的某特性,其中light 指定光源编号,在一个场景最多定义八个不同的光源,编号为GL-LIGHT0,GL-LIGHT1,…,GL-LIGHT7,参数pname指定光源特性的名称,即是什么种类的光。如下表取值,参数param为指向param所指属性值的指针,它可以指向一个数值,也可以指向一个值,具体有所定义的属性而定
95
6.6.1光源的定义 表5.2 pname参数的取值及意义 GL_AMBIENT (0.0,.0.0,0.0,1.0)
环境光的RGBA强度值 GL_DIFFUSE (1.0,1.0,1.0,1.0) 漫反射光的RGBA强度值 GL_SPECULAR 镜面反射光RGBA强度值 GL_POSITION (0.0,0.0,1.0,0.0) 光源坐标(x,y,z,w) GL_SPOT_DIRECTION (0.0,0.0,-1.0) 聚光灯投影方向(x,y,z) GL_SPOT_EXPONENT 0.0 聚光灯指数 GL_SPOT_CUTOFF 180.0 聚光灯截止角度 GL_CONSTANT_ATTENUATION 1.0 定长衰减因子 GL_LINER_ ATTENUATION 线性衰减因子 GL_QUADRATIC_ ATTENUATION 二次衰减因子
96
6.6.1光源的定义 1、颜色 在glLight()参数pname取值为GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR 时指定光源中相应组成部分的颜色强度。 GL_AMBIENT指定环境光的RGBA强度,当其特性值为{0.0,0.0,0.0,1.0},表示没有环境光这是默认状态。 GL_DIFFUSE指定漫反射光的RGBA强度,默认情况下对于GL_LIGHT0,GL_DIFFUSE 特性值为{1.0,1.0,1.0,1.0},对于其他编号为GL_LIGHT1,…,LIGHT7的光源,该特性值为{0.0,0.0,0.0,0.0}这特性可以视为光源的颜色。 GL_SPECULAR用于指定镜面反射的RGBA强度,默认时,对于GL_LIGHT0该特性值为{1.0,1.0,1.0,1.0},对于其他光源,该特性值为{0.0,0.0,0.0,0.0}。
97
6.6.1光源的定义 2、位置 使用GL_POSITION定义光源位置坐标(x,y,z,w),当w=0时,表示定义的位置在无穷远,而(x,y,z)仅说明光的方向,此时叫方向光源。当w≠0时,则定义一个较近的光源,(x,y,z)表示光源的坐标。
98
6.6.1光源的定义 3、衰减 光线强度随光源距离的增加而减少,若光源是无限远时,则光线强度不衰减。对于一般的位置光源,OpenGL使用下面的衰减因子来衰减光线的强度。 衰减因子=
99
6.6.1光源的定义 其中,d为光源位置到物体顶点的距离。 kc为GL_CONSTANT_ATTENUATION 默认值为1.0
ke为GL_LINER_ ATTENUATION 默认值为0.0 kg为GL_QUADRATIC_ ATTENUATION 默认值为0.0
100
6.6.1光源的定义 4、聚光 一般情况下,光源光线是向四周发射,可以使用GL_DOT_CUTDFF来限制光线的范围,缺省是1800。当然,除了指定光发散角度外,还需指定聚光状态下的方向,例如: glLlightf(GL_LIGHT0,GLSPOT_CUTOFF,45.0);//45角范围 GLfloat spot_direction[]={-1.0,-1.0,0.0}; glLightfv(GL_LIGHTO,GL_SPOT_DIRECTION,spot_direction)
101
6.6.2材质的定义 OpenGL用材质来描述物体表面特性,通过制定物体表面对光的反射率来确定物体的颜色设置材质属性的函数是:
Void glMaterial{i f}(GLenum face,GLenum pname,TYPE param); 其中参数face是GL_FRONT,GL_BACK或GL_FRONT_AND_BACK指定当前材质作用物体的哪一面.
102
6.6.2材质的定义 参数pname设置材质的属性,由表5.3所示 表5.3 pname的取值及意义 属性名称 默认值 意义
GL_AMBIENT (0.2,0.2,0.2,1.0) 对环境光的反射率 GL_DIFFUSE (0.8,0.8,0.8,1.0) 对漫反射的反射率 GL_AMBIENT_AND_ DIFFUSE 对环境和漫反射的反射率 GL_SPECULAR (0.0,.0,0.0,1.0) 反射颜色 GL_SHININESS 0.0 反射指数 GL_EMISSION (0.0,0.0,0.0,1.0) 辐射光色 GL_COLOR_INDEX (0,1,1) 环境散射和反射索引
103
6.6.2材质的定义 例如,将当前材质的散射和环境反射率设置为(0.1,0.5,0.8,1.0)
GLfloat mat_amb_diff[]={0.1,0.5,0.8,1.0} glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_ DIFFUSE, mat_amb_diff
104
6.6.3 OpenGL的光照实例 程序见教材.
105
6.7纹理映射 在三维图形绘制中仅有光滑曲面显示是不够的,在一定的面上采用相应的纹理会增强真实感。因而,三维图形绘制中纹理映射是广泛使用的,进行纹理映射需完成以下几件事: 1)定义纹理; 2)控制滤波; 3)说明映射方式; 4)绘制场景给求顶点的文理坐标和几何坐标。
106
6.7.1定义纹理 一般情况下,纹理是单个图像,通常是二维的当然也有一维纹理和二维纹理进行图形绘制,调用以下函数定义二维纹理映射:
Void glTexImage2D(GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); 其中target指定目标纹理,只能GL_TEXTURE_2D; Level表示多级分辨率的纹理图像的级数,若只有一种分辨率,level为0; Components是从1~4的数,1:选择R; 2:选择RA;3:选择RGB; 4:选择RGBA。 Width,height是纹理大小; Border是指边界宽度,只能是0,1; Format描述映射格式,可以是以下符号常量
107
6.7.1定义纹理 Type 表示数据类型,可以是以下常量 Level用于指定不同分辨率的纹理,使用时要考虑纹理滤波的问题
108
6.7.2控制纹理滤波 1、滤波 原指纹理图像是个方形图像把它映射到复杂的物体上,一般不能图像上的一个像素对应屏幕的一个象素。因此局部放大或缩小时就要定义合适的滤波方式 Void glTexParameter(GL_TEXTURE->D,GL_TEXTURE_MAG_FILTER,GL_NEAREST) Void glTexParameter(GL_TEXTURE->D,GL_TEXTURE_MIN_FILTER,GL_NEAREST) 前者是放大滤波,后者是缩小滤波
109
6.7.2控制纹理滤波 2、重复与循环 纹理映射可以重复映射或缩限映射,重复映 射对纹理可以在自己的坐标S,T方向重复。 对于缩限映射,有
Void glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_REPEAT); Void glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_REPEAT); 对于缩限映射,有 Void glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAR_S,GL_CLAMP); Void glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP);
110
6.7.3 映射方式 定义纹理映射方式是指认定纹理图像映射到目标及以获得最终RGBA值的方式。OpenGL提供了三种纹理映射方式,一种是简单地把纹理地颜色作为最终地颜色来使用,这叫刻纸方式;另一种是使用纹理来调节目标区地颜色,以获得最终的颜色;最后是使用纹理颜色和目标区颜色相融合。这些细节可以用设置纹理环境的方式来控制。
111
6.7.3 映射方式 OpenGL通过一下命令设置纹理环境:
Void glTexEnv{i f}(GLenum target,GLenum pname,TYPE param); Void glTexEnv{i f}v(GLenum target,GLenum pname,TYPE params); 在函数中,参数target必须取GL_TEXTURE_ENV;pname指定被设置参数不符号常量,若是GL_TEXTURE_ENV_MODE,则param可以式GL_DECAL,GL_MODULATE,或GL_BLEND,说明纹理值在原来颜色不同的处理方式。pname是GL_TEXTURE_ENV_COLOR时,param是包含4个浮点数(R,G,B,A)的数组,这些值只在采用GL_BLEND纹理系数时才采用。
112
6.7.4 纹理坐标定义 纹理图像是方形的,纹理坐标可包含1-4个坐标,即s,t,r,g坐标,它们区别于对象的x,y,z,w坐标,也不同于计算坐标u,v。对于一维纹理,使用s坐标,二维纹理使用s,t坐标,当前纹理坐标的设置由下列函数来完成 Void glTexCoard{ }{s i f d}[v](TYPE coorde) 该函数设置当前纹理坐标,然后调用glVertext()所产生的顶点都赋予当前的纹理。
113
6.7.5 纹理坐标的自动生成 有时不需要为对象的每个顶点赋予纹理坐标,可以使用下列函数来自动 生成纹理坐标:
void glTexGen{i f d}{v}(GLenum coord,GLenum pname,TYPE param) 在该函数中,参数coord的取值为GL_S,GL_T,GL_R或GL_Q,它指明 是否生成s,t,r,或g纹理坐标。Pname参数的取值为GL_TEXTURE_GEN _MODE,GL_OBTECT_PLANE或GL_EYE_PLANE, param是一个整数,其值为GL_OBTECT_LINEAR,GL_EYE_LINERA 或GL_SPHERE_MAP。
114
6.7.6 一个纹理的实例 具体程序见教材
Similar presentations