蒙特卡洛光线追踪 计算机图形学冬季作业

每日在实验室学(hua)习(shui),不知不觉图形学作业要交了。虽然不会做,但是要交作业,还是得逼一把自己,在实验室博士师姐热心的帮我要了博士师兄的作业后,我满怀期待的打开,一脸失望的退出。okkkkkkk ! 不过是光线追踪而已,我自己做就好,周日不休息也并不是不能接受的嘛~微笑脸,在此感谢师姐师兄以及在网上写博客的各位大佬,感谢你们的帮助!

【转】参考博客链接 https://blog.csdn.net/sunacmer/article/details/7451861

【转】MonteCarloPathTracing的参考代码链接 https://github.com/ybbbbt/MonteCarloPathTracing

光线追踪的原理

  • 光的基本传递模型

    1. 在计算机图形学中,我们要渲染一个场景,我们要渲染一个场景,假定有一个指定的光源,我们用它发出的光线来描述光能的传递过程,当整个场景中的光能信息被我们计算出来后,我们收集这些信息转化为像素点的亮度和颜色。
    2. 光线在物体表面经过会发生反射和漫发射,光线透过物体会发生折射和散射。具体产生哪种效果由物体的表面属性来定,表面可以同时存在反射,折射,漫反射等多种属性,各种属性按一定比例混合之后才是其表面反射模型。
    3. 一点的在某一个视线方向上的光亮度=该点在该方向的自身发光亮度+半球入射光能在该方向所产生的反射光亮度
    4. 关于散射,高度真实的散射是一个很难模拟的物理过程,一般在渲染中都不会采用过于复杂的物理模型来表示散射,而是采用一些取巧的办法来计算散射。
    5. 在常见的渲染中,有两种效果很难模拟,但是它们会使人眼觉得场景更真实。
      1. color bleeding :入射光为漫反射,受光表面属性为漫反射,出射光是漫反射。比如把一本蓝色的纸制的书靠近白色的墙,墙上会有浅浅的蓝晕。
      2. caustics:入射光为镜面反射或折射,受光表面属性为漫反射,出射光是漫反射。比如把一个装了红色葡萄酒的酒杯放在木桌上面,会有光透过杯中的酒在桌上形成一块很亮的红色区域。 
  • 传统的逆向光线追踪

    1. 正向光线追踪(从光源出发,正向跟踪每一根光线在场景中的传递过程,然后收集信息)的缺陷:计算了大量对当前屏幕颜色不产生贡献的信息,而且它把看不见的物体也计算在内,极大的浪费了效率。
    2. 逆向光线追踪:从视点(人眼)出发,向投影屏幕发出光线,然后追踪这个光线的传递过程。如果这个光线经过若干次反射折射后打到了光源上,则认为该光线是有用的,递归的计算颜色,否则就抛弃它。很显然,这个过程是真实光线投射的逆过程,它同样会产生浪费(那些被抛弃的逆向光线),而且只适用于静态渲染(视点发生变化就要重新进行计算)。 但是效率提高了,因为只计算对人眼有用的光线,看不见的光线不计算了。
    3. 逆向光线追踪算法像素点的亮度来自于:
      1. 由光源直接照射而引起的光亮度 (即从视点到一个像素的光线直接射到光源上)
      2. 来自环境中其它景物的反射折射光在表面产生的镜面反射光亮度 (即从视点到一个像素的光线与景物相交经过反射折射回到了光源)
      3. 来自环境中其它景物的反射折射光在表面产生的规则透射光亮度 (都是逆向的过程)
      4. 预设定的像素点漫反射颜色
    4. 逆向光线追踪的算法描述
      1. 从视点出发,经过投影屏幕上的每一个像素向场景发射一根虚拟的光线。 
      2. 求光线与场景最近的交点。 
      3. 递归跟踪: 
        1. 如果当前交点所在的景物表面为理想镜面,光线沿其镜面反射方向继续跟踪。 
        2. 如果当前交点所在的景物表面为规则投射表面,光线沿其规则投射方向继续跟踪。 
      4. 递归异常结束: 
        1. 光线与场景中的景物没有交点 
        2. 当前交点所在的景物表面为漫反射表面 
        3. 跟踪层次已经超过用户设定的最大跟踪层数 
        4. 所跟踪的光线对显示像素的光亮度的贡献小于一预先设定的阀值 
      5. 递归正常结束: 光线于光源相交,取得光亮度值,按递归层次反馈。 蒙特卡洛光线追踪 计算机图形学冬季作业_第1张图片
    5. 光线追踪的效率问题:要把大量的光线与景物求交,如何避免无谓的求交计算是提升算法效率的关键。早期的光线追踪算法都是通过各种空间划分技术来避免无谓的求交检测,这些方法对于之后的理论同样有效,常见的空间划分方法分为两类:
      1. 基于网格的平均空间划分,
      2. 基于轴平行的二分空间划分。 
  • 蒙特卡洛光线追踪

    1. 对传统的逆向光线追踪的改进传统的逆向光线追踪算法有两个突出的缺点,就是表面属性的单一,和不考虑漫反射。我们不难通过模型的修正来缓解这两个问题。我们首先认为一个表面的属性可以是混合的,比如它有20%的成分是反射,30%的成分是折射,50%的成分是漫反射。这里的百分比可以这样理解,当一根光线打在该表面后,它有20%的概率发生反射,30%的概率发生折射,50%的概率发生漫反射。然后我们通过多次计算光线跟踪,每次按照概率决定光线的反射属性,这样在就把漫反射也考虑了进去。具体的算法如下:
      1. 从视点出发,经过投影屏幕上的每一个像素向场景发射一根虚拟的光线。
      2. 当光线与景物相交时按照俄罗斯轮盘赌规则决定他的反射属性。 
      3. 根据不同的反射属性继续跟踪计算,直到正常结束或者异常结束。如果反射的属性为漫反射,则随机选择一个反射方向进行跟踪。 
      4. 重复前面的过程,把每次渲染出来的贴图逐像素叠加混合,直到渲染出的结果达到满意程度。 
    2. 蒙特卡罗光线追踪也需要使用空间划分技术来提高算法的效率,最常用的是平衡kdtree。

蒙特卡洛光线追踪作业的实现

参考上面的github仓库,比我写的好多了

 

 

你可能感兴趣的:(c,cpp)