一、蒙特卡洛积分

蒙特卡洛积分主要解决的问题是当被积函数很难被以函数的形式表示时,需要对该被积函数指定概率密度函数并进行多次采样。然后用采样得到的局部面积除以局部采样点的概率来近似得到整体的面积(积分)。

当采样次数足够多时,将这些整体近似值除以采样次数,就能得到一个整体值得平局,则该整体值的平均就表示该积分的近似值。

可见,采样次数越多,最后得到的值越精确

二、蒙特卡洛路径追踪

https://blog.csdn.net/Master_Cui/article/details/119898277中,渲染方程的形式如下

但是问题在于,如何对该渲染方程的积分项进行求解呢?在这里,就用到了蒙特卡洛积分

先只考虑直接光照,表示如下图所示,积分项一共有三个,所以,fx就是入射radiance*brdf*n.wi

再看下图,假设入射光线的概率密度函数服从均匀分布,因此,就可以从单位半球上的任意一点入射,因此,任意一点的概率就是1/2π,2π是单位半球的面积

所以,概率密度函数就是

因此,在只考虑直接光照的情况下,原始的积分项就可以写成

伪代码如下

考虑完直接光照后,再考虑间接光照(弹射),该如何计算Q点反射出能radiance呢

Q点本身是直接接受光照,反射出来的光线自然就是和上述的直接光照相同,只不过,Q点反射出来的光线需要再被当做入射光线,因此,这是个递归的过程,伪代码如下

至此,通过蒙特卡洛积分算出了全局光照,但是还是有两个小问题

第一个问题是光线随着反射次数的增多会出现指数级的增长

考虑下图,比如从一百个方向进行采样,最终进入相机的光线只有一个,但是,如果这100个光线是经过了一次反射之后得到的,那么,这100个光线中的每个光线也要采样100次,那么也就是说,此时场景中需要有10000个光线,随着反射次数增多,场景中的光线就会出现指数级别的增长,对渲染速率有消耗

解决这个问题的办法就是每次只在一个方向上进行采样,因此,伪代码需要进行如下修改

但是,由于只进行一次采样,随机性太大,效果必然不好,那么就可以进行对多条路径分别采样求平均即可,如下图

因此,伪代码再次进行修改

这样就解决了采样方向过多而导致的光线数量指数级增长的问题

第二个问题是上述递归没有退出条件,这个退出条件该如何写呢,这里借助了概率的思想。假设光线会出现反射的概率为P,那么,当光线相机接收到该光线时的Radiance就是L0/P,光线如果不仅进入相机的概率就是1-P,那么相应的radiance自然就是0。这样做之所以可行是因为整体的radiance期望L是不变的

因此,伪代码也需要进行进一步修改

到目前为止,蒙特卡洛光追算法基本OK,但是还有个小问题,就是有一部分光线被浪费了,导致效率不高

如下图所示,当对光线进行采样时,如果光源很大,那么能保证该光源发出的很多光线都被采样到,但是如果光源很小,那么,光源发出中的光可能只有极个别会被采样到,那么,光源中的其他光线就没法被采样到,这就导致光源的光线会被浪费。

因此,如果可以对光源的单位面积进行积分,那就可以解决光源光线浪费的问题。当前是对半球的单位立体角积分,所以,就需要找到半球单位立体角和光源单位面积的关系。

从而可以对积分变量进行换元。

因为单位立体角等于单位面积除以半径的平方,可以,先计算出把dA的方向调整到与dw一致,调整后,dA调整后的值是dA*cosθ,最后在除以两点距离的平方,就能得到dA与dw的关系,如下

这样,反射方程和蒙特卡洛积分就可以写成如下形式

至此,伪代码进一步修改

如果需要判断光线和反射点中间是否有物体遮挡,可以从光源发出一条光线,判断是否和物体相交即可

最后放一张蒙特卡洛路径追踪和真实照片的对比

几乎一毛一样

参考

GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

19、计算机图形学——蒙特卡洛路径追踪相关推荐

  1. 计算机图形学【GAMES-101】9、蒙特卡洛路径追踪(Path Tracing)(光源采样)

    快速跳转: 1.矩阵变换原理Transform(旋转.位移.缩放.正交投影.透视投影) 2.光栅化(反走样.傅里叶变换.卷积) 3.着色计算(深度缓存.着色模型.着色频率) 4.纹理映射(重心坐标插值 ...

  2. 计算机图形学十五:基于物理的渲染(蒙特卡洛路径追踪)

    蒙特卡洛路径追踪 摘要 1 蒙特卡洛积分(Monte Carlo Integration) 2 蒙特卡洛路径追踪(Monte Carlo Path Tracing) Reference (本篇文章同步 ...

  3. 光线追踪渲染实战:蒙特卡洛路径追踪及其c++实现

    项目代码仓库: GitHub:https://github.com/AKGWSB/EzRT gitee:https://gitee.com/AKGWSB/EzRT 目录 写在前面 光线追踪简介 渲染方 ...

  4. 【学习日志】2022.08.19 计算机图形学、OpenGL、疼迅云游戏引擎面试、GLAD、GLFW、virtual

    计算机图形学知识图谱 .学习路线 OpenGL 概述 简介 - LearnOpenGL CN (learnopengl-cn.github.io) 当前比较流行的搭配是 freeglut + glew ...

  5. 计算机图形学【GAMES-101】11、渲染前沿技术介绍(双向路径追踪BDPT、MLT、光子映射、实时辐射度、外观建模)

    快速跳转: 1.矩阵变换原理Transform(旋转.位移.缩放.正交投影.透视投影) 2.光栅化(反走样.傅里叶变换.卷积) 3.着色计算(深度缓存.着色模型.着色频率) 4.纹理映射(重心坐标插值 ...

  6. 计算机图形学(光线追踪)

    笔记:光线追踪 Why Ray Tracing? Ray-Tracing Algorithm(光线追踪算法) Basic Ray-Tracing Algorithm Whitted-Style Ray ...

  7. 计算机图形学【GAMES-101】13、光场、颜色与感知

    快速跳转: 1.矩阵变换原理Transform(旋转.位移.缩放.正交投影.透视投影) 2.光栅化(反走样.傅里叶变换.卷积) 3.着色计算(深度缓存.着色模型.着色频率) 4.纹理映射(重心坐标插值 ...

  8. 计算机图形学【GAMES-101】14、动画(物理模拟、质点弹簧系统、粒子系统、运动学、动作捕捉、欧拉方法)

    快速跳转: 1.矩阵变换原理Transform(旋转.位移.缩放.正交投影.透视投影) 2.光栅化(反走样.傅里叶变换.卷积) 3.着色计算(深度缓存.着色模型.着色频率) 4.纹理映射(重心坐标插值 ...

  9. 计算机图形学【GAMES-101】8、辐射度量学与光线追踪

    快速跳转: 1.矩阵变换原理Transform(旋转.位移.缩放.正交投影.透视投影) 2.光栅化(反走样.傅里叶变换.卷积) 3.着色计算(深度缓存.着色模型.着色频率) 4.纹理映射(重心坐标插值 ...

最新文章

  1. selenium 常用操作
  2. openstack网络服务neutron
  3. des vue 双倍长 解密_[转]单倍长密钥加密和双倍长密钥加密,银联直联终端62域难点详解...
  4. CF A. DZY Loves Hash
  5. 白嫖我常用的 11 个超火的前端必备在线工具,终于有时间上班摸鱼了
  6. Git命令,合并分支到master,并提交远程仓库,将本地分支推送到远程仓库
  7. PHP 销毁指定目录
  8. jzoj3054-祖孙询问【LCA】
  9. create react app创建的项目运行test的时候不能解析webpack的alisa配置的问题
  10. throws Exception的意思
  11. spine 2.1.27 Pro 叠加方式(Blending)
  12. 为什么强烈推荐你使用单表查询?(续篇)
  13. (一) 开天辟地入门篇(mvc)
  14. TSAP(1) : DateTimes
  15. CAD技巧—教你快速查看CAD文件信息和文件版本
  16. strapi v4,调用用户注册接口时出现“Email is already take“的解决方法
  17. sub eax, _PAGESIZE; decrease by PAGESIZE test dword ptr [eax],eax ; probe page
  18. Java应用性能分析工具:async-profiler(配合FlameGraph生成火焰图)
  19. C++字符串赋值、拼接、查找、替换、存取、插入删除和子串
  20. 最通俗的理解什么是冒泡

热门文章

  1. jps could not synchronize with target
  2. Android 之 Fagment 完全解析
  3. Foreach与Random
  4. 删除某个文件夹下的所有文件
  5. Java记录 -22- Java的基类Object详解
  6. Android中Google Drive显示黑屏问题分析
  7. linux下mv命令移动目录的二种情况
  8. Linux下的摄影后期处理软件
  9. 批量获取成员机管理员组用户信息
  10. pandas数据清洗