在当前的游戏引擎中,使用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];否则,就可以通过重心坐标的越界方式找到下一个其可能位于的四面体,如此进行若干次迭代之后就可以正确定位到其所在的四面体,或是到达所有四面体集合的边缘。为了快速定位一个点对应的四面体,可以有多种方法:

  1. 选择所有四面体中处于较中心位置上的一个四面体作为Spawn点,来进行目标体的查找(Presentation中使用的方法)
  2. 随机选择一个四面体作来初始点,来进行目标体的查找
  3. 使用各种空间分割方法,如BVH等来对四面体集进行空间组织后加速目标体的查找

当然,在使用上述方法的过程中又会有多种优化方式,比如一些信息的Cache,像记录上一次的目标四面体作为下次查询的初始点等。

对于目标点位于四面体集合外侧的情况,使用边界扩展的方法来进行插值计算。如上图所示(以2D情形为例),其中的黑色线条为体集合的外缘,而绿色区域为每个三角面向外侧的扩充;其中的绿色线条方向为交界顶点处的法向量(这其实也相当于计算每个外表面对应的Voronoi区域)。然后,对于每个目标点P通过投影得到其对应的原始三角面中的位置P',以P'计算其对应三角形的重心坐标后用此三角形上的三个点来插值得到P点的最终结果值。但是这种方法会在集合外侧得到与到集合表面距离无关的插值结果,而实际情况中想要的应该是:外侧体面对于目标点的影响应该随着该点到面的距离增大而减弱。不过这个也比较简单,可以对最终的外缘插值结果再增加一个针对距离d的衰减变化即可。

与常规方法的比较

最后,将基本四面体的Probe插值方法与传统的插值方法进行对比。整体来说,这种方法还是不错的,如果引擎中有之前的均匀分布的Probe系统之后,修改到这种基于四面体插值还是比较容易的。由于Probe的均匀分布,因而可以不错助于其它方式(如TetGen)而直接生成其所对应的四面体网格,而对于数据结构的修改也不是很大。对于某一个物体记录四面体Cache之后的查找更新操作也是比较快的。就算不带来效率提升也不至于也不用损失太多的性能(具体数据还木有来得及对比)。不过使用基于四面体的方法之后最大的一个优势就是可以在引擎中将此前以Probe集合为基本单位的Probe系统转化为以单个Probe为基本单位的新系统,Probe的生成与控制方式更加灵活,Unity里应该就是这种方法。

其它的一些优化

  1. 在边界插值时可以将距离变化影响也考虑在内,这样只需针对d施加一个合适的衰减函数即可(线性或非线性的)。但是要注意此函数在d=0点处的值应为1,以保证落在边缘表面上的点的插值结果的正确性。
  2. 可以使用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插值)的更多相关文章

  1. SQL Standard Based Hive Authorization(基于SQL标准的Hive授权)

    说明:该文档翻译/整理于Hive官方文档https://cwiki.apache.org/confluence/display/Hive/SQL+Standard+Based+Hive+Authori ...

  2. 基于GDAL的栅格图像空间插值预处理

    转自 基于GDAL的栅格图像空间插值预处理——C语言版 基于GDAL的栅格图像预处理 前言 栅格数据和矢量数据构成空间数据的主要来源,怎样以开源方式读取并处理这些空间数据?目前有多种开源支持包,这里只 ...

  3. 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 ...

  4. 【sqli-labs】 less12 POST - Error Based - Double quotes- String-with twist (基于错误的双引号POST型字符型变形的注入)

    加个双引号 通过报错信息猜测SQL语句 , 将括号闭合掉,通过注释后面的条件登录

  5. 【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" ...

  6. 基于gdal的格网插值

    格网插值就是使用离散的数据点创建一个栅格图像的过程.通常情况下,有一系列研究区域的离散点,如果我们想将这些点转换为规则的网格数据来进行进一步的处理,或者和其他网格数据进行合并 等处理,就需要使用格网插 ...

  7. 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 ...

  8. 基于预计算的全局光照(Global Illumination Based On Precomputation)

    目录 基于图像的光照(Image Based Lighting,IBL) The Split Sum Approximation 过滤环境贴图 预计算BRDF积分 预计算辐射度传输(Precomput ...

  9. Light Probe

    [Light Probe] Light Probes provide a way to capture and use information about light that is passing ...

随机推荐

  1. UEditor实现前后端分离时单图上传

    首先,需要下载部署ueditor相关代码,可以参考一篇简单的博客,这里不再赘述: 环境搭建好后,我们先简单使用一下,启动http://web.yucong.com:8080/ueditor/index ...

  2. 使用HttpClient实现并发请求

    在.Net 4.0之前,一直是依靠HttpWebRequest实现Http操作的.它默认有一个非常保守的同一站点下最大2并发数限制,导致默认情况下HttpWebRequest往往得不到理想的速度,必须 ...

  3. MySql数据库事务正常提交,回滚失败

    问题:在初次练习Mysql数据库事务时,事务正常提交,但是在遇到异常应当回滚时,回滚失败. 代码如下: //2.更新操作. public void update(Connection conn, St ...

  4. android:ListView bbs Demo

    我们制 作的 message_left.9.png 可以作为收到消息的背景图,那么毫无疑问你还需要再制作一张 message_right.9.png 作为发出消息的背景图. 图片都提供好了之后就可以开 ...

  5. 使用JDBC在MySQL数据库中快速批量插入数据

    使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(10W+),如何提高效率呢? 在JDBC编程接口中Statement 有两个方法特别值得注意: void addBatch ...

  6. 用oc写爬虫之HTMLParser

    最近刚好有一些小需求,就尝试用OC来写一些简单的爬虫抓取网页上的数据: 发现了一个非常好用的HTMLParser工具 ; 语法是OC的,通过分析网页结构:可以很轻松的抓取需要的数据: 但是提前需要了解 ...

  7. Uploadify导致Chrome频繁崩溃Crash

    上传功能是工作中经常会遇到的问题,应该作为开发标配的技能每个人都会. 我选用的是Uploadify 3.1.2进行上传,使用方法参考之前的一篇文章, 今天记录下一个我遇到的很神奇的bug chrome ...

  8. maven本地仓库中存在jar包,但编译不成功,显示jar包不存在

    介绍一下背景,项目要迁移进坑人的离线的内网开发,将在同事那编译通过的代码和maven仓库拷进内网,打算编译通过之后再上传私服,结果配好maven之后,本地库中的部分jar包显示没有引入,如下面的波浪线 ...

  9. SSL介绍(Secure socket Layer & Security Socket Layer)

    一个应用程序的安全需求在很大程度上依赖于将如何使用该应用程序和该应用程序将要保护什么.不过,用现有技术实现强大的. 一般用途的安全通常是可能的.认证就是一个很好的示例. 当顾客想从 Web 站点购买某 ...

  10. C#:文件夹匹配

    //文件夹匹配:对比文件夹,相同的目录结构.所有文件名称小写相同,制定文件外的MD5值相同 ,则两个文件夹匹配成功! /// <summary> /// 批量匹配书籍H5资源包 /// & ...