欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UE4 光照

程序员文章站 2022-06-10 23:48:04
...

static light

static light只有间接光,没有直接光。光照和阴影烘焙到lightmap;static light通过indirect lighting cache Sample Grid(需要有lightmass importance volume)影响动态物体。

stationary light

光源位置不变,但颜色和亮度会变。这是stationary light和static light的区别。后者在运行时,什么都不能改变。另外,运行时改变亮度只影响直接光照。因为间接光照是预先用lightmass烘焙的,不会改变。三种光照可移动性的光照中,stationary光照效率最高,中等易变形,中等性能消耗。
stationary光照的间接光照和阴影都存储在lightmap中;直接阴影存储在Shadowmap中。这些光照用到Distance Field Shadows,也就是说即使光照的物体lightmap分辨率很低,还是会很清晰。

直接光照

用延迟着色动态渲染。所以,运行时,可以改变亮度和颜色。通过改变Visible属性可以使直接光照显示或隐藏。

直接阴影

光源的实时阴影是主要性能消耗。动态光带阴影开销是动态光不带阴影开销的20倍。所以stationary光可以在静态物体上有静态阴影,但是有限制。

static阴影

不透明物体

lightmass在build light过程中对静态物体上的stationary light生成了远距离shadowmap。即使在比较小的分辨率下,远距离shadowmap依然提供了准确的阴影过渡。远距离shadowmap也需要接收静态光照的staticMesh有单独的展uv。
最多能有4个重叠的stationary光照有静态阴影,因为光必须映射到shadowmap贴图的不同通道,所以最多有4个重叠的stationary光照。StationaryLightOverlap viewMode可以看重叠。当不能再分配通道时,光源图标会变成红色的叉。

半透明物体

半透明物体从stationary光接收阴影的开销也特别小。lightmass从运行时的透明静态几何体预计算阴影深度贴图。这种形式的阴影比较糙,以米为单位。静态阴影深度贴图的分辨率在BaseLightmass.ini文件中,StaticShadowDepthMapTransitionSampleDistanceX 和StaticShadowDepthMapTransitionSampleDistanceY 控制,默认是100,表示每一米一个纹素。

dynamic阴影

动态物体(移动性设为Movable的staticMesh组件或SkeletonMesh组件)需要与远距离shadowmap中得到的世界的静态阴影融为一体。这是通过Per Object阴影来实现的。每个动态物体从stationary光照创建2个动态阴影:一个控制静态环境投影到物体上的阴影,一个控制物体投影到环境的阴影。stationary光照的开销来源于它所影响的物体,它影响的物体足够多的时候,用Movable光照更划算。
逐物体阴影将一个shadowmap映射到物体的包围盒上,所以包围盒需要精确。skeletal mesh要有一个物理资源,粒子相同的包围盒需要足够大以容纳所有粒子。

平行光动态阴影

平行光stationary光很特殊,因为它既要支持静态阴影又要通过csm支持整个场景的阴影。动态阴影通过距离融入静态阴影,过渡一般无法分辨。改变Dynamic Shadow Distance StationaryLight属性为你想要过渡发生的范围。
movable组件在平行光用了csm的同时仍会创建逐物体的阴影。这种行为在动态阴影距离较小的时候有用,但距离大的时候会产生不必要的开销。关掉逐物体阴影,通过不勾选光源上的Use Inset Shadows For Movable Objects属性

间接光照

stationary光将他们的间接光照存储在lightmap(像static光一样)。间接光照不能在运行时改变颜色和亮度,也就是说即使不勾选visible,build light时,间接光照也会烘焙到lightmap中。光照上的IndirectLightingIntensity影响构建光照时,给定光源影响间接光照的程度。后处理体积设置上有IndirectLightingIntensity属性,能运行时改变,用来控制所有光照的lightmap贡献程度。

stationary光的Area阴影

stationary平行光有一个阴影属性位于Lightmass下面,Use Area Shadows for Stationary Lights。开启后,距离投射阴影的物体越远,阴影越柔和。

Movable光照

完全动态光照和阴影,坐标、旋转、颜色 亮度 falloff 半径,所有有的属性都能改变。没有间接光,不会烘焙到lightmap。

阴影

整个场景都用动态阴影,开销较大。开销来源于光照影响的mesh数及这些mesh的三角形数。所以,投射阴影的可移动光源的半径越大开销越大。

阴影缓存

当点光源或聚光灯不动的时候,我们会存储这个光源用的shadowmap以备下一帧所用。缓存是默认开启的。可以检测缓存对性能开销的影响:1.选择关卡中所有要投射动态阴影的光源;2.将光源可移动性设为Movable,Cast Shadow也勾选上;3.控制台输入Stat Shadowrendering查看动态阴影开销;4.r.Shadow.CacheWholeSceneShadows 0关闭缓存,r.Shadow.CacheWholeSceneShadows 0比较性能数据中的CallCount和InclusiveAug 数量。
缓存对性能开销影响特别大。我们可以通过r.Shadow.WholeSceneShadowCacheMb控制shadowmap缓存用的最大内存数。
shadowmap缓存的限制:
图元的Mobility属性为Static或Stationary;
关卡中材质没有用World Position Offset
光源类型为点光源或聚光灯,Movable,ShadowCasting开启
用了动画细分或像素深度偏移的材质当阴影深度缓存的时候会产生瑕疵。

Indirect Lighting Cache

4.18版本后, Volumetric Lightmap 代替 Indirect Lighting Cache成为默认体积光方式了。要重新用间接光照缓存,设置World Settings > Lightmass Settings > Volume Lighting Method为Sparse Volume Light Sample。
间接光照缓存工作方式:lightmass在关卡中放置采样点,在烘焙光照的时候计算采样点处的间接光照;渲染动态物体时,间接光照缓存检查该物体是否有可用光照,如果有,则用;如果没有(物体是新的或没有移动太多),间接光照缓存从预计算的光照采样点插值计算间接光照缓存。
光照采样点放置在lightmassImportanceVolume里面。
通过Show->Visualize->Volume Lighting Samples可以看到lightmass生成的采样点。
但这种工作流需要的内容比较少,有时候这种方式不能在一些区域无法得到比较多的细节,比如一个角色在悬浮空间中乘坐电梯或者飞行;这时,可以通过在这些区域放置LightmassCharacterIndirectDetailVolumes 得到更多的细节。
间接光照缓存也允许预览没有执行built light物体的光照。

sky light

sky light捕获到关卡较远处,并作为光源用到场景中。天空的外表和它的光照或反射要匹配,即使你的天空是来自大气层或天空盒上的层云或远处的山。你同样需要人为指定一个所用的cubemap。

Scene Capture

Skylight只在特定情况下捕获场景:
静态skylight,在构建光照时更新;
固定或动态skylight,加载时会更新,在Recapture Sky调用的时候也会更新。当你更换Skybox所用的贴图时,也并不会自动更新,需要用上面的方法手动更新。
应该用Skylight而不是Ambient Cubemap代表天空的光照,因为Skylight支持局部阴影,避免室内被天空照亮。

移动性

static完全烘焙到lightmap,消耗很少。在移动开发中,只支持static skylight。只有场景中static和stationary属性的Actor和灯光会被capture,用于照明。只有材质的自发光贡献被static skylight所捕获。所以要确定skylight的材质球设为unlit。

预计算sky light

当用static或stationary天光烘焙光照的时候,光照和阴影数据会被存放到lightmap中。

改善的static sky light directionality

4.18以前,static sky light被3阶球谐lightmass所表示,在太阳升起和落下的时候,无法捕获到一些细节。一个滤波的cubemap现在默认使用,提高了分辨率。lightmass也基于final gather射线的数量选择合适mipmap的cubemap贴图,避免锯齿。

stationary sky light的bent normal

stationary sky light的光照跟光照烘焙是分开的。lightmass烘焙的阴影保存方向遮挡信息,称为bent normal。这是从像素到最不被遮挡的方向的一个方向。最被遮挡的区域为skylight用这个方向方向,而不是表面法线法线,提高了裂纹处的质量。

多反弹

来自sky light的间接光照的多反弹通过调节world settings>lightmass>num sky lighting bounces设置来调整。设为10的效果远远好于设为1的效果。
要想让你的skylight反弹效果比较明显,你的材质需要在大多数情况下有较高的diffuse值。这个值越大,烘焙时间越长。

属性

sky light的属性可分为两个范畴:light和sky light。

light

强度:光源发射的全部能量
光源颜色:指定光发出的颜色
影响world:是否影响world
投射阴影
投射静态阴影:从static物体投射阴影
投射动态阴影:从动态物体投射阴影
间接光照强度:来自光源的间接光照的程度
体积散射强度:来自这个光源的体积散射强度。这个影响强度和光源颜色。
投射体积阴影:是否对体积雾产生阴影

sky light

源类型:是捕获远处场景然后用作光源还是用指定的cubemap。当捕获场景的时候,距离sky light比SkyDistanceThreshold大的任意物体都会被包含。 SLS captured Scene:从捕获场景构建sky light;sls specified cubemap
cubemap:如果源类型是指定cubemap,此处代表指定的cubemap
Source Cubemap Angle:源cubemap旋转的角度
cubemap分辨率:处理的cubemap 的mipmap0的最大分辨率,必须是2的整数幂。
sky distance阈值:捕获物体的最近距离(也被反射capture使用)
capture emissive only:只捕获自发光物体,节省开销。当用capture every frame的时候,推荐使用。
小的半球是否是固体色:所有来自小半球的光照是否应该设为0.可以用来阻止来自小球体的光照泄漏
Recapture Scene:触发操作。

半透明光照

Per-Pixed半透明光照开启通过在材质上设置:Translucency下Screen Space Reflection勾选,Lighting Mode设为Surface ForwardShading。

平面反射

ssr和平面反射

UE4支持实时平面反射,相比ssr它能提供更精确的反射表现,当然开销也更大。这是由平面反射的工作方式决定的,平面反射实际上从反射方向上把关卡重新渲染了一遍。SSR会有光的泄漏在某些地方,这是因ssr无法反射屏幕外的物体。

开启屏幕反射

  1. 通过勾选项目设置,渲染,lighting里Support global clip plane for Planar Reflections,然后重启ue。2.从Visual Effects下,拖Planar Reflection Actor到场景中。3.可以用G键显示或隐藏平面反射Actor,可以移动、旋转、缩放平面反射Actor调整位置,实现需要效果。

平面反射Actor属性

属性:扭曲强度、平面反射贴图滤波粗糙度值(值越大,gpu消耗越大)、平面反射消失开始距离,平面反射完全消失距离、平面反射开始消失角度、平面反射完全消失角度、屏幕百分比(降采样百分比影响gpu消耗,也影响反射质量)、fov(值越大,渲染消耗越大)、双面渲染场景(如果水平面开启了这项,要将水平面加到Hidden Actors中)、lod距离参数(设置大于1的值使平面捕获用比主视图更小的lod,加速捕获pass的执行)。

平面反射Actor Scene Capture属性

平面反射Actor有许多控制被捕获的实时反射的性能消耗的属性。
Primitive Render Mode:1. Render Scene Primtive (Legacy)渲染场景中所有图元;2.渲染场景图元:渲染除了Hidden Actors列表中的所有图元;3.Use ShowOnly 列表:只渲染在Show Only Actors列表中的Actor。
Hidden Actors:在Scene Capture中隐藏的场景Actor列表;
Show Only Actor:关卡中Actor列表
Capture Every Frame:是否每帧更新,如果不勾选,这个控件只在加载和删除时,渲染。
Capture on Movement:是否在移动时,更新capture内容。如果想在蓝图中手动capture,就要设为disabled。
Always Persist Rendering State:即使每帧capture为关闭的,还能持续渲染状态。这使运动模糊的速度和taa能够被计算。
Max View Distance Override:scene capture中渲染图元的最大渲染距离。在反射平面在一个封闭的区域比如室内或走廊时,将远距离物体从反射平面中裁剪掉。
Capture Sort Priority:为了解决多个capture组件相互依赖,在帧中设置capture优先级对gpu上的scene capture排序。
Profiling Event Name:设置profiling事件的名称当profiling gpu 的时候。
高级属性:
常见的显示属性:常见的显示标志对一些风格和Actor是否渲染到scene capture中进行开关。比如抗锯齿,雾,static和skeletal mesh等。
高级显示属性:常见的高级的显示标志,对一些风格和Actor是否渲染到scene capture中进行开关。比如,植被,instanced 静态mesh,paper2D Sprites等。
后处理显示属性:bloom,人眼自适应,运动模糊是否渲染到scene capture。
光源类型显示属性:sky light是否渲染到scene capture。
光组件显示属性:AO,动态阴影是否渲染到scene capture。
Hidden Show Flags:光照和后处理是否渲染到scene capture的开销。

平面反射的限制

平面反射可以提供逼真的反射,但也有一些限制:

  1. 平面反射使整个场景渲染两遍,所以在渲染线程和gpu上,你要为这个预算一半的时间;
  2. 限制世界中平面反射数量。一般,一个都比较多了。
  3. 适当的规定平面反射的大小,这样在平面反射不可见的时候就能裁剪掉;
  4. 渲染平面反射Actor的开销直接来自于场景中需要渲染的东西。三角形较多,dc较高的场景,性能开销越大,因为这些开销跟平面百分比无关。

平面反射性能

开启和关闭平面反射的开销可在GPU Visualizer窗口看到。完全用动态光照和阴影的场景,开启和关闭前后相差31ms;而用stationary和预计算光照和阴影的移动端的场景,开启和关闭前后相差1.67ms。因为后者的复杂性和大小都比前者小很多。

反射环境

反射环境特性在关卡的每个区域都提供了有效的有光泽的反射。许多重要的材质比如金属材质依赖于各个方向的反射,也就是反射环境所提供的。对动态物体反射和锐利的反射的支持需要额外的内存开销。

快速创建反射环境

想要快速获取你的工程关卡里的反射环境,可以照着下面这样做:

  1. 在关卡中加入几个光源,并构建光照;
  2. 从VIsual Effects下,选择Sphere Reflection加入到场景中。
    如果在场景中看不到反射效果,或者反射效果没有你想要的那么强,你可以这样:
  3. 确认你的材质球高光较明显,粗糙度较低,以更好地显示反射;
  4. 用Refection视图模式查看哪些被captured,以便知道哪些材质球需要调整。

用反射环境创建一个关卡

第一步,创建包含间接光照的diffuse光照。用lightmap,可以参考Lightmass页,如果不熟悉的话。一般的导致light mass间接光照无法正常工作的原因可能包含但不限于以下几个:

  1. 缺少lightmassImportanceVolume;
  2. 缺少或错误的lightmapUV;
  3. 世界属性里的Force No Precomputed Lighting设为true了。
    由于关卡的diffuse颜色是要被反射环境反射的颜色,我们需要做以下几点以获得更好的结果:
  4. 直接照明的区域和阴影区域有强烈的对比;
  5. 明亮的diffuse照明区域是会在反射中清晰显示;
  6. 较暗的阴影区域是反射最可见的地方;
  7. 用lit 视图模式,show flag里Specular关闭,就可以看到反射Capture看到的关卡的样子了。
    设置关卡的材质跟反射环境互相结合也很重要”
  8. 平的,镜面曲面会暴露出cubemap的结合投影到简单形状上的误差;
  9. 弯曲的几何体或粗糙的表面都能屏蔽这些误差,提供可信的结果;
  10. 用细节法线贴图或指定用在平面区域上的材质的某种程度的粗糙度将会有更好的反射效果。
    平面反射在你想要反射的区域进行捕获。将sphere capture放在你想要反射的关卡的地方,放在反射球内,关卡就会投影到这个球状物体内。避免把capture放的里几何体很近,这样的话,几何体会很显著,挡住了后面的重要的细节。

有光泽的间接高光

从技术角度说,反射高光提供了间接高光。我们通过分析光照获取直接 高光,但那只提供了在少数明亮区域的反射。我们也从Sky light从天空获得高光,但那也只提供了局部反射,因为Sky light cubemap是无限远的。间接高光使关卡的所有部位向所有其他部位反射高光,这对于金属类的没有diffuse影响的材质是非常重要的。
反射环境通过在许多点捕获静态关卡,然后把它重新投影到在反射下的球上。美术通过放置ReflectionCapture捕获点。反射在编辑时,为了辅助放置,实时更新,但运行时不变。将捕获的关卡投影到简单形状上,提供了反射的近似视差。每个像素在多个cubamap之间混合以获得最终结果。小的ReflectionCapture Actor覆盖大的,所以根据需要你可以在一些地方提炼反射视差的精确度。比如,你可以在屋子的中间房要给capture,然后通过在房屋的角落放置更小的capture优化反射。
通过从captured cubemap生成不同模糊程度的mipmap,可以支持不同光泽度的材质。
只在比较粗糙的表面上用cubemap反射会导致非常亮的反射,由于缺少局部遮挡导致的泄露。可以通过继续用lightmass生成的lightmap数据来解决。cubemap反射和lightmap间接高光通过材质的粗糙度进行混合。一个非常粗糙的材质(完全diffuse)会收敛于lightmap数据。这个混合主要结合了cubemap高细节部分光照数据和lightmap低频的另一部分光照数据。为了使这一部分准确工作,只有间接光照能在lightmap里。这意味着只有Stationary光源的间接光照可以改善粗糙表面的反射质量。静态光源不能和反射环境一起用,因为静态光源的直接光照也会烘焙到lightmap中。注意:这个与lightmap的混合也意味着map需要有有意义的间接diffuse光照,光照必须被烘焙以看到结果。

反射capture和lightmap的混合

当用Reflection Capture Actor时,ue4混合了来自Refelection Capture的间接高光和来自lightmap的间接diffuse光。这帮助我们减少泄露,因为反射cubemap只在空间里的某一点捕获,而lightmap在所有接收的表面计算,包含了局部阴影信息。
lightmap混合对于粗糙表面工作良好,这个方法在光滑表面表现并不好,因为来自Reflection Capture Actor的反射和其他方法像屏幕空间反射、平面反射并不匹配。所以,lightmap混合不用于特别光滑的表面。一个粗糙度为0.3的表面会获得完全的lightmap混合,逐渐变化到粗糙度0.1时,没有lightmap混合。这也使Reflection Capture和屏幕空间反射能更好的匹配,更难清晰地分辨出两者之间的过渡。

lightmap混合和现存的内容

默认情况下,lightmap混合是开启的,也就是说它会影响现有的内容。在有反射泄露到光滑表面上的情况,泄露情况会更加明显。为了解决这个问题,可以在关卡周围放置额外的Reflection Capture Actor来帮助减小泄露。或者可以revert回老的lightmap混合方式,通过 Edit > Project Settings > Rendering > Reflections,取消勾选 Reduce lightmap mixing on smooth surfaces。
也可以微调lightmap混合的程度,通过控制台命令:
r.ReflectionEnvironmentBeginMixingRoughness (default = 0.1)
r.ReflectionEnvironmentEndMixingRoughness (default = 0.3)
r.ReflectionEnvironmentLightmapMixBasedOnRoughness (default = 1)
r.ReflectionEnvironmentLightmapMixLargestWeight (default = 1000)

高质量反射

默认反射品质设置在性能和视觉品质之间取得了平衡,可能还是有些情况,想要获得更好的品质反射。下面介绍了获得高品质反射的可行的方法。

高精度static Mesh顶点法线和切线编码

得到高品质反射的一个重要因素是顶点法线和切线描述的准确性。特别高密度的mesh会导致相邻顶点整量化为相同的顶点法线和切线值。这会导致法线方位的块状跳跃。我们增加了将法线和切线编码成16bit每通道向量,使开发者在高品质和编码vertex buffer用多少额外内存间权衡。
方法:

  1. 在static mesh编辑器里打开一个static mesh,
  2. 在详细面板,展开lod0选项;
  3. 在lod0的下面,build Settings下,展开选项,开启Use High Precision Tangent Basis选项,并点击Apply Changes按钮应用。
    改变设置后,视口也会自动更新。反射的质量和static mesh细分的密集度直接相关。有更少细分的static mesh比有更多细分的static mesh拉伸的瑕疵更严重。

高精度GBuffer法线编码

开启高精度GBuffer法线编码选项会使GBuffer用更好的精度的法线编码。更高精度的GBuffer法线编码将法线向量编码进3个通道,每个通道有16bit。用这个更高精度的编码使像SSR这样的技术依赖于高精度法线。
开启方法:

  1. Edit->Project Setting->Engine->Rendering->Optimizations->GBuffer Format,从default改变为High Precision Normals。注意,这个编码需要增加的gpu内存,开启这个会直接影响工程的性能。
  2. 改变GBuffer格式不需要重启引擎,你可以很快看到不同的格式对于反射效果的影响。

Reflection Capture形状

现在又两种反射capture形状:球形和盒形。形状非常重要,因为它控制关卡的哪部分捕获到cubemap上,关卡以什么形状被反射重新投影上。关卡的那部分能接受cubemap的反射。

球状

球状是现在用的最多的。它不匹配被反射的几何的形状,但它没有不连续性或边角,球形有一个半径控制哪些像素会被cubemap所影响,关卡会被重新投影到的球形。

盒形

盒形在使用上有限制,一般只用在走廊和长方形房间里。

编辑反射探针

更新反射探针

反射探针不是自动更新的。只有下面几种情况会自动更新探针:
加载一个场景;
直接编辑Reflection Capture Actor的属性;
构建关卡光照。
其他情况,你需要点击Reflection Capture的update Captures按钮进行更新。

在一个反射探针中用custom hdri cubemap

反射探针需要有指定用哪个cubemap和指定cubemap大小的能力。 开发者可以选择最适合他们的性能,内存,品质需求的分辨率。
可以用custom cubemap,直接拖到Reflection Capture Actor上,然后点击更新Capture按钮刷新即可。

更改Reflection Probe分辨率

project setting->Engine > Rendering >Textures >Reflection Capture Resolution,修改reflection capture resolution。注意:如果用了高的分辨率贴图,会增大gpu内存需求。

调整skylight反射分辨率

选择Skylight ,Detail下Light下,source type选择SLS Specified Cubemap,选择cubemap,然后修改下面的Cubemap Resolution。

混合多个反射探针数据

场景里添加两个Reflection capture,调整两者的Influence Radius使他们相交。可以看到一个会影响另一个的效果。

性能考虑

反射环境消耗只依赖于影响屏幕上像素的capture数。非常类似于场景中的延迟光照。Reflection captures被他们的影响半径所限制,所以会很有效地被裁剪掉。光泽度通过cubemap的mipmap实现,所以在尖锐和粗糙反射之间的性能差别很小。

限制

  1. 这种方式的反射是近似的。物体的反射很少能匹配关卡中的实际物体,因为投影到简单的形状上。所以,倾向于场景反射中的物体的多个版本,多个cubemap混合到一起。平的、光滑的产生镜面反射的表面显示这种问题更明显。用细节的法线贴图和粗糙度来帮助打碎反射,减小误差。
  2. 将关卡捕获到cubemap是一个较慢的过程,要在游戏线程外部实现。所以,动态物体无法被反射,尽管他们能从静态关卡接受反射。
  3. 为了减少错误,只有关卡的diffuse被捕获。纯高光的表面(比如近似)会用他们的specular,好像他们会在捕获过程中被diffuse。
  4. 当一个墙的两面有不同的光照条件时,会有严重的泄露。一面会有正确的反射,但会泄露到另一面。
  5. 由于dx11硬件限制,cubemap用来捕获关卡的,最多有128个,世界中最多一次开启341个反射捕获。

阴影投射

世界中的阴影会使物体更接地气,给观察这一种深度和空间的感觉。静态阴影消耗跟渲染差不多,但动态阴影是性能上的最大开销。下面会讲述ue4中4种阴影投射。

静态光源

静态光源投射完全静态的阴影和光照,也就是说他们不会向动态物体投射直接影响(静态光照会烘焙到间接光照缓存中,所以会有一部分影响)。

平行光csm(cascading shadow map)(整个场景阴影)

Directional Stationary Lights很特殊,因为他们通过csm和静态阴影同时支持整个场景的阴影。动态阴影通过距离融合进静态阴影,Dynamic Shadow Distance StationaryLight属性调节过渡的范围。

Stationary Light Shadows

动态物体(StaticMeshComponents 或SkeletalMeshComponents为movable的物体)必须融合进来自远距离shadowmap的静态阴影。这是通过Per Object 阴影实现的。每个移动的物体都有两个stationary 光源的动态阴影:控制静态世界投影到物体上的,控制物体投射到静态世界上的。stationary光源的唯一阴影开销来源于它所影响的动态物体。这也意味着,开销变化会很大。依赖于有多少动态物体。如果动态物体特别多,用可移动的光源更划算。
逐物体的阴影被动态控件使用,通过将一个shadowmap应用到物体的边界,所以包围盒必须准确。skeletal mesh需要有物理资源;粒子系统,包围盒需要足够大,包含所有粒子。

动态阴影

动态光源投射到所有物体上,完全动态的光照和阴影。不会烘焙,*地投射动态阴影到所有物体上。static mesh,skeletal mesh,特效等,从动态光源上接收和投射阴影。
动态阴影是开销最大的。

预览阴影

编辑了stationary或static光源后,光照变为unbuilt,previe shadow可以让你知道当光照重建后,shadow是什么样子的。这些阴影带有“preview” 字样。

弯曲的法线贴图

在材质中用弯曲的法线会改善他们对光照和阴影的响应。

用弯曲法线的好处

  1. 减少光照构建后,光照泄露数。
  2. 和AO一起用,改善diffuse间接光照。通过对间接光照使用弯曲法线而不是 法线来使diffuse间接光照更接近GI。

创建弯曲法线

为了得到高质量弯曲法线贴图,并匹配ue对怎么计算弯曲法线贴图的假设,需要确保创建弯曲法线贴图时遵循下面几点:

  1. 用Cosine Distribution;
  2. 用Substance Designer 6生成弯曲法线,像生成标准的normalmap或ao map一样;
  3. 生成弯曲法线时,确保你的角色是T-pose;
  4. 弯曲法线和ao用同样的距离;
  5. 弯曲曲线和normal map在同样的坐标空间。

在ue中用弯曲法线

在材质图表中添加Bent Normal custom output节点,将你的弯曲法线贴图连接到所创建的节点上。同时,要保证有一个ao贴图连接到Ambient Occlusion输出上。

反射遮挡

弯曲法线贴图很强大,但又跟传统不同,这是用在反射遮挡或高光遮挡上的。一个AO贴图遮挡了diffuse间接光照,而反射遮挡也是类似的概念,但是用在高光间接光照上。

胶囊阴影

通过用一个物理资源做的代表角色的胶囊体来开启对Skeletal Mesh的soft阴影投射 的支持。soft阴影使角色在间接光照区域更真实,并在直接光照区域有soft阴影。

胶囊体阴影综述

角色胶囊体代表

用来支持软阴影的角色的近似表示的物理资源创建。由于胶囊体绑定了角色的骨骼,阴影可以在场景中移动,并准确地投射。

用法

打开skeletal mesh,在detail面板,lighting>shadow physics asset中设置要给capsule阴影用的物理资源。

胶囊体阴影设置

Capsule Direct Shadow:开启直接光照(移动光照)的软阴影;
Capsule Indirect Shadow:开启预计算光照(lightmap和skylight)的软阴影;
Capsule Indirect Shadow Min Visibility:间接光照区域,胶囊体阴影的亮暗。

Capsule Indirect Shadow

如果开启,角色的胶囊体代表会基于光照构建过程中,lightmass放置和计算的体积光照采样点,投射平行软阴影。如果你用了远距离ao,则软阴影会从你的角色投射,但不会使用方向性。
Capsule Indirect Shadow使在一些传统的shadowmap表现不好的地方表现更真实。
开启胶囊体间接阴影后,只有一个skylight作为光源的开放区域,方向性比较低,由于光照来自各个地方,当用预计算光照时,会在角色下方产生像灯泡一样的轻微的soft阴影。
在封闭的区域,光从开放区域进来的地方,间接光照缓存通过角色经过区域的采样点融合赋予胶囊体阴影方向性和softness。在门道处,角色的阴影很轻微,方向性不强烈,但当角色从门道移动开,阴影的强度和方向性增强。
Indirect Minimum Shadow Visibility属性:可以调节在用预计算光照的间接光照区域,胶囊体阴影最暗的程度。在需要降低capsule自阴影的区域或者降低阴影强度的区域,这个属性很有用,可以用来和周围阴影很好的融合。

capsule直接阴影

开启后,平行光的light source angle和spot或点光源的source radius用来定义接收阴影的soft程度。允许当直接光照时,直接控制capsule阴影的强度。
光源角度:平行光属性,用来创建soft区域阴影的动态阴影方法。调这个属性时,离投射阴影物体越远,阴影越软。
源半径:类似于光源角度,stationary聚光灯或点光源的source半径用来给你的角色软阴影。当用一个较大的值时,离投射阴影物体越远,阴影越软。
一旦光照已经构建好了,调整source radius属性不需要重新构建光照。这个属性只影响capsule阴影或mesh distance field开启的可移动actor。

性能

capsule阴影的gpu性能开销正比于所用capsule的数量,角色的数量,他们的阴影影响的屏幕大小。

GPU Cost with 10 Capsules Time in milliseconds (ms)

A single character on screen 0.29 ms
Each additional character on screen 0.05 ms
这个实现是非常高效的,它在half分辨率下,考虑深度升采样,计算阴影。同时用屏幕tile裁剪来降低阴影的光照,使只在需要的地方计算阴影。

限制

  1. 需要Dx11,因为tiled延迟实现需要compute shader;
  2. 可移动的点光源和聚光灯当前不支持;
  3. 误差mesh形状会有自阴影误差;
  4. 当胶囊体阴影太软,以至于变成ao,会有一个误差在阴影中,产生一个硬线。

mesh远距离场

ue4用远距离场使你游戏里的static mesh actor有动态ao和阴影。actor的mesh远距离场代表可以用在其他特性上,比如gpu粒子碰撞,甚至材质编辑器创建动态flowmap及其他。

如何工作

Signed Distance Field(sdf,矢量距离场)用来代表静态mesh的表面。通过将到最近的表面的距离存储到一张体积贴图中工作。mesh外部的任意一点都是正距离,mesh内部的任意一点都是负距离。下面的例子中,正向距离被追踪和存储来代表树。
sdf第一个有用的属性是当追踪一条射线时,你可以安全地跳过空的区域,因为到最近表面的距离已经是已知的了。这样,求交集只需要很少的几步。通过追踪一个距离场,很容易产生一个可见性结果,也就是说,当射线与mesh相交时,这个光源就会产生阴影。
sdf第二个有用的用途是当追踪一条射线时,通过追踪一个闭塞物体传输的射线的最近距离,不需要额外开销就能计算出一个近似的圆锥体交集。这个近似使用距离场做一个软的区域阴影和天空遮挡成为可能。这个属性是远距离ao等一些特性的关键,因为很小数量的圆锥体可以计算一个接收点的整个半球的软的可见性。

场景表现

创建的每个场景都由所放置的actor的mesh远距离场构成。当mesh远距离场生成时, 他们用三角形追踪离线生成一个体积贴图。这个方法在所有方向计算矢量距离场射线来获取最近的表面及其信息。
可以通过视图的Show > Visualize > Mesh Distance Fields看到mesh远距离场。

https://docs.unrealengine.com/en-us/Engine/Rendering/LightingAndShadows/LightMobility/StationaryLights
https://docs.unrealengine.com/en-us/Resources/ContentExamples/Lighting/2_2
https://docs.unrealengine.com/en-US/Engine/Rendering/LightingAndShadows/IndirectLightingCache
https://zhuanlan.zhihu.com/p/38125862
http://gad.qq.com/article/detail/41824
http://blog.sina.cn/dpool/blog/s/blog_7449610f0102w624.html?vt=4