Unity光照笔记

问题

在做项目中遇到了播放中切换场景后地面阴影是纯黑的问题,不得不研究一下光照。先放出官方文档。

Lighting 窗口 - Unity 手册

播放中切换场景后地面阴影是纯黑

只有投到地面的阴影是纯黑的。且跳转到使用相同Terrain的场景没有问题。

相关文章:

关于Unity在游戏运行过程中切换场景导致场景变暗的问题_unity切换场景后变暗-CSDN博客

Unity 切换场景变黑的问题_unity场景变黑了怎么变成原来的样子-CSDN博客

生成光照,可以解决。

这个操作生成了这几个文件:

对LightingData的官方介绍:

光照数据资源 - Unity 手册

没怎么看懂,大概是一个减小实时渲染开销的文件。我以为会把物体的影子刷到地面上,其实没有。

后来我发现设置static的物体在播放中是禁止改transform的,应该也就是在播放中才把背阴面、阴影这些刷到场景里,没播放时还是实时光照。

地形里树的阴影在相机离近时消失

这好像是官方文档里说的"光渗":

阴影故障排除 - Unity 手册

按里面的说法给树的Mesh Renderer的阴影选Two sided,没用。

生成光照特别慢

直接问了deepseek:

在unity的lighting settings里哪些参数可以显著加快生成光照的速度?

在 Unity 的 **Lighting Settings** 中,优化光照烘焙(Lightmapping)速度的关键参数主要集中在 **烘焙质量** 和 **计算复杂度** 的平衡上。以下是能显著加快生成光照的核心参数及其优化策略:


**一、全局参数优化**

| **参数** | **推荐调整** | **效果说明** |

|---------------------------|-----------------------------------------------------------------------------|-----------------------------------------------------------------------------|

| **Lightmapper** | 选择 **Progressive GPU**(需支持显卡)或 **Progressive CPU**(保守模式) | GPU 加速比 CPU 快 2-5 倍,但需 NVIDIA RTX 或 AMD RDNA2 以上显卡支持。 |

| **Lightmap Resolution** | 降低全局分辨率(默认 40 → 可试 **20-30**) | **最直接影响速度**,分辨率减半可减少 4 倍计算时间,但会降低光照细节。 |

| **Lightmap Padding** | 从默认 2 → 改为 **4-8**(根据模型间距调整) | 减少 Lightmap 贴图数量,但过度增大可能导致光照重叠。 |

| **Compression** | 勾选 **Compress Lightmaps** | 减少 Lightmap 内存占用,间接优化烘焙效率(但可能引入轻微噪点)。 |


**二、间接光照优化**

| **参数** | **推荐调整** |

|---------------------------------|-----------------------------------------------------------------------------|

| **Indirect Resolution** | 设置为 **Lightmap Resolution 的 0.25-0.5 倍**(如 Lightmap=40 → Indirect=10-20) |

| **Bounces** | 减少间接光反弹次数(默认 2 → **1**,复杂场景可试 0) |

| **Filtering (Direct/Indirect)** | 开启 **Auto** 或 **Advanced > Filter Radius 降低至 1-2** |


**三、环境光遮蔽 (AO) 优化**

| **参数** | **推荐调整** |

|-------------------------|---------------------------------------------|

| **Ambient Occlusion** | 关闭或降低 **Max Distance**(默认 1 → **0.5**) |

| **AO Quality** | 降低采样数(默认 High → **Medium/Low**) |


**四、模型与 UV 优化**

  1. **标记静态物体**
  • 仅对必要物体勾选 **Contribute GI**,减少烘焙对象数量。
  1. **简化 UV 展开**
  • 确保模型有合理展开的 **UV2**(避免重叠或拉伸,使用 **Auto UV** 或手动优化)。
  1. **Texel Density**
  • 统一场景模型的 **光照贴图像素密度**(如 20 texels/unit),避免部分物体分辨率过高。

**五、场景分块烘焙**

  • 使用 **Lighting Proxy** 或手动分块烘焙(仅烘焙修改区域)。

  • 通过 **Lighting > Generate Lighting** 的 **Partial Bake** 模式局部更新。


**六、进阶技巧**

  • **降噪加速**:启用 **Denoising**(Progressive Lightmapper)可减少采样数(**Direct/Indirect Samples** 降低 50%)。

  • **剔除小物体**:对小于 1 米或远距离物体关闭 **Cast Shadows** 和 **Contribute GI**。

  • **材质简化**:避免使用高反射(Metallic > 0.8)或自发光(Emission)材质,它们会增加光线反弹计算。


**优化前后对比示例**

| **场景复杂度** | **默认参数烘焙时间** | **优化后烘焙时间** | **质量损失** |

|------------------|---------------------|--------------------|--------------------|

| 小型室内场景 | 15 分钟 | 2-3 分钟 | 细节模糊(可接受) |

| 中型开放场景 | 2 小时 | 20-30 分钟 | 间接光轻微噪点 |


**注意事项**

  • **测试迭代**:建议从最低质量(**Lightmap Resolution=10**)开始测试,逐步提高至可接受质量。

  • **混合光照**:对动态物体使用 **Mixed Lighting**(Baked Indirect + Realtime Direct),减少实时计算负担。

  • **版本差异**:Unity 2021+ 的 **Progressive Lightmapper** 比旧版 **Enlighten** 更快更稳定。

通过以上参数调整,可显著减少光照烘焙时间,尤其适合快速迭代开发或低端硬件环境。牺牲部分细节质量换取效率提升,根据项目需求灵活平衡!

物体背阴面贴图有花斑

然后用了一组很低的参数,生成的光照贴图在房子背阴面是这样的:

同时在物体的Mesh renderer下有这个警告,说的应该就是这个问题。

又看了另一个有花斑的模型,没有这个警告,好像又不是因为Overlapping UV。

发现在模型导入设置里勾选Generate Lightmap UVs可以解决。

几个实验

主光源baked后生成光照的效果

场景没有阴影,人物没有被照亮。

可能也和光照设置有关。设置是这样的:

主光源Mixed,勾选Baked GI,Shadowmask

看起来和默认的实时光照一样。

光照相关资产文件

Lighting Settings

后缀为.lighting。是填在光照窗口Scene页签的文件。如果不填下面的设置都被禁用,因为使用了默认设置。

Lighting Data Asset

后缀为.asset。是生成光照费半天劲生成的文件之一。

Reflection Probe-0

后缀为.exr。是生成光照生成的文件之一。

光照贴图

分为较亮的dir结尾的、比较暗的light结尾的。它们是成对出现的,同一对是应用于同一些表面的。看检查器里的Texture Type可知第一种叫Directional Lightmap,第二种叫Lightmap。

一些理解

关于光照有很多参数:static(包括物体static和光源static)、光照的模式(实时、烘焙、混合)及其他设置、物体Mesh Renderer的设置、光照设置资产。

首先,只有对static物体,生成光照才有意义。

间接光照:物体背阴面、物体被其他物体遮挡的区域都收不到直接光照,靠间接光照照亮。物体阴面或阴影区全黑就是没有间接光照。

生成光照中一些模型黑色的部分是正在计算的部分。过一会会显示正常。

对Lightmap padding的理解:是生成的光照贴图里这些形状之间填充的纹素个数。

降低Draw Call

降低draw call(unity里叫batches)的方法有:

模型减少材质;

模型尽量共用材质;

烘焙灯光;

遮挡剔除;

遮挡剔除

在测试中遇到了1400次draw call的情况。把运行暂停,把场景里的对象分组失活,发现:

失活城镇3:1402>1119。失活城镇1:1397>953。此处城镇1是相机视野内的但是离得很远已经被地形完全挡住的城镇,但是造成了400多次Draw Call。

直接问deepseek:

在 Unity 中,要让被地形遮挡的物体不调用 Draw Call,需要通过 **遮挡剔除(Occlusion Culling)** 技术实现。以下是完整的实现步骤和优化方法:


**一、核心原理**

  • **遮挡剔除(Occlusion Culling)**:通过预计算或运行时检测,跳过对相机视野中**被其他物体完全遮挡的物体**的渲染,从而减少 Draw Call 和 GPU 负载。

  • **地形作为遮挡体**:将地形标记为遮挡物(Occluder),其他物体标记为被遮挡物(Occludee),Unity 会自动处理遮挡关系。


**二、实现步骤**

1. **启用遮挡剔除**

  • 打开 **Window > Rendering > Occlusion Culling**。

  • 在 **Bake** 选项卡中,确保 **Occlusion Culling** 功能已启用。

2. **标记静态物体**

3. **烘焙遮挡数据**

  • 在 **Occlusion Culling** 窗口的 **Bake** 选项卡中调整参数:

  • **Smallest Occluder**:设置地形细节级别(例如 `10`,单位:米,值越小精度越高)。

  • **Smallest Hole**:遮挡孔洞的最小尺寸(通常保持默认 `0.25`)。

  • 点击 **Bake** 生成遮挡数据,完成后会在场景中生成 **Occlusion Culling Data** 文件。

4. **验证效果**

  • 在 Scene 视图顶部下拉菜单中选择 **Occlusion Culling** > **Visualization**。

  • 移动相机,被地形遮挡的物体会显示为**红色(未渲染)**,可见物体为**绿色(已渲染)**。


**三、动态物体的处理**

若需要被遮挡的物体是动态的(如移动的敌人),需结合以下方法:

1. **脚本检测遮挡**

```csharp

using UnityEngine;

public class DynamicOcclusion : MonoBehaviour {

private Renderer rend;

void Start() {

rend = GetComponent<Renderer>();

}

void Update() {

// 检测物体是否被地形遮挡

if (Camera.main != null) {

Vector3 viewportPos = Camera.main.WorldToViewportPoint(transform.position);

bool isVisible = GeometryUtility.TestPlanesAABB(

GeometryUtility.CalculateFrustumPlanes(Camera.main),

rend.bounds

);

rend.enabled = isVisible; // 根据可见性开关渲染器

}

}

}

```

  • 将此脚本附加到动态物体上,根据可见性动态启用/禁用渲染。

2. **LOD(细节层次)配合**

  • 对中远距离物体使用低模(LOD1/LOD2),减少被遮挡时的计算开销。

**四、注意事项**

  1. **遮挡烘焙参数优化**
  • **Smallest Occluder** 值过大可能导致小物体无法遮挡其他物体,建议根据场景比例调整。

  • 复杂场景可分层烘焙:先烘焙地形,再烘焙建筑等大型物体。

  1. **性能权衡**
  • 遮挡剔除的预计算需要时间,适合静态场景。

  • 动态遮挡(如上述脚本)会增加 CPU 开销,需测试平衡。

  1. **地形设置**
  • 确保地形的碰撞体(Collider)完整,否则可能无法正确遮挡。

**五、常见问题**

Q1:烘焙后遮挡无效?

  • 检查物体是否标记为 **Occludee Static**。

  • 调整 **Smallest Occluder** 值,确保小于遮挡物的尺寸。

Q2:如何减少遮挡数据体积?

  • 增大 **Smallest Occluder** 和 **Smallest Hole** 的值。

  • 移除不必要的静态物体标记。


**六、替代方案**

  • **视锥体剔除(Frustum Culling)**:Unity 默认启用,仅渲染相机视锥体内的物体。

  • **硬件遮挡查询(Hardware Occlusion Query)**:适合高端设备,但需手动实现。

通过合理配置遮挡剔除,可显著减少地形遮挡区域的 Draw Call,尤其适用于开放世界或复杂室内场景! 🌟

照做之后在遮挡剔除Visualization看效果。远方有一些房子被剔除了,还有一些应该剔除的没剔除。这时候再运行,看向远方的小镇,batches最多只有700多次了,失活远方小镇batches还会降到500多次。然后就研究调整参数把这几个房子也剔除了。

URP项目动态合批设置的位置

Unity性能优化篇(三) SRP/URP动态合批开启与注意事项_unity 开启动态合批-CSDN博客

偏好>Core Render Pipeline>All Visible>项目设置>Graphics>Scriptable Render Pipeline Settings>Rendering

相关推荐
蒸蒸yyyyzwd13 分钟前
学习笔记 八股手撕
笔记·学习
揣一尾游鱼yu1 小时前
Spring上(IOC)笔记
java·笔记·spring·ioc
小李不想当小白3 小时前
BKP备份寄存器与RTC实时时钟(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
瑞码空间5 小时前
JSP与Servlet核心开发与CRUD实战笔记
java·笔记·servlet·jsp
La Pulga6 小时前
【FreeRTOS源码学习笔记】链表的实现
数据结构·笔记·stm32·mcu·链表·嵌入式·freertos
wuyoutrans8 小时前
以色列专利OA答复翻译,重点要避开哪些坑?
笔记
宝绿特塑业再生科技8 小时前
HDPE再生颗粒户外家具表面粉化机理与改性技术全解析
笔记·户外家具·再生塑料·塑木桌椅
Solange__8 小时前
在线3D预览器、Blender和游戏引擎怎么选?按5类任务比较格式、隐私与编辑性
人工智能·游戏·3d·游戏引擎·blender·1024程序员节·关卡设计
凉、介9 小时前
深入理解 ARMv7-A | Generic Timer
笔记·学习·嵌入式·arm
n 55!w !1089 小时前
MySQL笔记整理2
数据库·笔记·mysql