Unity光照笔记

发布于 2019-04-07  80 次阅读


本篇内容零散的记录一些光照方面的知识。
本篇中测试使用的Unity版本为2019.1.0b10。
因为着色计算中少不了光照,所以这方面的知识不要回避为好。女神书上多次提到“排除Lightmap、cookie的情况”,但是对于做项目的人来说,不能总停留在理论或者猜想阶段。
我希望的是,我综合利弊后确认项目中的确不需要考虑某个关键词或者光照烘焙,于是将对应的可能性排除。

Unity中的光照类型

工程很复杂的时候,场景里面有什么光不一定能很快理清,我们应该从一个空的场景开始。
当场景中没有任何光源、环境光、探针时,场景里的物体应该是全黑的。
直接光:Hierarchy中创建的平行光源、点光源、锥形光源,用于直接照亮物体(diffuse)。
间接光:环境光、实时GI、光照探针、折射探针、自发光,用于间接照亮物体(ambient、reflect、refract)和自发光(emission)。
衰减因子:环境光遮蔽、阴影衰减、光照衰减。

每个像素的最终颜色值均通过光照公式计算出来,数据的准备由Unity帮我们完成。
Cubemap
Cubemap相当于用6个面组成的正方形,从中心处射出任意射线必定击中一个点,这个过程用于理解Cubemap采样。
当Cubemap作为Skybox时,相当于给相机添加了一个Skybox组件,单纯平移相机时不会修改Cubemap采样的角度。
无光的世界
新建一个scene,创建一个Cube(使用了标准shader),此时Cube是被照亮的。
删除默认的平行光,Cube黑了(没开Auto Generate时),默认的天空还是亮的。
在Lighting Setting中,开启Auto Generate自动烘焙,Cube又亮了,比较灰。
设置Skybox Material为空,Cube变灰,背景变成相机的Background颜色。
此时Source的下拉选项中,skybox作为默认环境光源将不再生效,等同于Color。
设置Ambient Color,此时Cube颜色完全跟着Ambient Color走。
在无光的世界里:
FinalColor = Ambient
或者说,构成环境贴图的Cubemap此时由单色的面构成。
Skybox
设置Source为Color,Ambient Color设置为(0,0,0),再恢复默认的天空盒子。
此时环境色不再提供任何光照强度,Cube上依然有微量的光照。
调整Environment Reflections下的Intensity Multiplier,为0时Cube全黑。
FinalColor = Ambient + Reflect(Source)
这里的Reflect描述了物体表面的反射现象,观察方向相对法线的反射方向用于采样,被采样的目标为Source,默认为Skybox。
Intensity Multiplier作为环境反射部分的系数,最大值1表示正常水平。
Bounces表示反射的光照最多会被反射的次数,最小值1表示反射到1个物体以后就不会继续反射了。
将Source设置为Custom后,Cube变为全黑,此时我们可以指定用于环境反射的Cubemap。
反射现象等同于镜面反射高光,与观察角度有关。
现在我们可以总结一下skybox的意义
当渲染流水线中Queue低于2500的物体绘制完毕后,开始绘制skybox,没深度记录的片元都去采样一次。
可以作为环境光的Cubemap、环境反射的Cubemap,这两个过程是分别独立的,描述了环境光和反射现象。
至此,光照设置的Environment部分基本完成了。

Realtime/Mixed Lighting
Realtime Global Illumination:实时全局照明,控制Realtime光源是否产生间接光(realtime lightmap,这个lightmap会实时更新),个别Realtime光源产生间接光的比率可以通过光源的Indirect Multiplier属性调整。
间接光:这里指光直接照到物体后的反射、折射现象,而折射的光继续参与漫反射、转化为热能、反射(水底)等过程。
间接光的产生必须准守能量守恒,这个任务是由Shader完成的,也就是Unity提供的标准Shader。
而使用自定义的Unlit Shader,需要手动编程进行光照计算。
Baked Global Illumination:烘焙全局照明,控制Mixed/Baked光源是否产生间接光(baked lightmap,这个lightmap不会更新)。
Mixed光源在有烘焙数据时则使用烘焙数据,Baked光源必定使用烘焙数据。
Lighting Mode:指定Mixed光源的工作模式。
substrative:烘焙Mixed光源对静态物体的直接光照,间接光照、阴影。
shadowmask:烘焙Mixed光源对静态物体的间接光照和阴影,实时光照在运行时计算。
baked indirect:仅烘焙Mixed光源对静态物体的间接光照,实时光照和阴影在运行时计算。

Lightmapping Settings
光照映射设置,必须开启烘焙GI才能生效。这里使用默认的Progressive CPU光照系统。
Prioritize View:是否优先烘焙Scene视口中的物体。
Multiple Importance Sampling:环境采样时是否开启Multiple Importance Sampling。
Direct Samples:直接光采样次数。
Indirect Samples:间接光采样次数。
Environment Samples:环境光采样次数。
Bounces:间接光的反弹次数。
Filtering:指定烘焙过程中的减噪方案。
Indirect Resolution:开启Realtime GI后可用。可能是指realtime lightmap的分辨率,无法观察。
Lightmap Resolution:Baked Lightmap中,1个Unit对应的像素数。
Lightmap Padding:Baked Lightmap中,shape之间的像素间隔。
Padding过小或者Lightmap分辨率不够时可能造成"Overlapping UVs"问题。
Lightmap Size:设置整个Lightmap的像素尺寸,一张Lightmap不够时会增加Lightmap数量。
Compress Lightmaps:是否压缩Baked Lightmap,可能产生偏差。
Ambient Occlusion:是否在Bake Lightmap时,模拟环境光遮蔽。
Directional Mode:Directional模式下lightmap存储更多的光照信息帮助标准shader计算
Indirect Intensity:realtime/baked lightmap中间接光的强度系数。
Albedo Boost:增加反照率(漫反射的光量)。
Lightmap Parameters:一整套lightmap参数。

Other Settings
Fog:是否在场景中使用雾效。
Halo Texture:指定用于绘制光源周围的光晕的贴图。
Halo Strength:光晕强度。
Flare Fade Speed:光源→相机的lens flare持续时间。
Flare Strength:lens flare的强度。
Spot Cookie:Spot光源的衰减贴图。

Generate Lighting
生成光照,也就是烘焙光照数据。
Baked光源和Mixed光源对Lightmap Static的物体的光照生成对应的Lightmap。
需要展开模型的第二套UV,模型的Import面板中勾选 ‘Generate Lightmap Uvs’。

Cookie Texture
将纹理类型设置为cookie,指定光源类型和Alpha from Grayscale,生成Cubemap。
可作为阴影遮罩,黑色的部分造成阴影。模拟透过窗户的光照。只能有realtime光源可使用。

加快烘焙速度
①缩放不重要的对象,如变化少的对象、只接受间接光的对象。
②修改Lightmap Parameters。
An Introduction to Lightmapping in Unity
Reducing precompute times from hours to minutes

Light Probes

光照探针。
为什么需要使用光照探针:
当光源分为Realtime、Mixed、Baked三种模式后,场景中的物体也要区分为实时和静态。
静态的物体在烘焙的过程中保存了光照计算的结果,在渲染流水线中只需要采样lightmap即可完成着色。
实时的物体接受Realtime光源提供的光照,参与光照计算进行着色。实时的物体也可以采样lightmap吗?
lightmap的采样过程与Cubemap不同,更类似于Tex2D,第二套UV用于lightmap的采样。
一张lightmap上会包含复数物体的多个面的UV展开图+UV着色图。
这种情况下实时物体是找不到在lightmap中的采样坐标的,作为立体物体最好是对Cubemap采样。
一个Light Probe,可以理解为一个对环境采样后的Cubemap。

如何使用光照探针
在Hieraichy中右键-Light-Light Probe Group,得到Light Probe Group组件,这个组件用于管理场景中的所有Light Probe,其Transform没有意义,重要的是Light Probe的位置。
Edit Light Probes:进入光照探针编辑模式。
Add Probe/Select All/Delete Selected/Duplicate Selected:对复数探针的位置调整。
一个探针相当于一个Cubemap,记录了从周围所有角度射向这个点的Backed Lighting,也就是采光过程,所以光照探针像是一个光源。
采样角度:从物体表面一点到探针的方向/从物体质心到表面一点;不确定,我倾向于后者。
前者只能做到面向探针的那一面有采样角度,且距离探针越远角度越集中,需要多个探针合作才能照亮所有面。
后者只考虑表面上的点在整体的相对位置,可以实现全方位采样,但是忽视了探针的位置因素。
实时物体对lightmap的采样依赖于4个Light Probe构成的封闭空间,越近的Ligh Probe影响比例越大。
观测方式:选中实时物体时可显示正在对其生效的4个Light Probe。
Light Probe效果分析
Light Probe生效的机制并没有考虑到场景中可能存在的阴影突变和颜色突变。
我们通过Cubemap采样得到颜色值,这种模式产生的颜色突变通常是移动过程中切换了采样目标Light Probe造成的。
所以这里考虑2种运动方式:在固定的4面体内移动;质心超出边界时切换一个Light Probe到达新的四面体内。
所以无法反映出明确的阴影边界线或者颜色边界线,只能是切换Light Probe时突然变色。
如何合理放置Light Probe
在整个空间范围内,明暗交替、色调交替处的两边各放置一个Light Probe,通过这样的方式达到模拟颜色突变的效果。

Reflection Probe

为什么要有反射探针
反射是物体的自然现象,表面越光滑的物体反射的光量越多,在标准shader中可以调整材质的Reflective值。
反光色=反光率·(视角方向相对于法线的反射方向对环境的采样)
在自定义shader中,我们可以对环境Cubemap进行采样获得反光色,就像从镜子里面看到周围的物体。
在标准shader中,并不会去采集周围物体的颜色,逐像素计算每个点的反光色是很困难的。
测试:新建场景,Cube使用绿色材质,Sphere的金属度和光滑度设置为最大值1。
观测结果:Sphere的表面完全镜面反射后,依然看不到周围的Cube,显示的默认skybox的颜色。
初步结论:默认的skybox相当于提供了一个默认的反射探针,对反射光的采样目标默认为skybox。
在Hierarchy中右键-Light-Reflection Probe,创建反射探针。
自建反射探针的意义:代替系统默认的反射探针,记录指定的反射内容。
反射探针就像摄像机一样,记录周围的环境,也相当于Cubemap,被其记录下的内容我们称为"记录目标"。
反射探针有一个Bounding Box,对范围内所有标准shader中含有Reflective属性的物体生效。
进入反射探针的编辑模式可以调整Bounding Box的范围。
Type:三种工作模式,Baked/Custom/Realtime,用于指定记录目标;对"哪些物体会受到影响"没有要求。
本例中Sphere采样方向:Sphere质心→表面一点。
当Shpere移动时,反射到的内容不会发生变化,与Shpere和反射探针的相对位置无关,但是要在其范围内。
Baked记录目标:范围内标记为Reflection Probe Static的物体+skybox。
Realtime记录目标:范围内任何物体+skybox,可以在Culling Mask中将不需要记录的物体排除。
Custom:指定的Cubemap。
注:反射探针也可以作为光源。
在无光的世界中,环境光为指定的颜色值,导致反射探针即使在无光的情况下所有面都铺满环境色(r,g,b)。
而自然界中的物体或多或少都有反射属性,可以从反射探针中采样到少量的环境色。

其他

问:Light Probe的被采样方向
问:什么是采样
问:为什么采样需要很多次,是什么原因造成每次采样的结果不同。
问:一次采样与一帧的区别。
渲染流水线中完成后备缓冲后,前后缓冲交换生成下一帧,称为一帧。
一次采样可以理解为一次光照计算,包括后期处理。


关注成长,注重因果。