在Unity移动端实现动态天气和时间系统,同时保证性能和视觉效果,确实是一个常见的挑战。你提出的问题——静态场景保持烘焙间接光照效率,动态元素响应实时主光源变化——正是解决这个问题的核心思路。全实时光照在移动端几乎是性能杀手,所以“混合照明”是我们的最佳策略。
下面我将详细介绍如何通过Unity的内置功能和一些技巧来实现这一目标:
核心策略:混合照明(Mixed Lighting)
Unity的混合照明模式(Mixed Lighting Mode)正是为了解决你这样的需求而设计的。它允许部分光照信息被烘焙,同时允许其他部分保持实时,从而在性能和灵活性之间取得平衡。对于动态天气和时间系统,最关键的是将主方向光(太阳/月亮)设置为混合模式。
1. 主方向光的设置(Directional Light)
光照模式(Mode)设置为
Mixed
:- 选择你的主方向光(通常用于模拟太阳或月亮)。
- 在
Inspector
面板中,将其Mode
属性设置为Mixed
。 - 当光照模式设置为
Mixed
时,它会对静态几何体贡献烘焙的间接光,并对动态对象贡献实时的直接光照和实时阴影。
动态控制方向光:
- 通过脚本,你可以实时调整这个方向光的旋转 (
Transform.rotation
) 来模拟时间的流逝,改变太阳/月亮的位置。 - 你还可以调整其颜色 (
Light.color
) 和强度 (Light.intensity
) 来模拟一天中不同时段的光线变化,或者天气(例如,阴天时强度降低,颜色偏灰蓝)。
- 通过脚本,你可以实时调整这个方向光的旋转 (
2. 静态场景的烘焙设置(Static Scene Baking)
标记为静态(Static):
- 场景中所有不动的几何体(地形、建筑、道具等)都必须在
Inspector
面板中勾选Static
。 - 更精确地说,是勾选
Contribute GI
,这表明它们将参与全局光照(Global Illumination)的计算。
- 场景中所有不动的几何体(地形、建筑、道具等)都必须在
光照设置窗口(Lighting Window -
Window > Rendering > Lighting
):- 环境光照(Environment Lighting):
- 将
Source
设置为Skybox
。你的Skybox材质应该能反映当前时间或天气。烘焙时,Skybox的颜色和亮度将作为环境光的来源,影响间接光照。 - 你也可以通过脚本动态调整Skybox的材质或参数(例如,白天用晴朗Skybox,夜晚用星空Skybox),并重新烘焙来反映环境光的巨大变化,但对于平滑过渡,主要还是依赖主方向光。
- 将
- 混合光照模式(Mixed Lighting Mode):
- 在
Lighting
窗口的Lightmap Settings
部分,Mixed Lighting
下拉菜单有两个主要选项:Baked Indirect
(烘焙间接): 这是你当前需求的首选。它会将Mixed
模式光照的间接部分烘焙到Lightmap中,而直接光照和阴影则保持实时。这样,静态物体在间接光照上获得了高性能,同时能够实时响应主光源的直接光照和阴影。Shadowmask
(阴影遮罩): 这种模式会将静态物体对静态物体的阴影烘焙成遮罩,而实时光照只计算动态物体对静态物体及动态物体自身的阴影。Shadowmask
能提供更精确的阴影,但会增加显存开销。根据移动端性能,Baked Indirect
往往是更安全的折衷方案。
- 在
- 环境光照(Environment Lighting):
生成光照贴图(Generate Lightmaps):
- 调整完所有设置后,点击
Generate Lighting
按钮。Unity会计算并烘焙静态场景的间接光照。
- 调整完所有设置后,点击
3. 动态元素的实时响应(Dynamic Elements)
实时直接光照和阴影:
- 你的角色和其他动态物体将接收来自
Mixed
模式主方向光的实时直接光照。 - 它们也会投射和接收实时阴影。请注意优化阴影质量和距离,因为实时阴影是性能开销大户。在
Quality Settings
中调整阴影分辨率、距离和级联数量(Cascaded Shadows)以适应移动端。
- 你的角色和其他动态物体将接收来自
光照探头(Light Probes)获取间接光:
- 关键点! 动态物体不会从Lightmap中获得间接光照,它们需要通过光照探头(Light Probes)来模拟场景的间接光照氛围。
- 放置光照探头组(Light Probe Group): 在场景中放置
Light Probe Group
,并在动态物体可能移动的区域均匀分布探头。 - 烘焙光照探头: 在生成Lightmap时,Unity也会计算这些光照探头捕捉到的间接光照信息。
- 动态物体材质: 确保你的动态物体(角色、可移动道具等)使用的材质支持光照探头。通常,Unity的标准着色器和URP/HDRP的默认着色器都支持。
反射探头(Reflection Probes):
- 如果场景中有需要反射的动态物体(例如水面、金属),可以放置
Reflection Probes
。 - 可以设置为
Baked
或Realtime
。对于动态环境,Realtime
更能反映变化,但性能开销巨大,通常只用于少量关键反射或在高性能设备上。对于大部分情况,Baked
配合Custom
或Skybox
更新频率可以尝试。
- 如果场景中有需要反射的动态物体(例如水面、金属),可以放置
4. 优化与注意事项
- 通用渲染管线(URP/HDRP): 强烈建议在移动端项目中使用 通用渲染管线 (URP)。URP专门为移动平台进行了优化,提供了更现代、更高效的渲染路径,并且对混合照明的支持也很好。在URP中,你会使用
Lit
或Simple Lit
Shader,并配置Renderer Features
。 - 光照贴图分辨率: 不要使用过高的光照贴图分辨率。根据场景复杂度,逐步尝试,找到视觉效果和包体大小、显存开销的最佳平衡点。
- 压缩格式: 烘焙的光照贴图可以进行压缩,减少内存占用。在
Lightmap Settings
中调整。 - 剔除(Culling): 确保你的动态光照(例如点光源、聚光灯)有合适的剔除距离,只在需要时才点亮。主方向光通常是全局的,不受剔除影响。
- 环境光更新: 即使是
Baked Indirect
模式,如果Skybox的整体色调在白天和黑夜之间变化巨大,你可能需要考虑在运行时通过脚本调整RenderSettings.ambientSkyColor
,RenderSettings.ambientEquatorColor
,RenderSettings.ambientGroundColor
来近似模拟环境光的变化,使其与动态方向光和Skybox更好地融合。 - 脚本控制细节:
- 可以通过一个主脚本来管理时间的流逝和天气的变化。
- 这个脚本可以控制
Directional Light
的旋转、颜色、强度。 - 同时,它还可以控制
RenderSettings.skybox
材质参数(例如,调整材质的曝光、色调,或直接切换不同的Skybox材质)来模拟天空的变化,并影响环境光。
通过以上混合照明方案,你可以让静态场景享受烘焙光照带来的高性能,同时确保动态的角色和物体能对实时的主光源变化做出准确的视觉响应,从而在移动平台上实现一个既美观又高效的动态天气与时间系统。