之前一直在考虑这样一个问题,在实际生活中的光源都是有体积的,但是图形学中,很多时候我们用简单的点光源,面光源,或者方向光来模拟实际生活中这些光源,势必会产生一些误差,同时导致很多效果不好做。那么在离线渲染中要怎么对不规则光源进行渲染呢?首先很容参考的是之前我用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)的更多相关文章

  1. 基于光线追踪的渲染中景深(Depth of field)效果的实现

    图形学离线渲染中常用的透视摄像机模型时根据小孔成像的原理建立的,其实现通常是从向成像平面上发射ray,并把trace这条ray的结果作为成像平面上对应交点的采样结果.即: 图片来自<Fundam ...

  2. 【原】实时渲染中常用的几种Rendering Path

    [原]实时渲染中常用的几种Rendering Path 本文转载请注明出处 —— polobymulberry-博客园 本文为我的图形学大作业的论文部分,介绍了一些Rendering Path,比较简 ...

  3. 画面渲染:实时渲染(Real-time Rendering)、离线渲染(Offline Rendering)[转]

    实时渲染(Real-time Rendering) 实时渲染的本质就是图形数据的实时计算和输出.最典型的图形数据源是顶点.顶点包括了位置.法向.颜色.纹理坐标.顶点的权重等.在第一代渲染技术中(198 ...

  4. 渲染路径-实时渲染中常用的几种Rendering Path

    http://www.cnblogs.com/polobymulberry/p/5126892.html?utm_source=tuicool&utm_medium=referral 回到顶部 ...

  5. 在离线环境中发布.NET Core至Windows Server 2008

    在离线环境中发布.NET Core至Windows Server 2008 0x00 写在开始 之前一篇博客中写了在离线环境中使用.NET Core,之后一边学习一边写了一些页面作为测试,现在打算发布 ...

  6. 在离线环境中使用.NET Core

    在离线环境中使用.NET Core 0x00 写在开始 很早开始就对.NET Core比较关注,一改微软之前给人的印象,变得轻量.开源.跨平台.最近打算试着在工作中使用.但工作是在与互联网完全隔离的网 ...

  7. 借助CAD在Altium Designer中定义不规则PCB外形

    借助绘图软件CAD在Altium Designer中定义不规则PCB外形. 工具/原料 CAD2007 Altium Designer2015 方法/步骤 借助CAD绘制的不规则外形,保存成DXF格式 ...

  8. 在离线环境中安装Visual Stuido 2017

    在离线环境中安装Visual Stuido 2017 0x00 写在前面的废话 因为工作上大多数都是在离线环境中进行的,进出离线环境很麻烦,所以之前很长一段时间都在使用VS2010.后来尝试换了VS2 ...

  9. [转]在离线环境中发布.NET Core至Windows Server 2008

    本文转自:http://www.cnblogs.com/durow/p/5765145.html 0x00 写在开始 之前一篇博客中写了在离线环境中使用.NET Core,之后一边学习一边写了一些页面 ...

随机推荐

  1. 如何设置word里的代码格式,使之有底纹的效果

    1.测试平台:word2013 2.步骤:设计->底纹->填充->应用于->确定 3.效果:

  2. 解决网站在负载均衡环境下SESSION丢失的问题

    在WEB场中,动态网页往往会因为几台主机做了负载而产生SESSION丢失的问题,网上也有很多的介绍,我这里只将我经历的过程给大家分享一下:   系统要运行在负载平衡的 Web 场环境中,而系统配置文件 ...

  3. Android开发探秘之四:利用Intent实现数据传递

    在Android开发过程中,很多人都熟悉Intent,这是个用于在多个View之间共享数据的类.本节主要是继承上节,通过点选ListView中的文本,把文本中的URL加载到一个新的页面上,并且打印出来 ...

  4. Android开发探秘之一:创建可以点击的Button

    感觉到自己有必要学习下手机开发方面的知识,不论是为了以后的工作需求还是目前的公司项目. 当然,任何新东西的开始,必然伴随着第一个HelloWorld,Android学习也不例外.既然才开始,我就不做过 ...

  5. [MetaHook] Quake FMOD function

    QFMOD.h #ifndef QFMOD_H #define QFMOD_H #include "fmod.h" extern FMOD_RESULT (F_API *qFMOD ...

  6. LINUX第五次实验报告

    北京电子科技学院(BESTI) 实     验    报     告 课程:信息安全系统设计基础                     班级: 201353 姓名:刘世鹏 郝爽 学号:2013530 ...

  7. 疯狂位图之——位图生成12GB无重复随机乱序大整数集

    上一篇讲述了用位图实现无重复数据的排序,排序算法一下就写好了,想弄个大点数据测试一下,因为小数据在内存中快排已经很快. 一.生成的数据集要求 1.数据为0--2147483647(2^31-1)范围内 ...

  8. Ubuntu 上创建常用磁盘阵列

    RAID(Redundant Array of Independent Disk 独立冗余磁盘阵列)技术是加州大学伯克利分校1987年提出,最初是为了组合小的廉价磁盘来代替大的昂贵磁盘,同时希望磁盘失 ...

  9. http技术交流提纲

    http技术交流提纲地址:http://lazio10000.github.io/tech/http/#/bored

  10. iOS -- 生成有logo的二维码

    - (void)createLogoImage { NSArray *filter = [CIFilter filterNamesInCategory:kCICategoryBuiltIn]; NSL ...