【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 点击确定后会出现一个黑框,这是命令框,我们的操作要在这命令 ...
随机推荐
- 将Maven项目打包成可执行jar文件(引用第三方jar)
方法一. mvn assembly 或 mvn package (一个jar包) 把依赖包和自己项目的文件打包如同一个jar包(这种方式对spring的项目不支持) <build> ...
- Ionic 2: ReferenceError: webpackJsonp is not defined
I'm new to Ionic. I have started project with super template. But when I try to run the app in brows ...
- 用echarts写的轨迹图demo
轨迹图预览: [下载地址]:https://github.com/zhangzn3/trail-graph.git
- Niagara物联网框架机制一(笔记)
一.介绍: Niagara是Tridium公司研发的设计用于解决设备连接应的软件框架平台技术,应用框架是一个软件工程中的概念,不同于普通的软件,它是用于实现某应用领域通用完备功能的底层服务,使用这种框 ...
- django----常用功能
request.path_info 获取url地址
- php 常用字符函数学习
1.addcslashes 要向字符串中的特定字符添加反斜杠 <?php header('Content-type:text/html;charset=utf8'); $str='are you ...
- Python os.walk() 方法遍历文件目录
概述 os.walk() 方法用于通过在目录树中游走输出在目录中的文件名,向上或者向下. os.walk() 方法是一个简单易用的文件.目录遍历器,可以帮助我们高效的处理文件.目录方面的事情. 在Un ...
- Python语音识别(计算器)
第一步关于导入模块的事,我试了好几个方法才发现在好像win7系统没有语音识别功能,我用了win10的又需要重新下载一个包 这样子,win32com.client模块就可以使用了 import win3 ...
- win10ssh连接ubuntu服务器并本地绘图
update @ 2018-11-07 00:36:38 用xrdp+tigervnc等的组合,可以使用原生unity桌面.具体教程见ubuntu日常使用指南 工具准备 win10上: xshell, ...
- JS高级程序设计3
PS:有一小部分写在了 JS 2017了 JSON <!DOCTYPE html> <html lang="en"> <head> <me ...