mcpField
U
unity-lighting-vfx

unity-lighting-vfx

github.com/nice-wolf-studio创意与媒体4092 次安装6 周前更新
代码仓库

关于 unity-lighting-vfx

面向 Unity 开发者的灯光与视觉特效参考技能,涵盖照明、全局光照、探针及粒子系统。还提供 VFX Graph 用法、C# 控制模式和常见误区。

主要功能

  1. 01实时、烘焙与混合照明
  2. 02全局光照与环境反射
  3. 03Light Probe 与 APV
  4. 04粒子系统模块参考
  5. 05VFX Graph 基础与模式
  6. 06C# 特效控制示例

适用场景

  1. 01为静态与动态场景选择灯光模式
  2. 02为移动对象配置间接照明
  3. 03比较 Particle System 与 VFX Graph
  4. 04排查照明和特效性能问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nice-wolf-studio/unity-claude-skills --skill unity-lighting-vfx

安装后在 Claude Code 中输入/unity-lighting-vfx确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
lighting-guide.md
particle-system.md
vfx-graph.md

详细介绍

Unity 光照与视觉效果

光照模式

Unity 提供三种光照模式,用于控制光照的计算方式。

实时光照
  • 在运行时每帧计算光照
  • 支持动态更改强度、颜色和位置
  • 投射阴影的距离不超过阴影距离
  • 默认仅提供直接光照(无反弹光)
  • 运行时开销较高,尤其是在复杂场景或低端硬件上
  • 适用于:动态对象、闪烁效果、移动光源
烘焙光照
  • 在 Unity 编辑器中执行计算,并将光照数据保存到磁盘
  • 运行时,Unity 会加载预先计算的数据,而不是动态计算
  • 将直接光照和间接光照都烘焙到光照贴图中
  • 使用光照探针存储移动对象所需的信息
  • 运行时无法修改光照属性;不会照亮动态 GameObject
  • 不提供镜面反射贡献
  • 适用于:静态场景、复杂的间接光照、对性能要求较高的场景
混合光照
  • 将烘焙间接光照与实时直接光照结合起来
  • 具体行为取决于 Lighting 窗口中的 Lighting Mode 设置
  • 投射实时阴影(不是烘焙的软阴影)
  • 运行时可以更改属性(仅影响实时部分)
  • 开销始终高于完全烘焙的光照
  • 适用于:背景光照已烘焙,但需要动态阴影的场景

重要提示: 所有烘焙/混合模式都要求启用烘焙全局光照。如果未启用,混合光照和烘焙光照的行为会与实时光照相同。

光源类型

定向光
  • 位于无限远处,沿一个方向发光
  • 光线彼此平行,强度不会随距离衰减
  • 模拟太阳/月亮;每个新场景默认都包含一个定向光
  • 与程序化天空系统关联;旋转定向光可创建昼夜效果
点光源
  • 位于一个点上,向所有方向均匀发光
  • 强度遵循平方反比定律(随距离平方增加而衰减)
  • 用于灯具、爆炸、局部照明
聚光灯
  • 位于一个点上,以圆锥形发光
  • 圆锥角度可调;光线边缘会逐渐变暗(半影)
  • 角度越大,渐隐区域越大
  • 用于手电筒、车头灯、探照灯
面光源
  • 由矩形或圆盘定义;光线从表面均匀发出
  • 遵循平方反比定律;产生柔和、细腻的明暗效果
  • 仅用于烘焙——运行时不可用
  • 用于路灯、逼真的室内照明

全局光照

全局光照(GI)用于模拟光线在表面之间反弹,从而产生逼真的间接光照。

烘焙 GI
  • 使用 Progressive Lightmapper(CPU 或 GPU)将间接光照预先计算到光照贴图中
  • 结果存储在光照贴图纹理和光照探针中
  • 在 Lighting 窗口的 Bake 设置下进行配置
  • GPU Progressive Lightmapper 支持配置图块大小,可缩短烘焙时间
环境光照

Lighting 窗口的 Environment 选项卡中提供三种环境光源:

  • 天空盒:使用天空盒材质颜色,从不同角度提供环境光
  • 渐变:分别设置天空、地平线和地面颜色,并平滑混合
  • 颜色:在整个场景中提供均匀的环境光

强度乘数(0-8,默认值为 1)用于控制环境光亮度。

环境反射
  • 来源:天空盒或自定义 Cubemap/RenderTexture
  • 可配置分辨率、压缩和强度乘数
  • Bounces 设置用于控制对象之间反射计算的迭代次数

光照探针与自适应探针体积

光照探针
  • 在整个场景的空旷空间中捕捉光照信息
  • 运行时,使用最近的探针对动态 GameObject 的间接光照进行近似计算
  • 为移动对象提供间接反弹光,并支持 LOD 系统
  • 必须使用 Light Probe Groups 手动放置
  • 存储烘焙光照信息;同时适用于直接光照和间接光照
自适应探针体积(APV)

APV 是 URP 中用于替代手动放置光照探针的现代方案:

  • 自动放置探针 —— 无需手动调整光照探针组的位置
  • 逐像素光照 —— 与逐对象方案相比,质量更出色
  • 场景烘焙 —— 使用烘焙集同时烘焙多个场景
  • 运行时调整 —— 使用光照方案和天空遮挡实现动态变化
  • 支持大型世界 —— 为广阔的开放世界环境提供流式加载数据
  • 数据灵活性 —— 可从 AssetBundles 或 Addressables 加载
  • 可配置探针密度和体积大小,并提供可视化工具

反射探针

将周围环境的球形视图捕获为立方体贴图,用于反射材质。

类型
类型描述
烘焙仅捕获静态 GameObject;性能最佳
自定义使用自定义纹理捕获动态对象
实时在游戏过程中更新;可配置刷新模式
主要属性
  • 重要性:多个探针重叠时的渲染优先级
  • 强度:着色器计算中的纹理亮度
  • 盒体投影:为室内场景启用投影映射(需要 URP 配置)
  • 盒体大小/偏移:决定反射贡献的世界空间包围盒
  • 混合距离:延迟探针的混合距离
实时选项
  • 刷新模式:唤醒时、每帧或通过脚本
  • 时间分片:一次渲染所有面、单独渲染各面、不进行时间分片

粒子系统与 VFX Graph

功能粒子系统VFX Graph
模拟基于 CPU基于 GPU
粒子数量数千数百万
渲染管线所有管线仅限 URP/HDRP
创建方式Inspector 模块基于节点的图形编辑器
物理效果内置碰撞自定义碰撞块
脚本编写完整的 C# API基于事件的 C# API
子发射器原生支持GPU 事件上下文
最适合小型/中型效果、移动平台大规模效果、高端平台

选择指南:

  • 目标平台为移动设备、效果简单、需要完全通过 CPU 端脚本控制,或目标为内置渲染管线时,请使用 粒子系统
  • 需要海量粒子、GPU 驱动的模拟、复杂的基于节点的创作,或面向使用 URP/HDRP 的高端平台时,请使用 VFX Graph

粒子系统模块

模块用途
Main初始状态:生命周期、速度、大小、重力、模拟空间
Emission粒子发射的速率和时机
Shape发射体积/表面和起始速度方向
Velocity over Lifetime根据粒子年龄修改运动
Noise生成有机、混乱运动的湍流
Limit Velocity over Lifetime实现自然减速
Force over Lifetime模拟物理力
Inherit Velocity子发射器粒子匹配父粒子的速度
Lifetime by Emitter Speed根据发射器速度调整生命周期
Color over Lifetime / by Speed根据年龄或速度改变颜色
Size over Lifetime / by Speed根据时间或速度改变尺寸
Rotation over Lifetime / by Speed改变方向
Collision粒子与场景几何体碰撞
Triggers将粒子指定为碰撞触发器
Sub Emitters可发射其他粒子的粒子
Texture Sheet Animation纹理网格动画帧
Trails渲染运动轨迹
Lights在粒子上生成实时光照
External Forces风区和力场
Renderer图像/网格变换、着色、过度绘制
Custom Data为粒子附加自定义数据

VFX Graph 基础

系统
  1. 生成系统:由单个生成上下文管理发射
  2. 粒子系统:初始化 -> 更新 -> 输出的连续流程
  3. 网格输出系统:单个网格输出上下文
Context
  • Spawn:执行每个帧以计算生成数量。状态:Running、Idle、Waiting。可配置循环时长、计数和延迟
  • Initialize:在粒子诞生时运行,设置初始状态。为新生成的粒子处理 Blocks。可配置边界和容量
  • Update:每帧处理所有存活粒子。自动执行:位置积分、旋转积分、老化和回收
  • Output:渲染粒子(Quad、Mesh 等)。没有输出端口。可自定义渲染 Blocks
图形元素
  • Blocks:Context 中可堆叠的节点;每个节点处理一项操作;按从上到下的顺序执行
  • Operators:低级属性工作流节点,连接到 Block/Context 端口
  • Properties:可通过属性工作流连接
  • Settings:每个 Context 中可编辑但不可连接的值
GPU 事件

实验性功能,由 GPU 计算事件(普通事件由 CPU 计算)。无法使用 Blocks 自定义。

常见模式(C#)

创建并配置灯光
using UnityEngine;

public class LightSetup : MonoBehaviour
{
    void Start()
    {
        GameObject lightObj = new GameObject("Dynamic Light");
        Light light = lightObj.AddComponent<Light>();
        light.type = LightType.Point;
        light.color = Color.yellow;
        light.intensity = 2.0f;
        light.range = 15f;
        light.shadows = LightShadows.Soft;
        light.shadowResolution = UnityEngine.Rendering.LightShadowResolution.Medium;
    }
}
创建实时反射探针
using UnityEngine;
using UnityEngine.Rendering;

public class ProbeSetup : MonoBehaviour
{
    void Start()
    {
        GameObject probeObj = new GameObject("Realtime Reflection Probe");
        ReflectionProbe probe = probeObj.AddComponent<ReflectionProbe>();
        probe.size = new Vector3(10, 10, 10);
        probe.mode = ReflectionProbeMode.Realtime;
        probe.refreshMode = ReflectionProbeRefreshMode.EveryFrame;
        probe.resolution = 256;
        probe.hdr = true;
    }
}
在运行时控制粒子系统
using UnityEngine;

public class ParticleController : MonoBehaviour
{
    ParticleSystem ps;

    void Start()
    {
        ps = GetComponent<ParticleSystem>();

        // Modify emission rate -- cache module in local variable first
        var emission = ps.emission;
        emission.rateOverTimeMultiplier = 50f;

        // Modify main module
        var main = ps.main;
        main.startLifetime = 3f;
        main.startSpeed = 5f;
        main.simulationSpace = ParticleSystemSimulationSpace.World;
    }

    void OnTriggerEnter(Collider other)
    {
        // Burst emit particles
        ps.Emit(100);
    }

    void OnDisable()
    {
        ps.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
    }
}
VFX Graph 运行时控制
using UnityEngine;
using UnityEngine.VFX;

public class VFXController : MonoBehaviour
{
    VisualEffect vfx;
    VFXEventAttribute eventAttr;

    void Start()
    {
        vfx = GetComponent<VisualEffect>();
        eventAttr = vfx.CreateVFXEventAttribute();

        // Set exposed properties
        vfx.SetFloat("SpawnRate", 100f);
        vfx.SetVector3("Direction", Vector3.up);
        vfx.playRate = 1.5f;
    }

    void OnTriggerEnter(Collider other)
    {
        // Send custom event with attributes
        eventAttr.SetVector3("position", other.transform.position);
        vfx.SendEvent("OnHit", eventAttr);
    }

    public void StopEffect()
    {
        vfx.Stop();
    }
}
按需刷新反射探针
using UnityEngine;

public class ProbeRefresher : MonoBehaviour
{
    ReflectionProbe probe;

    void Start()
    {
        probe = GetComponent<ReflectionProbe>();
        probe.refreshMode = UnityEngine.Rendering.ReflectionProbeRefreshMode.ViaScripting;
    }

    public void RefreshReflections()
    {
        probe.RenderProbe();
    }

    public bool IsReady()
    {
        return probe.IsFinishedRendering(probe.RenderProbe());
    }
}

反模式

灯光反模式
  1. 实时灯光过多:每盏实时灯光都会增加逐帧开销。静态灯光请使用 Baked 或 Mixed
  2. 忘记启用烘焙全局光照:未启用此功能时,Mixed/Baked 灯光会静默回退到 Realtime
  3. 反射探针重叠但未设置 Importance 值:会导致闪烁;务必设置 Importance 以确定优先级
  4. 使用 Area Lights 并期待其在运行时生效:Area Lights 仅用于烘焙;运行时不会产生光照
  5. 忽略 Indirect Multiplier:保留默认值可能导致反弹光过亮或过暗;请针对每盏灯光进行调整
  6. 未正确设置 Shadow Bias:值过低会导致自阴影伪影(shadow acne);值过高会导致阴影悬浮(阴影与物体分离)
  7. 在大型场景中手动放置 Light Probe:在 URP 中改用 Adaptive Probe Volumes(APV),以实现自动化的逐像素高质量效果
粒子系统反模式
  1. 未缓存模块引用:每次访问模块结构体的属性都会立即写入原生代码;请缓存模块变量
  2. 对附着效果使用 World 模拟空间:粒子会逐渐偏离移动的父对象;附着 FX 请使用 Local 空间
  3. CPU 上的粒子数量过多:Particle System 受 CPU 限制;粒子数超过 10K 时,请考虑使用 VFX Graph
  4. 忘记调用 Stop/Clear:即使不可见,未清理的粒子系统仍会消耗 CPU
VFX Graph 反模式
  1. 在移动设备上使用 VFX Graph 实现简单效果:GPU 开销以及对 URP/HDRP 的要求,使其对于简单的移动端效果而言过于复杂
  2. 未在 Initialize 中设置 Capacity:默认容量可能分配过多或过少的 GPU 内存
  3. 忽略 Bounds:边界设置不正确会导致可见效果被剔除;务必在 Initialize Context 中配置边界
  4. 每帧发送事件但不进行节流:SendEvent 会产生 CPU-GPU 同步开销;请批量处理事件派发或进行节流

关键 API 快速参考

Light(UnityEngine.Light)
成员类型描述
type属性LightType(Directional、Point、Spot、Area)
color属性发出的光线颜色
intensity属性亮度乘数
range属性最大距离(Point/Spot)
spotAngle / innerSpotAngle属性锥形光束的外角和内角
shadows属性LightShadows(None、Hard、Soft)
shadowResolution属性阴影贴图质量
shadowBias / shadowNormalBias属性减少阴影伪影
bounceIntensity属性GI 反弹强度
cookie属性投射的纹理遮罩
cullingMask属性基于图层的筛选
colorTemperature属性以开尔文为单位的 CCT
lightmapBakeType属性烘焙配置
bakingOutput属性上次烘焙的贡献详情
AddCommandBuffer()方法在指定时机执行 GPU 命令
ParticleSystem(UnityEngine.ParticleSystem)
成员类型描述
main / emission / shape属性模块访问结构体
particleCount属性当前活动粒子数
isPlaying / isPaused / isStopped属性播放状态
Play() / Pause() / Stop()方法播放控制
Emit(count)方法立即生成粒子
Simulate(time)方法快进模拟
GetParticles() / SetParticles()方法直接访问粒子数据
Clear()方法移除所有粒子
TriggerSubEmitter()方法激活子发射器
VisualEffect(UnityEngine.VFX.VisualEffect)
成员类型描述
visualEffectAsset属性指定或更改效果图
playRate属性模拟速度
aliveParticleCount属性活动粒子数
Play() / Stop() / Reinit()方法播放控制
SendEvent(name, attr)方法触发效果图事件
CreateVFXEventAttribute()方法创建事件载荷
SetFloat() / SetVector3() / etc.方法设置公开属性
GetFloat() / GetVector3() / etc.方法读取公开属性
HasFloat() / HasVector3() / etc.方法检查属性是否存在
ResetOverride(property)方法恢复原始值
ReflectionProbe(UnityEngine.ReflectionProbe)
成员类型描述
mode属性Baked/Custom/Realtime
size / center属性边界框配置
intensity / importance属性亮度和优先级
boxProjection属性启用盒形投影
refreshMode / timeSlicingMode属性实时更新配置
RenderProbe()方法强制刷新立方体贴图
IsFinishedRendering()方法检查分时渲染是否完成
BlendCubemap()方法混合两个立方体贴图

相关技能

  • unity-graphics -- 渲染管线(URP/HDRP/内置)、着色器、材质、摄像机
  • unity-2d -- 2D 光照(URP 2D Renderer)、精灵渲染
  • unity-platforms -- 特定平台的光照质量等级、移动端优化

Additional Resources

评论

支持 Markdown