基于链表的实时屏幕空间反射技术

2018-03-14 10:21:17孟蓉蓉
现代计算机 2018年4期
关键词:链表视点内存

孟蓉蓉

(视觉合成图形图像技术国防重点学科实验室,四川大学,成都 610065)

0 引言

现今,在电影和游戏软件领域,反射是很重要的一项视觉效果。使用光线追踪技术的全局光照算法结合双向反射分布函数(Bidirectional Reflectance Distribu⁃tion Function,BRDF)可以在物体表面产生真实的反射效果。但是相关算法的代价相当昂贵,因为这些算法需要在光线追踪步骤花费大量的计算资源。

游戏产业中,用来生成实时反射效果最常见的算法是环境映射。在理想的反射表面它可以模拟貌似真实的反射效果,但是它无法生成自反射效果。环境映射算法另一个显著的缺点就是在动态场景里,它会降低渲染效率,因为动态更新每一帧的环境贴图代价较大。

近来,很多 SSR(Screen-Space Reflections)算法被提出,这些方法基于屏幕空间而非基于世界坐标系。它从相机位置出发,发射一条入射光线到屏幕上的任意一个像素点,根据法线计算出出射光线,用光线追踪技术计算出射光线和场景的交点,Hierarchical-Z算法可以用来加速求交的过程。SSR算法的主要问题在于物理缓冲区中的信息有限,无法处理反射光线与背面场景相交的问题。

本文提出一个改进的SSR算法,这个算法用来解决原有算法的背面丢失问题。解决这个问题的主要方法是扩充G-Buffer(Geometry Buffer)信息。原有算法的G-Buffer只有场景表面的信息,导致出射光线和场景背面求交时交点丢失。我们使用链表的方式动态对物理缓冲区进行扩充,将背面信息以链表的方式进行存储。当求交点在场景背面时,我们会查找链表,使得背面交点信息被补全。

1 屏幕空间反射

屏幕空间反射算法是基于图像的算法,它从当前视点出发在G-Buffer中做光线跟踪,求到实时的反射结果。屏幕空间反射算法存在一下几点问题:

(1)对于几何体不可见的部分,我们没有办法计算它在屏幕中的反射结果,因为反射结果是基于不完整的场景信息。如图1所示,从视点出发发射两条光线,求反射光线与场景的交点,a点和b点的结果分别是a'和b'点,因为b'对视点来说不可见,所以b处的反射值为空。

(2)场景中的信息不完整可能导致反射错误。如图2所示,红色区域被遮挡,处于视点不可见的范围内,从视点出发计算a点和b的反射点,当到达红色区域时,SSR算法进入一个进退两难的境地,如果结束光线追踪,那么a点和b点的反射结果为空,如果继续光线追踪,那么反射光线与场景进行求交的结果是a''和b',显然a''不是a的结果,a的正确结果应该是a'。不管光线追踪是否继续,SSR算法都会存在错误结果。

图1

图2

2 算法描述

本文算法将G-Buffer用链表的方式进行扩充。算法步骤如下:

(1)渲染整个场景,将处于同一像素的片元存放到一个G-Buffer链表中,再对每条链表中的片元按照深度进行排序;

(2)对像素进行遍历,通过光线追踪计算出每个像素的反射值,将反射值存放到纹理中;

(3)将反射值与场景原有的颜色混合。

2.1 G-Buffer中数据填充和链表排序

本文算法将G-Buffer构建成单向链表的结构,链表访问方式为先进后出模式。在这个链表结构中,我们要在节点中存放上一个节点的索引,同时我们需要存放片元的颜色信息。因为后续光线追踪步骤中需要用到深度值,所以我们要存放每个片元的深度值。场景中背面求交的比例占整个场景的比例为10%到20%,所以链表第二层被查找的概率也是10%到20%,以此类推,链表中第三层被查找的概率微小,所以链表最大长度为3已经能够满足需求。通过上述描述,我们构建的链表结构如图3所示。

图3

G-Buffer中的内存因为链表结构被增加,为了减少内存和带宽的开销,我们压缩链表的内存,整体内存压缩率为50%左右。每个节点中,Index为整数,Color为4个浮点数,Depth为一个浮点数,在32位系统中,每个链表节点占24个字节。HLSL和GLSL本身都支持字节压缩,以GLSL为例,GLSL中的packUnorm4x8函数支持将四个浮点型数压缩为一个无符号型整数,也就是说可以将16个字节的内存压缩为4字节。压缩以后,每个链表节点占12个字节。

在后续处理过程中,我们需要找到每个像素中链表的起始位置,所以我们需要一个辅助的纹理存放每个链表头结点的索引值。关于链表存储方式,我们采用如下方式,我们分配一块连续的物理内存存放链表数据,每个节点在物理内存中的偏移量为链表的节点索引。为了保证节点索引值的唯一性,我们使用GLSL中的Atomic Counter,这个缓存对象存储一个unsigned int的变量值,我们每处理一个片元,缓存对象自增加1,我们把缓存对象的当前值作为链表的索引值。借助这个索引值,我们可以将节点数据存入到对应的物理内存中。

因为在光线追踪步骤,我们需要遍历链表去找反射点,所以我们需要对链表按照深度进行排序,方便以后对链表的遍历。

2.2 求反射值

我们增加了G-Buffer的内存,但是并没有破坏GBuffer的结构,所以在我们的算法中仍然可以使用Hi-Z加速结构。在一般的SSR算法中,我们会对场景的二维深度值进行处理,构建Hi-Z算法所需要的层级深度图,供光线追踪时加速求交使用。在本文算法中,我们对G-Buffer进行扩充,由二维数据变成了三维数据,深度图因此也变成了三维深度图。为了方便起见,我们对G-Buffers中的最靠近视点的片元深度构建层级结构,不考虑链表中其他的深度值。因为在光线追踪步骤,大部分情况是处理可见场景的反射,所以用Hi-Z加速可见场景的求交速度是很有必要的。用最靠近视点的片元深度生成层级图,不会破坏原来的加速结构,也给链表求交提供了额外的空间。

我们从视点出发,发射一条入射光线到屏幕上的某一像素点,根据此像素点的法线求出反射光线的方向。当前像素点为反射光线的起始点,光线按照反射光线的方向前进。这个过程,我们会使用Hi-Z算法进行加速。如果我们在可见场景中找到反射光线与场景的相交点,那么求交过程结束。如果我们检测到交点在背面,我们会对当前链表进行遍历。如果当前链表中有满足条件的片元,我们就视为找到反射点,否则光线跟踪步骤会继续前进,对后续的链表进行排查,直到寻找到合适的值。

2.3 反射贴图的处理

我们将每个像素的反射结果放到一个纹理里,在光线追踪结束以后,我们用反射结果贴图与场景原来的贴图做叠加。因为本文算法计算的是实时反射结果,所以我们只用一条反射光线做光线追踪以节约计算成本。此外,我们计算反射值的步骤是在片元着色器阶段,起点为片元坐标。本算法的这两个特点决定了我们得到的反射值是离散的数据,在最终结果处理的时候会在屏幕上产生噪点,影响最后效果。所以我们得到反射值贴图以后,我们会对反射值做高斯模糊,让反射值贴图的噪声减少。

3 实验结果

我们用本文算法和原有的SSR算法对比,光线追踪步骤中的步长和迭代次数一致,生成出来的效果对比如图4所示。图4左边为原有的SSR算法的效果,从图中可以看到,原有的SSR算法因为背面信息缺失,导致该算法在处理背面反射时中失去作用。红色圈中的部分应该反射鼎的底部,但是原有的算法没有办法得到底部的信息。图4右边为本文算法,因为链表结构补全了一部分缺失的信息,我们在求反射效果时能够通过链表得到正确的反射结果。

图4

4 结语

SSR算法因为其效率高效,在很多追求效率的软件和游戏中有广泛的应用。但是由于其本身算法的局限性,处理效果会有瑕疵。本文算法针对原有算法信息不足导致反射结果不完整的问题,提出解决方案。通过动态链表对数据进行扩充。同时我们考虑到内存开销,对数据进行压缩。但是本文算法在光线追踪步骤,因为数据量的增大,求交时间会增加。未来工作会进一步优化反射求交的效率,让算法整体效率提升。

[1]Greene,Ned.Environment Mapping and Other Applications of World Projections[N].IEEE Computer Graphics and Applications:IEEE,1986:21-29.

[2]Stachowiak,Tomasz.Stochastic Screen-Space Reflections[R].SIGGRAPH 2015 Advances in Real-time Rendering in Games Course,2015.

[3]Uludag,Yasin.Hi-Z Screen-Space Cone-Traced Reflections[M].GPU Pro 5,2014:149-192.

[4]Thibieroz,Nicolas.Order-Independent Transparency Using Per-Pixel Linked Lists[M].GPU Pro,2011:409-431.

[5]Umenhoffer,Tamas and Patow,Gustavo,Szirmay-Kalos,Laszlo.Robust Multiple Specular Reflections and Refractions[M].GPU Gems,2007:387-407.

[6]王晨昊,汤晓安,孙即祥,马伯宁.带有位置修正的环境映射[J].中国图象图形学报,2012(03).

猜你喜欢
链表视点内存
基于二进制链表的粗糙集属性约简
“春夏秋冬”的内存
当代陕西(2019年13期)2019-08-20 03:54:22
跟麦咭学编程
基于链表多分支路径树的云存储数据完整性验证机制
视点
河南电力(2016年5期)2016-02-06 02:11:24
让你每天一元钱,物超所值——《今日视点—2014精萃》序
新闻前哨(2015年2期)2015-03-11 19:29:22
两会视点
中国水利(2015年5期)2015-02-28 15:12:40
链表方式集中器抄表的设计
电测与仪表(2014年1期)2014-04-04 12:00:22
基于内存的地理信息访问技术
寻找新的视点