离线渲染中的不规则光源(Meshlight)
之前一直在考虑这样一个问题,在实际生活中的光源都是有体积的,但是图形学中,很多时候我们用简单的点光源,面光源,或者方向光来模拟实际生活中这些光源,势必会产生一些误差,同时导致很多效果不好做。那么在离线渲染中要怎么对不规则光源进行渲染呢?首先很容参考的是之前我用path tracing模拟环境光照的例子(http://www.cnblogs.com/starfallen/p/3520021.html),即给光源所包含的所有三角面加上一个发光属性,然后直接使用path tracing渲染场景,当从视点发出的ray击中这些三角面中的一个时,认为成功找到一条有效路径。这个方法是可行的,只是效率实在太低了,特别是当光源面积比较小的时候。使用bidirectional path tracing就能解决这个问题,但是我们都知道BDPT是需要对光源进行采样的,而如何在不规则光源上采样就是这个问题的关键了。这个问题,我自己一开始也是没有想出来该怎么做,在向Len3d大牛请教之后才明白,下面来看它的解决方案。
为了简化问题,我们只考虑均匀光源,即光源面上每个点的亮度是一样的,那么在光源上采点的问题也可以看成是如何在一个给定mesh上均匀采样一个点的问题。我们知道一个mesh是由很多三角面组成的,要在mesh上采样一个点,首先要采样一个三角面,然后再在三角面上取一个点。取点的依据是光源的表面积,也就是要把光源的表面积算出来,这里我们就用组成光源的所有三角面的面积表示光源表面积了。接下来是把所有光源上的三角形按照面积做成一个cdf(cumulative density function),然后用这个cdf来对光源三角形进行采样得到一个目标三角形,最后在这个目标三角形上取一个点即可。为了更形象一点说明,举一个例子:

如上图,假设光源由ABCD四个三角形构成,它们的面积分别是A=4,B=2.2,C=1.8,D=2,光源总面积S为10,cdf就是ABCD按顺序的累计概率密度函数p(x)。
p(A)=A/S=0.4;
p(B)=(A+B)/S=0.62;
p(C)=(A+B+C)/S=0.8;
p(D)=(A+B+C+D)/S=1.0;
于是正如上图最后的表格所示,采样的时候,我们先随机产生一个0-1的随机数r,
if (r<=p(A)) 取到三角形A;
else if(r<=p(B)) 取到三角形B;
else if(r<=p(C)) 取到三角形C;
else 取三角形D;
当然这样做的话,算法复杂度就是O(n),对于一些复杂的光源来说,通常有成千上万的三角面,效率显然是不足的。利用cdf函数单调递增的特点,可以考虑折半查找的方法,每次取三角形序列中间位置的三角面R,并比较该三角面的cdf值与随机数r的大小(比较r与p(R)的大小),依次递归。或者做一个哈希桶,比如把cdf函数10等分,把0-0.1区间的三角形放在一起,0.1-0.2区间的三角形放在一起,以此类推,当取到随机数r的时候,先判断r落在哪个区间上,然后再对这个区间中的三角形进行查询,选取合适的三角形。
选取到合适的三角形后,接下来就是要在这个三角形上均匀取一个点,方法很多,我参考的是网上给出的方法(http://stackoverflow.com/questions/4778147/sample-random-point-in-triangle):给定三角形三个顶点A,B,C以及两个[0,1]随机数r1,r2,随机取点P:
P = (1 - sqrt(r1)) * A + (sqrt(r1) * (1 - r2)) * B + (sqrt(r1) * r2) * C
这样一来,主要的问题就解决了,得到了光源的采样点后,剩下的就和bidirectional path tracing算法其余的部分一致了。下面两张图是用了meshlight的渲染结果:


最后要说的一点是,虽然这个方法也可以处理不均匀光源或者带纹理的光源,但是由于没有进行重要性采样,所以效率不高,更好的方法是在构造cdf函数的时候把表面亮度考虑进去,但是目前我没有做这一点。
离线渲染中的不规则光源(Meshlight)的更多相关文章
- 基于光线追踪的渲染中景深(Depth of field)效果的实现
图形学离线渲染中常用的透视摄像机模型时根据小孔成像的原理建立的,其实现通常是从向成像平面上发射ray,并把trace这条ray的结果作为成像平面上对应交点的采样结果.即: 图片来自<Fundam ...
- 【原】实时渲染中常用的几种Rendering Path
[原]实时渲染中常用的几种Rendering Path 本文转载请注明出处 —— polobymulberry-博客园 本文为我的图形学大作业的论文部分,介绍了一些Rendering Path,比较简 ...
- 画面渲染:实时渲染(Real-time Rendering)、离线渲染(Offline Rendering)[转]
实时渲染(Real-time Rendering) 实时渲染的本质就是图形数据的实时计算和输出.最典型的图形数据源是顶点.顶点包括了位置.法向.颜色.纹理坐标.顶点的权重等.在第一代渲染技术中(198 ...
- 渲染路径-实时渲染中常用的几种Rendering Path
http://www.cnblogs.com/polobymulberry/p/5126892.html?utm_source=tuicool&utm_medium=referral 回到顶部 ...
- 在离线环境中发布.NET Core至Windows Server 2008
在离线环境中发布.NET Core至Windows Server 2008 0x00 写在开始 之前一篇博客中写了在离线环境中使用.NET Core,之后一边学习一边写了一些页面作为测试,现在打算发布 ...
- 在离线环境中使用.NET Core
在离线环境中使用.NET Core 0x00 写在开始 很早开始就对.NET Core比较关注,一改微软之前给人的印象,变得轻量.开源.跨平台.最近打算试着在工作中使用.但工作是在与互联网完全隔离的网 ...
- 借助CAD在Altium Designer中定义不规则PCB外形
借助绘图软件CAD在Altium Designer中定义不规则PCB外形. 工具/原料 CAD2007 Altium Designer2015 方法/步骤 借助CAD绘制的不规则外形,保存成DXF格式 ...
- 在离线环境中安装Visual Stuido 2017
在离线环境中安装Visual Stuido 2017 0x00 写在前面的废话 因为工作上大多数都是在离线环境中进行的,进出离线环境很麻烦,所以之前很长一段时间都在使用VS2010.后来尝试换了VS2 ...
- [转]在离线环境中发布.NET Core至Windows Server 2008
本文转自:http://www.cnblogs.com/durow/p/5765145.html 0x00 写在开始 之前一篇博客中写了在离线环境中使用.NET Core,之后一边学习一边写了一些页面 ...
随机推荐
- js中的预加载与懒加载(延迟加载)
js中加载分两种:预加载与延迟加载 一. 预加载,增强用户的体验,但会加载服务器的负担.一般会使用多种 CSS(background).JS(Image).HTML(<img />) . ...
- node.js乱码问题【WebStorm环境】
昨天看了一个晚上的jade视频, 感觉就是我想要的东西, 相见恨晚, 赶紧在WebStorm这个IDE中,写代码,测试 /** * Created by xa87 on 2016/1/22. */ v ...
- #Linux学习笔记# Linux在线帮助文档man page
man是manual的简称,表示手册页.Linux系统的帮助手册页是按照章节(SECTION)来存储了.man手册页分为下面几个章节. 1 普通命令 2 内核提供的系统调用 3 库调用(C库函数) 4 ...
- [USACO2003][poj2185]Milking Grid(kmp的next的应用)
题目:http://poj.org/problem?id=2185 题意:就是要求一个字符矩阵的最小覆盖矩阵,可以在末尾不完全重合(即在末尾只要求最小覆盖矩阵的前缀覆盖剩余的尾部就行了) 分析: 先看 ...
- redis学习笔记——(2)
4.Redis中的string类型 String类型是最简单的类型,一个Key对应一个Value,String类型是二进制安全的.Redis的String可以包含任何数据,比如jpg图片或者序列化的对 ...
- Bootstrap3.0学习第十七轮(JavaScript插件——模态框)
详情请查看http://aehyok.com/Blog/Detail/24.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链接:ht ...
- addLoadEvent方法解析
onload方法在网页加载完毕时,会自动执行,但是该方法有个缺点就是只能执行一个方法. onload的限制 比如下面的代码: <script type="text/javascript ...
- EF---结合三层方法的应用
1 public class CustomerDAL 2 { 3 //数据库上下文对象 4 YYMMVCEntities db = new YYMMVCEntities(); 5 /// <su ...
- Samba实现Linux与Window文件的传输
Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通 ...
- 每天一个linux命令(42):crontab命令
前 一天学习了 at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系统则是由 cron (crond) 这个系统服务来控制的. Linux 系统上面原本就有非常多的计划性工作,因此 ...