Gouraud明暗处理的探索
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
图4 4, 边 # 桶
活化多边形表(省略了部分数据项)
活 化 多 边 形 表 123 中 的 每 一 个 多 边 形 , 都 有 一 个 边 # 桶。图 " 是图 $ 中多边形 2+ 的边 # 桶。边 # 桶的长度等于多 边形相交的扫描线数。边 # 桶的结点中,存放了每条边端点 中较大的 0 值、 增量 !6、 0 值较小一端的 6 坐标和 7 坐标。 另外,为了满足程序运行的需要,还要求有边上点的红绿蓝分 量值、红绿蓝的增量、边所属的多边形编号。结点的数据结构 定义如下8
!"#$%#& 明暗处理的探索
邹耀斌
摘
要
从 !"#$%#& 明暗处理模型的基本原理出发,以简单四面体为研究对象,分析了其 数据结构和算法,并给出了核心代码。 !"#$%#& 明暗处理,双线性插值,扫描线算法,指针的指针
关键词
*+,-!. 中提供了两种明暗处理模型,分别叫平面明暗处 理( /0%1 )2%&3-4)和光滑明暗处理( )5""12 )2%&3-4 ),后者又 称为 !"#$%#& 明暗处理。 平面明暗处理是一种快而高效的绘制方法,但是由于它做 了两个如下的假设,其一是光源和视点都在无穷远,其二是光 线 . 和视线 6 恒定。结果是光的反射强度 7 只是物体表面上点 法向 8 的函数,即 7 9 : ; 8 < 。对于表面用多边形表示的物体, 同一个多边形域内的每一个点,由于其法向都相等,所以,反 射光强也相等。这样,在同一个多边形内,其光强是不变的, 用平面明暗处理生成的图像仍然像一幅填充图。即使是两个不 同的多边形,只要它们的法向相同,其表面的光强就无法区 分。 !"#$%#& 明暗处理模型是由 !"#$%#& 等人首先提出来的, 目的是用来克服平面明暗处理模型上述缺陷,以解决多变形之 间光强的光滑过渡问题,用该模型渲染的图像具有很强的真实 感,在很多场合能满足人们的需求。 国内外很多计算机图形学的教科书上对这两个明暗处理模 型均有讨论,但是,讨论都仅涉及理论而很少在实现上花费笔 墨。虽然在 *+,-!. 中已经封装 !"#$%#& 明暗处理(通过调用 40=2%&,>"&,0 ; !.?=>**@A < 来指定),但是却没有包含另一种 真实感更强的模型—— — B2"-, 明暗处理模型的实现,而在一些 需要更高图像质量的场合又需要我们使用 B2"-, 明暗处理模型 进行渲染。有鉴于此,本文首先从 !"#$%#& 明暗处理模型的基 本原理出发,以简单四面体为研究对象,详细地分析了实现该 模型所采用数据结构和算法,并给出了该算法实现的核心代 码。在理解了 !"#$%#& 明暗处理模型的实现基础之上,进一步 理解并实现 B2"-, 明暗处理模型将是理所当然的事情(这将在 笔者的后续文章《 B2"-, 明暗处理的深度探索》进行讨论), 这也是笔者写此文的初衷。
, 写 成 增 量 形 式 为 : D’ ( $ / D’ E ! D* F! * E ! D% 式中, ! D* / 向和 % 方向的增值。 (!)计算多边形在点(0, ’)处的深度值 ( 0, ’, D0’)为多边形 2 内的一点,其中, D0’ 为多边形 2 # !D% / 分别为多边形 2 在 * 方
图$
多边形和它对应的多边形 # 桶 (省略了部分数据项)
ቤተ መጻሕፍቲ ባይዱ
图"
边 # 桶(省略了部分数据项)
#!
!""#$ %
!"#$%$& ’!()*! !+%,$ ./! "0##$(1 2 2 边的最大 " 值 &345! 67/!$(’$*!8 97/!$(’$*!1 2 2 边的较小 " 值的 68 9 坐标值 &345! %6:$(;*5/1 2 2 ! 68 当前边斜率的倒数 &345! ($%8 ,($$/8 <3)$1 2 2 边上点的红绿蓝分量值 &345! %6=$%:$(;*5/8 %6>($$/:$(;*5/8 %6?3)$:$(;*5/1 2 2 红绿蓝的增量 ! 7 ./! ./%$6:43",4/1 2 2 边所属的多边形编号 !+%,$ # /$6!1 @ +%,$1 !" 活化边表 #$% 活化边表 #$% 中记录多边形边界与当前扫描线相交的各 个边对信息。 #$% 是一个链表,随扫描过程动态变化。活化边 表中结点所包含的信息和边 & 桶结点所包含的信息一致,两者 的数据结构是相同的。 ’" 深度缓存 () () 用来存放一个扫描行中各个像素的深度值,所以其大 小为一个扫描行的长度,即屏幕行方向的像素点的个数。但 是,在 *+ 中,所需要的缓冲区大小由窗口客户区决定,而窗 口客户区随着窗口大小变化而变化,所以,在本文采用了内存 的动态分配法分配深度缓存。 () 声明为一个指向整型变量的 指针。定义如下: ./!# A?1 2 2 深度缓存 ," 四面体几何表示结构 定义的 数据结构用来表示四 面体的几何 信息,其中 -./0 1234567 和 -.81234567 分别对应于计算多边形在其边界上的深度 值 ! ./ 和 ! .8 。 !"#$%$& ’!()*! !?5’$:43",4/ ./! ./%$6:43",4/1 2 2 多边形编号 ./! */!1 2 2 多边形拥有的顶点数 %*:! # #B$(!$6’1 2 2 多边形的顶点数组 C 根据 */! 的 2 2 值进行内存的动态分配 D &345! %96:$(’*5/8 %9":$(’*5/1 2 2 为快速计算多边形 2 2 边界和内部点深度 C 9 D 的增量 @ ?5’$:43",4/1
图!
多边形与扫描线相交成边对
二、数据结构
为了有效利用上述相关性,笔者在 %&’()’* 明暗处理模型 实现中设计了如下数据结构。 +, 顶点数据结构 为了简化问题并突出实质,笔者对 +, + 和 +, ! 两小节涉及 的顶点法向和平均光强的计算进行了省略,取而代之的是直接 给顶点赋以颜色值,这种简化从理论和实践均表明,对 %&’()’* 明暗处理模型实现没有本质的影响(事实上顶点的光 强可以用简单光照模型进行计算,所得到光强结果最终在计算 机中仍是用 -%. 三原色表示)。在这个前提下 / 笔者给出的顶 点数据结构如下: !"#$%$& ’!()*! !%*+! , -.! /0 "0 12 3 3 顶点的 /0 "0 1 坐标值 -.! ($%0 4($$.0 56)$2 3 3 顶点的红、 绿、 蓝分量值 7 %*+!2 !, 多边形 # 桶 图 $ 为多边形和它对应的多边形 # 桶。桶的长度与扫描线 的数目一样多。根据根据多边形顶点中最小的 0 坐标 / 插入多
一条扫描线内部 # 横坐标 *& 由 *+ 到 *- 递增 # 当 *& 由 0 增为 0 ( $ 时 # 多边形内的点 ) 0 ( $# %& , 的光强可以由同一扫描行左侧 的 点 ) 0# %& , 的 光 强 作 一 次 加 法 得 到 # 即 .0 ( $# & / .0# & ( ! .&, 。 1" 三维对象的消隐显示 在前面介绍了如何计算物体表面的点对光的反射强度。现 在问题是,如何显示物体。在显示三维对象时,不仅要决定物 体的各个面在视图区中的位置、决定物体上各个点的光强度 (颜色),而且要决定哪些面是可见的,必须显示出来;哪些 面被遮挡不可见而必须消除掉,以加速三维对象的渲染。 在点与多边形的包含性测试和深度计算时,扫描线消隐算 法充分利用了边的相关性和点的相关性,大大加快了三维对象 的渲染速度。我们先讨论如何利用相关性来提高点与多边形的 包含性检测和深度计算的速度,然后导出扫描线消隐算法。 ($)计算投影多边形 23的边 4 与扫描线 % / ’ 的交点 *’ 需要说明的是,为方便测试三维空间中不同多边形上点的 深度,投影多边形采用的是平行投影法,因为采用平行投影我 们可以通过只取多边形顶点的坐标就可以算出顶点的深度并进 行深度比较,而如果采用透视投影法,那么深度测试将要增加 比例因子从而增加了计算量。但是,在深度测试完成后,为了 在屏幕上看到比较逼真的三维效果,最后渲染时是需要采用透 视投影的(可以参考 506678+9 函数)。 设 边的 直 线方 程为 :* ( ;% ( < / =, 则 在 % / ’ 这根 扫 描线 在点(0, ’)处的深度,则 $, ’ , 处 , 多 边 形 2 的 深 度 为 , 8" =# 而在点 ) 0 ( / E
-、 8、 @ 为多边形的面方程系数,且 8" =。若 8 / =,则说明多 边形 2 的平面与屏幕 ABC 面垂直。当扫描线向上移动时候, 如果采用增量算法 # 当扫描线 %& 由 ’ 变成 ’ ( $ 时 # 新扫 描线上的点 ) *+ # ’ ( $ , 和 ) *-# ’ ( $ , 的光强 # 可以由前一条扫描 线与边的交点 ) *+ # ’ , 和 ) *-# ’ , 的光强作一次加法得到: .+# ’ ( $ / .+# ’ ( ! .+ , .-# ’ ( $ / .-, ’ ( ! .-, # 。而在 2 在 此 交 点 处 的 深 度 为 : / 即 % / ’ ( $ 时,边 4 与扫描线的交点为(*’ ( $, ’ ( $),多边形
图’
双线性光强(扫描线为 ())
#"
!""#$ %
!" 双线性光强插值 用多边形顶点的光强进行双线性插值 # 可以求出多边形上 各点和内部点的光强。在这个算法步骤中,把线性插值与扫描 线算法相互结合,同时用增量算法实现各点光强的计算。增量 算法首先由顶点的光强插值计算各边的光强# 然后由各边的光 强插值计算出多边形内部点的光强,如图 $ 所示。 双线性光强插值的公式如下(扫描线为 %&):
!""#$ %
#&
边形在多边形 # 桶中的位置。对于多边形 # 桶的结点,要记 录其编号和其顶点中最大的 0 坐标;为了在程序运行的过程中 动态分配边 # 桶所需要的内存空间,还需要定义多边形的最小 0 值;其它的还包括指向边 # 桶的指针、指向边 # 桶的活化边 表的指针以及边 # 桶的指针内存空间是否已经分配的标识。结 点数据结构定义如下: !"#$%$& ’!()*! !+86"48. , -.! -.%$/+86"48.2 3 3 多边形编号 -.! "9##$(2 3 3 多边形的最大 " 值 -.! ":8;$(2 3 3 多边形的最小 " 值 0 由 "9##$( 和 ":8;$( 3 3 可以确定该为边 < 桶动态分配多少内存 =%4$ ## #=%4$’2 3 3 指向边 < 桶的指针 =%4$ # >*!-?$2 3 3 边 < 桶的活化边表 @ A=B C DEE: 5A*!-?$+86"48.2 3 3 当前多边形是否已经分配了 3 3 #=%4$’ 内存空间 0 防止内存的重复分配 !+86"48. # .$/!2 7 <8<8+86"48.2 $, 活化多边形表 123 123 中记录与当前扫描线相交的各个多边形的信息,它的 结点所包含的信息和多边形 # 桶的结点是一致的。图 4 表示了 扫描线为 0 5 + 和 0 5 $ 时图 $ 的活化多边形表。
,写成增量形式为: D0 ( $0 / D0# ’ E ! D* 。这表明, 在求出多边形 2 在( 0, ’)处的深度值 D0’ 后,用一个减法就可 以得到这个多边形在同一条扫描线上相邻后续点(0 ( $, ’)处 的深度值 D0 ( $# ’ 。 (1)判断点(0, ’)是否在投影多边形 23内 在扫描线 % / ’ 上,计算投影多边形 23 的每条边与扫描线 的交点。如图 ? 所示,扫描线 G 与多边形的边界线交于四点 H、 I、 J、 K,而且,凡是 H L A L I、 J L A L K 的点,都在多 边形内形成区间段。象这样隔点都在多边形内的区间段,其端 点所在的两条边成为边对。对多边形上任何一条边,只要它不 是水平的,总能找到与之组成边对的边,从边的最低点(即 % 值较小的端点)到边的最高点(即 % 值较大的端点)为止,每 一条扫描线与边对相交形成的区间段都在多边形内。
一、理论基础
!"#$%#& 明暗处理是先计算物体表面多边形各顶点的光强 C 然后用双线性插值 C 求出多边形内部区域中各点的光强。它的 基本算法描述如下: ; ’ < 计算多边形顶点的平均法向; ; D < 计 算顶点的平均光强; ; E < 插值计算离散边上的各点光强; ; F < 插值计算多边形内域中各点的光强。下面介绍算法中的每一个 步骤。 ’G 顶点法向的计算 假 设 顶 点 H 相 邻 的 多 边 形 有 I 个 C 法 向 分 别 为 8’ C 8DC G G G 8IC 取顶点 H 的法向为: 8% 9 ; 8’ J 8D J . J 8I < K I DG 顶点平均光强计算 在 !"#$%-& 提出明暗处理方法时 C B2"-, 还没有提出简单 光反射模型。在最初的双线性光强插值法中,顶点的光强采用 的下式计算: 7 9 7% L% J 7+L+ ; . ・ 8% < K ; $ J I < 。当然,现在也可 以 采 用 下 面 的 简 单 光 照 模 型 计 算 顶 点 的 光 强 : 7 9 7% L% J 7+ L& ; .48 < J 7+ L) ; A48 < -。
上,边与扫描线的交点的 * 坐标为: *’ /
# 这里 : " =。
若 : / =,则说 明边 4 与水 平轴平行 。在 % / ’ ( $ 这根 扫描线 上,交点的 * 坐标为: 成增量方式为: *’ ( $ / *’ ( ! *。令 ! * / 。写 ,其中 > 表
示边的斜率。这样,将边与前一条扫描线的交点做一次简单的 加法,就可以得到与下一条扫描线的交点。 (?)计算多边形在其边界上的深度值 设 4 为多边形 2 的一条边,与扫描线的交点为 *’,则多边 形 2 在交点( *’ , ’)处的深度为: ,式中 +、