APP下载

使用多层深度采样的屏幕空间环境光遮挡

2011-09-07宋云鹏康一梅

计算机工程与设计 2011年7期
关键词:环境光纹理绘制

宋云鹏, 刘 芳, 刘 娜, 康一梅

(1.北京航空航天大学软件学院,北京100191;2.中国科学院软件研究所计算机科学国家重点实验室,北京100190;3.中国科学院研究生院北京100049)

0 引 言

屏幕空间环境光遮挡技术是在传统的环境光遮挡技术基础上发展起来的一种近似的全局光照计算方法。它利用屏幕空间中的深度信息,重建场景中每个点及其周围几何体的空间相对位置关系,以此计算当前点被周围几何体遮挡的情况,即当前点的环境光遮挡值。相对于传统环境光遮挡方法使用光线跟踪的计算方法,这种方法更加高效。随着可编程图形处理器的发展,出现了一些使用GPU加速的屏幕空间环境光遮挡计算方法,Bavoil等[2]提出了一种完全在GPU上计算的基于水平线的屏幕空间环境光遮挡算法,该方法利用水平角逼近的方式估计周围几何体的形状,并由此计算环境光遮挡值,对以往的方法做了很大的改进。

本文首先介绍了环境光遮挡算法以及深度剥离技术的发展情况,其中详细介绍了使用GPU加速的屏幕空间环境光遮挡算法以及桶型深度剥离算法。然后本文在BAVOIL等[2]的算法基础上提出了一种使用多层深度采样的屏幕空间环境光遮挡算法,对传统的屏幕空间环境光遮挡算法进行了一定的改进。之后,本文对实验结果进行了分析与总结。

1 相关工作

1.1 环境光遮挡

本文中解决的问题是Bavoil等[2]算法中由于深度信息不足造成的不可见点的遮挡贡献丢失的问题。下面介绍一些与本文工作相关的环境光遮挡算法。

Pharr等[7]最先利用GPU加速计算环境遮挡的算法,其基本原理是采用阴影图来确定从当前绘制点某个方向上发出的光线是否被场景中的其它物体遮挡。该算法需要绘制场景多遍,但仍比基于光线跟踪的环境遮挡算法有了较大的加速。Kontkanen等[8]提出环境遮挡域算法,通过对场景中的物体建立包围盒来加速光线与场景的求交过程。Bunnell等[9]使用圆盘来表示场景中的物体,通过计算圆盘间的相互遮挡值来近似场景中物体的遮挡情况。这类算法由于需要对场景预计算,所以难以高效地绘制动态变形的场景。REN等[10]采用球形遮挡物体和球面调和函数来计算近似环境遮挡值。由于其预计算量较小,可以较好地支持可变形物体,但是对于包含较多数量物体的场景,其性能下降。

Shanmugam等[1]采用GPU计算环境遮挡值,其核心思想是采用当前绘制点在屏幕空间上的投影像素点的邻域信息来计算该点的遮挡值。其优点是计算过程与场景的几何复杂度无关且无需预计算,但其不足之处在于在采样过程中将物体表面采样区域近似为球体,导致对遮挡面积的过度估计,使得绘制结果通常比真实结果更暗。

Bavoil等[2]提出了一种新的基于水平线的屏幕空间环境遮挡计算方法。该方法解决了Shanmugam等[1]方法中的遮挡估计不足的问题,且不需要任何与场景相关的预计算,因而可以实时的模拟场景的中的间接光照。但是与Shanmugam等[1]的方法类似,该方法的采样过程全部在可见点上进行,对于处于复杂几何体遮挡下的不可见点的遮挡值没有进行计算,因此会造成遮挡不足的问题。对于深度复杂度较高的场景,产生的绘制错误尤为明显。进而导致最终渲染生成的图像真实感不足。

1.2 深度剥离

传统的深度剥离算法一次绘制只能收集一个层次的深度信息,尽管这种方法可以获得精确的层次深度信息,但是当需要多层深度信息时,就需要进行多次的绘制,效率十分低下。Bavoil提出的K-Buffer[6]算法使用GPU上提供的多重渲染目标缓存(MRT)保存多个片元的信息,对每一个片源根据深度进行插入排序,可以在一个场景绘制过程中为每个像素至多收集K个片元。但由于在GPU上无法保证正确的读写顺序,当多个片元对应同一个存储位置时就会出现错误。之后Bavoil[11]利用NVIDIAGeforce8开始支持的输出纹理的最大、最小混合方式,实现了一个最大(最小)深度缓存,可以在一遍场景绘制过程中同时输出最近和最远的深度信息。

LIU[3]提出了一种在一遍绘制过程中收集多层深度信息的算法。首先使用Bavoil[11]的方法输出当前场景中每个像素的最近和最远深度,然后根据当前像素的深度范围划分为若干个深度段,每个段中的深度信息由不同的输出纹理来保存。通过将场景绘制一遍,在片元着色器中将位于不同深度段的片元深度信息保存在不同的纹理中,从而达到了在一遍绘制中收集多层深度信息的目的。尽管该方法不能获得每一层的精确深度,但是却可以为一些效果计算提供足够的深度信息。

2 使用多层深度采样的屏幕空间环境光遮挡

2.1 算法整体流程

本文假设场景中的物体之间没有相交的情况,并约定法向量朝向视点方向为向前方向,反之则是向后方向。片元的深度则是指在视点坐标系中片元到视平面的距离。

本文算法的流程是:第一遍从视点绘制场景,将每个像素上的最大深度和最小深度保存下来,这样就得到了每个像素上的深度变化范围。第二遍仍然从视点绘制场景,利用在第一遍绘制的场景深度图,根据每个像素的深度变化范围,使用桶型深度剥离算法将每个像素的多个深度输出到多个 MRT中。第三遍根据前两遍获得的深度信息,计算整个场景的环境光遮挡。

2.2 桶型深度剥离算法

LIU[3]的方法首先需要将场景中每一个像素的最大与最小深度保存到一张纹理中。这样就可以获得场景中每个像素对应的深度范围。然后再从视点方向绘制场景,在绘制的过程中,根据每个像素的深度范围,将深度等分为n(n=1,2,3…)个深度段,并用不同的输出纹理保存不同深度段中的值。在绘制片元的过程中,根据每个片元的深度,计算该片元对应的深度段,将片元的深度保存在对应的纹理中。在保存的过程中,可以根据不同的需要设置输出纹理的混合方式,如最大值混合或者最小值混合,相应地可以得到每个深度段中的最大或者最小深度值。

在本文的第一遍绘制过程中,首先关闭场景的深度检测,开启最大纹理混合,在片元程序中将当前片元的深度取负存储在输出纹理的第一个通道,将原深度值存储在第二个通道。这样,在绘制结束后就可以得到一张存储了当前场景每一个像素的最小和最大深度值的纹理。

第二遍仍然从视点绘制场景,关闭深度检测,开启最小纹理混合。在片元处理程序中,根据第一遍绘制纹理对应像素上的深度范围和使用的输出纹理数量,将深度分割为N段(N为使用MRT数目的两倍)。这里需要注意,为了减少场景绘制次数,将每个多重渲染目标(MRT)的4个颜色通道分配给两个“桶”,即每个桶占用两个颜色通道。其中一个通道存储法向量方向向前的片元的深度,另一个通道则用于存储法向量向后的片元深度。这样每个桶就同时存储了这一深度段内的法向量向前的片元深度,以及法向量向后的片元深度。之后,需要计算当前片元法向量与视点向量的点积,如果为正则该片元方向向前,存储于桶的第一个通道中,反之则存储于对应桶的第二个通道中。

当两次场景绘制完成后,就可以得到一组存储有该场景不同深度段深度信息的纹理,这些纹理的每个通道中都存储着一个纹理值。这些纹理值根据它们存储的通道位置的不同(r通道存正向片元深度,g通道存储反向片元深度,b通道存储正向片元深度,a通道存储反向片元深度)存储不同朝向的片元深度。

2.3 计算环境光遮挡

首先回顾Bavoil等[2]提出的基于水平线的环境光遮挡算法,该算法的核心是通过在屏幕空间内进行采样,确定当前被遮挡片元周围最大的遮挡体的体积,从而计算当前片元被周围几何物体遮挡的程度。

对于场景中的每个片元P,其环境光遮挡值可以采用以下公式近似计算

式(1)中所有采样点的坐标采用球面坐标系。如图1所示,其中 (∈[0,2])为采样点方位角,h()为沿该方向与P点构成的最大水平仰角,t()为水平线与法向平面的夹角。W()函数为用户定义的线性衰减函数。在具体的公式中,定义W()=max(0,1-r()/R),其中r()为P点与 方向上最大水平仰角对应点的距离,R是对P点有遮挡影响的最大半径,该函数用于消除处于最大半径R之外的点对P的影响。

图1 BAVOIL [2]算法原理

当P点周围存在多个层次的几何物体时,由于算法只关心P点周围最大的水平仰h()max,就会造成P点遮挡值计算错误,如图2所示。因此就需要使用桶型深度剥离的方法提取足够的深度信息,以消除由于深度信息不足造成的遮挡错误。

图2 在出现多层物体时遮挡错误

使用桶型深度剥离算法调整后的算法原理如图3所示。在每个片元方向向前的深度层次上寻找该层次内的最大水平仰角,反之则寻找最小的水平仰角。最后将各个层次的环境光遮挡值按照片元的朝向进行求和操作。在具体的实现过程中需要从之前完成的深度纹理中读取深度信息,由于硬件速度的限制,因此不能够无限制的读取纹理数据,只能采用有限采样的方法。在片元处理程序中,当前片元P的环境光遮挡计算公式如下所示

式中:h()=max(t(),h()[i],…)(i=0,2,4…),即 h()——在第 i层深度沿 方向的最大水平仰角。反之,当i为奇数时,h()=min(t(),h()[i],…)(i=1,3,5…),即 h()为在第 i层深度沿 方向的最小水平仰角。这样就可以有效的消除多层几何体重叠造成的反方向片元的遮挡影响。

图3 使用多层深度信息修正后的算法

下面介绍本文算法在最后一遍绘制中的环境光遮挡计算过程:首先在当前绘制片元周围的一定范围内进行采样点采样,沿采样方向 进行采样。根据采样点屏幕空间坐标(u,v)读取在第二遍输出纹理中保存在该像素点上的n个深度段中的深度值,并将其存入一个float型的数组Depth[n]中,并且将第一个桶的第一通道数据存储在下标为0的元素中,第一个桶的第二个元素存储在下标为1的元素中,以此类推。然后按照下标递增的顺序遍历这个数组,在遍历数组的过程中寻找各个层次的最大水平仰角h()并计算各层深度对P点的环境光遮挡值。

具体计算过程如下:每次在进行深度遍历和计算h()时,需要根据片元的朝向寻找该层深度的最大h()或最小h()。因此,设置一个float类型的数组h[n],用于保存在 方向上各深度层对应的h()。在遍历的过程中,假设当前标号为i的深度值为Depth[i],向量n和P为当前片元的法向量和屏幕空间坐标,向量v为当前片元到视点的向量。根据深度编号i以及深度值的不同,分为以下几种情况:

(1)对下标为i(i=0,2,4,6……),即i为偶数的数组元素,根据前文提到的深度装填方法,这些元素存储的深度值都是正向片元的深度值。在这种情况下,计算当前片元P与采样点S之间的水平仰角h(),即

比较这个h()与h[i]元素中存储的值的大小,取两者间较大的赋值给h[i]。

(2)对下标为i(i=1,3,5…),即i为奇数的h[n]数组元素,这些元素存储的深度值为反向片元的深度值。在这种情况下,同样参照式(4)计算当前片元与采样点S间的水平仰角h(),比较h()与h[i]元素中存储的值的大小,取两者间较小的赋值给h[i]。

(3)当深度值Depth[i]为0或者1时,证明该元素没有存储任何有效的深度值,不做任何进一步计算。

当遍历深度元素结束后,h[n]数组中就存储了沿 方向的所有深度层次中的最大水平仰角h()max,这时开始计算这一方向上的混合屏幕空间环境光遮挡值。使用式(3)计算每一个h[n]数组元素的环境光遮挡值HAO(,i)(i=0,1,2…)。片元着色程序继续对下一个采样方向进行采样,完成所有方向的遮挡值计算,使用式(2)计算对P点的最终环境光遮挡值。

3 GPU实现

3.1 实现平台

我们使用Ogre1.7.1(object-oriented graphics rendering engine)渲染引擎以及C for Graphics(Cg)着色语言实现了本文的主要算法。文中使用的深度范围保存部分使用了(rendertotexture,RTT),桶型深度剥离算法通过(multirendertargets,MRT)完成。实验所用系统平台为UbuntuLinux9.10,3DAPI为OpenGL 3.2,硬件平台为IntelCore22.8GHzCPU,GPU采用NVIDIAGe-Force GTX260+896MB显存。

3.2 实现流程

在获取每个像素点的最大以及最小深度的时,启用最大混合方式,禁用背面裁剪和深度测试,输出纹理格式使用Ogre渲染引擎提供的PF_FLOAT32_RGBA格式。在片元着色程序中输出如下值:float4(-Z,Z,0.0f,0.0f),其中Z是当前片元在视点坐标系中的深度值。在最后输出纹理中每个纹素的R分量保存了该像素上的最小深度,G分量保存了该像素的最大深度。

在第二遍绘制场景进行桶型深度剥离的过程中,启用最小混合方式,禁用背向面裁剪和深度测试,这样可以保证距离视点最近处的深度可以被正确的剥离出来。在输出时使用了4张纹理作为MRT来保存深度段中的值。由于所用MRT的格式为PF_FLOAT32_RGBA,所以MRT的每个颜色分量都可以保存一个32位的深度值,这样一张MRT的每个纹素可以保4个深度值。但是由于我们使用每两个分量保存一个深度段内的前向片元深度以及后向片元深度值,因此4张MRT纹理可以保存8个深度段的16个深度值。在最后一遍进行环境光遮挡计算的过程中,恢复背向面裁剪和深度测试,并且关闭所有颜色混合方式。按照本文的算法将最终结果绘制出来。

4 实现结果与分析

4.1 实现结果

本文中的实验结果输出分辨率均为800x600。采样方向为8个,每个采样方向上15个采样点,采样半径45像素。一些实验结果如图4所示,绘制帧率如表1所示。

4.2 分析

本文的算法与Bavoil[2]的方法相比,计算了在复杂几何场景下的多层深度的片元的遮挡贡献,使得最终的结果更加真实。

图4 Buddha Dragon Bunny模型的绘制效果

表1 本文方法的绘制帧率

对比bavoil[2]算法与本文方法对相同的Dragon模型的渲染结果。如图5所示,可以明显看出,在使用桶型深度剥离算法获取更多层的深度信息后,更多的物体阴影细节被更加准确的计算出来,相对于仅考虑单一深度的原算法,具有更加准确的渲染质量和真实感。

图5 本文方法与Bavoil等 [2 ]方法的渲染结果对比

由于本文的方法只能保存有限层数的深度信息,所以在计算的过程中不可避免的出现一些误差。对一般的场景来说,本文算法中使用的16层深度信息基本上可以用来产生理想的结果。通过实验表明,当使用的深度超过4层以后,对渲染质量的影响很小,但是却会极大的降低性能。

5 结束语

本文通过使用桶型深度剥离算法对BAVOIL[2]的算法进行扩展,提出一种使用多层深度采样的屏幕空间环境光遮挡算法。这是一种多遍绘制的方法,在充分考虑场景深度层次信息基础上计算环境遮挡,对部分遮挡不足的区域进行加权遮挡补偿,使得计算的结果更加符合真实的场景情况。

但是该算法仍然是一种基于图形后处理阶段的环境光遮挡计算方法,即渲染出的环境光遮挡纹理实际上保存的是一种环境光的权值,需要和原场景进行乘积混合,进而生成最终的计算结果。在这种算法中,即便获取了足够的深度信息,仍然不能够有效的计算间接光反射造成的阴影减弱的问题。未来将在场景的光照计算阶段将间接光反射的因素考虑进来,对本文的方法进行改进。

[1]Shanmugam P,Arikan O.Hardware accelerated ambient occlusion techniques on GPUs[C].Gooch B,Sloan P-P J.Proceedings of ACM Symposium in Interactive 3D Graphics and Games.ACM,2007:73-80.

[2]Bavoil L,Sainz M,Dimitrov R.Image-space horizon-based ambient occlusion[C].ACM SIGGRAPH Sketches,2008.

[3]Liu F,Huang MC,Liu X-H,et al.Efficient depth peeling via bucket sort[C].Proceedings of the 1st High Performance Graphics Conference,2009:51-57.

[4]Liu X-H,Hao X-G,Huang M-C,et al.Fast soft shadow by depth peeling[C].ACM SIGGRAPH Posters,2010.

[5]Ristchel T,Grosch T,Seidel H.Approximating dynamic global illumination in image space[C].Interactive 3D Graphics and Games.Boston,Massachusetts:ACM,2009.

[6]Bavoil L,Callaham S,Comba J,et al.Multi-fragment effects on the GPU using the k-buffer[C].Interactive 3D Graphics and Games.Seattle,Washington:ACM,2007.

[7]Pharr M,Green S.GPU Gems:programming techniques,tips,and tricks for real-time graphics[M].Dynamic Ambient Occlusion and Indirect Lighting,Boston:Addison-Wesley,2004:279-292.

[8]Kontkanen J,Laine S.Ambient occlusion fields[C].Proceedings of the Symposium on Interactive 3D Graphics and Games.Washington DC:ACM,2005:41-48.

[9]Bunnell M.Dynamic ambient occlusion and indirect lighting[C].GPU Gems,Pharr M.Addison Wesley,2005:223-233.

[10]RenZ,Wang R,Snyder J,et al.Real-timesoft shadows in dynamic scenes using spherical harmonic exponentiation[C].ACM SIGGRAPH Papers.New York,USA:ACM,2006:977-986.

[11]Bavoil L,Myers K.Order independent transparency with dual depth peeling[R].Santa Clara:NVIDIA Cooperation,2008.

[12]刘芳,黄梦成,刘学慧,等.基于桶内动态融合的透明现象的高效绘制[J].计算机辅助设计与图形学学报,2010,22(3):382-387.

猜你喜欢

环境光纹理绘制
基于Excel VBA和AutoCAD的滚动轴承参数化比例图绘制方法
基于BM3D的复杂纹理区域图像去噪
Vishay新型高灵敏度环境光传感器用于可穿戴设备
超萌小鹿课程表
单帧图像下的环境光遮蔽估计
使用纹理叠加添加艺术画特效
放学后
TEXTURE ON TEXTURE质地上的纹理
超赞柔性屏幕
消除凹凸纹理有妙招!