Photon Mapping算法学习总结

最近在尝试归纳UE的间接光方案,了解到其用于间接光计算的Lightmass流程使用的算法就是photon mapping,为了追本溯源,对整个光照计算逻辑有一个更为清晰的认识,这里对photon mapping算法进行了一番简单的学习,这里将学习材料整理之后文档输出出来,一方面希望读者看到有谬误之处可以不吝指正,另一方面也希望后面看到其他相关材料可以补充进来,不断完善相关主题的内容。

正文

1. Photon Mapping算法实现逻辑

Photon Mapping算法最早由Jensen在96年提出,中间经过众多大佬的优化与修正,产出了一系列的实现算法,这里将按照一定的逻辑关系输出多种算法的实现策略,方便理解与阅读。

1.1 标准算法

Jensen在96年提出的Photon Mapping(PM)算法是整个算法逻辑的基础,因此这里会先介绍这个算法的具体实现逻辑。

标准PM算法由两个pass组成,分别是Photon Map Generation Pass与Lighting Pass。

1.1.1 Photon Map Generation Pass

这个Pass主要用于完成Photon(光子)的发射以及Photon Map的创建工作,其实现逻辑给出如下:

  1. 从光源向各个方向发射photon,如下图所示

从光源视角来看,部分方向出发的photon是不会与场景发生碰撞的,因此为了节省消耗提升效率,这里可以通过为photon增加一个标记来判断是否需要进行碰撞检测迭代,通常会采用一个叫做projection map的贴图来指明有效的发射方向,如下图所示,红色方框中的那一段就是有效的发射方向:

那么如何判定是否会发生碰撞呢?简单来说,就是从光源视角,将场景分割成多个Cell,每个Cell对应于projection map上的一个像素,当Cell中没有物件时,将projection map上的对应像素标记为off即可。

如下图所示,不同光源的发射方向是不一样的,点光是均匀方向,面光源则是随机发射:

每个发射的photon的主要参数为flux而非Radiance,也就是光通量,这个数值通常用于表征发射功率,数值可以用光源的Flux除以发射的光子数来求得:

光子发出之后,就会进入与场景的交互过程,整个交互过程可以看成多次迭代,每次迭代为photon在当前的位置沿着当前的速度与场景发生的一次碰撞检测:

  1. 碰撞过程中将数据存储在photon map中
    1.1 photon map说是一个map,实际上会将之以KD-Tree(也就是三维空间中的二叉树)结构进行存储。在Lighting Pass会需要进行大量的空间查找,使用KD-Tree有助于实现算法加速
    1.2 实际上只有发生漫反射时的数据才需要存储,镜面反射的数据会在Lighting Pass中通过Ray Tracing来得到
    1.3 photon map中像素数据格式如下图所示:
struct photon
{
  float x,y,z;//碰撞位置
  char p[4];//RGBE编码的光照flux
  char phi, theta;//入射光方向
  short flag;//用于KD-Tree结构的数据
}

每次碰撞后根据交互类型决定是否进行下一次迭代:

  • 继续迭代
    • 反射
    • 折射
  • 终止迭代
    • 吸收
    • 逸出,即射出场景之外

交互类型由概率确定的:现实中的光线与物件碰撞后是多种交互类型并存的,但是按照这种模式计算会增加复杂度,为了简化计算,假设photon碰撞后能量不变,每次碰撞只发生一种交互,交互类型由概率确定,即类似于俄罗斯轮盘,根据材质属性,设定各种交互类型的发生概率,根据概率触发后续行为。

1.1.2 Lighting Pass

Lighting Pass就是用photon map来完成场景光照计算,来深入实现细节之前,先来看看光照计算的总体公式。

1.1.2.1 光照公式

最终我们需要计算屏幕空间上每个像素(或者三维空间的probe的SH系数求解同样需要计算各个方向的Radiance或者Irradiance)的Radiance,而这个Radiance包含四个部分:

这四个部分的计算公式给出如下:

由于最终需要计算的是Radiance,而photon中存储的却是flux,因此公式需要经过一次转换:

由于

L(x, \vec{\omega}) = \frac{d {\Phi}^2(x, \vec{\omega})}{d \omega cos \theta d A}

因此可以有:

1.1.2.2 光照计算逻辑

光照有两种计算方式,分别是直接使用photon map数据作为光照结果以及photon map作为间接光与焦散计算数据。

1.1.2.2.1 直接使用photon map数据作为光照结果

直接使用photon map数据作为光照结果的计算方式,其实现逻辑给出如下。

对于屏幕空间中对每个像素而言,可以直接根据photon map来估计其亮度与颜色,这过程本质上是概率密度估计。而由于光子分布是无规律的,因此可以使用非参数估计法,具体来说有如下三种方式:
1. 直方图估计
1.1 具体算法
1.1.1 将场景分割成大小相同的cell
1.1.2 统计每个cell中的光子数目占比m
1.1.3 将m除以cell的体积作为整个cell中的所有点的光子密度
1.2 特点
1.2.1 缺点:密度函数不够平滑

2. 核函数估计
2.1 具体算法
2.1.1 设定一个估计范围
2.1.2 统计这个范围内的光子数据
2.1.3 为范围内的每个光子设定一个权重,权重与到当前像素的距离平方成反比, 这是与直方图估计的主要区别
2.1.4 光子数目占比需要考虑权重,最终依然需要除以体积作为光子密度
** 2.2 特点**
2.2.1 优点:相对于直方图估计而言,密度函数变得平滑

3. KNN(k近邻)估计
3.1 具体算法
3.1.1 以目标点为球心,选取最近的k个光子作为样本
3.1.2 求得k个光子的最小包围球的半径r
3.1.3 光子密度=k/(nV),k是光子数目,n是总的光子数目,V是包围球的体积
3.2 特点
3.2.1 缺点
3.2.1.1 光子数目较少,且r不是无穷小使得这个算法是有偏的,只有光子密度无穷高,r趋近于0,结果才是无偏的。r的存在会导致两种误差:boundary bias,物体边缘部分会存在偏差;topological bias,物体凹凸不平的区域会存在偏差。在使用不同的估算算法的时候,结果表现也有所不同:球面估计,通常是过估计,即过亮;碟形估计或者表面法向量约束,则会导致过暗。

直接使用photon map用于光照计算的特点为:

  1. 优点:计算效率高
  2. 缺点:内存消耗较高,存在低频误差,不适合用作直接光照输入数据

其结果如下图所示:

1.1.2.2.2 photon map作为间接光与焦散计算数据

因为photon map直接用于光照结果会存在低频误差等原因,因此后面通常会使用photon map作为间接光与焦散计算数据。

最终的光照计算会拆分成两条不同的计算路径:

  1. 光线追踪处理
  • 漫反射表面的直接光照
  • 镜面反射
  1. photon map处理
  • 漫反射表面的间接光照
  • 焦散光照

漫反射表面的间接光照中,由于photon分布比较稀疏,直接按照前面的非参数估计方法计算得到的结果精度较差,通常会采用final gathering(FG)算法来提升精度。

如下图所示,FG算法的实现逻辑是:

  1. 在屏幕空间创建一系列final gathering点,可以直接为每个像素分配一个
  2. 在每个FG点处,沿着法线朝着上半球面发射多条FG射线
  3. 每条射线与场景漫反射表面碰撞后,通过KNN算法求得碰撞点的光照亮度与颜色
  4. 将多条FG射线的采样结果进行平均
  5. 将多个FG点的计算结果进行平均

这个算法的特点有:

  1. 优点:可以使用较少的全局漫反射光子就能得到较好效果
  2. 缺点:耗时高,想要得到较好效果,需要生成数百条FG射线;不能消除boundary bias跟topological bias

焦散光照的计算这里就给出一个大概,后续有时间再来补充:photon map除了存储全局漫反射光子,还需要存储全局焦散光子(折射),这类光子的数量要较大,之后按照KNN算法进行直接光照计算,给出几张效果图:

原始的PM算法是有偏差的:

  • boundary bias
  • topological bias

表现为:

  • 灰暗的墙角
  • 错误的颜色辉映
  • 漏光

1.2 photon ray splatting算法

这个算法是07年由Herzog等人提出来,跟原始算法相比,相当于将思路反过来。

整个算法依然是分成两个pass,分别是eye tracing跟photon tracing。

在eye tracing pass中,先进行视觉空间的光线追踪,为屏幕空间的每个像素发射一条射线,每条射线与漫反射表面的交点通过KD-Tree记录下来。

在photon tracing pass中,光源发射多个光子,这里的光子是一个带有一定宽度的光子,宽度会决定后面碰撞过程中的覆盖范围,如下图所示:

每个光子在碰撞的过程中通过前面的KD-Tree检测周边一定范围内的eye sample,将光子对一定范围内的eye sample进行亮度与颜色叠加。

这个算法的优点是可以较好的解决前面的两种偏差(boundary bias,topological bias),缺点则是依然存在偏差(proximity bias),这个偏差需要发射大量光子才能消除,在splatting算法中由于不需要存储photon map,而eye sample是跟屏幕空间像素有关,通过KD-Tree是可以存储下来的。

1.3 Progressive Photon Mapping(PPM)算法

这个算法是08年由Hachisuka等人提出,相当于将splatting算法中的photon tracing进行多轮,每一轮使用不同的半径r(这里的r是指光子的检测范围吗?),每一轮都渲染出一张图片,随着轮数的增加,r也越变越小,光子数目越来越多(是多轮累积的结果,还是随着轮数增加光子数目也增多?),结果也越来越好。由于倒转了顺序,光子搜集算法又从KNN变换回了直方图,虽然KNN能够以较少光子得到较好效果,但是由于PPM算法中光子已经较多,这个优势已经不明显了,由于光子数目增多了,所以在PPM算法中甚至不需要消耗高昂的Final Gathering了。

其不足之处在于难以模拟反射模糊、运动模糊、DOF等效果,效果图给出如下:

1.4 Stochastic Progressive Photon Mapping(SPPM)算法

这个算法是09年由Hachisuka等人提出,与PPM的区别是,eye tracing也是多轮,相当于进行多次splatting算法,每轮eye tracing会对射线方向进行轻微扰动,实际上并不是真的对eye tracing进行多轮,而是在photon tracing之后对eye sample进行一下扰动,如下图所示:

这个算法的优点是鲁棒、健壮,在光滑反射的效果远好于PPM;缺点则是算法效率低于PPM。

1.5 正向SPPM算法

这个算法是11年由Claude Knaus等人提出,跟SPPM算法逻辑一致,不同的是不再如Splatting算法一样翻转原始Photon Mapping算法的实现逻辑,而是采用跟原始Photon Mapping算法一样的算法流程。

2. Photon Mapping算法的特点

Photon Mapping算法的优点有:

  • 容易模拟SDS(Specular-Diffuse-Specular)光线传播路径的效果,可用于模拟光线追踪难以实现的焦散现象
  • 相对于光线追踪的高频瑕疵,Photon Mapping算法所导致的瑕疵较为低频,不易察觉

其缺点则为统计上有偏算法,有偏算法是指期望值跟实际数值存在偏差的统计方法

参考

[1] photon mapping学习笔记
[2] 再谈光子映射
[3] Lightmass源码分析之 经典Photon Mapping算法介绍
[4] Lightmass分析(一) 光子映射(Photon Mapping)简介
[5] Photon Mapping
[6] Global Illumination using Photon Maps
[7] Photon Mapping
[8] Final Gathering

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容