📅  最后修改于: 2021-01-13 09:41:14             🧑  作者: Mango
当我们查看包含不透明对象和曲面的图片时,则无法从视图中看到那些靠近眼睛的对象后面的对象。我们必须去除这些隐藏的表面才能获得逼真的屏幕图像。识别和去除这些表面称为“隐藏表面问题” 。
有两种消除隐藏表面问题的方法–对象空间方法和图像空间方法。对象空间方法在物理坐标系中实现,图像空间方法在屏幕坐标系中实现。
当我们想在2D屏幕上显示3D对象时,我们需要确定屏幕上从选定的观看位置可见的那些部分。
此方法由Cutmull开发。这是一种图像空间方法。基本思想是测试每个表面的Z深度以确定最接近(可见)的表面。
在这种方法中,每个表面一次在整个表面上单独处理一个像素位置。比较像素的深度值,并且最接近(最小的z)表面确定要在帧缓冲区中显示的颜色。
它非常有效地应用于多边形表面。可以按任何顺序处理表面。为了从较远的多边形覆盖较近的多边形,使用了两个名为帧缓冲区和深度缓冲区的缓冲区。
深度缓冲区用于存储在处理表面(0≤深度≤1)时(x,y)位置的深度值。
帧缓冲器用于存储每个位置(x,y)的颜色值的强度值。
通常将z坐标标准化为[0,1]范围。 z坐标的0值表示后裁剪窗格,z坐标的1值表示前裁剪窗格。
步骤1-设置缓冲区值-
深度缓冲区(x,y)= 0
帧缓冲区(x,y)=背景色
步骤2-处理每个多边形(一次一个)
对于多边形的每个投影的(x,y)像素位置,计算深度z。
如果Z> depthbuffer(x,y)
计算表面颜色,
设置depthbuffer(x,y)= z
帧缓冲区(x,y)=表面颜色(x,y)
这是一种识别可见表面的图像空间方法。该方法仅具有一条扫描线的深度信息。为了要求一条深度值扫描线,我们必须在处理下一条扫描线之前,将所有与给定扫描线相交的多边形进行分组和处理。为此,维护了两个重要的表,即边表和面表。
边表-包含场景中每条线的坐标端点,每条线的反斜率以及指向多边形表的指针,以将边连接到曲面。
多边形表-它包含平面系数,表面材质属性,其他表面数据,并且可能是指向边缘表的指针。
为了便于搜索穿过给定扫描线的表面,形成了有效的边缘列表。活动列表仅存储按递增x顺序与扫描线交叉的那些边缘。还为每个表面设置一个标志,以指示沿扫描线的位置是在表面内部还是外部。
从左到右处理每条扫描线上的像素位置。在与表面的左侧相交处,表面标志被打开,而在右侧,标志被关闭。仅当多个表面的标志在特定扫描线位置打开时,才需要执行深度计算。
区域细分方法通过定位那些表示单个表面一部分的视图区域来加以利用。将总查看区域分成越来越小的矩形,直到每个小区域都是单个可见表面的一部分或根本没有任何表面的投影。
继续此过程,直到可以轻松地将细分分析为属于单个曲面或将其缩小为单个像素的大小为止。一种简单的方法是在每一步将区域依次分为四个相等的部分。曲面与指定的区域边界可能具有四种可能的关系。
周围表面-完全包围该区域的表面。
重叠表面-一部分在区域内,一部分在区域外。
内表面-完全在区域内的表面。
外表面-完全在区域外的表面。
用于确定区域内表面可见性的测试可以通过这四个分类来说明。如果满足以下条件之一,则无需进一步细分指定区域-
一种用于识别多面体背面的快速而简单的对象空间方法是基于“内-外”测试的。如果点(x,y,z)位于面的视线内,则该多边形必须是背面(我们在那张脸里面,无法从我们的观看位置看到它的正面)。
我们可以通过考虑具有笛卡尔分量(A,B,C)的多边形表面的法向矢量N来简化此测试。
通常,如果V是从眼睛(或“相机”)位置观察的方向上的矢量,则该多边形为背面
VN> 0
此外,如果将对象描述转换为投影坐标,并且您的观看方向平行于观看z轴,则-
V =(0,0,V z )和VN = V Z C
因此,我们只需要考虑C的符号为法向向量N的分量。
在右手观看系统中,其观看方向沿负$ Z_ {V} $轴,如果C <0,则多边形为背面。此外,由于您的法线的z分量为C = 0,因此我们看不到任何面观看方向朝向该多边形。因此,通常,如果多边形的法向向量具有z分量值,则可以将其标记为背面-
C <= 0
可以在采用左手查看系统的包装中使用类似的方法。在这些程序包中,可以根据沿顺时针方向(不同于右手系统中使用的逆时针方向)指定的多边形顶点坐标来计算平面参数A,B,C和D。
另外,背面的法线向量指向远离观察位置的方向,当观察方向沿正$ Z_ {v} $轴时,其背面C> = 0。通过检查定义对象的不同平面的参数C,我们可以立即识别所有背面。
A缓冲区方法是深度缓冲区方法的扩展。 A缓冲区方法是由Lucas电影制片厂开发的一种可视性检测方法,用于渲染系统“渲染您所见的一切”(REYES)。
A缓冲区在深度缓冲区方法上扩展以允许透明胶片。 A缓冲区中的关键数据结构是累积缓冲区。
A缓冲区中的每个位置都有两个字段-
深度字段-存储正或负实数
强度字段-存储表面强度信息或指针值
如果depth> = 0,则存储在该位置的数字是与相应像素区域重叠的单个表面的深度。然后,强度字段将存储该点表面颜色的RGB分量以及像素覆盖率的百分比。
如果深度<0,则表示对像素强度的多表面贡献。强度字段然后存储指向表面数据的链接列表的指针。 A缓冲区中的表面缓冲区包括-
该算法与深度缓冲算法一样进行。深度和不透明度值用于确定像素的最终颜色。
深度排序方法同时使用图像空间和对象空间操作。深度排序方法执行两个基本功能-
首先,按深度减小的顺序对表面进行分类。
其次,从最大深度的表面开始按顺序对表面进行扫描转换。
在图像空间中执行多边形表面的扫描转换。解决隐藏表面问题的这种方法通常称为画家算法。下图显示了深度排序的效果-
该算法从按深度排序开始。例如,多边形的初始“深度”估计可以被认为是该多边形的任何顶点的最接近的z值。
让我们将多边形P放在列表的末尾。考虑其z范围与P重叠的所有多边形Q。在绘制P之前,我们进行以下测试。如果以下任何一项测试是肯定的,则我们可以假定P可以在Q之前画出。
如果所有测试均失败,则我们使用另一个平面拆分P或Q。新切割的多边形将插入到深度顺序中,并且过程将继续。从理论上讲,这种划分可以生成O(n 2 )个单独的多边形,但实际上,多边形的数量要少得多。
二进制空间分区用于计算可见性。要构建BSP树,应从多边形开始并标记所有边缘。一次仅处理一个边缘,请扩展每个边缘,以便将平面分成两部分。将第一条边作为根放置在树中。根据它们在内部还是外部添加后续边。跨越树中已有边的扩展的边将被分为两部分,并且都添加到树中。
从上图开始,首先以A为根。
列出图(a)中的所有节点。
把所有的都在根A的前向节点A的左侧的节点,并把所有那些根A向右侧后方如图(b)中示出的节点。
首先处理所有前面的节点,然后再处理后面的节点。
如图(c)所示,我们将首先处理节点B。由于节点B前面没有任何内容,因此我们将NIL放在了其中。但是,我们在节点B的后面有节点C ,因此节点C会到达节点B的右侧。
对节点D重复相同的过程。