PBRT-V3中是用3d grids来表示非均匀介质的。
一、非均匀介质的表示
之前做的笔记截图如下:
接下来关于“密度”和“sigma_t”的理解就是个人YY啦!
假设每个小正方体中最多可以装64个粒子。
那么,小正方体中保存的密度值=该小正方体中装的粒子数目/64。
比如,小正方体中只装了32个粒子,则对应的密度为0.5。
GridDensityMedium类中的成员变量sigma_t保存的是一个基准值。什么是“基准值”呢?即“光线打中粒子时,Medium对光线能量的衰减系数“。
比如:
假设某Medium中小正方体存放的密度值最大为0.75,当光线打中某个小正方体时,粒子被打中的最大概率为0.75。
那么,对应的sigma_t_max=sigma_t*0.75。
(举这个例子的原因是:后面需要用到sigma_t_max)
二、非均匀介质的采样
Woodcock提供了一种叫做“delta tracking ”的方法来对非均匀介质进行采样。示意图如下:
前面提到小正方体中不是没有装满粒子嘛?
delta tracking的第一步:将所有小正方体都“装满”粒子,将“非均匀介质”转换成“均匀介质”。
(如上图红色小球表示。)
后续则可以按照“均匀介质”的处理方式来处理。
只是要考虑一个概率问题。毕竟光线只有撞击到蓝色粒子时才是“有效”的,需要考虑的概率问题:就是光线撞击到某小正方体时,小正方体中蓝色粒子被撞击到的概率。
只要蓝色粒子被撞击到,就可当做“均匀介质”来处理:主要是求衰减系数beta_medium。
参考:Q129:PBRT-V3,均匀介质的采样(15.2.1章节)
而且,非均匀介质中是不考虑R、G、B各个方向的分量的,所以求解更为简单:
beta=beta_medium=sigma_s/sigma_t;
如果光线没有撞击到蓝色粒子,那么beta=beta_surface=1,即撞击点不在Medium中,在Surface上。
delta tracking接下来具体怎么做呢?
1,用一个bounding box将整个Medium包起来,光线撞击box得到两个点t_min、t_max。
2,对Medium进行采样,
从t_min开始,按照均匀介质中的标准指数步长进行采样。注意,这里的sigma_t_max=sigma_t*density_max。
假设desity_max=0.75,单个小正方体中最多可以装64个粒子。光线撞击到的某个小正方体对应的密度值是0.5,
此处如果使用的参数是sigma_t,那么该小正方体中粒子被撞击的概率=0.5;
此处如果使用过的参数是sigma_t_max(即sigma_t*0.75),那么该小正方体中粒子被撞击的概率=density/density_max=0.5/0.75;
3,对于每一采样点t_s,先得到对应的坐标点,然后根据坐标点计算得到其对应的小正方体,从而得到该小正方体的密度值,然后根据density_max计算得到该小正方体中粒子被撞击的概率p_s。
在程序中怎么实现某件事情可能发生可能不发生呢?怎么按照一定概率来执行某段代码呢?
引入一个0到1之间的随机数r。
如果p_s小于r,则执行某段代码;反之,不执行。
4,某粒子被撞中,此处即为有效采样点,即为撞击点,说明“采样点在Medium中”。保存此处的MediumInteraction信息。
5,反之,说明当前采样点t_s无效,继续迭代,产生新的采样点,重复“步骤3”。
6,若t_s>t_max,说明采样点已经离开Medium,说明撞击点不在Medium中(即在Surface上),返回beta=beta_surface=1。
相关代码截图:
三、非均匀介质的透明度(Transmittance)
关于透明度Tr的值:撞到蓝色粒子时,Tr=0;没有撞到蓝色粒子时,Tr=1。
前面我们已经知道撞到蓝色粒子的概率=被撞击的小正方体中的密度值density除以最大密度值density_max,即density/density_max。
那么,每次撞击小正方体(每次采样)时,对应的Tr的期望值E(Tr)=(density/density_max)*0+(1-density/density_max)*1=1-density/density_max
所以,非均匀介质最终的透明度等于介质所有采样点对应的透明度的期望值的累积(不用考虑是否撞击到蓝色粒子,计算的是透明度的期望值)。
因为E(Tr)=1-density/density_max<1,采样过程中,透明度Tr不断累乘,所以Tr的值会越来越小。
当小到某个阀值时,可以考虑用Russian Roulette终止采样。
相关代码截图如下: