基于有向距离场(Signed Distance Field, SDF)的碰撞检测


基于有向距离场(Signed Distance Field, SDF)的碰撞检测

项目简介

SDF 碰撞检测 Demo,演示如何使用有向距离场实现高效的角色碰撞检测和移动。包含 2D/3D 场景示例和可视化烘焙工具。

项目地址:SDFCollision

有向距离场

有向距离场(Signed Distance Field,简称 SDF)是一种描述空间中任意一点到某个几何形状最短距离的数学表示方法,通过符号指示点的位置:

符号 含义
正值 点在形状外部
负值 点在形状内部
零值 点位于形状边界上

SDF 通过将场景中每个点到障碍物表面的距离存储为标量值,可在 O(1)时间内查询碰撞,实现高效的碰撞检测。

快速使用

  1. Assets 目录下的文件导入到你的 Unity 工程中
  2. 打开 SDFDemo(3D)或 SDFDemo2D(2D)场景
  3. 运行即可看到碰撞效果

SDF 烘焙

打开烘焙窗口

菜单栏选择 Tools > SDF Baker

SDF Baker 界面

参数说明

参数 说明
地图的长度/宽度 场景中烘焙区域的实际尺寸(米)
每个分块的宽高 每个 SDF 数据块的物理尺寸(米)
每个体素的大小 每个采样点的精度,越小精度越高
烘焙方向 XY 或 XZ 平面,决定 2D 碰撞的平面方向
起始点 Transform 拖入 Transform 自动计算烘焙原点

烘焙步骤

  1. 设置场景参数
  2. 拖入起始点 Transform(或手动设置起始位置)
  3. 选择保存路径(必须在 Assets/Resources/ 下)
  4. 点击 Bake SDF 开始烘焙

烘焙完成后会生成:

  • SDFConfig.json - 配置文件
  • SDF 数据文件(Texture2D 格式)

API 参考

SDFManager

碰撞管理器,挂载在场景中作为单例使用。

using SDFCollision;

获取距离

// 获取世界坐标到最近障碍物的距离
float distance = SDFManager.Instance.GetDistanceFromPoint(worldPosition);

// distance > 0 表示在障碍物外部
// distance < 0 表示在障碍物内部
// distance = 0 表示在障碍物表面

碰撞后滑行

// 检测碰撞并计算滑行方向(推荐用于角色移动)
// moveVec2: 移动向量
// position: 当前世界坐标
// radius: 角色半径
// buffer: 碰撞缓冲距离(适当增大可避免频繁反弹)
Vector2 newMoveDir = SDFManager.Instance.CheckAndCorrectMoveDir(
    moveVec2,
    position,
    radius,
    buffer: 0.1f
);

碰撞后反弹

// 检测碰撞并计算反射方向
Vector2 newMoveDir = SDFManager.Instance.CheckAndReflection(
    moveVec2,
    position,
    radius
);

SDFConfig

烘焙配置类,存储烘焙参数和 SDF 数据路径。

// 通过路径加载配置
SDFConfig config = SDFConfig.LoadSDFConfig("SDFTextures");

// 字段说明
public int gridLength;      // 网格长度(X 轴方向)
public int gridWidth;      // 网格宽度
public int chunkSize;      // 单个分块的分辨率
public float voxelSize;    // 体素大小
public bool isXY;          // 烘焙方向:true = XY, false = XZ
public Vector3Int startPos;// 烘焙起始点
public string sdfDataPath; // SDF 数据文件路径

核心概念

梯度与法线

在 SDF 碰撞检测中,梯度向量指向障碍物表面法线方向,用于计算碰撞后的滑行或反射方向。通过有限差分法计算:

gradient = (SDF(x+δ) - SDF(x-δ)) / 2δ

缓冲距离

buffer 参数控制碰撞缓冲区域大小:

  • 值越小:碰撞响应越灵敏,但可能出现频繁弹跳
  • 值越大:移动越平滑,但可能穿墙

文章作者: 草莓多多
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 草莓多多 !
  目录