Unity基础:Light灯光组件入门——Directional Light、Point Light与Spotlight

Unity基础:Light灯光组件入门------Directional Light、Point Light与Spotlight

大家好,欢迎回到Unity教程系列。上一篇文章我们学习了Camera相机------它决定了玩家"看到什么"。今天我们要学习的是决定"场景看起来怎么样"的另一关键要素------Light灯光。

灯光是游戏视觉的灵魂。同样的场景,不同的灯光布置可以营造完全不同的氛围------明亮欢快的午后、阴森恐怖的黑夜、温暖舒适的室内。掌握了灯光,你才能真正驾驭场景的氛围感。这篇文章将带你从零开始认识Unity的灯光系统。

一、光照系统概述

1.1 光照的重要性

想象一下:你精心建模的场景,给所有物体贴上了高清纹理,但如果灯光设置不当------太暗、太亮、阴影生硬、颜色不对------整个场景就会显得"不对劲"。反之,即使使用简单的几何体和材质,合理的光照也能让场景看起来非常舒适。

在游戏开发中,光照不仅影响视觉效果,还直接影响性能。实时光照越复杂,GPU的计算负担越重。因此,理解光照原理并做出合理的取舍,是游戏开发者的重要能力。

1.2 Unity光照的三种模式

Unity支持三种光照模式:

Realtime(实时):光照和阴影在每帧动态计算。支持动态物体,但性能开销最大。适合移动的光源(如角色身上的手电筒、移动的车辆灯光)。

Baked(烘焙):光照和阴影提前计算好并"烘焙"到光照贴图(Lightmap)中。运行时不需要重新计算,性能最优。但只能用于标记为Static(静态)的物体,且光源位置不能改变。

Mixed(混合):结合了实时和烘焙的优点。静态物体使用烘焙光照,动态物体使用实时光照。

💡 对于移动平台游戏,尽可能多地使用Baked光照是最重要的性能优化手段之一。

二、Directional Light------平行光

2.1 什么是平行光

💡 Directional Light(平行光)模拟的是无限远处的光源发出的平行光线。最典型的例子就是太阳------因为太阳距离地球足够远,到达地面的光线可以近似为平行光。

平行光的关键特点:

  • 所有光线方向一致(平行),不随距离衰减
  • 光源位置不影响光照效果(只有方向重要)
  • 照亮整个场景中的所有物体(覆盖范围无限)
  • 每个场景通常只有一个主平行光(模拟太阳)

2.2 平行光属性详解

Type:灯光类型,设置为Directional。

Color(颜色):灯光的颜色。白天太阳偏暖(微黄),月光偏冷(蓝白)。

Intensity(强度):灯光的亮度。默认值为1。值越大越亮,设为0则等于关闭。

Indirect Multiplier(间接光照倍增强度):控制间接光照(反弹光)的强度。增大这个值可以让暗面更亮,模拟更强的环境光反射。

Shadow Type(阴影类型)

  • No Shadows:不产生阴影。性能最好。
  • Hard Shadows:硬阴影,边缘锐利。
  • Soft Shadows:软阴影,边缘柔和。视觉效果更真实,但性能开销更大。

Cookie:灯光遮罩纹理。可以用来模拟树影、百叶窗投影等效果。

Culling Mask:与Camera的Culling Mask类似,控制哪些Layer的物体受此灯光影响。

2.3 平行光的典型设置

对于一个室外场景的"太阳"平行光:

复制代码
Type: Directional
Color: 微暖的白色(如 #FFF4E0)
Intensity: 1.0 - 1.5
Rotation: 绕X轴旋转30-60度(控制太阳高度角)
Shadow Type: Soft Shadows

📝 平行光的Rotation非常重要,它决定了光线的方向------Y轴旋转控制太阳在天空中的"高度"(类似纬度),X轴旋转控制"方位"(类似经度)。

csharp 复制代码
// 代码中设置平行光
Light sunLight = GetComponent<Light>();
sunLight.color = new Color(1f, 0.96f, 0.88f); // 暖白色
sunLight.intensity = 1.2f;
sunLight.shadowStrength = 0.8f;

三、Point Light------点光源

3.1 什么是点光源

💡 Point Light(点光源)模拟的是从空间中一个点向所有方向均匀发射光线的光源。最典型的例子就是灯泡、蜡烛、火把、魔法光球。

点光源的关键特点:

  • 光线从一点向四周辐射
  • 光照强度随距离衰减(离光源越远越暗)
  • 有一个有限的影响范围(Range)
  • 性能开销高于平行光(需要计算距离衰减)

3.2 点光源属性详解

Range(范围):光源的最大影响距离。超出Range的物体不受此灯光影响。合理设置Range对性能很重要------Range越大,需要光照计算的物体越多。

Intensity(强度):点光源的中心亮度。

Color(颜色):灯光的颜色。暖色(黄/橙)适合烛光、火把,冷色(蓝/紫)适合魔法、科技灯光。

Shadow Type:点光源也能产生阴影,但性能开销显著高于平行光阴影(因为需要渲染6个方向的阴影贴图,对应立方体的6个面)。

Mode(模式)

  • Realtime:实时光照
  • Baked:烘焙光照
  • Mixed:混合模式

3.3 点光源的衰减曲线

点光源在Range范围内的衰减曲线可以通过Light组件面板底部的光照曲线图查看。默认是线性到二次衰减的混合。

在Inspector中,你可以看到一个光照强度随距离变化的小图表。右上角的按钮可以在不同的衰减模式之间切换(需要特定的渲染管线支持)。

3.4 使用场景

点光源适合:

  • 室内灯泡、吊灯
  • 火把、篝火、蜡烛
  • 魔法球、能量核心
  • 爆炸的瞬间闪光
  • 角色的手电筒(配合Spotlight更好)
csharp 复制代码
// 代码中创建点光源
GameObject lightObj = new GameObject("PointLight");
Light pointLight = lightObj.AddComponent<Light>();
pointLight.type = LightType.Point;
pointLight.range = 10f;
pointLight.intensity = 2f;
pointLight.color = Color.yellow;

四、Spotlight------聚光灯

4.1 什么是聚光灯

💡 Spotlight(聚光灯)模拟的是从一个点向特定方向以锥形发射的光线。最典型的例子就是手电筒、舞台追光灯、汽车前灯。

聚光灯的关键特点:

  • 光线限制在圆锥范围内
  • 有照射方向(由Transform的Rotation决定)
  • 随距离衰减,圆锥边缘也有衰减
  • 有Range(距离范围)和Spot Angle(圆锥张开角度)

4.2 聚光灯属性详解

Range(范围):聚光灯的最大照射距离。

Spot Angle(聚光角度):圆锥的张开角度(度)。取值范围0-179。角度越大,照射范围越广,但边缘衰减越剧烈。

Inner / Outer Spot Angle(部分渲染管线支持):控制内层(全亮区)和外层(渐变衰减区)的角度差异。内角和外角差值越大,边缘过渡越柔和。

Intensity(强度):灯光的中心亮度。

Color(颜色):灯光的颜色。

Shadow Type:聚光灯的阴影性能开销介于平行光和点光源之间------聚光灯只需要渲染一个方向的阴影贴图。

4.3 制作一个手电筒

csharp 复制代码
// 创建手电筒灯光
GameObject flashlightObj = new GameObject("Flashlight");
Light flashlight = flashlightObj.AddComponent<Light>();
flashlight.type = LightType.Spot;
flashlight.range = 20f;
flashlight.spotAngle = 45f;
flashlight.intensity = 3f;
flashlight.color = new Color(1f, 0.95f, 0.8f); // 微暖白光
flashlight.shadows = LightShadows.Hard;

// 让手电筒跟随玩家
flashlightObj.transform.SetParent(playerCamera.transform);
flashlightObj.transform.localPosition = Vector3.zero;
flashlightObj.transform.localRotation = Quaternion.identity;

五、其他灯光类型

5.1 Area Light(区域光)

Area Light模拟的是从一个矩形区域发射的光线。它产生的光照最自然(因为真实世界中的大部分光源都有面积),但它有一个重要限制:

⚠️ Area Light只能用于Baked光照(烘焙),不能用于实时光照。这意味着它只能影响静态物体。常用于模拟天花板灯带、窗户光、显示器屏幕光等。

5.2 Emissive Material(自发光材质)

严格来说这不是灯光组件,但自发光材质也可以产生光照效果(在Baked GI中)。将材质的Emission属性设为大于0的值,在烘焙全局光照时,该材质会成为"间接光源",照亮周围的静态物体。

六、阴影系统

6.1 阴影的工作原理

Unity使用Shadow Mapping(阴影贴图)技术来生成阴影:

① 从灯光视角渲染场景,记录每个像素的深度

② 从相机视角渲染场景时,检查每个像素在灯光视角下的深度

③ 如果某个像素被其他物体遮挡(深度更大),说明它在阴影中

6.2 阴影质量设置

Edit > Project Settings > Quality 中,可以设置阴影质量:

  • Shadow Resolution:阴影贴图分辨率(Low/Medium/High/Very High)
  • Shadow Distance:阴影渲染的最远距离
  • Shadow Cascades:级联阴影的数量(平行光专用,提高近距离阴影质量)

💡 级联阴影(Cascaded Shadows)是平行光的特殊优化:距离相机越近的区域使用越高分辨率的阴影贴图,远处使用低分辨率。级联数量通常设为2或4,具体取决于场景规模和性能要求。

6.3 阴影性能优化建议

  • 移动平台上优先使用Hard Shadows或关闭阴影
  • 降低Shadow Resolution可以显著减少内存和渲染开销
  • 减小Shadow Distance(只让近距离物体投射阴影)
  • 在MeshRenderer组件中关闭不重要物体的"Cast Shadows"和"Receive Shadows"

七、场景布光实践

7.1 三点布光法

三点布光(Three-Point Lighting)是摄影和电影中经典的布光方法,同样适用于游戏场景:

主光(Key Light):场景的主要光源,通常是一个Directional Light(室外)或Point Light/Spotlight(室内)。主光定义场景的整体亮度和主要阴影方向。

辅光(Fill Light):用于照亮主光产生的阴影区域,降低对比度。通常是主光亮度的30%-50%,放置在主光的对面方向。

轮廓光(Rim Light / Back Light):从物体的侧后方照射,为物体边缘添加亮边,帮助物体从背景中分离出来。虽然游戏中不常用,但角色展示场景可以考虑。

7.2 室内场景布光

一个典型室内场景的光源设置:

复制代码
Key Light(主光): Point Light, 位于房间中央天花板
Fill Light(辅光): Point Light, 低强度, 角落位置
Accent Light(点缀光): Spotlight或小Point Light, 用于照亮特定区域
Ambient Light(环境光): 通过Lighting设置中的Environment Lighting

7.3 室外场景布光

复制代码
Sun(太阳): Directional Light, 偏向暖色
Ambient(环境光): 天空散射光, 通过Lighting设置
Reflection(反射): Reflection Probe捕捉环境反射

八、Lighting窗口设置

8.1 打开Lighting窗口

Window > Rendering > Lighting 打开光照设置窗口。

8.2 关键设置

Environment(环境)

  • Skybox Material:天空盒材质(定义天空外观和环境反射)
  • Sun Source:指定哪个Directional Light是太阳
  • Environment Lighting:环境光照(从天空盒采样得到的间接光)
  • Environment Reflections:环境反射设置

Scene(场景)

  • Lightmapper:选择光照烘焙器(Progressive CPU/GPU或Enlighten)
  • Indirect Resolution:间接光照分辨率
  • Lightmap Resolution:光照贴图分辨率

Mixed Lighting(混合光照)

  • Lighting Mode:混合光照模式(Shadowmask、Subtractive、Baked Indirect)

九、代码中操作灯光

9.1 动态控制灯光

csharp 复制代码
using UnityEngine;

public class LightController : MonoBehaviour
{
    private Light lightComponent;
    
    void Start()
    {
        lightComponent = GetComponent<Light>();
    }
    
    // 淡入效果
    public System.Collections.IEnumerator FadeIn(float duration)
    {
        float elapsed = 0;
        float startIntensity = 0;
        float targetIntensity = lightComponent.intensity;
        
        lightComponent.intensity = 0;
        
        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            lightComponent.intensity = Mathf.Lerp(0, targetIntensity, elapsed / duration);
            yield return null;
        }
    }
    
    // 闪烁效果
    public System.Collections.IEnumerator Flicker(float duration, float minInterval, float maxInterval)
    {
        float elapsed = 0;
        
        while (elapsed < duration)
        {
            lightComponent.enabled = !lightComponent.enabled;
            float waitTime = Random.Range(minInterval, maxInterval);
            yield return new WaitForSeconds(waitTime);
            elapsed += waitTime;
        }
        
        lightComponent.enabled = true;
    }
}

9.2 昼夜循环

csharp 复制代码
using UnityEngine;

public class DayNightCycle : MonoBehaviour
{
    public Light sunLight;
    public float cycleDuration = 120f; // 一个完整昼夜循环的秒数
    public AnimationCurve intensityCurve;
    
    void Update()
    {
        // 太阳绕X轴旋转(模拟升起和落下)
        float sunAngle = (Time.time / cycleDuration) * 360f;
        sunLight.transform.rotation = Quaternion.Euler(sunAngle, 0, 0);
        
        // 根据太阳高度调整亮度
        float normalizedAngle = sunAngle % 360;
        float intensity = Mathf.Sin(normalizedAngle * Mathf.Deg2Rad);
        sunLight.intensity = Mathf.Clamp(intensity, 0.1f, 1.5f);
    }
}

十、本篇总结

✅ 本文核心知识点回顾:

  • Directional Light模拟无限远光源(太阳),光线平行无衰减
  • Point Light模拟点光源(灯泡),光线从一点向四周辐射,有Range范围
  • Spotlight模拟锥形光束(手电筒),有方向、Range和Spot Angle
  • Area Light只能用于烘焙,产生最自然的光照效果
  • 阴影质量在Quality Settings中配置,级联阴影提高平行光阴影质量
  • 三点布光法(主光+辅光+轮廓光)是经典布光方案
  • 移动平台应优先使用Baked光照以优化性能

📝 下一篇文章将学习C#脚本的创建与挂载------如何让你的游戏物体活起来。

动手任务

① 在一个测试场景中分别添加Directional Light、Point Light和Spotlight,调整参数观察效果

② 尝试三点布光法布置一个简单场景

③ 写一个让灯光闪烁的脚本


关于作者:拥有多年Unity开发经验的游戏开发者,专注Unity系统化教学与最佳实践分享。

相关推荐
郝学胜-神的一滴5 小时前
[简化版 GAMES 104] 现代游戏引擎 04:从0到1构建你的游戏世界
c++·游戏·unity·游戏引擎·软件工程·unreal engine
是嘟嘟啊1 天前
【Unity DOTS】EntityCommandBuffer 与 JobHandle
unity·ecs·dots·unity dots·job·burst·burstjob
xcLeigh1 天前
Unity基础:Camera相机组件详解——透视投影与正交投影的区别
数码相机·unity·游戏引擎
玖玥拾1 天前
Unity3D RPG 入门项目(二)移动 Bug 修复、环绕相机、NPC 任务系统、UI 穿透处理
unity·游戏引擎
Yasin Chen1 天前
Unity UGUI RectMask2D 原理
unity·游戏引擎
hashiqimiya1 天前
unity---unity编译手机apk人物角色移动
unity·游戏引擎
LONGZETECH1 天前
传统实训 vs 仿真实训:从技术架构拆解新能源汽车教学的范式之变
c语言·3d·unity·架构·汽车
SomeB1oody2 天前
【RustyML入门】2.0. 经典机器学习
开发语言·后端·机器学习·rust·教程
℡枫叶℡2 天前
Unity - 图集大小与内存占用
unity·图集内存