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

相关推荐
愚戏师3 小时前
Linux复习笔记(六)shell编程
linux·笔记·shell
.(ᗜ ˰ ᗜ) .4 小时前
机器学习笔记2
笔记
小葡萄20254 小时前
黑马程序员c++2024版笔记 第一章 变量和基本类型
笔记·c++20
顾子茵4 小时前
计算机图形学基础--Games101笔记(一)数学基础与光栅化
笔记·图形渲染
黄暄5 小时前
初识计算机网络。计算机网络基本概念,分类,性能指标
笔记·学习·计算机网络·考研
Alice-YUE6 小时前
【HTML5学习笔记1】html标签(上)
前端·笔记·学习·html·html5
Alice-YUE6 小时前
【HTML5学习笔记2】html标签(下)
前端·笔记·html·html5
jerry6096 小时前
LLM笔记(五)概率论
人工智能·笔记·学习·概率论
烧火大爷6 小时前
现代计算机图形学Games101入门笔记(十四)
笔记