我们知道离开Volume时候的光照亮度
Lo=Li*T+∫T*(Le(p,w)+σs(p,w)*∫p(w1,w)*L(w1)*dw1)*dt
其中T=exp(-∫(σs(p,w)+σa(p,w))*dt).
我们注意到公式中的In-Scattering部分
∫σs(p,w)*∫p(w1,w)*L(w1)*dw1)*dt
这里有两次积分过程。第一次是计算四周的光线散射到视线方向,第二次积分是对光线传播途中进行积分。我们知道第一次积分的时候的四周的光线其实也是多次散射的结果,我们这里适当的简化,我们假设我们在
第一次积分的时候只考虑直接照射的光线经过吸收和Out-Scattering后剩余的亮度,而不考虑散射来的光线亮度。这样就可以得到简化后的In-Scattering部分
∫σs(p,w)*∫p(w1,w)*L1(w1)*dw1)*dt //L1(w1)代表w1方向的只考虑吸收和Out-Scattering过程光线亮度
我们知道只考虑吸收和Out-Scattering的时侯 L1(w1)=Ls*Ts(w1),这里Ls表示光源的直接照射,Ts(w1)代表光线到达散射微粒的吸收和Out-Scattering过程。于是In-Scattering部分为
∫σs(p,w)*∫p(w1,w)*Ts(w1)*Ls(w1)*dw1)*dt
我们观察内部的对于球形的积分,我们的积分空间是以微粒为中心所在的球。那么我们对于这个积分可以使用SH来解开成为dot操作。我们将积分号内部分成两个部分,p(w1,w)*Ts(w1)和Ls(w1)。我们假设整个微粒所在的Volume对于环境来说很小,那么每一个微粒的Ls(w1)都是一样的,不同的就是在p(w1,w)*Ts(w1)部分。我们将这两个部分投影到SH上面可以分别得到系数。对于每一个微粒来说他们的Ls(w1)的系数是一样的,p(w1,w)*Ts(w1)的系数是不一样的,而且对于每一个w都有一组不一样的系数。我们可以把对于不同的w的系数保存在cube map中以备查找。这样我们碰到一个问题,就是每个微粒都有cube map,这样的结构对于硬件是不友好的。我们只能继续简化我们的操作。我们将上面提到的Ts(w1)忽略掉,那么对于所有的微粒就可以用同样的cube map来保存了(可能会需要多张,因为精度的需要)。
我们在下来看看最外面的积分,我们首先假设σs(p,w)在传播途中是恒量。我们可以使用蒙特卡罗积分法来近似的计算这个积分,我们取视线穿过Volume的两头的作为我们的采样,那么我们只需要计算出这两点微粒的结果和/2就可以得到近似值了。
通过上面的操作,我们有了对于微粒的N组系数(p(w1,w)投影得到)Ti(w)保存在cube map中,靠w也就是视线的方向来获取。同时还有周围环境的一组Ls(w1)的系数Li。我们通过一些技巧还能获得视线方向的Volume深度d.那么计算的时候我们首先渲染一边Volume到Texture,这次渲染我们把Volume的前面和后面的Ti(w)相加。接下来我们把这个相加得到的值和环境的Li作dot操作。并乘上σs*d/2得到了In-Scattering的结果。
最后把视线方向的吸收,Out-Scattering和上面计算得到的In-Scattering加起来就能得到我们所需的近似值了。
还没有实践不知道最终的效果会是怎么样的。