UDN
Search public documentation:

ShadowingReferenceCH
English Translation
日本語訳
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

UE3 主页 > 光照 & 阴影 > 阴影参考指南
UE3 主页 > 关卡设计师 > 阴影参考指南
UE3 主页 > 光照师 > 阴影参考指南

阴影参考指南


文档概要: UE3中使用的阴影方法的详细参考指南。

概述


虚幻引擎 3 会使用一些截然不同的阴影解决方案:

  • Whole-scene dynamic shadows - 可以移动的光源会使用整体场景动态阴影。
  • Per-object dynamic shadows - 不可移动光源照亮可移动或动态对象会根据对象使用动态阴影。
  • Precomputed shadows - 不可移动光源照亮静态对象会使用预计算阴影贴图。
  • Precomputed lighting - 静态光源照亮静态对象会使用预计算光照贴图。

光源类


对于每个类型的光源,您都可以将它们放置在世界中,这里有一些不同的可以控制光源的阴影表现的类。这些类会通过在运行时以某种方式更改限制光源,或者将这个光源指定为一个“主”光源。

  • 每个光源的基类(例如,PointLight)是该光源的静态版本。它会将基于对象的动态阴影与预计算光照结合在一起使用。
  • 该光源的可移动子类可以在运行时移动。它会使用整体场景动态阴影。
  • 该光源的 Toggleable(可切换)子类不可以进行移动,但是它可以在运行时更改颜色和亮度。它会将基于对象的动态阴影与阴影地图结合在一起使用。
  • 该光源的 Dominant(主)子类与 Toggleable(可切换)光源类似,但是会使用距离场阴影地图。

LS_SpotLight.jpg LS_MovableSpotLight.jpg LS_ToggleableSpotLight.jpg LS_DominantSpotLight.jpg
聚光源 可移动
聚光源
可切换
聚光源

聚光源

使用建议

对于大多数光源,您应该使用基础的光源类: PointLight 、SpotLight 和 DirectionalLight。这些类对运行时性能多少都会有一些影响,因为它们都使用的是预计算光照。

对于不需要移动但是需要更改它们的颜色、亮度或运行时启用的状态的光源,您应该使用 Toggleable 光源子类: PointLightToggleable、SpotLightToggleable、DirectionalLightToggleable。这些类会将预计算阴影与运行时基于像素的光照结合在一起使用,对运行时性能只有一点影响。

对于大多数场景,您将需要具有一小部分可以将预计算阴影与比您可以通过预计算光照获得的质量较高的光照结合在一起使用的光源。对此,您要使用 Dominant 光源子类: DominantPointLight、DominantSpotLight 和 DominantDirectionalLight。这些类与 Toggleable 光源子类相似,但是有所限制,所以每个对象只能受到一个单独的 Dominant 光源影响。 它使得 Dominant 光源在运行时比 Toggleable 光源的效率稍高一点。要了解更多信息,请参阅主光源

对于您需要光源移动的情况,您必须使用 Movable 光源子类: PointLightMovable、SpotLightMovable 和 DirectionalLightMovable。这些类会在运行时每帧计算阴影和光照,所以它们对运行时性能的影响很大。

阴影类型


基于对象的动态阴影

不可移动光源将会对它们会影响的动态对象使用基于对象的动态阴影。基于对象的动态阴影是通过从光源的视角为对象渲染深度缓冲然后将其映射到世界上进行工作的。距离光源比投射的阴影深度缓冲中的深度更远的像素会进行阴影投影。使用过滤器在投影和照亮的区域之间创建一个软边。

在这个屏幕截图中,一辆飞起来的载具 (Cicada) 将会在桥上投下一个软的动态阴影。

LS_DynamicShadowing.jpg

基于对象的动态阴影的质量和投射情况由屏幕上投射的深度缓冲平截头体的大小决定,这取决于这个动态对象的边界盒大小。 这意味着它对于边界盒紧凑的对象最适用。 没有关联物理资源的骨架网格物体将会有一个松散的边界盒,它在运行时不会根据关节动画改变,所以它们的质量比较低,阴影消耗比较高。因此,带有物理资源的骨架网格物体将会包含一个每一帧通过关节动画计算的紧凑边界盒,所以它们的质量更高,阴影消耗更少。 由于这个原因,您应该为每个骨架网格物体创建一个物理资源?,无论它是否会有基于物理的动画。

您可以使用 "show shadowfrustums" 控制台命令,或者编辑器视窗的 Show(显示)->Advanced Flags(高级标志)菜单中的阴影平截头体选项,查看供基于对象的动态阴影使用的平截头体。

在这个屏幕截图中,骨架网格物体没有为它分配物理资源。这样它由蓝色长方体(为了可以看到添加了黑色的轮廓线)表示的阴影平截头体很大而且效率低。

LS_SkeletalMeshLooseShadowBounds.jpg

在这个屏幕截图中,骨架网格物体为它分配了物理资源。因此它由蓝色长方体(为了可以看到添加了黑色的轮廓线)表示的阴影平截头体比较紧凑而且效率高。

LS_SkeletalMeshTightShadowBounds.jpg

为了处理从静态对象投射到动态对象上的阴影,不可移动光源将会创建第二个基于对象投射的阴影的深度缓冲。这个深度缓冲将会通过光源和动态对象之间的静态对象进行创建。

在这个屏幕截图中,这个骨架网格物体通过预计算的阴影使阴影投射到它的上面。确保您将一个 DynamicLightEnvironments 分配给了这个动态骨架网格物体,取消勾选 "Use Boolean Environment Shadowing(使用布尔环境阴影)" 可以允许动态预阴影(SkeletalMeshCinematicActor 默认情况处于关闭状态)。

LS_DynamicShadowWithPrecomputedShadowSkeletalMesh.jpg

在这个屏幕截图中,这个插值的静态网格物体通过静态环境几何体使阴影投射到它的上面。确保您将一个 DynamicLightEnvironment 分配给了这个插值静态网格物体,取消勾选 "Use Boolean Environment Shadowing(使用布尔环境阴影)" 可以允许动态预阴影(InterpActor 默认情况处于打开状态)。

LS_DynamicShadowWithPrecomputedShadowStaticMesh.jpg

模块化阴影

基于对象动态阴影可以是模块化阴影或者是正常阴影。正常阴影会将阴影投射光源的影响作用遮罩到阴影接收器,而模块化阴影只会通过模块化的阴影颜色对阴影接收器的最终颜色进行模块化。静态光源需要模块化阴影来将基于对象的动态阴影与此类静态光源使用的预计算光照结合在一起,

在这个屏幕截图中,使用的是正常阴影。

LS_NormalDynamicShadows.jpg

在这个屏幕截图中,使用的是模块化阴影,Mod Shadow Color 被设置为 0.f, 0.f, 0.f, 1.f(黑色)。

LS_BlackModulatedShadows.jpg

LS_BlackModulateShadowProperties.jpg

在这个屏幕截图中,Mod Shadow Color 被设置为 1.f, 0.f, 0.f, 1.f(红色)。

LS_RedModulatedShadows.jpg

LS_RedModulateShadowProperties.jpg

静态光源和可切换光源默认为模块化阴影,而主光源默认为正常阴影。

整体场景动态阴影

对于可移动光源,使用的是整体场景动态阴影。整体场景阴影的工作方式与基于对象动态阴影的投射阴影深度缓冲相似,但是不会为每个对象创建一个投射的阴影深度缓冲,它们会为整体场景使用一个固定数量的阴影深度缓冲。聚光源使用一个单独的阴影深度缓冲,电光源使用六个与立方体的面对应的阴影深度缓冲,而定向光源使用一个或多个以观察者为中心的级联型阴影深度缓冲。

在这个屏幕截图中,一个可移动点光源投射的是整体场景阴影。

LS_WholeScenePointLightShadowing.jpg

在这个屏幕截图中,一个可移动聚光源投射的是整体场景阴影。

LS_WholeSceneSpotLightShadowing.jpg

在这个屏幕截图中,一个可移动定向主光源投射的是整体场景阴影。

LS_WholeSceneDirectionalLightShadowing.jpg

与基于对象的动态阴影不同,整体场景动态阴影无法进行模块化。

级联型阴影地图

定向主光源可以为整体场景阴影使用级联型阴影深度缓冲。如果光源是不可移动的,那么可以将级联型阴影深度缓冲与预计算阴影相混合,对附近的对象使用级联型阴影深度缓冲,对远处的对象使用预计算阴影。

LS_WholeSceneDirectionalLightShadowing.jpg

预计算阴影

可切换光源使用的是预计算阴影。使用在渲染这个光源时使用的灰度蒙板存储预计算阴影,或者是对于主光源使用一个带符号的距离场。

LS_ShadowMaps.jpg

预计算光照

静态光源在静态对象上使用预计算光照。预计算光照会将所有静态光源结合在一起。所以光源在运行不会再被分离开。由于这个原因,静态光源只可以通过动态对象投射模块化的基于对象的阴影。

LS_LightMaps.jpg

阴影不透明度


所有类型的阴影都会遵守蒙板材质不透明度。

LS_MaskedShadows.jpg

只有那些通过 Toggleable(可切换)光源或静态光源被静态对象投射的阴影会遵守半透明材质不透明度。

LS_TranslucentStaticShadows.jpg

为了使半透明材质将动态阴影投射为蒙板材质,请将该材质的Cast Lit Translucency Shadow As Masked属性设置为 true 并设置 Opacity Mask(不透明度蒙板)材质参数。

LS_StaticTranslucentShadowsDynamicMaskedShadows.jpg

阴影及光照贴图分辨率


预计算阴影与 BSP

要更改用于 BSP 表面的阴影贴图和光照贴图的分辨率,请选择这个表面或这些表面,然后点击 F5。这样做将会调出 Surface Properties(表面属性)菜单。

SurfProp.jpg

Pan/Rot/Scale 选项下,您将会找到一个 Light map(光照贴图) 值。这个值越低,最后产生的阴影的分辨率越高,如下面中的图片所示:

MapQuality.jpg

预计算阴影及静态网格物体

预计算阴影同样也会被投射在静态网格物体几何体上。默认情况下,阴影因数都是针对每个顶点进行计算的。要想得到更好的阴影分辨率,应该为每个静态网格物体生成一个阴影贴图。

阴影贴图要求所有的 UV 数据都是唯一的。不允许镜像或者并列显示。如果您的静态网格物体的 UV 具有镜像、堆叠、并列显示的情况,那么您将需要创建第二组新的唯一 UV。要了解有关如何设置多组 UV 的更多信息,请参阅 VertexBlendingTutorial

在静态网格物体编辑器中打开您的静态网格物体(在通用浏览器窗口中双击它)。将想要得到的数值填入到 LightMapResolution 中。默认值为 0,它代表将不会创建阴影贴图。

切记,会为关卡文件中您的网格物体的每个实例生成一个单独的阴影贴图,这样可能会出现明显的内存分支。

lightMapMesh.jpg

如果您的网格物体有多个 UV,那么请选择您想要为 LightMapCoordinateIndex 中的阴影地图使用的设置。默认值是 0,它是 UV 的初始设置。

注意,UV 通道的数量将会列在渲染窗口的左上方。

下面是一个基于顶点阴影 vs. 阴影贴图的示例图。

ShadowMaps.jpg

阴影选项


属性 默认值 说明
DirectionalLightComponent 级联型阴影贴图 整体场景动态阴影半径 0 或 2000 以观察者为中心的整个场景动态阴影的半径,它可以根据与相机之间的距离替代预计算阴影。半径为 0 会禁用动态阴影。目前只在定向主光源上支持这项功能。
DirectionalLightComponent 级联型阴影贴图 整体场景动态阴影级联数量 1 以观察者为中心的整个场景动态阴影的半径,它可以根据与相机之间的距离替代预计算阴影。半径为 0 会禁用动态阴影。目前只在定向主光源上支持这项功能。
DirectionalLightComponent 级联型阴影贴图 级联分布指数 4 应用于级联变换距离作为 WholeSceneDynamicShadowRadius 部分使用的指数。指数为 1 表示级联变换将会发生在与它们的分辨率成正比的距离。值大于 1 会使变换更靠近这个相机。
PointLightComponent Lightmass 阴影指数 2 光源的自发光表面而不是光源所影响的表面的半径。
LightComponent 光源组件 投射阴影 True 这个光源是否应该投射阴影。
LightComponent 光源组件 投射静态阴影 True 这个光源是否应该通过静态对象投射阴影。 同时还需要将 Cast Shadows(投射阴影)设置为 True。
LightComponent 光源组件 投射动态阴影 变量 这个光源是否应该通过动态对象投射阴影。 同时还需要将 Cast Shadows(投射阴影)设置为 True。
LightComponent 光源组件 投射组合阴影 True 光源是否应该通过使用组合光照的对象投射阴影(例如,一个启用了光源的环境)。
LightComponent 光源组件 影响组合阴影方向 True 如果 bCastCompositeShadow=TRUE,光源是否应该影响组合阴影的方向。
LightComponent 光源组件 非模块化的自阴影 False 如果启用了这项,并且光源可以投射模块化阴影,那么它会使通过这个光源渲染的阴影的自阴影使用法线阴影混合。使用它可以获得更好的自阴影质量,同时还会在光照贴图的环境上有一个阴影。启用这个选项后,它会使将这两种方法结合使用所产生的渲染消耗最多。
LightComponent 光源组件 仅限自阴影 False 光源是否应该只通过在它上面的动态对象投射阴影。
LightComponent 光源组件 强制动态光源 False 光源是否应该投射阴影,就好像它是可以移动的那样,不考虑它的类。
LightComponent 光源组件 光源阴影模式 变量 适用于光源的阴影类型。
LightComponent 光源组件 阴影过滤质量 SFQ_Low 适用于由光源投射的动态阴影的过滤的质量。
LightComponent 光源组件 Mod 阴影颜色 黑色 要使用可以从这个光源(前提是它可以投射模块化阴影)接收动态阴影的像素进行模块化的颜色。
LightComponent 光源组件 最小阴影分辨率 0 加载可以渲染阴影物体深度的最小尺寸(以贴图像素为单位)。它还可以控制阴影渐变,只要阴影分辨率达到 MinShadowResolution,它就会完全淡出。值为 0 默认为 SystemSettings 中的 MinShadowResolution。
LightComponent 光源组件 最大阴影分辨率 0 加载可以渲染阴影物体深度的最大尺寸(以贴图像素为单位)。值为 0 默认为 SystemSettings 中的 MaxShadowResolution。
LightComponent 光源组件 阴影渐变分辨率 0 低于它阴影就会开始淡出的分辨率(以贴图像素为单位)。只要阴影分辨率达到 MinShadowResolution,它就会完全淡出。值为 0 默认为 SystemSettings 中的 ShadowFadeResolution。
LightComponent 光源组件 使用直接光源贴图 True 如果在静态光源上设置为 false,那么会强制它使用预计算阴影而不是使用预计算光照。
Material 半透明物质 投射带光照的半透明阴影作为蒙板 False 是否将材质的不透明通道视作是一个蒙板而不是动态阴影中的部分不透明物质。
PrimitiveComponent 光照 投射阴影 True 会控制图元组件是否应该投射阴影。当前,动态图元不会接收来自静态对象的阴影,除非同时启用了这个标志和 bCastDynamicSahdow。
PrimitiveComponent 光照 投射动态阴影 True 可以控制在非预计算阴影的情况下图元是否应该投射阴影,例如图元在光源和动态对象之间。这个标志仅在CastShadow设置为TRUE时才有用。目前,动态图元将不会从静态物体上接受阴影,除非这个标志和CastShadow标志都被启用了。
PrimitiveComponent 光照 投射静态阴影 True 可以控制图元是否应该通过非移动阴影投射光源投射阴影。 同时还需要将 Cast Shadow(投射阴影)设置为 True。
PrimitiveComponent 光照 强制直接光照贴图 False 即使光源可能没有设置为使用光照贴图,但是将强制使用影响这个图元的所有静态光源的光照贴图。这意味着,图元将永远不会从阻挡静态光源的动态物体上接受任何阴影。在动态光源的情况下将可以正确地投射阴影。
PrimitiveComponent 光照 仅限自阴影 False 如果这一项为 true,那么图元只会对自己投影,不会在其他图元上投射阴影。当其他图元上的阴影不易察觉的时候可以将它作为一项优化使用。
PrimitiveComponent 光照 没有 Mod 自阴影 False 只适用于移动设备平台! 如果这个选项为 true,那么图元将不会接收到投射的 mod 阴影,不是来自于它本身或者任何其他 mod 阴影投射过来的。可以使用它避免自阴影失真现象。
PrimitiveComponent 光照 可以接受动态主光源阴影 True 对于那些不需要接收主光源阴影的对象的优化。它适用于那些占用大量 GPU 时间并且贴图边界紧密没有接收到来自主光源的明显阴影的对象,例如树。
PrimitiveComponent 光照 投射隐藏的阴影 False 如果该项为 TRUE,那么图元将会投射阴影,即使在 bHidden 为 TRUE 的情况下。它会控制图元是否应该在隐藏的情况下投射阴影。这个标志仅在CastShadow设置为TRUE时才有用。
PrimitiveComponent 光照 将阴影投射为双面的 False 这个图元是否应该就好像它是一个双面材质那样投射动态阴影。
PrimitiveComponent 光照 使用预计算阴影 变量 是否允许图元使用预计算阴影或光照。