3.6 光照 (Lighting) 与阴影 (Shadow)


文档摘要

3.6 光照 (Lighting) 与阴影 (Shadow) 三、Unity 核心模块 3.6 光照 (Lighting) 与阴影 (Shadow) 在 Unity 3D 游戏中,光照和阴影是至关重要的组成部分。它们不仅直接影响场景的视觉效果和氛围,还能增强沉浸感和真实感。一个精心设计的光照系统能够塑造物体的形状、材质,突出场景的深度和空间感,而阴影则为场景增加立体感和真实性,帮助玩家更好地理解物体之间的相对位置关系。本章节将深入探讨 Unity 中的光照和阴影系统,包括光源类型、光照模式、阴影类型、阴影设置、以及如何通过代码进行光照和阴影的控制和优化。 3.6.1 光照 (Lighting) 基础 光照是构建任何 3D 场景的基础。

3.6 光照 (Lighting) 与阴影 (Shadow)

三、Unity 核心模块

3.6 光照 (Lighting) 与阴影 (Shadow)

在 Unity 3D 游戏中,光照和阴影是至关重要的组成部分。它们不仅直接影响场景的视觉效果和氛围,还能增强沉浸感和真实感。一个精心设计的光照系统能够塑造物体的形状、材质,突出场景的深度和空间感,而阴影则为场景增加立体感和真实性,帮助玩家更好地理解物体之间的相对位置关系。本章节将深入探讨 Unity 中的光照和阴影系统,包括光源类型、光照模式、阴影类型、阴影设置、以及如何通过代码进行光照和阴影的控制和优化。

3.6.1 光照 (Lighting) 基础

光照是构建任何 3D 场景的基础。在 Unity 中,光照系统模拟了现实世界中光线的传播和物体表面的反射,从而使场景中的物体能够被看见并呈现出不同的视觉效果。理解光照的基础概念和 Unity 中的光照组件是掌握光照技术的首要步骤。

3.6.1.1 光源类型 (Light Types)

Unity 提供了多种光源类型,每种光源都有其独特的特性和应用场景。了解这些光源类型及其属性,能够帮助开发者根据不同的需求选择合适的光源,并调整其参数以达到最佳的光照效果。Unity 中主要的光源类型包括:

  • 方向光 (Directional Light): 模拟来自无穷远的光源,例如太阳光。方向光具有统一的光照方向,照射场景中所有物体,且不随距离衰减。

    • 特点: 平行光线,无限距离,全局光照。

    • 应用场景: 模拟太阳、月亮等自然光,适用于室外场景或需要全局统一光照的场景。

  • 点光 (Point Light): 模拟从一个点向四周发射光线的光源,例如灯泡、蜡烛等。点光的强度会随着距离衰减。

    • 特点: 球形光照,光线向四周发散,距离衰减。

    • 应用场景: 模拟局部光源,例如房间内的灯泡、火把、爆炸效果等。

  • 聚光灯 (Spot Light): 模拟从一个点向特定锥形区域发射光线的光源,例如舞台灯光、手电筒等。聚光灯的光线强度和照射范围可以通过锥形角和衰减距离进行控制。

    • 特点: 锥形光照,光线方向可控,可设置锥形角和衰减。

    • 应用场景: 模拟舞台灯光、手电筒、汽车前灯等需要定向照明的场景。

  • 区域光 (Area Light): 模拟从一个面光源发射光线的光源,例如窗户、荧光灯管等。区域光能够产生柔和的阴影,但计算成本较高,通常用于烘焙光照贴图。

    • 特点: 面光源,产生柔和阴影,计算成本高,主要用于烘焙。

    • 应用场景: 模拟窗户光、天光等需要柔和阴影的室内场景,通常用于静态光照烘焙。

可以使用 Mermaid 的 graph TD 图来可视化这些光源类型:

代码实践 - 创建和调整光源:

在 Unity 编辑器中,可以通过菜单栏 GameObject -> Light 创建各种类型的光源。创建光源后,可以在 Inspector 面板中调整光源的各种属性,例如颜色、强度、模式、阴影类型等。

以下代码示例展示了如何通过脚本动态创建和调整光源的属性:

using UnityEngine; public class LightControl : MonoBehaviour { public Light myLight; void Start() { // 创建一个点光源 GameObject lightGameObject = new GameObject("MyPointLight"); myLight = lightGameObject.AddComponent<Light>(); myLight.type = LightType.Point; // 设置光源位置 lightGameObject.transform.position = new Vector3(0, 3, 0); // 设置光源颜色和强度 myLight.color = Color.yellow; myLight.intensity = 2f; // 启用阴影 myLight.shadows = LightShadows.Soft; } void Update() { // 动态调整光源强度 (例如,通过键盘输入控制) if (Input.GetKey(KeyCode.UpArrow)) { myLight.intensity += Time.deltaTime; } if (Input.GetKey(KeyCode.DownArrow)) { myLight.intensity -= Time.deltaTime; } } }

内容详解:

  • GameObject lightGameObject = new GameObject("MyPointLight");: 创建一个新的空 GameObject 作为光源的载体。

  • myLight = lightGameObject.AddComponent<Light>();: 为 GameObject 添加 Light 组件,该组件负责控制光源的各种属性。

  • myLight.type = LightType.Point;: 设置光源类型为点光。

  • lightGameObject.transform.position = new Vector3(0, 3, 0);: 设置光源在世界坐标系中的位置。

  • myLight.color = Color.yellow;: 设置光源颜色为黄色。

  • myLight.intensity = 2f;: 设置光源强度为 2。强度值越高,光照越亮。

  • myLight.shadows = LightShadows.Soft;: 启用软阴影。

  • Update() 函数中的代码: 演示了如何通过键盘输入动态调整光源的强度,实现实时的光照效果变化。

3.6.1.2 光照模式 (Lighting Modes)

Unity 提供了三种主要的光照模式,用于控制光照的计算方式和性能开销。不同的光照模式适用于不同的场景和性能需求。理解这些光照模式对于优化游戏性能和实现所需的光照效果至关重要。Unity 中的光照模式包括:

  • 实时光照 (Realtime Lighting): 实时计算场景中的光照效果,包括直接光照和反射光照。实时光照能够动态地响应场景中物体和光源的变化,提供最灵活和动态的光照效果。

    • 特点: 动态光照,实时计算,灵活度高,性能开销大。

    • 适用场景: 需要动态光照效果的场景,例如角色移动、动态光源、昼夜循环等。

  • 烘焙光照 (Baked Lighting): 预先计算场景中的静态光照效果,并将光照信息存储在光照贴图 (Lightmap) 中。烘焙光照能够显著降低运行时性能开销,并实现高质量的全局光照效果,例如全局光照 (Global Illumination, GI)。

    • 特点: 静态光照,预先计算,性能开销低,高质量全局光照。

    • 适用场景: 静态场景,例如室内场景、固定布局的关卡等,追求高质量光照和性能优化的场景。

  • 混合光照 (Mixed Lighting): 结合了实时光照和烘焙光照的特点。混合光照允许部分光源进行实时计算,同时将静态光源的光照效果烘焙到光照贴图中。混合光照可以在性能和灵活性之间取得平衡。

    • 特点: 部分动态,部分静态,性能和灵活性平衡。

    • 适用场景: 包含动态物体和静态物体的场景,例如角色可以在预烘焙光照的场景中移动,并与实时光源交互。

可以使用 Mermaid 的 graph TD 图来可视化这些光照模式:

内容详解:

  • 实时光照 (Realtime Lighting):

    • Unity 的实时光照系统基于物理的光照模型,能够模拟光线的反射、折射、散射等现象。

    • 实时光照的计算量较大,尤其是在场景中光源数量较多、阴影质量较高时,会显著增加 GPU 的负担。

    • 实时光照适用于需要动态光照效果的游戏,例如角色移动时,光照和阴影需要实时更新。

  • 烘焙光照 (Baked Lighting):

    • 烘焙光照通过预先计算场景中静态光源的光照效果,并将结果存储在光照贴图中。

    • 光照贴图是一种纹理,存储了场景中每个表面接收到的光照信息。在运行时,Unity 只需要读取光照贴图,而无需进行实时的光照计算,从而大大降低了性能开销。

    • 烘焙光照适用于静态场景,例如室内场景、建筑场景等。烘焙光照可以实现高质量的全局光照效果,例如光线在墙壁和天花板之间的反弹,产生更柔和、更自然的照明效果。

    • 烘焙光照的缺点是无法处理动态物体和动态光源。场景中的动态物体不会接收烘焙的光照,动态光源的光照效果也不会被烘焙。

  • 混合光照 (Mixed Lighting):

    • 混合光照模式旨在结合实时光照和烘焙光照的优点,在性能和灵活性之间取得平衡。

    • 在混合光照模式下,开发者可以选择哪些光源进行实时计算,哪些光源进行烘焙。通常,静态光源(例如窗外的阳光、环境光)会被烘焙,而动态光源(例如手电筒、爆炸效果)则会实时计算。

    • 混合光照模式允许动态物体接收来自烘焙光源的间接光照,并与实时光源进行交互,从而在保证一定程度动态性的同时,降低性能开销。

代码实践 - 设置光照模式:

光照模式的设置主要在 Unity 编辑器的 "Lighting" 窗口中进行 (Window -> Rendering -> Lighting)。在 "Scene" 选项卡中,可以设置 "Lighting Mode" 为 "Realtime", "Baked" 或 "Mixed"。

也可以通过代码访问和修改光照设置,但通常情况下,光照模式在编辑器中设置即可。以下代码示例展示了如何访问当前的光照设置:

using UnityEngine; using UnityEngine.Rendering; public class LightingSettingsControl : MonoBehaviour { void Start() { // 获取当前的光照设置 LightingSettings currentLightingSettings = RenderSettings.lightingSettings; // 打印当前的光照模式 (注意,运行时无法直接获取 Lighting Mode 的字符串表示) Debug.Log("Current Lighting Mode (Internal Value): " + currentLightingSettings.mode); // 在运行时,更多的是关注光照质量和性能相关的设置,例如反射探针更新频率等。 Debug.Log("Reflection Probe Refresh Mode: " + RenderSettings.defaultReflectionMode); } }

内容详解:

  • LightingSettings currentLightingSettings = RenderSettings.lightingSettings;: 获取当前的全局光照设置对象。

  • Debug.Log("Current Lighting Mode (Internal Value): " + currentLightingSettings.mode);: 打印当前光照模式的内部数值表示。 请注意, LightingSettings.mode 返回的是一个枚举值,而不是直接的字符串 "Realtime", "Baked" 或 "Mixed"。 在运行时,更多的是通过调整和查询光照质量和性能相关的参数,而不是直接修改光照模式本身。

  • Debug.Log("Reflection Probe Refresh Mode: " + RenderSettings.defaultReflectionMode);: 演示了如何访问其他光照相关的设置,例如反射探针的更新频率。

3.6.1.3 光照设置 (Lighting Settings)

Unity 的 "Lighting" 窗口提供了丰富的全局光照设置,用于控制场景的整体光照效果和烘焙参数。这些设置影响着全局光照 (Global Illumination, GI)、环境光照、光照贴图的分辨率和质量等。理解和合理配置这些设置对于优化光照效果和性能至关重要。

"Lighting" 窗口主要包含以下几个选项卡:

  • Scene: 场景级别的光照设置,包括光照模式、全局光照、环境光照、雾效等。

  • Environment: 环境光照设置,包括天空盒、环境光源、环境反射等。

  • Other Settings: 其他光照设置,包括光照贴图压缩、光照探针更新频率、阴影距离等。

  • Lightmaps: 烘焙光照贴图的管理和查看。

常用的光照设置包括:

  • Lighting Mode (光照模式): 如前所述,选择 "Realtime", "Baked" 或 "Mixed" 光照模式。

  • Realtime Global Illumination (实时全局光照): 启用或禁用实时全局光照。启用实时 GI 可以实现更真实的光照效果,但性能开销较大。

  • Baked Global Illumination (烘焙全局光照): 启用或禁用烘焙全局光照。启用烘焙 GI 可以实现高质量的全局光照效果,且运行时性能开销低。

  • Environment Lighting (环境光照): 设置环境光源的来源和强度,例如天空盒、颜色、渐变色等。

  • Environment Reflections (环境反射): 设置环境反射的来源和强度,例如天空盒、自定义反射探针等。

  • Shadowmask Mode (阴影遮罩模式): 用于混合光照模式,控制阴影遮罩的质量和性能。

  • Lightmap Resolution (光照贴图分辨率): 设置烘焙光照贴图的分辨率。分辨率越高,光照细节越丰富,但烘焙时间和存储空间也会增加。

  • Lightmap Compression (光照贴图压缩): 设置光照贴图的压缩格式,以减少存储空间。

  • Ambient Occlusion (环境光遮蔽): 模拟物体缝隙和角落的阴影效果,增强场景的深度感。

  • Fog (雾效): 添加雾效,增强场景的氛围和深度感。

代码实践 - 调整全局光照设置:

以下代码示例展示了如何通过脚本访问和修改一些常用的全局光照设置:

using UnityEngine; using UnityEngine.Rendering; public class GlobalLightingControl : MonoBehaviour { void Start() { // 获取当前的光照设置 LightmappingSettings currentLightmappingSettings = Lightmapping.settings; // 修改光照贴图分辨率 (示例,实际应用中需要根据场景大小和需求调整) currentLightmappingSettings.maxAtlasWidth = 2048; currentLightmappingSettings.maxAtlasHeight = 2048; // 修改环境光颜色 RenderSettings.ambientLight = Color.gray; // 启用/禁用环境光遮蔽 (示例,需要在 Renderer Feature 中配置 Ambient Occlusion 效果) // 运行时无法直接控制全局 Ambient Occlusion 的开关,通常通过 Renderer Feature 或 Post Processing Volume 来实现 // 例如,如果使用 Post Processing Volume,可以这样控制: // PostProcessVolume volume = GetComponent<PostProcessVolume>(); // if (volume != null) // { // UnityEngine.Rendering.PostProcessing.AmbientOcclusion ao; // if (volume.profile.TryGetSettings(out ao)) // { // ao.active = true; // 或 false 禁用 // } // } } }

内容详解:

  • LightmappingSettings currentLightmappingSettings = Lightmapping.settings;: 获取当前的烘焙光照设置对象。通过 Lightmapping.settings 可以访问和修改烘焙相关的参数,例如光照贴图分辨率、烘焙质量等。

  • currentLightmappingSettings.maxAtlasWidth = 2048;currentLightmappingSettings.maxAtlasHeight = 2048;: 修改光照贴图的最大宽度和高度。 这会影响烘焙出的光照贴图的分辨率。

  • RenderSettings.ambientLight = Color.gray;: 修改环境光的颜色。 RenderSettings 类包含了许多全局渲染设置,包括环境光、雾效、天空盒等。

  • 环境光遮蔽 (Ambient Occlusion) 的代码注释: 说明了全局环境光遮蔽通常不是通过 RenderSettings 直接控制开关,而是通过 Renderer Feature (URP/HDRP) 或 Post Processing Volume 来实现。 代码示例中给出了使用 Post Processing Volume 控制 Ambient Occlusion 效果的思路 (需要项目中已经配置了 Post Processing Volume 和 Ambient Occlusion 效果)。

3.6.2 阴影 (Shadows) 详解

阴影是光照效果的重要组成部分,它能够增强场景的立体感和真实感。在 Unity 中,阴影的生成和渲染涉及到光源设置、材质设置、渲染管线等多个方面。理解阴影的类型、设置和优化方法,能够帮助开发者创建更具沉浸感和视觉吸引力的游戏场景。

3.6.2.1 阴影类型 (Shadow Types)

Unity 提供了两种主要的阴影类型,用于控制阴影的质量和性能开销:

  • 硬阴影 (Hard Shadows): 也称为锐利阴影。硬阴影的边缘清晰锐利,计算成本较低,但视觉效果相对生硬。

    • 特点: 边缘锐利,计算成本低,视觉效果硬朗。

    • 适用场景: 对性能要求较高,对阴影质量要求不高的场景,例如移动平台游戏、低端设备游戏等。

  • 软阴影 (Soft Shadows): 也称为柔和阴影。软阴影的边缘模糊柔和,更接近真实世界中的阴影效果,但计算成本较高。

    • 特点: 边缘柔和,计算成本高,视觉效果真实。

    • 适用场景: 对阴影质量要求较高,性能允许的场景,例如 PC 游戏、主机游戏、高端设备游戏等。

可以使用 Mermaid 的 graph TD 图来可视化这两种阴影类型:

内容详解:

  • 硬阴影 (Hard Shadows):

    • 硬阴影的生成原理相对简单。对于每个像素,Unity 只需要判断该像素是否被光源直接照射到。如果被照射到,则该像素不受阴影影响;否则,该像素处于阴影中。

    • 硬阴影的边缘清晰锐利,没有模糊效果。这使得硬阴影在视觉上显得比较生硬,不太真实。

    • 硬阴影的计算成本较低,因为只需要进行简单的遮挡判断。

  • 软阴影 (Soft Shadows):

    • 软阴影的生成原理更复杂。软阴影考虑了光源的尺寸和形状,模拟了光线从不同角度照射到物体表面时产生的半影 (Penumbra) 效果。

    • 软阴影的边缘模糊柔和,更接近真实世界中的阴影效果。

    • 软阴影的计算成本较高,因为需要进行更复杂的采样和滤波操作。 Unity 中常用的软阴影实现技术包括 Percentage Closer Filtering (PCF)、Percentage Closer Soft Shadows (PCSS) 等。

代码实践 - 设置阴影类型:

阴影类型可以在光源组件的 Inspector 面板中进行设置。在 "Shadows" 选项组中,可以设置 "Shadow Type" 为 "No Shadows", "Hard Shadows" 或 "Soft Shadows"。

也可以通过代码动态设置光源的阴影类型:

using UnityEngine; public class ShadowTypeControl : MonoBehaviour { public Light myLight; public LightShadows currentShadowType = LightShadows.Soft; void Start() { if (myLight == null) { myLight = GetComponent<Light>(); } if (myLight != null) { myLight.shadows = currentShadowType; } } void Update() { // 动态切换阴影类型 (例如,按下空格键切换硬阴影和软阴影) if (Input.GetKeyDown(KeyCode.Space)) { if (myLight.shadows == LightShadows.Soft) { myLight.shadows = LightShadows.Hard; currentShadowType = LightShadows.Hard; Debug.Log("Shadow Type: Hard Shadows"); } else { myLight.shadows = LightShadows.Soft; currentShadowType = LightShadows.Soft; Debug.Log("Shadow Type: Soft Shadows"); } } } }

内容详解:

  • public Light myLight;: 声明一个 Light 类型的公共变量,用于在 Inspector 面板中关联光源。

  • public LightShadows currentShadowType = LightShadows.Soft;: 声明一个 LightShadows 类型的公共变量,用于存储当前的阴影类型,并默认为软阴影 (LightShadows.Soft)。 LightShadows 是一个枚举类型,定义了光源的阴影类型,包括 None (无阴影), Hard (硬阴影), Soft (软阴影)。

  • myLight.shadows = currentShadowType;: 在 Start() 函数中,将光源的 shadows 属性设置为 currentShadowType,从而初始化光源的阴影类型。

  • Update() 函数中的代码: 演示了如何通过按下空格键动态切换光源的阴影类型,在硬阴影和软阴影之间切换。

3.6.2.2 阴影设置 (Shadow Settings)

除了阴影类型,Unity 还提供了丰富的阴影设置,用于控制阴影的质量、性能和渲染效果。这些设置可以在光源组件的 Inspector 面板中的 "Shadows" 选项组中进行调整,也可以在 "Quality Settings" (Edit -> Project Settings -> Quality) 中进行全局设置。

常用的阴影设置包括:

  • Shadow Resolution (阴影分辨率): 控制阴影贴图的分辨率。分辨率越高,阴影细节越丰富,但性能开销也越大。

  • Shadow Strength (阴影强度): 控制阴影的深浅程度。强度越高,阴影越黑。

  • Shadow Bias (阴影偏移): 用于解决阴影自遮挡问题。适当调整 Bias 值可以减少或消除阴影表面的条纹或错误阴影。

  • Shadow Normal Bias (阴影法线偏移): 另一种偏移设置,用于解决法线方向的阴影自遮挡问题。

  • Shadow Distance (阴影距离): 控制阴影的渲染距离。超过该距离的阴影将被裁剪,以提高性能。

  • Shadow Cascades (阴影级联): 用于方向光,将阴影渲染区域分割成多个级联,每个级联使用不同的分辨率,以在近处提供高分辨率阴影,在远处提供低分辨率阴影,从而在性能和质量之间取得平衡。

  • Shadowmask Mode (阴影遮罩模式): 用于混合光照模式,控制阴影遮罩的质量和性能。

可以使用 Mermaid 的 graph TD 图来可视化一些重要的阴影设置:

内容详解:

  • Shadow Resolution (阴影分辨率):

    • 阴影贴图是一种纹理,用于存储阴影信息。阴影分辨率决定了阴影贴图的像素大小。

    • 更高的阴影分辨率可以提供更精细的阴影细节,例如更清晰的阴影边缘、更丰富的阴影纹理。

    • 阴影分辨率越高,GPU 需要渲染的像素越多,性能开销也越大。 需要根据目标平台和性能预算选择合适的阴影分辨率。 常用的分辨率选项包括 "Low", "Medium", "High", "Very High"。 也可以自定义分辨率数值。

  • Shadow Strength (阴影强度):

    • 阴影强度控制了阴影的深浅程度,取值范围通常为 0 到 1。

    • 当阴影强度为 1 时,阴影最黑。 当阴影强度为 0 时,阴影完全消失。

    • 可以根据场景的氛围和光照风格调整阴影强度。 例如,在恐怖游戏中,可以使用较深的阴影来增强阴森恐怖的气氛。

  • Shadow Bias (阴影偏移) 和 Shadow Normal Bias (阴影法线偏移):

    • 阴影自遮挡问题是指物体表面错误地投射阴影到自身表面,导致出现条纹或错误阴影。

    • Shadow Bias 和 Shadow Normal Bias 可以通过将阴影投射面稍微向光源方向偏移来解决自遮挡问题。

    • 需要根据场景和物体模型的具体情况调整 Bias 值。 过小的 Bias 值可能无法解决自遮挡问题,过大的 Bias 值可能会导致阴影与物体分离,出现 "Peter Panning" 现象。

  • Shadow Distance (阴影距离):

    • Shadow Distance 定义了从摄像机到场景中物体的最大距离,超过该距离的物体将不再渲染阴影。

    • 减小 Shadow Distance 可以减少需要渲染阴影的物体数量,从而提高性能。

    • 需要根据场景的大小和摄像机的视角范围调整 Shadow Distance。 在大型开放世界场景中,可以适当减小 Shadow Distance,以提高性能。

  • Shadow Cascades (阴影级联):

    • Shadow Cascades 是一种用于优化方向光阴影的技术。

    • 它将摄像机的视锥体分割成多个区域 (级联),每个级联使用不同的阴影贴图分辨率。

    • 靠近摄像机的级联使用较高的分辨率,以提供高质量的阴影细节。 远离摄像机的级联使用较低的分辨率,以减少性能开销。

    • Shadow Cascades 可以在近处提供高质量阴影的同时,控制远处的性能开销,从而在性能和质量之间取得平衡。 常用的级联数量选项包括 "No Cascades", "Two Cascades", "Four Cascades"。


发布者: 作者: 转发
评论区 (0)
U