Vray教程:DMC核心和早期终止机制

修改
鏉ユ簮: 爷⑤-缺德 浏览 2858 日期 2011-10-24 0

下面我列出需要调用mc分布式光线追踪过程的特性和子功能块:

1:fixed类型的图像反走样器(当其取值大于1时,会调用mc分布式过程来对每像素进行反走样。)

2: adaptive dmc sampler类型的图像反走样器(老版本叫adaptive qmc sampler,它和fixed类型唯一的区别是带有自适应过程)

3:vray mtl材质中的模糊反射和模糊折射特性的计算(当你将vray mtl中的reflection面板或refraction面板里的glossy值调为任何小于1的值时,即打开了glossy effect(模糊特性)计算的过程,这个过程将调用mc分布式过程。)

4:vray dirt map 贴图的计算过程(也就是我们常说的vray 的ao,这一过程需要调用mc分布式光线追踪来发射大量探测光线去收集每个像素周围的阻塞情况。)

[next]

5:vray面光源的软阴影计算过程(与传统的光线追踪投下的生硬阴影边缘不同,vray的面光靠mc分布式光线追踪发射的次级光线来摸拟出面光源应有的阴影虚化效果。)

6: vray的运动模糊特性(运动模糊的计算依靠的是分布式光线追踪算法对时间域的离散计算,所以这个过程完全依赖mc分布式过程。)

7:vray的摄像机景深特效(景深的实现依靠的是分布式光线追踪对空间距离的离散计算。)

8:irradiancemap的计算过程 (在irmap的计算过程中,当通过prepass分析图像并放下采样点后,需要从采样点向周围环境的虚拟半球空间发射分布式光线以探测和收集信息,从而计算出采样点本身像素的最终gi结果,这个过程也就是调用mc分布式光线追踪来完成的,而hsph subdivs决定的其实就是这个过程中发射半球分布式光线的数量。)

[next]

9:brute force算法计算gi的过程 (brute force即老版本的qmc gi算法,无论你在vray间接照明面板的主gi引擎还是次级gi引擎中打开brute force,都是直接调用mc分布式过程对图像上每一个像素进行gi计算)

根据上表中列出的主要依靠mc分布式过程的特性,我们不难看出mc分布式光线追踪算法在vray中的主导性地位,那么,请大家至少记住上表中我所提到的这几种情况,因为它们的计算过程都和下面我要讲的这个面板里提供的参数有关,那就是vray dmc sampler (vray dmc核心采样管理器)。

原来这个面板的名字叫"vray qmc sampler",vray从1.5版开始更名为"dm c",这里很多朋友对此都有不解,到底dmc与qmc的区别在哪里?有没有区别,提及于此,我先为大家理清楚几个概念:

[next]

首先,理解一下mc,也就是monte carlo(蒙特卡罗),蒙特卡罗其实是一种分布式积分,而蒙特卡罗算法专门用这种积分所产生的分布概率来产生各种模糊数据,其实上表所涉及的特性都是为了解决模糊效果,反走样其实就是为了将图像锯齿模糊化,模糊反折射也是为了产生模糊但有源于真实情况的反折射成像,运动模糊其实就是为了让成像根据运动速度与时间的关系产生出模糊效果,诸如此类。

而什么又是qmc呢?全名是quasi-monte carlo(准蒙特卡罗),这其实是纯蒙特卡罗算法的一个变种,它缩减了算法取样的范围,qmc所产生的随机样本全部来自于一个低差异数据序列,而不是传统mc的庞大假随机数生成,但事实上,vray在新版本中已经摒弃了qmc分布式特性,使用一种全新的mc变种算法,也就是接下来我们要说的dmc。

[next]

dmc的全称为:deterministic monte carlo (确定性蒙特卡罗),dmc作为mc的一个变种,其区别在于,mc生成用于模糊结果的采样点情况源于一个庞大的随机数据集,即使我们计算的情况或考虑的内容本身根本没有发生改变,但计算的模糊结果每一次都是不一样的。dmc则不同,dmc先依据某种规则考虑计算的重要性和内容的特质,然后事先确定一组数据序列,而样本则产生于这组已确定的数据序列,因此,多次的计算结果是一致的,这有利于动画的计算,以及更好的降低可能带来的噪点情况,dmc和qmc之间的区别在于,这两者选择产生样本的数据序列集不同,考虑规则不同。事实上,qmc只是dmc的一个子集。

ok,我们不需要在这些纯理论定义上浪费太多时间,点明一下就行,我着重要阐述的,是vray的这个核心dmc,是如何影响上表中这些功能实现的。

[next]

先来看看下面这个面板,这就是vray dmc sampler,vray的核心 :

首先理解,我们常说的分布式光线数量,其实就是分布式光线追踪的samples样本数,这是一个概念。

我们所见到的和分布式光线追踪有关的subdivis参数和样本数的关系是平方关系,也就是说,subdivis值的平方就是分布式光线数量(或样本数量)。

vray的dmc分布式光线追踪算法最终产生多少samples样本来得到一个模糊结果,取决于三个方面。

一方面取决于每个局部效果或功能块,我们用户指定了多少subdivs值,大家都知道上表中我列出的各个特性其面板里都有subdivis参数,那么这个参数是一个非常重要的基本决定性因素,事实上用户指定的每个功能部分的subdivis最终都要乘以面板中的global subdivs multiplier这个倍增器。

[next]

一方面,还取决于vray的重要性采样分析,这是一个自适应判断过程,虽然用户为每一个特性指定了subdivis值来确定其应有样本数量,但事实上vray认为它先要通过一个自适应过程判断一下待计算模糊效果的像素点(shade point)是否是一个重要性采样,这个规则很复杂,我不详细说明,比如暗的像素会比亮的像素需要更少的细节,比如远的会比近的需要更少的模糊细节,诸如此类,这个自适应判断过程的作用是要不要对这个像素使用全部的用户所指定的subdivis数量级别来生成分布式光线样本,如果某像素点实际上是比较远或暗的像素,vray认为用某个低于用户指定的subdivs值即可,越不重要的像素点就用越低于指定subdivs的值来生成样本。相反,相对重要的就用接近用户指定的subdivis值来产生样本。然而,用户可以指定vray重要性自适应分析对最终形成样本起改变作用的权重,面板上看到的adaptive amount值就是这个权重参数,当这个值为1时,vray将完全参考重要性分析的过程来决定如何优化(其实就是降低)用户指定的subdivs参数对某个像素点的影响,用户给定的subdivs值此时只是个理想状态,几乎完全要被这个重要性自适应判断过程所削减,降低adaptive amount这个权重,将使这个自适应过程改变用户决定权的情况降低,当降到零时,完全使用用户给定的subdivs值产生某像素点的样本,即理想状态。

[next]

最后,我们把经由第一个方面,和第二个方面后最终决定的样本数量叫做vray分布式额定样本数量。后面它还将受到早期终止机制影响。

最后一个方面,除了受用户指定的subdivis值,以及重要性自适应分析,还受一个机制影响,那就是早期终止机制,在不停产生分布式光线数量样本以计算模糊效果的过程中,vray会不停判断正在生成的模糊结果其噪点是否已经在承受范围内,如果达到承受范转,或者说达标,那么不管前两个方面所提到的因素最终确定了用多少样本来生成结果,即使目前并未分布够那个确定的样本数量,也立即停止,停止前完成min sapmles参数指定的最小样本生成数量。而这个判断噪点的标准,就是我们看到的面板中的noise threshold参数,这个参数越小,vray对模糊结果的噪声敏感程度就越高,vray所能容忍的噪点情况就越小,相反对质量要求就越高,早期终止将越晚出现,甚至完全不出现。反之,noise threshold参数越大,vray对模糊结果的噪声敏感程度就越低,所能容忍的噪点情况就越大,质量要求越低,早期终止容易越早出现。

[next]

说了这么多理论且抽象的东西,为了帮助大家理解,我举个例子:

以模糊反射为例,某vray材质我设置reflection glossy为0.65,这时其实就打开了模糊反射的计算,并且下面的subdivs值我给16(默认为8),换算过来就是应该产生16*16=256条分布式光线,或者说256样本数,即被赋材质的物体表面的每个像素点(shade point)将用256个样本光线来计算其模糊后效果,但这时情况并没这么简单,先分析该shade点是不是应该属于重要性采样,假定这个像素很远,也很暗,vray认为并不那么重要,于是说,用什么256个样本来采样,100个够了,但vray 说的100个和用户指定的256个谁更说了算,用adaptive amount权重来决定 ,当adaptive amount为1时,vray自适应重要性分析将占据一半的权重,即最终的样本数将为用户指定的256和vray认为的100的平均值,即178,如果为0,则完全按用户指定的256 个样本算,不考虑重要性分析,如果介于两者之间,比如adaptive amount默认为0.85,那么将按:

[next]

(vray认为的样本数*adaptive amount+用户指定的样本数*(2-adaptive amount))/2 这个公式来计算。

即:(100*0.85+256*(2-0.85))/2=190 ,也就是说这时用户占百分之115的权重,vray分析的占百分之85的权重,一

评论

{{ username ? username.charAt(0).toUpperCase() : '?' }}
Ctrl+Enter 发布
{{ (c.username || c.author_name || '?').charAt(0).toUpperCase() }}
{{ c.username || c.author_name }} {{ Utils.formatDate(c.created_at) }}