• Z-buffer算法


    1、Z缓冲区(Z-Buffer)算法

    1973年,犹他大学学生艾德·卡姆尔(Edwin Catmull)独 立开发出了能跟踪屏幕上每个像素深度的算法 Z-buffer

    Z-buffer让计算机生成复杂图形成为可能。Ed Catmull目 前担任迪士尼动画和皮克斯动画工作室的总裁

    Z缓冲器算法也叫深度缓冲器算法,属于图像空间消隐算法

    该算法有帧缓冲器和深度缓冲器。对应两个数组:

    intensity(x,y)——属性数组(帧缓冲器)

    存储图像空间每个可见像素的光强或颜色

    depth(x,y)——深度数组(z-buffer)

    存放图像空间每个可见像素的z坐标

    假定xoy面为投影面,z轴为 观察方向

    过屏幕上任意像素点(x,y) 作平行于z轴的射线R,与物 体表面相交于p1和p 2 点

    p1和p 2点的z值称为该点的深 度值

    z-buffer算法比较p1和p 2的z值, 将最大的z值存入z缓冲器中

    显然,p1在p 2前面,屏幕上(x,y) 这一点将显示p1点的颜色

    算法思想:先将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算法的优点:

    (1)Z-Buffer算法比较简单,也很直观

    (2)在象素级上以近物取代远物。与物体在屏幕上的出现 顺序是无关紧要的,有利于硬件实现

    z-Buffer算法的缺点:

    (1)占用空间大

    (2)没有利用图形的相关性与连续性,这是z-buffer算法 的严重缺陷

    (3)更为严重的是,该算法是在像素级上的消隐算法

    2、只用一个深度缓存变量zb的改进算法

    一般认为,z-Buffer算法需要开一个与图象大小相等的缓 存数组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) 计算多边形Pindexp在交点 (I,j) 处的光照
    颜色并显示
    }
    }
    

    关键问题:判断象素点(i,j)是否在pk的投影多边形之内, 不是一件容易的事。节省了空间但牺牲了时间。

    计算机的很多问题就是在时间和空间上找平衡

    另一个问题计算多边形Pk在点(i,j)处的深度。设多边 形Pk的平面方程为:

    点与多边形的包含性检测:

    (1)射线法

    由被测点P处向 y = -∞方 向作射线

    交点个数是奇数,则被测点在 多边形内部

    交点个数是偶数表示在多边形外部

    若射线正好经过多边形的顶点,则 采用“左开右闭”的原则来实现

    即:当射线与某条边的顶点相交 时,若边在射线的左侧,交点有 效,计数;若边在射线的右侧, 交点无效,不计数

    用射线法来判断一个点是否在多边形内的弊端:

    (1)计算量大

    (2)不稳定

    (2)弧长法

    以p点为圆心,作单位圆,把边投影到单位圆上,对应一段段 弧长,规定逆时针为正,顺时针为负,计算弧长代数和

    代数和为0,点在多边形外部

    代数和为2π,点在多边形内部

    代数和为π,点在多边形边上

    这个算法为什么是稳定的?

    假如算出来后代数和不是0,而 是0.2或0.1,

    那么基本上可以断定这个点在外部,可以认为 是有计算误差引起的,实际上是0。

    但这个算法效率也不高,问题是算弧长并不容易,

    因此又 派生出一个新的方法—以顶点符号为基础的弧长累加方法

    (3)以顶点符号为基础的弧长累加方法

    p是被测点,按照弧长法,p点 的代数和为2π

    不要计算角度,做一个规定来 取代原来的弧长计算

    同一个象限认为是 0,跨过一个象限是 π/2,跨过二个象限 是 π。

    这样当要计算代数和的时候,就不要去投影了,

    只 要根据点所在的象限一下子就判断出多少度,这样几乎没 有什么计算量,只有一些简单的判断,效率非常高

    小结

    z-buffer算法是非常经典和重要的,在图形加速卡和固件 里都有。

    只用一个深度缓存变量zb的改进算法虽然减少了 空间,但仍然没考虑相关性和连贯性

  • 相关阅读:
    收缩清空数据库
    ExecuteScalar 返回值问题
    JS“缺少标识符 字符串或数字”错误
    Access判断空字符串的SQL语句
    decimal与 float的区别
    按照特定的字符拆分字段
    php中heredoc与nowdoc的使用方法
    php 类接口继承练习
    委托
    关闭form前提示是否保存
  • 原文地址:https://www.cnblogs.com/cnblog-wuran/p/9830994.html
Copyright © 2020-2023  润新知