【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-6 直接光源采样
Chapter7 Sample Lights Directly
Preface
今天我们来讲这个还算牛逼的技术——直接光源采样
之前我们提到过,在2-7

前两篇我们也提到要减少噪点,就是图片上的黑点点,所以,所有的矛头都指向了这一篇。
简单说一下为什么会有那么多小点点,就是因为光线路径中没有触碰到光源,路径计算之后就会是黑色的点,可以通过发射大量的光线,比如计算每个像素点的时候发射8k~1w条采样光线进行路径计算;也可以路径计算方面做文章,比如加深路径计算递归深度;等等诸如此类。但是上述方法都是暴力解决法,相当耗时,我们可以运用数学对其进行优化,从而实现画质和效率的双面提升,这就是我们今天要讲的——直接光源采样!
Ready
可能您需要以下基础:
1.微分
2.立体角 (蒙特卡罗(三))
没了,剩下全靠想象
content
简明扼要。
我们朝光源方向发送光线或者生成朝向光源的随机方向都是很容易实现的,但是我们需要知道的是,pdf(direction)是什么呢?
引用书上一张图:

对于一个光源区域A,如果我们均匀采样该区域,那么这个pdf就等于1/A,意思就是每个点的概率均等
但是和我们的单位球体结合在一起的话,就比较麻烦了,见上图
?为什么老是提到单位球体呢??
因为我们的光线和物体表面的交点,会作为下一个eye,然后新的视线方向是表面单位球随机产生的方向,具体见1-5中的diagram7-3

好了,渊源就是酱紫,我们继续
如果那个小的微分区域dA的采样概率为
p_q(q)*dA(采样比例乘以微分区域),也就是dA/A
而对应到单位球体表面的很小的区域,即我们所述的方位角。方位角微分dΩ对应的采样概率为
p(direction)*dΩ
这里有一个用来描述dΩ 和 dA 的表达式:
dΩ = dA cosα / (distance(p,q)^2)
即:方位角微分区域:光源微分区域分成(球心到A中心距离平方)份,取其中的cosα代表的份额数
因为这个dA 和 dΩ的概率是相同的,所以就有如下等式
p(direction) * cosα * dA / (distance(p,q)^2) = p_q(q) * dA = dA / A
所以
p(direction) = distance(p,q)^2 / (cosα * A)
我们接下来就检验一下这个数学公式是否正确
但是代码可能非常丑
我们需要之前的光源的区域参数
list[cnt++] = new xz_rect(, , , , , light);
所以我们有以下的代码
rtvec lerp(const ray& sight, intersect* world, int depth)
{
hitInfo info;
if (world->hit(sight, (rtvar)0.001, rtInf(), info))
{
ray scattered;
rtvec emitted = info._materialp->emitted(info._u, info._v, info._p);
rtvar pdf;
rtvec albedo;
if (depth < && info._materialp->scatter(sight, info, albedo, scattered, pdf))
{
rtvec on_light = rtvec( + lvgm::rand01() * ( - ), , + lvgm::rand01() * ( - ));
rtvec to_light = on_light - info._p;
double distance_squared = to_light.squar();
to_light.self_unitization();
if (dot(to_light, info._n) < )
return emitted;
double light_area = ( - )*( - );
double light_cosine = fabs(to_light.y());
if (light_cosine < 1e-)
return emitted;
pdf = distance_squared / (light_cosine*light_area);
scattered = ray(info._p, to_light, sight.time());
return emitted + albedo *info._materialp->scatter_pdf(sight, info, scattered)*lerp(scattered, world, depth + ) / pdf;
}
else
return emitted;
}
else
return rtvec();
}
如下图:

因为我们一路做测试,做图形分析对比,所以我们上图是sample为250时候的效果
据说,sample为10时,效果依旧很好
所以又超快速运行了一个sample为10的

不管怎样,我们的图形噪点已经做到了比较不错的境地了,sample为10!!!
再看看之前的sample为250的图形效果

简直噪出天际线
关于本篇的那个图
天花板上灯光周围的噪声是由于灯光是双面的,灯光和天花板之间有一个狭窄空间。
我们可以通过将灯光法向量调至垂直向下来解决这一问题,同时让我们的灯光发射函数也做相应的处理
virtual rtvec emitted(const ray& rIn, const hitInfo& info, const rtvar u, rtvar v, const rtvec& p)const
{
if(dot(info._n,rIn.direction())<.)
return _emit->value(u, v, p);
else
return rtvec();
}
记得一起改了material基类,以及lerp的emit函数调用根据上述参数描述
所以我们又得到了一个sample为10的新图

没什么大的变化
只是灯光周围的噪点少了,解释:
因为灯光的法向量垂直向下,而我们的反射光线与反射之后与法向量的夹角为锐角的时候才进行纹理计算
而来自屋顶上面的光线与灯光区域碰撞反射的方向与法向量呈钝角(注意是反射之后的新方向不是入射光方向)则不计算返回黑色,默认光无法到达
感谢您的阅读,生活愉快~
【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-6 直接光源采样的更多相关文章
- 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-7 混合概率密度
Preface 注:鉴于很多网站随意爬取数据,可能导致内容残缺以及引用失效等问题,影响阅读,请认准原创网址: https://www.cnblogs.com/lv-anchoret/category ...
- 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-5 random direction & ONB
Preface 往后看了几章,对这本书有了新的理解 上一篇,我们第一次尝试把MC积分运用到了Lambertian材质中,当然,第一次尝试是失败的,作者发现它的渲染效果和现实有些出入,所以结尾处声明要 ...
- 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-4 基于重要性采样的材质初探
Preface 我们今天来把第三本书从开局到现在讲的一大堆理论运用到我们的框架中,那么今天我们首先将原始的材质改为基于重要性采样原理的材质 这一篇是代码工程中进行MC理论应用的初步尝试篇 Read ...
- 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-3 蒙特卡罗 (三)
开学人倍忙,趁着第二周周末,我们继续图形相关的博客 Preface 今天我们来介绍一些理论方面的东西,为Monte Carlo 应用到我们的光线追踪器做铺垫 我们今天会介绍两章的东西,因为有一章内容 ...
- 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-2 蒙特卡罗(二) 重要性采样
书本内容:见相册 preface 还记的我们上一篇说的Monte Carlo 维度诅咒吗 上一篇算是二维的例子吧,大家看了之后是否想着写一个一维的Monte Carlo模拟积分?(我想了,没写出来) ...
- 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-1 蒙特卡罗 (一)
今天起,我们就开始学习第三本书了 这本书主要讲的是蒙特卡罗渲染,以及相关的数学.术语概念等 这本书相较于前面两本有着什么不同,承担着什么样的任务,尚涉书未深,姑妄言之: 第一本书,带领我们初探光线追踪 ...
- html5的float属性超详解(display,position, float)(文本流)
html5的float属性超详解(display,position, float)(文本流) 一.总结 1.文本流: 2.float和绝对定位都不占文本流的位置 3.普通流是默认定位方式,就是依次按照 ...
- HTML中DOM核心知识有哪些(带实例超详解)
HTML中DOM核心知识有哪些(带实例超详解) 一.总结: 1.先取html元素,然后再对他进行操作,取的话可以getElementById等 2.操作的话,可以是innerHtml,value等等 ...
- Mysql超详解
Mysql超详解 一.命令框基本操作及连接Mysql 找到Mysql安装路径,查看版本 同时按快捷键win+R会弹出一个框,在框中输入cmd 点击确定后会出现一个黑框,这是命令框,我们的操作要在这命令 ...
随机推荐
- Java的动手动脑(六)
日期:2018.11.8 星期四 博客期:022 --------------------------------------------------------------------------- ...
- angular基础巩固
angular中的模块化 //定义模块 []为依赖的模块 moduleName可以使用[]模块中定义的controller filter .. var app=angular.module('modu ...
- 1873: This offer(zzuli)
题目描述 话说WX入职已经有一个多月了,公司boss突然扔给他了一个问题,如果解决不了的话就会被开除掉 - -#,情急之下他只能来请教你了,boss给了他N个不大于100的数,现在wx需要将这N个数通 ...
- LeetCode(108):将有序数组转换为二叉搜索树
Easy! 题目描述: 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组 ...
- border画梯形
<!doctype html><html lang="en"> <head> <meta charset="UTF-8&quo ...
- phpstorm2017.2.1破解
今天安装phpstorm时看了网上很多破解方法,基本上都是用http://idea.lanyus.com/ 提供的注册码或者直接在license server上粘贴譬如http://idea.lany ...
- cf1140E 回文串+染色方案dp
有点硬核的dp..要用到一个结论.. /* 把原串拆成奇偶串,再拆成极大连续的-1串:该串两端都是非-1数,中间都是-1,并且下标要么都是偶数,要么都是技术 然后对所有这些串进行dp,dp[i][0] ...
- CF1029E
一个看起来就不对的贪心居然是正解... 但仔细思考一下,这种贪心倒的确找不到反例.. 贪心思想:每次找出离根节点最远的点,然后由根节点向这个点的父节点连边,一直连到所有点都能被覆盖即可,这样构造出的一 ...
- Datagrip导入导出为一个sql文件详细说明 (mysql)
Datagrip导入导出为一个sql文件详细说明 导出: (我的无法截图, 借用一张) 导入: (我的无法截图, 再借用一张) 完
- docker 给none镜像打镜像
1.遇到none的镜像打tag方式: docker tag + docker ID + 命名:版本名 案例:docker tag 41b7307026c0 gitlab:test 这就 ...