Q91:真实地模拟透明材质(Realistic Transparency)

来源:互联网 发布:华硕超频软件 编辑:程序博客网 时间:2024/05/01 00:26

 

在“Q90”中,我们认为折射系数kt是一个常数,对应反射系数kr=1-kt。但是,实际情况则是:kt会因入射角的不同而变化。

 

这一章节,我们将真实地模拟透明材质。主要考虑两个问题:1,kt因入射角的不同而变化;2,透明材质对颜色的过滤

 

91.1 菲涅尔方程(The Fresnel Equations)

 

菲涅尔方程详细描述了“kt因入射角的不同而变化”的规律(注意,“菲涅尔方程”针对的是镜面反射和镜面折射)。

 






 

91.2 颜色过滤(Color Filtering)

 

当光线在介质中传播时,由于光线和介质中的分子相互作用,随着传播距离的增长,导致光线发生散射。如果这种散射和光线的波长相关,则介质会呈现相应的颜色。




当光线在介质中传播时,如下图:




 

光线在介质中的传播距离怎么求呢?

 

当光线进入介质时,即在撞击点处产生折射光线,我们要求的则是该折射光线在介质中的传播距离。这条折射光线撞击到物体的最小距离即为该光线在介质中传播的距离(如上图中的t1)。

 

当折射光线从介质内部撞击介质界面时,一方面会产生折射光线离开介质,另一方面则会产生反射光线。对于新产生的反射光线将继续在介质中传播,将继续衰减,这个传播距离怎么求呢?新的反射光线撞击到物体的最小距离即为该光线在介质中传播的距离(如上图中的r)。

 

91.3 C++代码实现

 

定义介质类“Dielectric


 

由上方类的定义,可以看出介质类对应着“菲涅尔反射模型”、“菲涅尔折射模型”,所以,接下来,我们需要定义这两个“模型”的类。

 

“菲涅尔反射模型”

 

主要代码如下:



 

 

“菲涅尔折射模型”

 

主要代码如下:



 

在定义好介质类及其对应的反射/折射模型,我们现在看看介质类的着色函数(Dielectric::shade())



 

Whitted::trace_ray()做一点点修改:

 


 

91.4 测试图形

 

相关测试代码:

 





 

输出图形:

 

91.4.1 对比测试Realistic Transparency图形、Simple Transparency图形

 

         dielectric_ptr->set_eta_in(1.6);

         dielectric_ptr->set_eta_out(1.0);

         dielectric_ptr->set_cf_in(1.0,1.0, 1.0);

         dielectric_ptr->set_cf_out(1.0,1.0, 1.0);

前边的是当前Realistic Transparency图形;后边的是之前Simple Transparency图形

  

(两张图形的差别貌似不明显,主要差异:参考Figure28.1,当入射角大于50度时,kr、kt会发生剧烈变化,而不是Simple Tranparency中那样还是保持常数。这个变化表现在介质球的轮廓附近的位置。)

 

 

         dielectric_ptr->set_eta_in(0.6);

         dielectric_ptr->set_eta_out(1.0);

         dielectric_ptr->set_cf_in(1.0,1.0, 1.0);

         dielectric_ptr->set_cf_out(1.0,1.0, 1.0);

前边的是当前Realistic Transparency图形;后边的是之前Simple Transparency图形

  

(两张图形的差别貌似不明显,主要差异:参考Figure28.2,当入射角大于30度小于41.8度时,kr、kt会发生剧烈变化,而不是Simple Tranparency中那样还是保持常数。这个变化表现在介质球刚好发射全反射时的附近位置。)

 

91.4.2 对比测试介质内外过滤颜色的图形

 

前边的是介质内部过滤颜色的图形;

         dielectric_ptr->set_eta_in(1.6);

         dielectric_ptr->set_eta_out(1.0);

         dielectric_ptr->set_cf_in(1.0,1.0, 0.0);

         dielectric_ptr->set_cf_out(1.0,1.0, 1.0);

 

后边的是介质外部过滤颜色的图形

         dielectric_ptr->set_eta_in(1.6);

         dielectric_ptr->set_eta_out(1.0);

         dielectric_ptr->set_cf_in(1.0,1.0, 1.0);

         dielectric_ptr->set_cf_out(1.0,1.0, 0.0);

   

但从这组测试来看:介质内部过滤颜色作用的是折射光线,介质外部过滤颜色作用的是反射光线。有折射光线是一定有反射光线;但是当入射角接近90度时,则接近镜面反射(只有反射光线没有折射光线)。这样一来,整体的反射光线则比折射光线多,所以介质外部过滤颜色作用的光线比介质内部过滤颜色作用的光线要多。“多的位置”即是“入射角接近90度的位置”(介质球轮廓位置)。所以,介质外部过滤颜色作用的介质球的轮廓要比介质内部过滤颜色作用的介质球的轮廓有更多的“黄色”。

 

 

前面这组测试图形“多的位置”并不明显,接下来,我们看看一组包含全反射的测试图形。

 

前边的是介质内部过滤颜色的图形;

         dielectric_ptr->set_eta_in(0.6);

         dielectric_ptr->set_eta_out(1.0);

         dielectric_ptr->set_cf_in(1.0,1.0, 0.0);

         dielectric_ptr->set_cf_out(1.0,1.0, 1.0);

 

后边的是介质外部过滤颜色的图形

         dielectric_ptr->set_eta_in(0.6);

         dielectric_ptr->set_eta_out(1.0);

         dielectric_ptr->set_cf_in(1.0,1.0, 1.0);

         dielectric_ptr->set_cf_out(1.0,1.0, 0.0);

 

  

在包含全反射的图形中,全反射部分的反射光线则全是介质外部过滤颜色作用“多出来的”。

  

91.5 其他说明

 

完整的代码,参考:http://download.csdn.net/detail/libing_zeng/9786258

 

Referrance

[1]. Kevin Suffern, Ray Tracing from theGround Up, A K Peters Ltd, 2007.


4 0