计算机图形学完整笔记(四):消隐

前言

如果你对这篇文章可感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。


第四章 消隐

4.1 消隐概述
4.1.1 消隐定义
  • 消隐

    • 如果把可见和不可见的线都画出来,会对视觉造成多义性。
    • 要消除二义性,就必须在绘制时消除被遮挡的不可见的线或面,即消除隐藏线和隐藏面,简称消隐。
4.1.2 消隐分类
  • 按消隐对象分类
    • 线消隐
      • 消隐对象是物体上的边,消除的是物体上不可见的边。
    • 面消隐
      • 消隐对象是物体上的面,消除的是物体上不可见的面,通常做真实感图形消隐时用面消隐。
  • 按消隐空间分类
    • 物体空间的消隐算法
      • 以场景中的物体为处理单元。假设场景中有 k 个物体,将其中一个物体与其余 k-1 个物体逐一比较,仅显示它可见表明以达到消隐的目的。
      • 此类算法常用于线框图的消隐。
      • Roberts 算法、光线投射法
    • 图像空间的消隐算法
      • 消隐算法的主流。
      • Z-buffer 算法
      • 扫描线算法
      • Warnock 消隐算法

4.2 物体空间的消隐算法
4.2.1 Roberts 算法
  • 算法步骤
    • 逐个的独立考虑每个物体自身,找出为其自身所遮挡的边和面 (自消隐)
    • 将每一物体上留下的边再与其它物体逐个的进行比较,以确定是完全可见还是部分或全部遮挡 (两两物体消隐)
    • 确定由于物体之间的相互贯穿等原因,是否要形成新的显示边等,从而使被显示各物体更接近现实。
  • 算法特点
    • 数学处理严谨,计算量甚大。算法要求所有被显示的物体都是凸的,对于凹体要先分割成多个凸体的组合。
4.2.2 光线投射法
  • 定义
    • 光线投射是求光线与场景的交点,该光线就是所谓的视线 (如视点与像素连成的线)
  • 特点
    • 一条视线与场景中的物体可能有许多交点,求出这些交点后需要排序,在前面的才能被看到。人的眼睛可以一目了然,但计算机做需要大量的运算。

4.3 Z 缓冲区算法 (Z-Buffer)
4.3.1 Z-Buffer 算法概述
  • 算法介绍

    • 该算法由 Edwin Catmull 独立开发,能够跟踪屏幕上每个像素深度的算法。
    • 该算法有帧缓冲器和深度缓冲器。
      • i n t e n s i t y   ( x , y ) intensity \ (x,y) intensity (x,y) —— 属性数组 (帧缓冲器),存储图像空间每个可见像素的光强或颜色
      • d e p t h   ( x , y ) depth\ (x,y) depth (x,y) —— 深度数组 (z-buffer),存放图像空间每个可见像素的 z 坐标
  • 深度

    • x o y xoy xoy 面为投影面, z z z 轴为观察方向。
    • 过屏幕上任意像素点 ( x , y ) (x,y) (x,y) 作平行于 z z z 轴的射线 R R R,与物体表面相交于 p 1 p_1 p1 p 2 p_2 p2 点。
    • p 1 p_1 p1 p 2 p_2 p2 点的 z z z 值称为该点的深度值。
  • 算法思想

    • 先将 Z Z Z 缓冲器中各单元的初始值置为最小值。当要改变某个像素的颜色值时,首先检查当前多边形的深度值是否大于该像素原来的深度值 (保存在该像素所对应的 Z Z Z 缓冲器的单元中)

    • 如果大于原来的 Z Z Z 值,说明当前多边形更靠近观察点,用它的颜色替换像素用来的颜色。

    • Z-Buffer算法 () { 
        	帧缓存全置为背景色, 深度缓存全置为最小z值;
      		for(每一个多边形) { 
            扫描转换该多边形;
      			for( 该多边形所覆盖的每个象素(x,y) ) {
              计算该多边形在该象素的深度值Z(x,y);
      				if( z(x,y)大于z缓存在(x,y)的值 ) {z(x,y)存入z缓存中(x,y);
      					把多边形在(x,y)处的颜色值存入帧缓存的(x,y);
      				}
      			}
      		}
      }
      
  • Z-Buffer 算法的优点

    • Z-Buffer 算法比较简单,也很直观。
    • 在像素级上以近物取代远物。与物体在屏幕上的出现顺序是无关紧要的,有利于硬件实现。
  • Z-Buffer 算法的缺点

    • 占用空间大
    • 没有利用图形的相关性与连续性 (严重缺陷)
    • 该算法是在像素级上的消隐算法 (很大缺陷)
4.3.2 Z-Buffer 算法改进
  • 算法改进

    • 只用一个深度缓存变量 z b zb zb 代替与图像大小相等的缓存数组,节省了空间。

    • z-Buffer算法 () { 
        帧缓存全置为背景色
      	for( 屏幕上的每个象素(i,j) ) {
          深度缓存变量zb置最小值 MinValue;
      		for(多面体上的每个多边形Pk) {
      			if(象素点(i,j)在pk的投影多边形之内) { //如何查看一点是否在多边形中
      				计算Pk在(i,j)处的深度值depth; //如何计算深度值
      				if(depth大于zb) {
                zb = depth;
      					indexp = k; (记录多边形的序号)
      				}
      			}
      		}
      		if(zb != MinValue)
      			计算多边形 P 在交点 (i,j) 处的光照颜色并显示
      	}
      }
      
  • 计算 P k P_k Pk 在点 ( i , j ) (i,j) (i,j) 处的深度

    • 多边形 P k P_k Pk 的平面方程为 a x + b y + c z + d = 0 ax+by+cz+d=0 ax+by+cz+d=0 d e p t h = − a i + b j + d c depth=-\frac{ai+bj+d}{c} depth=cai+bj+d
  • 计算一点是否在多边形中

    • 射线法

      • 核心:由被测点 P P P 处向 $y=-inf $ 方向作射线,交点个数是奇数,则被测点在多边形内部;交点个数是偶数表示在多边形外部。

      • 若射线正好经过多边形的顶点,则采用 “左开右闭” 的原则来实现。即:当射线与某条边的顶点相交时,若边在射线的左侧,交点有效,计数;若边在射线的右侧,交点无效,不计数。


      • 缺点:计算量大、不稳定 (浮点误差)

    • 弧长法

      • 核心:以 p p p 点为圆心,作单位圆,把边投影到单位圆上,对应一段段弧长,规定逆时针为正,顺时针为负,计算弧长代数和。
      • 代数和为 0,点在多边形外部;代数和为 2π,点在多边形内部;代数和为 π,点在多边形边上。
    • 以顶点符号为基础的弧长累加方法

      • 核心: p p p 是被测点,按照弧长法, p p p 点的代数和为 2π。不要计算角度,做一个规定来取代原来的弧长计算。

      • 在边上与内部均为 2π,外部为0。

      • ( x i , y i ) (x_i,y_i) (xi,yi) ( x i + 1 , y i + 1 ) (x_{i+1},y_{i+1}) (xi+1,yi+1)弧长变化象限变化
        ( +   + ) (+ \ +) (+ +) ( +   + ) (+ \ +) (+ +)0 1 → 1 1\rightarrow1 11
        ( +   + ) (+ \ +) (+ +) ( −   + ) ( - \ +) ( +)π/2 1 → 2 1\rightarrow2 12
        ( +   + ) (+ \ +) (+ +) ( −   − ) ( - \ -) ( )π 1 → 3 1\rightarrow3 13
        ( +   + ) (+ \ +) (+ +)$( + \ - ) $-π/2 1 → 4 1\rightarrow4 14
        ( −   + ) (- \ +) ( +) ( +   + ) (+ \ +) (+ +)-π/2 2 → 1 2\rightarrow1 21
        $ (- \ +)$ ( −   + ) ( - \ +) ( +)0$ 2\rightarrow2$
        $ (- \ +)$ ( −   − ) ( - \ -) ( )π/2 2 → 3 2\rightarrow3 23
        $ ( - \ +)$$( + \ - ) $π 2 → 4 2\rightarrow4 24
        $ ( - \ -)$ ( +   + ) (+ \ +) (+ +) 3 → 1 3\rightarrow1 31
        $ ( - \ - ) $ ( −   + ) ( - \ +) ( +)-π/2$ 3\rightarrow2$
        ( −   − ) (- \ -) ( ) ( −   − ) ( - \ -) ( )0$ 3\rightarrow3$
        $ ( - \ -)$$( + \ - ) $π/2 3 → 4 3\rightarrow4 34
        $(+ \ - ) $ ( +   + ) (+ \ +) (+ +)π/2 4 → 1 4\rightarrow1 41
        $(+ \ - ) $ ( −   + ) ( - \ +) ( +)$ 4\rightarrow2$
        $(+ \ - ) $ ( −   − ) ( - \ -) ( )-π/2$ 4\rightarrow3$
        $(+ \ - ) $$( + \ - ) $0$ 4\rightarrow4$

4.4 区间扫描线算法
  • 算法概述

    • 考虑Z-Buffer没有利用图形的相关性和连续性的缺陷,该算法放弃了Z-Buffer的思想(一个像素可能被多个多边形覆盖,即一个像素要多次判别,效率极低),是消隐算法中最快的算法之一。
  • 算法过程

    • 把扫描线和多边形的这些交点都求出来,对每个区间,只判一个像素的颜色,那么整个区间都是该颜色

    • 像素计算 -> 逐段计算,效率大大提高。

    • 确定小区间的颜色:

      • 小区间无任何多边形,如[a4, a5],用背景色显示
      • 小区间仅有一多边形,如[a1, a2],显示该多边形颜色
      • 小区间存在两个以上多边形,如[a6, a7],用深度检测
  • 算法实现问题

    • 如何求交点
      • 利用增量算法简化求交
    • 每段区间上要求 z 值最大的面,如何得知区间与哪些多边形相关
      • 利用区间扫描转换算法中的 AET 与 NET 得知

4.5 Warnock消隐算法
  • 算法概述

    • 区域子分割算法,发明人 Warnock (Adobe创始人),图像空间中非常经典的算法,其重要性不体现在其效率,而是体现在分治思想和堆栈数据结构的运用。
  • 算法思想

    • 把物体投影到全屏幕窗口
    • 递归分割窗口,直到窗口内目标足够简单(可以显示)
      • 若窗口分割至像素级别,仍有两个以上的面,则不必再分割。取窗口内最近的可见面颜色或所有可见面平均颜色即可。
  • 如何判断窗口内图形足够简单

    • 四种简单窗口图形

      • 窗口中仅包含一个多边形

      • 窗口与一个多边形相交,且窗口内无其它多边形 —— 直线方程作为判别函数

      • 窗口为一个多边形所包围

      • 窗口与一个多边形相分离


4.6 光栅扫描算法小结
  • 核心思想
    • 增量思想
      • 通过增量算法可以减少计算量。
    • 编码思想
    • 符号判别 → \rightarrow 整数算法
      • 尽可能地提高底层算法的效率,底层上提高效率才是真正解决问题。
    • 图形连贯性
      • 利用连贯性可以大大减少计算量。
    • 分而治之
      • 把一个复杂对象进行分块,分到足够简单再进行处理。

资料来源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gene_INNOCENT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值