Tetrahedron based light probe interpolation(基于四面体的Light Probe插值)
在当前的游戏引擎中,使用Light Probe来计算全局环境光对于动态物体的影响是一种很主流的方法。在预处理阶段生成完场景的Light Probe之后,传统的方法采用查找最近的8个相邻的Probe然后使用三线性的方式(Trilinear Interpolation)进行插值,但是这样的插值代价稍大,不过一个可行的优化就是尽可能地减少插值中使用的Probe的数量,比如由8个减少到4个不等。但是这时就不能再用三线性插值,而需要用其它的插值方法比如Inverse Distance等,不过这样就会带来另外一个问题,那就是使用的Probe一般是最近的几个(如三个到四个),如此一来当物体移动之时得到的最近Probe变化可能会比较明显,进而得到的插值结果也会不太连续,影响效果。今年的GDC上Unity的一篇Presentation提到了使用四面体来进行无序Probe的插值,稍花了些时间简单实验了下,还是蛮不错的。文章可以在这里看到:Slide,其最大的一个特点就是Probe可以无序地随机分布,这样在编辑器里边添加以后对美工还是蛮友好的。
四面体网格的生成
为了对Probe所对应的点集使用基于四面体的插值,首先就需要生成这堆点集所对应的四面体集合,这个问题属于传统几何图形学的典型问题,解决方法也很多,比如广泛用在三角细分算法中的Delaunay方法(Paper)。使用Delaunay的方法可以实现对三维空间点集的四面体化操作,不过鉴于此操作不是所关注的问题的关键所在,可以借助于已有的代码来完成该步骤。比如这里就有一个开源的代码库:TetGen(作者应该是一个身在德国的中国哥们)可以完成点集的四面体切分,当然这个里边还有其它不少更高级的功能,感兴趣也可以学习一下。它支持输入很简单的点集描述,然后在一些简单的配置参数下计算得到该点集的四面体化结果。比如对一堆随机生成的点集的四面体化效果如下所示:
四面体重心坐标的计算
要使用四面体对一个给定的目标点进行插值,就要计算其相对于该四面体的重心坐标,也即是其相对于四个顶点的权重比值。这个操作要在每次Probe进行更新的时候都需要进行,因而就要求效率尽可能地高,之前的blog中介绍了使用有向平面距离的方法来计算四面体重心坐标的方法,效率还可以。
其中,这里边的有向距离1 / D(a,PLbcd), 1 / D(b,PLacd), 1 / D(c,PLabd), 1 / D(d,PLabc)对于每个四面体来说均是固定的,因而就可以存储到每个体数据中以便加快效率。
空间数据结构的组织
由于常规的Probe分布是由对应的AABB或OBB来进行定位的,这样在查找目标点所对应的邻近Probe时可以直接进行对应。因为一个区域内的Probe一般是在三个方向上均匀分布的,也就相当于一个三维的数组结构,这样给定一个目标点的位置,就可以直接根据Probe的密度、各个方向上的size及step直接定位到其周边的相邻Probe (AABB 的操作最直接,对于OBB则需要做一个局部坐标系的转换,之后就跟AABB的计算相同),因而这种情况下对于整个Probe数据的组织就比较简单。但是使用基于四面体的方式之后,由于原始Probe的无序,因而这里的数据结构组织就较常规的方法有些区别。首先,对于四面体组织的网格,需要知道四面体间的拓扑信息,也即通过一个四面体能够找到其邻接的四面体,如果用ID来对应每个四面体的话那么在每个四面体中就需要添加四个存储其相邻体的ID数组。另外,由于四面体插值的频繁进行,而这里的插值方法又是使用面的方程来进行,因而就可以将每个面的描述信息也进行存储,这样来提高效率。但是四面体的面是可以公用的,虽然一个面最多只能被两个四面体共用,但还是有必要在存储前来删除冗余。这样其实最终的数据结构就可以如下描述:
- 点:点的位置;关联的Probe的ID或指针;
- 面:关联的三个点的ID;面方程;
- 体:关联的四个面的ID
当然,在上述描述的具体实现过程中还会有其它若干细节,比如要注意组成四面体的点与面之间的对应关系,以便正确找到下一个关联的四面体等;不过这些都比较琐碎且也是具体实现相关。
查找与插值的处理
由于在上述数据结构中存储了四面体之间的拓扑结构,因而在进行目标点对应的四面体定位时就可以使用这些拓扑信息。首先,对于点与四面体的关系及其对应的重心坐标可知:如果一个点在四面体内部,那么它对应的重心坐标均属于[0,1];否则,就可以通过重心坐标的越界方式找到下一个其可能位于的四面体,如此进行若干次迭代之后就可以正确定位到其所在的四面体,或是到达所有四面体集合的边缘。为了快速定位一个点对应的四面体,可以有多种方法:
- 选择所有四面体中处于较中心位置上的一个四面体作为Spawn点,来进行目标体的查找(Presentation中使用的方法)
- 随机选择一个四面体作来初始点,来进行目标体的查找
- 使用各种空间分割方法,如BVH等来对四面体集进行空间组织后加速目标体的查找
当然,在使用上述方法的过程中又会有多种优化方式,比如一些信息的Cache,像记录上一次的目标四面体作为下次查询的初始点等。
对于目标点位于四面体集合外侧的情况,使用边界扩展的方法来进行插值计算。如上图所示(以2D情形为例),其中的黑色线条为体集合的外缘,而绿色区域为每个三角面向外侧的扩充;其中的绿色线条方向为交界顶点处的法向量(这其实也相当于计算每个外表面对应的Voronoi区域)。然后,对于每个目标点P通过投影得到其对应的原始三角面中的位置P',以P'计算其对应三角形的重心坐标后用此三角形上的三个点来插值得到P点的最终结果值。但是这种方法会在集合外侧得到与到集合表面距离无关的插值结果,而实际情况中想要的应该是:外侧体面对于目标点的影响应该随着该点到面的距离增大而减弱。不过这个也比较简单,可以对最终的外缘插值结果再增加一个针对距离d的衰减变化即可。
与常规方法的比较
最后,将基本四面体的Probe插值方法与传统的插值方法进行对比。整体来说,这种方法还是不错的,如果引擎中有之前的均匀分布的Probe系统之后,修改到这种基于四面体插值还是比较容易的。由于Probe的均匀分布,因而可以不错助于其它方式(如TetGen)而直接生成其所对应的四面体网格,而对于数据结构的修改也不是很大。对于某一个物体记录四面体Cache之后的查找更新操作也是比较快的。就算不带来效率提升也不至于也不用损失太多的性能(具体数据还木有来得及对比)。不过使用基于四面体的方法之后最大的一个优势就是可以在引擎中将此前以Probe集合为基本单位的Probe系统转化为以单个Probe为基本单位的新系统,Probe的生成与控制方式更加灵活,Unity里应该就是这种方法。
其它的一些优化
- 在边界插值时可以将距离变化影响也考虑在内,这样只需针对d施加一个合适的衰减函数即可(线性或非线性的)。但是要注意此函数在d=0点处的值应为1,以保证落在边缘表面上的点的插值结果的正确性。
- 可以使用Least Square的方法并结合四面体的插值描述来对整个Probe系统进行优化,这样在给定一定的误差阈值之后,就可以减少Probe的数量。
下述为一些实验效果:其中的Probe是在一个指定的区域范围内以均匀的分布方式随机生成,数量为512个;Probe的球谐值采用球面蒙特卡洛采样方式计算得到;每个Probe球面上采样1024个点,场景采用BVH空间分割来加速求交测试:
其中的黑色线框即为当前角色中心所处于的四面体,从中可以看出:两个邻近不同位置的目标点对应了两个相邻的不同四面体。
转:http://blog.csdn.net/bugrunner/article/details/7485475
Tetrahedron based light probe interpolation(基于四面体的Light Probe插值)的更多相关文章
- SQL Standard Based Hive Authorization(基于SQL标准的Hive授权)
说明:该文档翻译/整理于Hive官方文档https://cwiki.apache.org/confluence/display/Hive/SQL+Standard+Based+Hive+Authori ...
- 基于GDAL的栅格图像空间插值预处理
转自 基于GDAL的栅格图像空间插值预处理——C语言版 基于GDAL的栅格图像预处理 前言 栅格数据和矢量数据构成空间数据的主要来源,怎样以开源方式读取并处理这些空间数据?目前有多种开源支持包,这里只 ...
- LED Decorative Light Manufacturer Introduction: LED Metal Table Light
Nowadays, when many people choose the desk light, they are worried that it will not be used for a lo ...
- 【sqli-labs】 less12 POST - Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)
加个双引号 通过报错信息猜测SQL语句 , 将括号闭合掉,通过注释后面的条件登录
- 【sqli-labs】 less4 GET - Error based - Double Quotes - String (基于错误的GET双引号字符型注入)
提交id参数 加' http://localhost/sqli/Less-4/?id=1' 页面正常,添加" http://localhost/sqli/Less-4/?id=1" ...
- 基于gdal的格网插值
格网插值就是使用离散的数据点创建一个栅格图像的过程.通常情况下,有一系列研究区域的离散点,如果我们想将这些点转换为规则的网格数据来进行进一步的处理,或者和其他网格数据进行合并 等处理,就需要使用格网插 ...
- LED Decorative Light Supplier - Decorative Use Of LED Light Strips
Led strip refers to the led assembly in the ribbon of the FPC (flexible circuit board) or PCB hard b ...
- 基于预计算的全局光照(Global Illumination Based On Precomputation)
目录 基于图像的光照(Image Based Lighting,IBL) The Split Sum Approximation 过滤环境贴图 预计算BRDF积分 预计算辐射度传输(Precomput ...
- Light Probe
[Light Probe] Light Probes provide a way to capture and use information about light that is passing ...
随机推荐
- 目标(web前端)
在学习web前端开发技术之前,对该课程的了解并不多,目标就是好好认真学习该课程的每一点知识,并好好掌握它.老师说该课程的内容比较多而且繁杂,那我希望我可以在今后的学习中有耐心的学好该门课程.
- windows 64位环境下php执行环境部署配置
1.下载安装包 地址可以网上找,我下载的是php-5.6.27-Win32-VC11-x64.zip 2.解压安装包,我的解压到D:\tools\php5.6 3.配置php.ini 在解压的目录中, ...
- centos 6.4配置samba+ldap认证
原文地址:http://www.centoscn.com/image-text/config/2015/0716/5866.html 1. 什么是samba Samba服务类似于windows上的共 ...
- normalize.css的使用
normalize.css有下面这几个目的: 保护有用的浏览器默认样式而不是完全去掉它们一般化的样式:为大部分HTML元素提供修复浏览器自身的bug并保证各浏览器的一致性优化CSS可用性:用一些小技巧 ...
- 【Javascript Demo】图片瀑布流实现
瀑布流就是像瀑布一样的网站——丰富的网站内容,特别是绚美的图片会让你流连忘返.你在浏览网站的时候只需要轻轻滑动一下鼠标滚轮,一切的美妙的图片精彩便可呈现在你面前.瀑布流网站是新兴的一种网站模式——她的 ...
- 微软BI 之SSIS 系列 - Lookup 中的字符串比较大小写处理 Case Sensitive or Insensitive
开篇介绍 前几天碰到这样的一个问题,在 Lookup 中如何设置大小写不敏感比较,即如何在 Lookup 中的字符串比较时不区分大小写? 实际上就这个问题已经有很多人提给微软了,但是得到的结果就是 C ...
- CentOS 7不能进入图形界面
开机后发现CentOS 7不能进入图形界面,进入终端模式后运行startx命令也报错,不知道什么原因,后来运行了yum upgrade命令,升级以后就可以进入图形界面了,同时也升级了.
- React 中 keys 的作用是什么?
Keys 是 React 用于追踪哪些列表中元素被修改.被添加或者被移除的辅助标识. render () { return ( <ul> {this.state.todoItems.map ...
- spring-mybatis-data-common程序级分表操作实例
spring-mybatis-data-common-2.0新增分表机制,在1.0基础上做了部分调整. 基于机架展示分库应用数据库分表实力创建 create table tb_example_1( i ...
- 转 可能是最漂亮的Spring事务管理
Snailclimb 2018年05月21日阅读 4246 可能是最漂亮的Spring事务管理详解 Java面试通关手册(Java学习指南):github.com/Snailclimb/… 微信阅读地 ...