Unreal Engine 4 的 光和影
UE4中的所有光源通过lightmass和直接两种方式作用于物体。同时灯光分直接光和间接光。各种灯光的Movable和Stationary类型都会对物体产生直接光照明。所有Static类型灯光,自发光材质物体以及Stationary经过lightmass后会对物体产生间接光照明。反射也是一种间接光照明(动态天光产生的天光反射属于直接光)
直接光都是动态光,可以实时变化颜色,亮度等等。所有的间接光都是静态光,但我们仍然可以通过后期以及材质来模拟的实时调整间接光的颜色和亮度
阴影分直接光阴影和间接光阴影;还有各种屏幕空间以及基于材质自身空间的阴影作为补充
直接光阴影必须有直接光存在。它们通常都是动态阴影
间接光阴影必须有间接光存在。它们可以是烘培后的静态阴影贴图;也可以是由 ILC/VLM 动态的阴影
光线的一个分支是走lightmass;先看下lightmass后产生的一些概念
关于lightmap
Lightmap为HDR,存有灯光方向信息
Stationary light build完灯光后还有Shadowmap;如果有Stationary天光会有sky occlusion map(Bent normal信息)
展UV的时候注意Min Lightmap resolution, 定义了UV块之间的距离。这个值要小于等于lightmap resolution,否则会出现lightmap像素无法匹配而溢出的问题
Lightmass设置对于品质和计算时间的影响
Lightmass portal提高lightmap的品质
Light Scenarios提供静态光变化的可能性
关于Mesh Distance Field:一种3D贴图,保存了到mesh最近表面的距离信息。mesh内部的是负距离
使用这些信息可以通过忽略掉空的区域加快阴影计算trace的速度,由于知道到到mesh表面距离,可以产生半影
关于ILC(indirect light cache间接光缓存)
球形谐波是一种非直射光cache的编码方式,也可以理解为如何把一张图片IBL编码到一个球体上的方式来表现这个位置光线的方向,强度,遮挡等信息。可以理解成一个非常低分辨率的cubemap(2*2像素每个面);编码的频率多少决定精度的高低, band的数量高低可以理解成LOD的概念,低级别的band可以表达大致的信息,但缺少细节,高级别的band里包含了更细腻的信息。 band的数量越多精度越高。一般游戏里出于实时渲染和内存的考量会使用2 band, 3band 一般使用于high end的渲染,比如Wetadigital在他们的电影渲染流程里应用的那样。 Cache的点的密度在电影渲染里会非常高,当然UE4里也是可以调节cache密度来符合不同性能和品质的要求
关于VLM(Volumetric ligthmap)
也是一种3阶球谐
ILC VS VLM
最主要的差别是VLM为逐像素插值(GPU),而ILC为逐物体(CPU)。像素级别插值带来的是更加细腻的光影过度,减少动态物体运动时间接光的突然变化;另外也为照亮Volumetric fog带来可能性
对比
打光前的准备:
PP 里AO关掉,EYE adaption关掉; SSR关掉
Directional light的特性:CSM,Far CSM, Modulated shadow(Mobile), Far distance Field Ray trace shadow; Capsule direct shadow只能由Directional light投射
• Far CSM可per object开启,可以选择性的来开启一些CSM距离外的大物体投影。
• Far Distance Field Ray Trace Shadow提供速度较快的ray trace shadow, 但精度较低,适合于中远距离CSM距离外的解决方案。前提需要开启mesh distance field
Sky light的特性:
• 动态Sky对物体产生直接的照明和直接的反射
• 动态Sky对物体产生Distance Field AO,这也是产生Distance Field AO的唯一类型的灯
• 动态物体的Distance Indirect Shadow
• Capsule Indirect shadow
• 静态天光会把直接光部分也cache到ILC里,结果可以通过ILC投射带有方向线性的Indirect shadow;否则只有反弹光被cache到ILC,Indirect shadow缺少天空明度的方向性
• 静态天光不产生sky的反射
• 静态天光产生的所有光(lightmap)以及反射都可以被材质AO和PP GI参数控制
• Stationary 天光,材质中的AO可以控制天光的反射和照明; 但无法控制Movable sky产生的反射和照明
• Sky cubemap下半部的颜色是地面的颜色,否则使用lower hemisphere is solid color来控制地面的颜色
• PP中的GI只能控制ILC和Lightmap中间接光的部分
• 移动仅支持静态skylight
反射
• 受ILC或者天光或则Lightmap影响,如果ILC和天光都是黑的(比如没有天光的全动态光环境),动态物体的反射也是黑的
• 无论是天光还是ILC还是lightmap照亮的,PP GI以及Material AO对其都有影响
• 因为PBR下所有材质都有一定的反射,所以即使是roughness 1的材质也会被reflection 影响其明暗
• 手机上采样最近的那个Reflection capture,除非开precise reflection(材质中)
• Reflection Capture的cubemap如果具有明显的方向性光源对于体现normalmap的效果以及反射高光的效果有利;尤其手机上,可以考虑使用自定义cubemap
移动平台灯光
• 首先调整好PP,在后期减少PC/Mobile差距:r.mobile.TonemapperFilm 打开;如果关掉TonemapperFilm需要调整Mobile Tonemapper(Contrast 0.15; Crush Hightlights 0)可以接近PC打开TonemapperFilm的效果
• 不支持所有distance field 相关的阴影。需要DX11以上
• 没有per-object投影,所以动态point light不投影
• 灯光类型:除所有静态灯外,动态Directional light, point light
• ICL和VLM都支持
• 角色阴影: single sample shadow from stationary lights
• Combined Static and CSM Shadowing 不需要CSM可以关掉,节省shader开销
• Lightmap direction可开关
• Reflection 采样方式为最近单个capture,无blend。除非high precise reflection 打开,最多混合3个,会占用贴图采样
• SSR, Contact shadow不起作用
阴影的种类
UE4为了平衡品质和效率使用了各种不同的阴影技术/方式;不同于离线渲染器;
所以由于效率的考量,UE4的阴影必须分开来讨论,分动态和静态,假阴影
另外为了更好区分应用,需要把直接光阴影和间接光阴影分开来看
• 静态的影子:
烘培到lightmap的阴影部分
stationary灯光烘培到shadowmap的影子,包括SDFS(Signed Distance Field Shadowmap); 以及Shadow Factor Shadowmap(打开灯光的Use Area Shadow For Stationary Light)
• 动态的影子:
CSM; Per-object shadow; Capsule shadow; Distance field shadow(DF shadow and DF soft shadow); Modulate shadow; DFAO
• 假阴影:
SSAO, Contact Shadow
• 直接光遮蔽:由直接光产生的阴影
Modulate shadow; capsule shadow; DF lightmap; Shadow factor shadowmap; Preshadows; Baked shadow on lightmap; DF shadow; DF soft shadow; CSM shadow; Per-object shadow; Contact Shadow
• 间接光遮蔽:
Baked shadow on lightmap; SSAO; DFAO; Capsule shadow;
• 静态物体能使用的阴影:
静态的影子;CSM; DF shadow (DF shadow & DF soft shadow); DFAO; SSAO; Contact Shadow
• 静态不能使用的影子:Capsule shadow; Per-object shadow
• 动态物体能使用的阴影: CSM; Capsule shadow(only for skeletalmesh); Per-object shadow; DF shadow(DF shadow & DF soft shadow); DFAO; SSAO; Contact Shadow
• Skeletal mesh不能使用的阴影:DF Shadows; DFAO
• 一些灯光特有的阴影:
CSM只能由Directional light投射
Capsule direct shadow只能由Directional light投射
• 材质中的光线屏蔽:
Material Ambient Occlusion Input:可以屏蔽所有ILC以及Lightmap,非动态天光(Static&Stationary?)以及静态反射产生的照明
关于Bent Normal
结合Material AO起作用;只能屏蔽间接光;外部预烘培,比如Substance Designer;作用于动态物体;Stationary天光build后为Staticmesh会生成Sky occlusion bent normal
Bent Normal效果
• 后期光线遮蔽:
Postprocess Indirect lighting intensity 影响Lightmap, 静态反射,ILC产生的照明
阴影的品质:
• 静态影子主要取决于lightmass的参数以及lightmap的分辨率,还有就是UV展的品质 具体见上
• 几个比较关键的参数是Static Lighting Level Scale越小精度越高; Indirect Lighting Quality越高质量越高,主要用来解决只有间接光照明区域产生的黑斑问题;Indirect Lighting Smoothness可以平滑一些lightmap的黑斑,色阶; Compress lightmaps对于高要求不压缩
• 对于Stationary lights使用Area light for shadowmaps可以产生虚影/半影
• Lightingmap的分辨率不需要太高,高了非常大的影响计算时间和磁盘内存空间
• Light portal的引用来提高天光的阴影
• 贴子Let’s Make Lightmass EPIC
• 动态的影子各种影子影响品质因素不同:
关于PCF filter。 动态影子的一种过滤处理方式,来提高影子的品质,开销高。动态影子filter的品质可以由r.ShadowQuality来控制PCF的fitler作用大小。 Shadow Filter Sharpen(Detail Panel中)可以来强化这个滤镜效果
• 动态阴影的精度显示是如何工作的
无论是CSM后者per-object shadow,都会有一个最大分辨率和最小分辨率。当前看到的阴影的精度取决于赋予的最大和最小分辨率的值,以及当前调用到了最大到最小之前的哪级。调用的机制取决于投射物屏幕空间的大小;越小,调用越低精度的阴影,直到达到其最小分辨率为止;越大调用越高精度的阴影,直到达到最大分辨率为止。我们可以通过一些设置和参数来提高最大最小阴影精度,以及提高或减小当前调用精度。比如提高最小精度可以强制提高屏幕空间占比并不是很大的物体的阴影精度;其他具体见下列参数解释
• 各种参数(主要影响CMS和Per-object shadow)
o r.Shadow.FadeResolution – 投射物在屏幕上的的分辨率多大的时候开始fade out(淡出)的行为。 Only for Per-Object Shadows
– 默认值: 64
– 减小这个值可以让阴影在更小的时候开始淡出,从另外角度讲也可以用作更远的距离开始淡出
o r.Shadow.MinResolution – 控制fade out结束的时候投射物在屏幕上的分辨率达到多大。这个值一般比FadeResolution 设置的小一些,以便有一个fade的过程。如果这个值比大于等于FadeResolution 大,那投射物在达到FadeResolution 的值之前就已经达到MinResolution,此时阴影突然消失,无fade过程。阴影消失后无开销。Only for Per-Object Shadows
– 默认值: 32
– 增加这个值可以提高远距离的阴影精度
o r.Shadow.TexelsPerPixel – 在一定距离调用比默认级别更高级(更高分辨率)的阴影,使得阴影更加清晰。 同样可以使用Shadow Resolution Scale(Detail Panel中)来提高或者减小阴影的调用级别
– 默认值: 1.27324
– 增加这个值来提高阴影的清晰度,精度;Only for Per-Object Shadows
o r.Shadow.RadiusThreshold 对于既使在CSM距离内屏幕空间太小的物体,也不会绘制阴影。这个值定义多小的物体需要绘制阴影
– 默认值: 0.03
– 减小这个值增加小物体CSM阴影的显示距离。Only for CSM Shadows;
o r.MinScreenRadiusForLights 灯光的可视距离。这个也可以由参数面板里Performance栏里的Max Draw Distance来控制(可配合Max Distance Fade range)
– 默认值 0.03
减小这个值使得更远距离的灯光还能照亮物体
o Scalebility: sg.shadowquality
[[email protected]]
r.LightFunctionQuality=0
r.ShadowQuality=0 PCF filter的品质,0不做PCF过滤,影子边缘锯齿(图见上面)
r.Shadow.CSM.MaxCascades=1
r.Shadow.MaxResolution=512 仅控制per-object shadow的精度
r.Shadow.MaxCSMResolution=512 仅控制CSM shadow的精度
r.Shadow.RadiusThreshold=0.06 见上
r.Shadow.DistanceScale=0.6 Scale CSM的显示距离,默认1
r.Shadow.CSM.TransitionScale=0
r.Shadow.PreShadowResolutionFactor=0.5 控制staticmesh在stationary light下投射到动态物体上的PreShadow的分辨率,越小越低
r.DistanceFieldShadowing=0
r.DistanceFieldAO=0
r.VolumetricFog=0
r.LightMaxDrawDistanceScale=0
• CSM的精度主要和参数有关。 距离越大越糊; 级数越少越糊;分布指数越大越把分布越靠向摄像机,否则越远离摄像机。增加这个值对于最近的阴影精度会增加,减小这个值增加中远距离的阴影精度
• Per-Object shadow品质受Actor的bounce大小影响,越大品质越差。 Point light的话还和距离物体的大小有关,越远越湖; Spot light和张角的大小有关,越大越糊
• DF shadow受mesh DF的精度影响,物体不要太大,不要有太多的非等比放缩
• Ray Trace Distance Field Shadow半影受到灯光面积大小影响。Point Light或者 Spot Light的面积以及Directional Light的Light Source Angle
• Capsule shadow受capsule本身setup是否合理,精度如何,light cache精度等影响。 受Directional light, Light Source Angle影响其半影大小
• Contact Shadow用来投射一些细小的影子,也可以弥补一些漏光问题
• SSAO受后期精度影响
r.AmbientOcclusionLevels=2
r.AmbientOcclusionRadiusScale=1.5
阴影的效率:
• 动态影子比静态费,动态影子还增加Draw call数量
• CSM很费,和面数有关,和屏幕覆盖率有关,和参数高低有关
• Per-object shadow也很费,和面数有关,和Actor数量有关,和屏幕空间覆盖率有关,和参数高低有关
• DF shadows 不受面数影响,效率比较高
• Capsule shadow 效率也很高,不受角色面熟影响
• SSAO和Contact shadow为后期效果,比较费
• Shadow map caching for movable lights:目前是自动开启, 可以大大降低Movale类型灯光对于静态环境的阴影开销(如果不移动)
• Single Sample Shadow from Stationary Lights开关单个component是否接受stationary light 从staticmesh cast的Preshadow
• 使用r.Shadow.PreShadowResolutionFactor来减小PreShadow的开销
• r.Shadow.ForceSingleSampleShadowingFromStationary 1 关闭所有静态物体到动态物体的shadow,使用light cache存储的遮蔽信息来shadowing动态物体。这个解决手机上角色无法被静态物体遮蔽的问题;PC上也可以减少Preshadowing 的开销
• Light Attachments as Group可以简化shadow frustum以及shadow的开销
实例开销
Paragon – console 60fps
• Static shadowmaps
Fortnite – console 30fps, fully dynamic
• 3 Cascades up to 4500 uu
• RTDF shadows up to 30,000
Kite – high end PC, huge open world
• 2 Cascades up to 10k
• RTDF shadows to 120k
• 3 Far Cascades up to 900k
阴影的控制:
通道;Cinematic; 灯光端/物件端
如何选择阴影:就是上面讲到的结合实际情况的一个平衡
• 静态物体尽量选择使用静态影子,无论从品质和效率方面都是如此
• 动态物体必须动态影子,根据品质和效率取舍:
• CSM品质可以很高,但没有半影,效率比较费,效率取决于被投射物体的面数,影子屏幕像素的覆盖率,还有阴影参数的精度高低
• Per-Object shadow 品质也可以很高,也没有半影,效率也比较费,效率取决于被投射物体的面数以及屏幕覆盖率,还有就是被投射物体的数量,及参数精度高低;这些都非常类似CSM,但因为CSM只能是直射光
• DF shadows(DF shadow & DF soft shadow)品质一般,受DF精度影响,不受面数影响,效率比较高,可以有半影
• DF AO:同上
• Capsule shadow: 品质一般,受capsule的数量精度设置是否合理等有关;跟light cache的精度有关;有半影,效率也很高;非常好的动态间接光遮蔽,尤其对于角色
• 效率上考虑不同距离使用不同类型的阴影,比如室外开阔场景动态阴影,地形不支持DF shadow, 远距离使用Far CSM,其他物体远距离使用DF shadow,因为DF shadow比CSM便宜,因此兼顾品质和效率
具体应用环境实例
- 室外开阔昼夜/变化灯光环境:灯光以直射光为主
CSM并调节品质距离等; 地形打开Far CSM; Per-object给远距离动态物体;Shadowmap Caching for movable light确保打开;角色可以Capsule shadow; 远距离静态物体DF shadow; DFAO打开; SSAO; Contact shadow;
- 室内或者多反弹环境:各种Spot/Point light
静态lightmap,静态物体走DF shadowmap;动态物体走per-object shadow并为间接光打开Capsule shadow;如果有室外天光照明,使用light portal来提高天光遮蔽的品质;不要开DFAO;SSAO可以开;如果有动态光静态物件可以关闭静态阴影,打开DF shadow;对于静态阴影注意灯光的形状对阴影的影响,包括灯光的形状,反弹板,自发光物体;Reflection是可以被lightmap遮蔽的,尤其对于特别光滑的表面;这个可以控制遮蔽的多少,在project setting里 Reduce lightmap mixing on smooth surfaces