unity 烘焙 光照贴图 以及一些灯光的相关问题(一)

本文深入探讨Unity中光照贴图(Lightmap)的原理及应用,解析RealtimeGI与BakedGI的区别,详解光照模式(Realtime、Mixed、Baked)对静态与动态物体的影响,以及如何利用Mixed光源实现动态阴影。

在做游戏场景的时候,由于一般场景大部分的物体都是静止不动的(static),如果这些物体使用实时光照的话,会有很大的性能开销,比如物体的阴影。但是由于很多情况下,场景中大部分物体的位置不会在游戏运行的时候改变,对应的阴影也不会改变。光照环境不改变的话(例如不会存在白天黑夜的切换)场景的展现效果也不会改变。因此针对这样的情况,我们会使用光照贴图(Lightmap)的技术,事先烘焙(bake)好效果,节省性能的消耗。

注:文章中有些字段的名称可能在不同的Unity版本中不一样,大家自己拓展了~

首先我们简单的搭建一个场景(如图),方便测试效果。场景里Scene内的物体勾选为static,胶囊体People为动态物体,然后有一个白色的光照。为了防止天空盒的影响,我们将Lighting设置中的环境光全部设置为黑色(Window->Rendering->Lighting Settings)。

 

Unity GI(global illumination 全局光照),有Realtime GI和Baked GI两种(如上图Lighting的设置中)。当我们将场景的物体勾选为静态物体的时候会发现对应的Mesh Renderer中,会自动配置上Lightmap的相关设置(Lighting设置中勾选了Auto Generate ,否则要手动烘焙一下)

选择上RealtimeGI的话会生成对应的Realtime Lightmap,会根据场景的灯光实时更新,选择上BakedGI的话会生成对应的Baked Lightmap,只有在烘焙的时候才会根据设置好的灯光更新(勾选了自动生成的话,每次灯光或静态物体改变都会重新烘焙)

Unity中光源的光照模式(Light组件的Mode属性)有三种,Realtime,Mixed和Baked。在不同的GI情况下,不同模式光源会产生不同的效果,我们可以在上面的测试场景中新增baked光源和mixed光源进行测试:

Realtime GI 和 Baked GI 都不勾选(静态物体无lightmap)

Realtime实时渲染时:静态物体和动态物体都会计算该光源
Mixed无法选择该模式
Baked无法选择该模式

 

只勾选Realtime GI(静态物体有 realtime lightmap)

Realtime

烘焙时:静态物体的realtime lightmap会计算接受到该光源的间接光

实时渲染时:静态和动态物体都会计算该光源

Mixed无法选择该模式
Baked无法选择该模式

我们会发现,场景和灯光都不变的情况下,勾选了Realtime GI,静态物体小方块的几个面比之前变得更白,底部还会出现一些白色的阴影。我们观察生成的realtime lightmap(双击详情)可以发现,图片的左上部分代表了两个正方形各自的六个面左下大面积的部分代表了平面Plane。而那些白色的部分就是realtime光源的间接光信息,平面贴近小方块的地方,光源折射会从平面折射到小方块的面上,也会从小方块的面上折射到平面上,形成间接光(光的折射是GI最重要的一部分bounces)。而远离小方块的地区没有间接光的接受,所以lightmap中显示为黑色。实时渲染的时候会计算lightmap信息和realtime光源信息,所以造成了更白的现象。

只勾选 Baked GI (静态物体有 baked lightmap)

Realtime

烘焙时:静态物体的baked lightmap不会计算该光源

实时渲染时:静态和动态物体都会计算该光源

Mixed

烘焙时:静态物体的baked lightmap会计算接受到该光源的间接光信息

实时渲染时:静态和动态物体都会计算该光源

注:不同的Lighting Mode设置会有不同的效果,文章的后面详细描述(当前为默认的shadowmask模式)

Baked

烘焙时:静态物体的baked lightmap会计算接受到该光源的直接光和间接光信息

实时渲染时:静态和动态物体都不会计算该光源

baked:

我们可以在场景中新增一个光源Baked,颜色选为红色,Mode选为baked,烘焙好后的效果图与光照贴图如下:

可以发现,动态物体(胶囊体)不受红光影响,lightmap为baked光源的红色,实时渲染的时候计算了realtime的白色光源。此时运行Unity,再修改baked光源颜色,或删除该光源都不会对场景产生影响。

但是此时你会发现场景中静态物体会产生两个阴影,一个realtime的实时阴影,一个baked的烘焙好的阴影,这肯定不是我们要的效果。若隐藏了realtime光源,则动态物体不会产生阴影,这显然也是不对的,游戏中不可能场景中的房子有阴影但是行走的人却没有。那如何使静态物体只有烘焙的阴影,但是动态物体有实时的阴影呢,这就需要下面的混合光源Mixed的帮助了。

mixed:

在bakedGI下,若场景只有realtime光源,则不会有lightmap,动态物体和静态物体的阴影都需要实时计算。若只有baked光源,则静态物体会烘焙好阴影,但是动态物体却不受该光源的影响,无法产生阴影。若你想把静态物体烘焙成lightmap,同时同一个光源又对动态物体产生影响,可以形成动态阴影,那就需要mixed光源的帮助了。

我们隐藏场景中的其他光源,新建一个光源,颜色选为绿色,Mode选为mixed,烘焙好后的效果图与光照贴图如下:

此时运行unity,移动胶囊体,阴影会随着跟着移动。隐藏小方块阴影并不会跟着消失,因为是事先烘焙好的。修改mixed光源的方向的话,动态物体的阴影和光照效果都会随之改变,静态物体的光照效果会改变但是阴影不会。

 

Realtime GI 和 Baked GI 都勾选(静态物体有 realtime lightmap和baked lightmap)

Realtime

烘焙时:静态物体的realtime lightmap会计算接受到该光源的间接光信息,baked lightmap不会计算该光源

实时渲染时:静态和动态物体都会计算该光源

Mixed

烘焙时:静态物体的realtime lightmap不会计算该光源信息,baked lightmap会计算接受到该光源的间接光信息

实时渲染时:静态和动态物体都会计算该光源

Baked

烘焙时:静态物体的realtime lightmap不会计算该光源信息,baked lightmap会计算接受到该光源的直接光和间接光信息

实时渲染时:静态和动态物体都不会计算该光源

若Lighting设置中Environment Lighting的Ambient Mode选择Realtime,运行时改变环境光的属性静态物体和动态物体的光照效果都会发生改变(静态物体的Realtime lightmap改变),而选择Baked,则会把环境光也烘培起来,运行时改变环境光,并不会改变静态物体的光照效果 。

 

搞清楚GI和光源的关系后,我们接下来看看Lighting设置中Mixed Lighting的Lighting Mode的三个设置。首先我们只勾选Baked GI,然后场景中只留之前绿色的mixed光源。

baked Indirect

只烘培静态物体的受到的间接光照,直接光以及阴影进行实时计算。运行时改变灯光,直接光照和阴影就会变,但间接光不变(如果间接光弱,视觉影响不大)。只减少间接光照的实时计算,适合对光照要求较高的场景,内存消耗小,当然性能的消耗也大。 

运行后的效果如下,动态与静态物体的阴影随着mixed光源实时计算,静态物体烘焙的间接光效果不变。

shadowmask

除了烘焙静态物体受到的光照,同时也会把静态物体受直接光照产生的阴影烘培到ShadowMask中,动态物体不受影响。运行时改变灯光,只有静态物体的间接光照和阴影不变。内存中多了一份Shadowmask,减少了静态物体阴影的计算,占用性能小了一点。

注意:开启Shadowmask需要在QualitySettings设置Shadowmask Mode为Shadowmask。

subtractive

烘焙静态物体受到的直接光和间接光的信息(包含阴影,如同baked光源)。运行时改变光照,静态物体直接光、间接光、阴影不受影响,性能消耗最小。 

<think>嗯,用户的问题Unity烘焙光照贴图时模型金属材质失效的问题。我需要先理解这个问题的具体情况。根据用户提供的引用,光照贴图烘焙后可能因为各种原因出现错误,比如UV问题、设置不当或者异步加载导致的问题。但用户提到的是金属材质失效,这可能与烘焙过程中的材质属性处理有关。 首先,金属材质在Unity中通常使用Standard Shader,依赖金属度(Metallic)和平滑度(Smoothness)参数。烘焙光照贴图时,如果材质的高光或反射部分没有被正确烘焙进去,可能导致材质看起来失效。可能的原因有几个方面: 1. **光照贴图设置问题**:可能没有启用高光或金属相关光照贴图通道。在光照贴图烘焙设置中,需要确认是否包含了高光信息。查看引用[4]提到的预计算实时光照选项,如果勾选了可能导致计算量过大,影响材质表现,但用户的问题可能更相关于是否保存了正确的光照信息。 2. **材质属性未正确标记为静态**:如果模型没有被标记为静态,Unity可能不会为它烘焙光照贴图。需要确保模型设置为Contribute GI或者Static。引用[1]中提到烘焙光照贴图配合光探头使用,但非静态物体可能需要动态处理,但金属材质如果是静态物体,必须正确标记。 3. **UV2通道问题**:光照贴图使用第二套UV,如果模型的UV2存在重叠或未展开,可能导致光照信息不正确。引用[2]提到UV不同导致光照图错乱,可能类似的问题影响金属材质的反射效果。 4. **Shader兼容性**:使用的Shader是否支持烘焙?Standard Shader应该支持,但如果自定义了Shader可能缺少必要的烘焙处理。需要检查材质使用的Shader是否正确,或者是否需要调整参数。 接下来,可能的解决方案包括检查光照贴图设置中的高光选项,确保材质和模型设置正确,检查UV2是否正确展开,以及验证Shader的兼容性。此外,引用[3]提到运行时切换光照贴图的方法,但用户的问题可能是在烘焙阶段,所以可能需要确保烘焙时参数正确。此外,取消预计算实时光照(如引用[4]所述)可能减少计算错误,但需看具体情况。 还需要考虑烘焙后的材质是否被正确应用,比如光照贴图是否被正确引用,或者材质是否在烘焙后覆盖了原有的金属属性。可能需要手动调整材质的属性,或者使用脚本来动态设置,如引用[3]中的方法。另外,检查烘焙后的光照贴图是否存在错误,比如黑色或异常区域,这可能表明光照信息未被正确生成。 综合这些可能性,应该逐步排查设置、UV、材质属性和Shader的问题,并参考用户提供的引用中的解决方案,比如检查资源导出设置(引用[2])、调整预计算设置(引用[4])等,来找到具体原因并解决。</think>### Unity烘焙光照贴图导致金属材质失效的原因及解决方案 #### 问题原因分析 1. **材质属性与光照贴图兼容性问题** Unity的金属材质(Standard Shader)依赖$Metallic$和$Smoothness$参数控制表面反射特性。若烘焙时未正确处理高光/反射通道,会导致金属感丢失[^1]。 2. **模型未正确标记为静态** 未勾选$Contribute\ GI$或$Static$选项的模型无法参与光照烘焙,导致材质无法接收烘焙结果[^2]。 3. **UV2通道错误** 光照贴图依赖第二套UV坐标(UV2),若存在重叠或未正确展开,会导致金属反射信息错乱。例如: $$UV2_{max} - UV2_{min} \notin [0,1]^2$$ 4. **Shader兼容性限制** 自定义Shader可能缺少`Lightmap`相关声明,导致烘焙后金属参数失效。标准Shader应包含以下代码段: ```hlsl #ifdef LIGHTMAP_ON half4 lightmapUV : TEXCOORD1; #endif ``` #### 二、解决方案步骤 1. **检查模型与材质设置** - 勾选模型Inspector面板的$Contribute\ GI$ - 在材质属性中确认$Metallic>0.5$(典型金属材质值) - 强制刷新材质:右键材质选择$Reimport$ 2. **调整光照贴图设置** - 打开$Window > Rendering > Lighting$ - 在$Lightmapping\ Settings$中启用$Baked\ Global\ Illumination$ - 勾选$Compress\ Lightmaps$防止高光数据丢失[^4] ```csharp // 代码验证光照贴图状态 Debug.Log(RenderSettings.lightmaps.Length); ``` 3. **修复UV2通道** - 在建模工具中重新展开UV2(建议使用Unwrap3D工具) - 导入设置勾选$Generate\ Lightmap\ UVs$(Unity自动生成) 4. **验证Shader兼容性** - 使用Standard Shader替代自定义Shader - 添加光照贴图混合代码: ```hlsl half4 bakedColor = tex2D(unity_Lightmap, IN.lightmapUV.xy); Albedo *= bakedColor.rgb; ``` #### 三、进阶调试方法 1. **对比测试法** 创建新场景仅包含金属材质模型,逐步添加复杂元素定位问题源[^3]。 2. **内存监控** 使用Profiler查看烘焙时的$Lightmap\ Memory$占用,异常峰值可能指示UV错误[^4]。 3. **脚本强制刷新** 运行时动态重置材质属性: ```csharp void Start() { GetComponent<Renderer>().material.SetFloat("_Metallic", 0.8f); } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值