局部光照和全局光照 在计算机图形学中全局光照(Global illumination)一般指的是2次或者2此以上的光源(自身也会产生光源)。一般经过一次表面折射或反射之后到达人眼或者场景中virtual camera。这种不考虑环境其他非光源表面对着色影响的光照模型称为局部光照(local illumination)。 先概述一下基础部分: 阴影 阴影对人眼视觉感知非常重要(可以查看我之前翻译的视觉感知)。直接光照渲染通常不考虑物体间的遮挡的光系(为了提高GPU快速光栅化 Cache),所以需要一个单独的通道pass来处理阴影。具体有shadow map(之前real time shadow)和shadow volume。 阴影贴图是以光源中的单个点为观察点。利用GPU光栅化渲染一张map,它只包含depth value,生成硬阴影(hard shadow)。 非点光源具有一定面积,生成为软阴影(soft shadow)。这种阴影分为本影和半影。 环境遮挡 对于更大面积的ambient light,例如ambient map,sky box and indirect light。光照是来自整个空间。 相应的技术解决技术有 SSAO。 反射 光线在与物体交互的时候,会多次反射或折射最后才会进入人眼或者摄像机,形成图像。如果物体表面非常光滑,产生反射。 相应技术有 Image-based lighting (IBL),这种技术将要反射“环境”渲染为一张图,然后渲染是通过查询二维的贴图来计算来自周围的环境光照,对于粗糙表面技术可以使用滤波来表示粗糙表面的效果。 间接光照 对一个shade point做整个半球的积分计算,计算昂贵。解决方案: 基于光照贴图(light map) 1对于静态物体,由于漫反射向各个方向均匀的反射,可以先被预计算,生成光照贴图的方法有: 光线追踪,辐射度方法,辐射照度缓存和光子映射(photo mapping)。 2对于动态物体在空白空间对环境光照进行稀疏采样,Unity称为光照探针(light probe),在运行的时候使用插值的方法来计算间接光照。(由于漫反射通常都是低频的,相邻点之间的颜色值变化不大,其间的点的值通过插值计算。)由于采样点都是预处理的,所以动态物体并不能影响场景中其他物体,他只能接受其他环境的影响。 光通过光泽面的反射和折射后多数光落在同一个漫反射表面点上,导致这些点的光照特别明亮。 散射 光进入物体后部分被吸收,部分散射。最后从物体表面发射出去,其中出射点和入射点位置可能不太一样。 焦散 在全局光照模型中,焦散(caustics)效果尤其明显。广义的焦散是指光从光源出发,经过至少一次光泽反射,最后通过一个光泽或漫反射面反射后进入摄像机。在计算机图形学中尤其指光通过光泽面的反射或折射后,多束光落在同一个漫反射表面点上(例如由于玻璃或水面等弯曲面使折射后多束光落在桌面上),导致这些点的光照特别明亮. Radiance是通过渲染方程计算出来的,我们使用反射率方程来计算: 查看基础部分—-》【光照学研究】—> https://rc.qzone.qq.com/2 KaJiya老先生提出的完整渲染方程: 通用的全局方法 求解渲染方程的两种常用的方法是有限元法和蒙特卡洛法。辐射度(radiosity)是基于第一种方法的算法,光线追踪使用第二种方法。主要流行的是第二种,因为他可以并行化。 第一种 辐射度法(Radiosity)【所有间接光都来自漫反射表面】 辐射度是一种计算图形技术,用于模拟漫反射之间的反射光,辐射度可以计算区域光的相互反射和软阴影。 第二种 基于蒙特卡洛光线追踪 【强烈的反射和折射 以及阴影】 发射射线追踪,最击中的采样点使用蒙特卡洛概率采样累积每一次的积分值算出radiance。 环境光遮挡 (Ambient Occlusion) 首先一般方便计算 假设光线都是恒定的均匀照明(真实世界一般不是均匀的)。 辐照度(irradiance)是入射radiance(辐射度)的余弦加权积分,一般来说,它取决于位置p和表面法线n。我们假设radiance为常数, Li (l) = LA,对于所有入射方向l。可以化简为(得到irradiance公式): 积分是在光线传入方向半球Ω上执行的,由于是均匀的,(irradiance不依赖于位置和法线)因此产生出平的着色效果。 但是这个方程下没有考虑任何可见性,有些方向可能会被物体的其他部分遮挡,这些方向会有不同的radiance,而不是LA。简单起见,我们假设radiance为零,这忽略了场景中其他物体的反射的所有光线,得到了一个简化的Cook和Torrance方程: 可见性函数的归一化余弦加权积分称为环境遮挡: 它代表了未被遮挡半球的余弦加权平均百分比。值范围从0(表面完全遮挡)到1(表面点没有被遮挡)。遮挡下的环境irradiance方程为: 上图右边所示,每个蓝色箭头显示平均未被遮挡方向,bent normal。 除了Ka值,Landis还计算一个未被遮挡的方向,称为bent normal,这个方向向量被计算为未被遮挡光方向的余弦加权平均值: 可见性和遮蔽 由于可见性函数在封闭几何中无法使用,Zhukov引入了映射函数p(l)来修改环境遮挡计算: 将p(l) 替换v(l) 相互反射计算 尽管环境遮挡令人信服,但他比由全局光照模拟产生的结果要暗,KA = 0 (可见性函数不可见) 环境遮挡和全局照明之间的一个区别是相互反射。 Stewart和Langer提出精确近似: 预计算环境遮挡 (只能对静态物体) 环境遮挡因子非常耗时,通常在渲染前离线进行。 基于蒙特卡洛预计算环境遮挡: 环境遮挡的动态计算 离线计算环境遮挡的方法涉及从每个表面点向场景投射大量光线,几十到数百条,并检查相交,这是昂贵的操作,实时方法关注于近似或避免大量此类计算的方法。 Bunnell通过将表面建模为为放置在网格顶点上的圆盘形元素的集合来计算环境遮挡因子KA和弯曲法线Nbent 屏幕空间方法 对象空间方法开销与场景复杂度成正比,然而,一些关于遮挡的信息可以纯粹地从屏幕空间数据中推出来,比如深度和法线。 Crytek开发了一种用于《孤岛危机》的动态屏幕空间环境遮挡(SSAO)方法,他们使用zbuffer作为输入,在全屏通道计算环境遮挡,每个像素的环境遮挡因子KA是同过一组低昂来计算的,这些点分布在像素位置周围一个球体上,与Z buffer相对应。 Loos和Sloan优化了Crytek的方法,使用蒙特卡洛积分。他们称为体积模糊度,并将其定义为: Szirmay-Kalos提出体积环境遮挡。 Bavoil提出了估计局部可见性问题。基于视角的环境遮挡(HBAO),给定一个点的方向,我们记录可见的最高物体的角度。 如果我们忽略余弦项,那么环境遮挡因子可以计算为视界上未遮挡部分的积分,或者,1减去视界下遮挡部分的积分: 式中h(φ)为切平面以上的地平角,t(φ)为切平面与视场矢量的切角,W(ω)为衰减函数。 1 / 2π 使积分标准化。 环境遮挡的着色 尽管我们在恒定的,远处的光照环境导出了环境遮挡值,我们将环境值应用到更复杂的光照场景中,考虑方程 上面包含了可见性函数v(l), 如果我们处理的是一个漫反射面,我们可以用Lambertian BRDF替换f(l,v),它等于次表面反照率Pss除以π。我们得到了: 我们可以利用Ka环境遮挡,化简公式为: 其中: 积分被看作是对入射radiance Li 应用方向滤波核K。 当Li和过滤函数K都使用球谐函数表示时,简化方程复杂性,归一化余弦核H: 这个只有当没有任何物体可以挡住入射光线时,近似时正确的。它包含了我们近似的滤波器相同角度范围。它完全忽略了能见度。但是方程中仍然包含KA项,因此在着色表面会出现与能可见度相关的变暗。 这意味着,在其最简单的形式中,环境遮挡的着色可以通过计算irradiance并乘以环境遮挡值来实现。 irradiance可以来自任何来源。例如,它可以从irradiance环境贴图中采样。 |