“体渲染”积分器是在“路径追踪”积分器的基础上考虑了场景中的介质,相当于是对“路径追踪”积分器的拓展。
所以,在学习“体渲染”积分器之前,得有“路径追踪”积分器的基础。参考:
Q124:PBRT-V3,“路径追踪”积分器(14.5章节)

一、那张关键的图

在学习“体渲染”时,一直感觉云里雾里。突然发现,理解“体渲染”积分器的关键竟然是这张图:

对应的方程:

上图和方程描述的是:
一条光线从p点出发,在某Medium中向前延伸,经过一段距离t和场景中的某Surface相交于p0点。

方程中参数解释如下:

p可以是Camera上的点,也可以是Medium或者Surface上的点。
若光线没有和场景中的任何Surface相交,则t=infinity()(无穷大)。
Lo(p0, -w)是交点p0处反射光线的辐射率。若没有交点,Lo(p0, -w)=0。
Tr(p0->p)表示能量从p0传播到p的传播率(即,衰减之后剩余的比例)。
Tr(p0->p)Lo(p0, -w)则表示:p0点反射的能量经过介质的衰减后,最终到达p点的能量。
p’表示光线上p点和p0点之间的任意位置,p’到p0的距离为t’(0 < t’ < t)。明显p’是在介质中。
Ls(p’, -w)表示在p’处的-w方向进入介质的能量(这个能量可能来自“自身发射的能量”和“直接光照”)。
Tr(p’->p)表示能量从p’传播到p的传播率(即,从p’点进入介质的能量经过介质的衰减后传到p点时剩余的比例)。
。光线上p’点到p点之间的任意位置都有能量从-w方向进入介质的,然后衰减,然后传到p点。所以,这个积分式子表示,p’点到p点之间所有位置从-w方向进入介质的能量经过衰减后到达p点的能量的总和。
Li(p,w)表示返回到p点能量。这个能量有两个来源:来自介质中进入的能量、来自交点p0反射的能量。

怎么求解Li(p, w)呢?
当然是用Monte Carlo方法来解这个积分方程。

设:f(s)表示光线上[p,p0]之间任意位置进入的经过衰减后返回到p点的能量。那么,

Monte Carlo方法当然是“采样、累加、求平均”啦!即:

现在需要求采样点sj对应的f(sj)和p(sj)。
分两种情况:

1,采样点在Medium中,0 < sj < t。
设该介质在w方向上是均匀的,设在介质中离p点单位距离被采样到的概率为p_medium(t’),那么:

另外,

2,采样点在Surface上,sj = t(或者说sj >= t。因为是沿着光线采样,先判断采样点是否在Medium中。若不在Medium中,则在Surface上)。

这个采样具体怎么执行呢?
一般是对图片上单像素点进行N采样,每次采样对应一条光线(即,会有N条光线从p点出来),然后产生一个[0,1]之间的随机数sui,那么sj=sui*t,然后判断sj的位置是在Medium中还是Surface上,然后计算相应的p(sj)和f(sj)。
至于“累加,求平均”,单像素点的采样计算会cover到。

另外:

程序实现上,会根据sj的位置计算出一个衰减系数beta(beta_medium或者beta_surface)。
由于f(sj)的不同,计算beta_medium和beta_surface的方式也是有差异的。

特别注意:

beta_medium表示直接光照进入介质后的衰减情况。

beta_surface表示Surface反射的光线进入介质后的衰减情况。所以,这种情况下总的衰减系数要在beta_surface的基础上再乘以直接光照和Surface相互作用时产生的衰减系数。

二、构建“体渲染”积分器的路径

1,光线从相机p0(为了便于描述路径,此处标记为p0,相当于“一、那张关键的图”中的p)出发,这条光线可能和场景中的几何物体发生撞击,也可能不发生撞击。考虑这两种情况:情况1,有交点,对应一个ray.tmax(即撞击点到光线起点的距离t);情况2,没有交点,ray.tmax还是初始值infinity()。
2,在含Medium的场景中沿着这条光线进行采样,采样点对应着一个t=sj。若sj小于ray.tmax,则采样点在Medium中;反之,采样点在Surface上。(注意到,如果“步骤1”中是“没有交点”的情况,则采样点必定在Medium中)。这个采样点就是p1(相当于“一、那张关键的图”中的p)。
3,若p1在surface上,情况则和“路径追踪”积分器是一样的,即:对p1点的BSDF1进行采样,得到一个方向wi1。若p1在medium中,则对p1点的Phase1进行采样,得到一个方向wi1。
4,新的光线从p1点沿着wi1出发……(重复“步骤1”,然后得到采样点p2、…、pn)

和“路径追踪”积分器一样,最终会得到这么一张路径图:

或者:

“体渲染”积分器和“路径追踪”积分器差异的地方:
“路径追踪”积分器中的p1、p2、……p(n-1)都是光线撞击Surface得到的,p1、p2、……p(n-1)在Surface上;
“体渲染”积分器中的p1、p2、……p(n-1)都是沿着光线采样得到的,p1、p2、……p(n-1)可能是在Medium中,也可能是在Surface上。

三、单一路径上返回到相机的光的计算

“路径追踪”积分器的做法是:
长度为i的路径上返回到相机的光的计算式子:

对于“体渲染”积分器,长度为i的路径上返回到相机的光的计算是类似的。
即:长度为i-1的路径上累积的衰减系数*第i-1个顶点上的直接光照的贡献。

差异的地方在于:
1,直接光照从光源到第i-1个顶点的过程也会因为Medium的存在而产生衰减(这个在EstimateDirect()是考虑);
2,系数累积:若第i-1个顶点在Medium中,无需对直接光照和该顶点的相互作用的衰减进行累积,因为beta_medium包含这个衰减;若第i-1个顶点在Surface上,需要累积直接光照和该顶点相互作用产生的衰减。

四、“体渲染”积分器的细节部分

通过前面的内容,对“体渲染”积分器有了大体的理解。
但是,并未涉及具体细节。比如:

1,光线在Medium中的散射过程、散射类型。
2,光线在不同Medium传播时,衰减系数Tr的具体计算。
3,直接光照进入Medium时在某个方向上的衰减情况,对应Phase函数的计算。
4,怎么对Medium进行采样(获得采样点之后,再能进一步判断采样点是在Medium中还是在Surface上)?不同的类型的Medium采样方式是不一样的。(Homogeneous Medium(均匀介质), Grid Medium(非均匀介质))
5,怎么对Phase函数进行采样(即,当某个顶点在Medium时,接下来光线应该往哪个方向传呢?这个方向有Phase函数决定)
……

还有各种细节需要学习。

但是,重点,
如果对“体渲染”积分器没有整体的理解,一开始就学习各种细节的话,那么非常容易、特别有可能直接陷入各种细节中。
然后,迷迷糊糊,云里雾里:不知道讲的是什么;不知道讲这个有什么用;只认识字(还多单词还不认识),不知道具体讲什么;……

Q127:PBRT-V3,理解“体渲染”积分器的关键竟然是这张图相关推荐

  1. Q128:PBRT-V3,“体渲染”积分器的“传播方程”(15.1章节)

    对比"路径追踪"积分器和"体渲染"积分器中长度为n的路径上返回的光的计算:

  2. GPU Gems1 - 9 有效的阴影体渲染

    这章全面讲述了用于实时阴影渲染中常见两种流派之一的阴影体(Shadow Volumes)技术,又称模板阴影(Stencil Shadows)技术,重点是得到正确的角度的情形,减少几何图形和填充率的消耗 ...

  3. [译]基于GPU的体渲染高级技术之raycasting算法

    [译]基于GPU的体渲染高级技术之raycasting算法 PS:我决定翻译一下<Advanced Illumination Techniques for GPU-Based Volume Ra ...

  4. Q126:PBRT-V3,VolPathIntegrator(体渲染)流程概述

    最近在学体渲染,老实说,挺费劲的! Medium的原理.采样.对应的光传播函数.VolPathIntegrator的实现等等,都已经过了一遍. 现总结一下初浅的理解吧. VolPathIntegrat ...

  5. 全局体渲染光照技术总结概括(截止到2014年)

    我打算尽可能详细整理一下体渲染的光照算法,从一篇比较详细的综述入手,里面的内容会根据需要进行展开. 目录 目录 1-材料散射 2-算法的分类 3-算法描述 3-1-基于局部区域的技术 3-1-1 基于 ...

  6. ThreeJS 中体渲染,利用噪声模拟烟,云

    ThreeJS 中体渲染,利用噪声模拟烟,云 体渲染的东西也看了一段时间了,这里结合Three.js中体积云的例子,实现shdertoy中的一个效果,先放效果图. Fire2 (shadertoy.c ...

  7. Cesium中实现体渲染

    体渲染 Volume Rendering 传统意义上我们构建模型都是通过构建物体的外表面去实现的,例如通过三角面构建模型,或者通过方程的形式构建隐式的表面模型. 而体渲染则是通过 3d 数据集渲染物体 ...

  8. 2018年 IEEE VIS 科学可视化与体渲染论文整理与分析

    因为最近工作的关系,需要研究一下IEEE VIS中2017年以后的与我之前主要方向(体渲染.医学可视化)有关的论文.我把这些年全部的论文进行了筛选和梳理,总共筛选出57篇论文,打算写一个文章来记录这些 ...

  9. 用体渲染的方法在Unity中渲染云(18/4/4更新)

    github: https://github.com/yangrc1234/VolumeCloud 更新的内容在底部 最近在知乎上看到一篇文章讲云层的渲染(https://zhuanlan.zhihu ...

最新文章

  1. 【题解】P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper
  2. 如何不能保证每次都请求成功
  3. java中this.value_java中关键字this的用法
  4. 关于JAVA并发编程你需要知道的——硬件篇
  5. java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍
  6. logging.getLogger(logger)
  7. java文件编译为class文件需要键入什么命令_cmd命令行 编译Java 文件
  8. android 全局定时器,高通Android LED驱动移植-GPIO,内核定时器
  9. 营口(熊岳)温泉旅游归来!
  10. iOS开发中设置UITextField的占位文字的颜色,和光标的颜色
  11. Auto.js抓取移动端数据实战
  12. cad会提示计算机中缺少,cad2014缺少shx文件该怎么解决?
  13. docker安装镜像
  14. 双系统卸载ubuntu
  15. 欧姆龙OMRON PLC之Host Link协议(一)
  16. python爬取豆瓣top250电影名称_Python--爬取豆瓣TOP250电影信息
  17. 2019牛客暑期多校训练营(第三场)----C-Guessing ETT
  18. 小程序开发笔记(二):微信小程序富文本编辑器editor的使用
  19. 写QT串口通信的UI界面时,数据输入文本框为什么要有文本(字符串)发送和十六进制发送?
  20. “掌上迎新”,这个学校把5400+新生安排的明明白白

热门文章

  1. Geant4在Ubuntu下的安装教程
  2. 图论 - 寻找fly真迹
  3. Codeigniter开发技巧:连接多个数据库(可实现DB读写分离)
  4. 如何在20130513image上,备份NAND到SD卡,然后把这个SD卡做成可以自启动的SD卡
  5. 【DP + 卖股票】LeetCode 123. Best Time to Buy and Sell Stock III
  6. 【链表递归构造二叉树】LeetCode 109. Convert Sorted List to Binary Search Tree
  7. 关于马克飞象中的Latex语法与CSDN中的区别
  8. javaweb基础----使用ajax校验用户名是否重复
  9. Spring 4 官方文档学习 Spring与Java EE技术的集成
  10. struts1(转)