EntityComponentSystemSamples 数学速查手册:Unity.Mathematics 类型、运算与 DOTS 实战全解析
【免费下载链接】EntityComponentSystemSamples项目地址: https://gitcode.com/GitHub_Trending/en/EntityComponentSystemSamples
本篇技术指南围绕当前仓库 EntitiesSamples 文档目录中的《Unity.Mathematics cheat sheet》(源文件见 mathematics.src.md,生成版见 mathematics.md)展开,系统梳理 DOTS(Data-Oriented Technology Stack)开发中最常用的数学类型、构造方式、运算符与静态方法,并深入仓库真实样例(Boids 群集模拟、HelloCube 旋转系统)印证这些 API 在 Burst 编译与 ECS 场景下的实际用法。读完本文,你将掌握向量/矩阵/四元数/随机数/噪声的全套速查索引,并能直接在 ECS Job 中写出可编译、可优化的数学代码。
说明:该文档由 Unity 的 dots-tutorial-processor 从
mathematics.src.md自动生成,其中的代码片段(向量创建、矩阵创建、运算符、随机数四段)实际内嵌自 Mathematics.cs,本文将其还原为完整可运行示例,并结合源码级证据展开讲解。原文档引用的外部 API 参考链接(docs.unity3d.com)此处不重复给出,方法名均可在Unity.Mathematics程序集内直接检索。
适用范围与重载约定
Unity.Mathematics的绝大多数方法都针对不同类型组合提供了大量重载。例如math.abs()不仅能处理标量,也能处理向量:
math.abs(new int3(5, -7, -1)) // 返回 new int3(5, 7, 1),逐分量取绝对值本文(与原速查手册一致)不会穷举全部重载组合,只给出每个 API 的语义与典型用法。需要完整签名列表时,请查阅Unity.Mathematics包的官方 API 参考。该包在本仓库各示例项目中均有引用,例如 EntitiesSamples/Packages/manifest.json 中的com.unity.mathematics依赖,正是所有 DOTS 样例(Boids、HelloCube、PhysicsSamples 等)能够直接using Unity.Mathematics;的前提。
核心类型总览
| 类型 | 说明 |
|---|---|
math | 包含大量静态数学常量与方法的主类 |
noise | 提供静态噪声生成方法的类 |
quaternion | 表示旋转的 struct |
Random | 用于生成随机数的 struct |
RigidTransform | 表示刚体变换矩阵的 struct(正交基 + 平移,无缩放) |
标量类型
| 类型 | 说明 |
|---|---|
half | 16 位浮点数(半精度) |
向量类型
| 类型 |
|---|
bool2、bool3、bool4 |
int2、int3、int4 |
uint2、uint3、uint4 |
float2、float3、float4 |
half2、half3、half4 |
double2、double3、double4 |
向量分量按惯例命名为x, y, z, w(1D 到 4D)。在 ECS 系统中,float3是最常见的坐标/方向载体,例如LocalToWorld.Position、LocalToWorld.Forward的类型均为float3(见 BoidSystem.cs)。
矩阵类型
| 类型 |
|---|
bool2x2、bool2x3、bool2x4、bool3x2、bool3x3、bool3x4、bool4x2、bool4x3、bool4x4 |
int2x2、int2x3、int2x4、int3x2、int3x3、int3x4、int4x2、int4x3、int4x4 |
uint2x2、uint2x3、uint2x4、uint3x2、uint3x3、uint3x4、uint4x2、uint4x3、uint4x4 |
float2x2、float2x3、float2x4、float3x2、float3x3、float3x4、float4x2、float4x3、float4x4 |
double2x2、double2x3、double2x4、double3x2、double3x3、double3x4、double4x2、double4x3、double4x4 |
命名规则为<元素类型><行数>x<列数>。例如float4x4即 4 行 4 列的浮点矩阵,是 DOTS 中LocalToWorld.Value与LocalTransform底层变换的核心载体。
向量创建与复制
以下代码对应示例源码 Mathematics.cs 中的vectorCreation()方法:
int4 i4 = new int4(1, 2, 3, 4); // x, y, z, w int2 i2 = int2.zero; // new int2(0, 0); // 像数组一样按索引访问分量。 int i = i4[2]; // int i = i4.z i4[0] = 9; // i4.x = 9 // 通过复制另一个向量的分量组合来创建向量(swizzling,分量重排)。 i4 = i4.xwyy; // new int4(i4.x, i4.w, i4.y, i4.y); i2 = i4.yz; // new int2(i4.y, i4.z); i4 = i2.yxyx; // new int4(i2.y, i2.x, i2.y, i2.x); // 由低维向量与标量组合创建向量。 i4 = new int4(1, i2, 3); // new int4(1, i2.x, i2.y, 3); i4 = new int4(i2, i2); // new int4(i2.x, i2.y, i2.x, i2.y); i4 = new int4(7); // new int4(7, 7, 7, 7); 单一标量填充全部分量 i2 = new int2(7.5f); // new int2((int) 7.5f, (int) 7.5f); 浮点转整型截断 // 通过显式类型转换创建向量。 i4 = (int4) 7; // new int4(7, 7, 7, 7); i2 = (int2) 7.5f; // new int2((int) 7.5f, (int) 7.5f);关键要点:
- swizzle 属性(如
xwyy、yz、yxyx)允许对分量自由重排与复制,是组合方向向量、交换通道时的常用技巧;DOTS 图形样例(如 RenderSwap)中即常见于 UV 与法线数据的通道重组。 - 构造函数支持“标量 + 低维向量 + 标量”的混合实参,编译器会按顺序展开填充。
- 从浮点构造整型向量采用截断(向零取整)而非四舍五入,精度敏感场景需自行
math.round。
矩阵创建与复制
对应 Mathematics.cs 中的matrixCreation()方法:
// 数值按行优先(row-major)顺序传入。 int2x3 m = new int2x3(1, 2, 3, 4, 5, 6); // 第一行:1, 2, 3 // 第二行:4, 5, 6 // 第一列:new int2(1, 4) int2 i2 = m.c0; // 第三列:new int2(3, 6) i2 = m.c2; // new int2x3(100, 100, 100, 100, 100, 100) 单一标量填充全部元素 m = new int2x3(100); m = new int2x3( new int2(1, 2), // 列 0 new int2(3, 4), // 列 1 new int2(5, 6)); // 列 2 // 将每个 int 分量转换为 float。 float2x3 m2 = new float2x3(m);关键要点:
- 构造函数接受行优先的平铺数值序列;而访问器
c0、c1、c2……是列(column)向量。c前缀即 column 的缩写,这一点在索引矩阵元素时极易混淆,务必区分“行优先输入”与“列访问”。 - 矩阵支持跨类型构造:
new float2x3(m)会对每个元素做数值转换。 - DOTS 中矩阵通常由
float4x4.TRS、float4x4.LookAt等工厂方法生成(见下文“旋转与变换”),极少手写元素。
向量与矩阵运算符
对应 Mathematics.cs 中的vectorMatrixOperators()方法:
int2 a = new int2(1, 2); int2 b = new int2(3, 4); // 加法:逐分量对应相加。 int2 c = a + b; // new int2(a.x + b.x, a.y + b.y) // 取负。 c = -a; // new int2(-a.x, -a.y) // 相等性:Equals 返回单个 bool(全分量相等才为 true)。 bool myBool = a.Equals(b); // a.x == b.x && a.y == b.y // 而 == 运算符返回逐分量的 bool 向量。 bool2 myBool2 = a == b; // new bool2(a.x == b.x, a.y == b.y) // 大于:同样逐分量比较。 myBool2 = a > b; // new bool2(a.x > b.x, a.y > b.y)向量与矩阵运算符(+、-、*、/、%、--、++、==、!=、<、>、<=、>=)均对对应分量成对执行操作。整型向量与矩阵类型还额外支持位运算符:&、|、~、<<、>>。
一个易错点:a == b得到的是bool2向量,若想得到“整体相等”的单个bool,应使用a.Equals(b),或对比较结果套用math.all(a == b)。逐分量比较结果常与math.select配合,实现 SIMD 友好的分支替代(见下文 Boids 样例)。
算术运算
| 方法 | 说明 |
|---|---|
math.fmod | x/y 的浮点余数 |
math.mad | 对三个标量或向量逐分量计算 (a * b + c)(乘加融合,减少舍入误差) |
math.modf | 同时返回模与小数部分 |
math.csum | 向量各分量的横向求和 |
math.rcp | 倒数(1 除以该值) |
math.mad在图形与物理代码中很常见:它把a * b + c合并为单次乘加运算,在 Burst/硬件支持时等价于 FMA 指令,既提速又降低中间截断误差。math.rcp与math.rsqrt这类“倒数”版本常用于把除法替换为乘法,例如 BoidSystem.cs 中InverseBoidCellRadius = 1.0f / boidSettings.CellRadius的预计算,正是“先取倒数、循环内用乘法”的典型优化模式。
指数与对数
| 方法 | 说明 |
|---|---|
math.ceillog2 | 以 2 为底的对数的向上取整 |
math.ceilpow2 | 大于等于输入的最小 2 的幂 |
math.exp | 常数 e 的幂 |
math.exp10 | 10 的幂 |
math.exp2 | 2 的幂 |
math.floorlog2 | 以 2 为底的对数的向下取整 |
math.log | 自然对数 |
math.log10 | 以 10 为底的对数 |
math.log2 | 以 2 为底的对数 |
math.pow | 幂运算 |
math.rsqrt | 平方根的倒数 |
math.sqrt | 平方根 |
math.ceillog2/math.floorlog2/math.ceilpow2在分配容量、计算 mipmap 层级、对齐缓冲区大小时非常实用,例如把数组长度向上取整到 2 的幂以配合NativeParallelMultiHashMap的桶数选择。
舍入与符号
| 方法 | 说明 |
|---|---|
math.abs | 绝对值 |
math.ceil | 向上取整 |
math.floor | 向下取整 |
math.round | 四舍五入到最近整数 |
math.sign | 符号:+1、0 或 -1 |
math.floor在 DOTS 中常与math.hash组合用于“空间网格哈希”——把连续位置量化到整数格再取哈希(见下文 Boids 的math.floor(localToWorld.Position * InverseBoidCellRadius))。
数值检查
| 方法 | 说明 |
|---|---|
math.isfinite | 是否为有限浮点值? |
math.isinf | 是否为无穷大? |
math.isnan | 是否为 NaN? |
math.ispow2 | 是否为 2 的幂? |
math.isnan/math.isfinite常用于防御式编程:对 Job 输入的位置、速度、旋转做合法性校验,在进入物理或渲染管线前及早发现问题。
类型转换
| 方法 | 说明 |
|---|---|
math.asdouble | 将 64 位整数的位模式重新解释为 double |
math.asfloat | 将 32 位整数的位模式重新解释为 float |
math.asint | 将 float 或 uint 的位模式重新解释为 int |
math.aslong | 将 double 或 64 位整数的位模式重新解释为 long |
math.asulong | 将 double 或 64 位整数的位模式重新解释为 ulong |
math.asuint | 将 float 或 int 的位模式重新解释为 uint |
math.f16tof32 | 半精度浮点值对应的单精度浮点表示 |
math.f32tof16 | 浮点值最近的半精度表示 |
math.frac | 浮点值的小数部分 |
math.trunc | 浮点值的整数部分(向零取整) |
as*系列是位模式重解释而非数值转换:不做任何数学运算,只是把同一串比特换一种类型看待,常用于哈希、编码颜色、快速比较浮点位序等底层技巧。f32tof16/f16tof32在顶点数据压缩、粒子属性打包(如把两个 float 塞进一个 uint)中广泛使用。
插值与钳制
| 方法 | 说明 |
|---|---|
math.clamp | 将值钳制到区间内 |
math.lerp | 两个值之间的线性插值 |
math.nlerp | 两个四元数之间的归一化线性插值 |
math.remap | 将值从源区间线性映射到目标区间(不钳制) |
math.saturate | 将值钳制到区间 [0, 1] |
math.slerp | 两个四元数之间的球面插值 |
math.smoothstep | 0.0f 到 1.0f 之间的平滑 Hermite 插值 |
math.step | 若 x >= y 返回 1.0f,否则返回 0.0f |
math.unlerp | 将值归一化到区间内(lerp 的逆运算) |
实用对照:clamp(x, a, b)与saturate(x)(等价于clamp(x, 0, 1))保证输出有界;smoothstep产生两端平滑的缓动曲线,常用于“渐入渐出”的权重过渡;remap与unlerp配合可把任意区间映射到 [0,1] 再反向映射。四元数插值时:追求速度用nlerp,追求恒定角速度的平滑旋转用slerp。
二值选择
| 方法 | 说明 |
|---|---|
math.shuffle | 从两个向量中挑选一个或多个指定分量 |
math.select | 依据布尔值在两个值之间挑选,类似三元运算符,但可按分量对两个向量逐分量挑选 |
math.cmax | 向量的最大分量 |
math.cmin | 向量的最小分量 |
math.max | 两个值中的较大者 |
math.min | 两个值中的较小者 |
math.select是 DOTS 代码中替代if/else的关键函数:它按分量从两个候选值中挑选(select(a, b, c)中 c 为 true 的分量取 b),且两侧参数都会被求值,天然适合 SIMD 与 Burst。Boids 样例中有非常典型的用法(见 BoidSystem.cs):
nearestDistance = math.select(nearestDistance, distance, nearest); nearestPositionIndex = math.select(nearestPositionIndex, i, nearest);这里用比较结果nearest作为掩码,一次性选出最近距离与最近索引,避免了循环内分支,也让 Job 能被 Burst 高效向量化。
哈希
更多哈希方案可参考 Collections 包。
| 方法 | 说明 |
|---|---|
math.hash | 对值求哈希 |
math.hashwide | 当需要把多个值一起哈希时,通常更高效的做法是:把各值分别传入hashwide(),将结果组合后再交给hash() |
math.hash在 DOTS 中常被用作“种子派生”与“空间哈希”。Boids 用它对量化的空间格坐标取哈希以构建邻域桶(见 BoidSystem.cs):
var hash = (int)math.hash(new int3(math.floor(localToWorld.Position * InverseBoidCellRadius))); ParallelHashMap.Add(hash, entityIndexInQuery);另外,Random.CreateFromIndex内部同样基于哈希把索引扩散为互不相关的随机流(见下文随机数一节)。
位运算与布尔运算
| 方法 | 说明 |
|---|---|
math.all | 所有布尔分量都为 true 时为 true |
math.any | 任一布尔分量为 true 时为 true |
math.bitmask | 将 bool4 转为位掩码:每个分量占 1 位(共 4 位),按 LSB 顺序(低位到高位)排列 |
math.countbits | 统计 1 位的个数 |
math.compress | 将掩码启用的向量分量向左压缩打包 |
math.lzcnt | 前导零计数 |
math.reversebits | 反转位顺序 |
math.rol | 循环左移 |
math.ror | 循环右移 |
math.tzcnt | 尾随零计数 |
math.all/math.any与逐分量比较运算符配合,可把“向量比较结果”汇总为单个布尔条件;math.bitmask则把分量条件打包成整数,可直接用于查表、索引或组合多个分支条件,是高性能筛选逻辑的常见工具。
三角函数、角度与弧度
| 方法 | 说明 |
|---|---|
math.acos | 反余弦 |
math.asin | 反正弦 |
math.atan | 反正切 |
math.atan2 | 双参数反正切(可判定象限) |
math.cos | 余弦 |
math.cosh | 双曲余弦 |
math.degrees | 弧度转角度 |
math.radians | 角度转弧度 |
math.sin | 正弦 |
math.sincos | 同时计算正弦与余弦(一次调用两者皆得) |
math.sinh | 双曲正弦 |
math.tan | 正切 |
math.tanh | 双曲正切 |
注意:Unity.Mathematics中所有三角函数默认以弧度为单位,因此角度参与运算前先用math.radians转换。math.sincos一次调用同时产出 sin 与 cos,比分别调用两次更高效,适合需要构建旋转矩阵或极坐标换算的场合。math.atan2(y, x)相对atan(y/x)能正确处理四个象限。
向量几何
| 方法 | 说明 |
|---|---|
math.cross | 叉积 |
math.distance | 两点之间的距离(支持 1 到 4 维) |
math.distancesq | 两点之间距离的平方(省去开方,1 到 4 维) |
math.dot | 点积 |
math.faceforward | 当两个向量指向同侧(夹角 <= 90°)时翻转向量 |
math.length | 点到原点的距离(向量模长) |
math.lengthsq | 点到原点距离的平方(省去开方) |
math.normalize | 归一化向量 |
math.normalizesafe | 归一化向量;若归一化结果不是有限值则返回默认值 |
math.project | 将向量投影到另一个向量上 |
math.projectsafe | 投影到另一个向量上;若投影结果不是有限值则返回默认值 |
math.reflect | 入射向量关于法线的反射 |
math.refract | 入射向量关于法线的折射 |
math.transform | 用 4x4 矩阵变换 3 维向量 |
工程要点:
distancesq/lengthsq返回距离平方(而不是原文档字面上的“平方根”语义——其设计意图恰是避免开方),在仅需比较远近的场景(如 Boids 的最近邻搜索)中用平方距离比较即可,性能远优于distance/length。Boids 的NearestPosition正是全程用math.lengthsq比较、最后才做一次math.sqrt(见 BoidSystem.cs)。normalizesafe/projectsafe是 DOTS 中强烈推荐的安全版本:零向量或非有限输入时返回默认值而非 NaN,避免除零导致的连锁污染。Boids 的航向计算全部使用math.normalizesafe(见 BoidSystem.cs)。reflect常用于弹跳与镜面计算;transform配合float4x4做局部到世界空间的坐标变换。
基向量方向(Cardinal Direction Vectors)
| 方法 | 说明 |
|---|---|
math.forward | Unity 坐标系中的前轴 |
math.back | Unity 坐标系中的后轴 |
math.up | Unity 坐标系中的上轴 |
math.down | Unity 坐标系中的下轴 |
math.left | Unity 坐标系中的左轴 |
math.right | Unity 坐标系中的右轴 |
这些常量返回 Unity 左手坐标系的单位轴向量(注意:Unity 的“前”是 +Z,与许多其他引擎不同),在构造LookRotation、做朝向矫正、以及 Boids 中quaternion.LookRotationSafe(nextHeading, math.up())(见 BoidSystem.cs)这类“朝某方向对齐上轴”的调用中必不可少。
矩阵运算(Matrix Ops)
| 方法 | 说明 |
|---|---|
math.determinant | 矩阵的行列式 |
math.fastinverse | 刚体变换(正交基 + 平移)的快速逆矩阵 |
math.inverse | 矩阵或四元数的逆 |
math.mul | 矩阵乘法 |
math.transpose | 矩阵转置 |
math.unitlog | 单位长度四元数的自然对数 |
fastinverse仅适用于无缩放的刚体变换矩阵(旋转 + 平移),利用正交基性质省去完整求逆,性能显著优于inverse,在大量视图/相机变换或每实体求逆的场景中应优先考虑;一旦矩阵含缩放则必须使用通用inverse。
旋转与变换
| 方法 | 说明 |
|---|---|
math.conjugate | 四元数共轭(翻转 x、y、z 的符号,w 不变),等价于反向旋转 |
math.orthonormalize | 对 float3x3 矩阵正交归一化 |
math.rotate | 用单位四元数旋转向量 |
math.unitexp | 四元数的自然指数(假设 w 为 0) |
quaternion.AxisAngle | 轴角旋转的四元数表示 |
quaternion.Euler | 欧拉角旋转的四元数表示(轴序由参数指定) |
quaternion.EulerXYZ | 欧拉角旋转的四元数表示(轴序 XYZ) |
quaternion.EulerXZY | 欧拉角旋转的四元数表示(轴序 XZY) |
quaternion.EulerYXZ | 欧拉角旋转的四元数表示(轴序 YXZ) |
quaternion.EulerYZX | 欧拉角旋转的四元数表示(轴序 YZX) |
quaternion.EulerZXY | 欧拉角旋转的四元数表示(轴序 ZXY) |
quaternion.EulerZYX | 欧拉角旋转的四元数表示(轴序 ZYX) |
quaternion.LookRotation | 由单位长度前向向量与单位长度上向量派生的旋转四元数 |
quaternion.LookRotationSafe | 由前向向量与上向量派生的旋转四元数(更安全,输入可非单位/非有限) |
quaternion.RotateX | 绕 X 轴旋转的四元数表示 |
quaternion.RotateY | 绕 Y 轴旋转的四元数表示 |
quaternion.RotateZ | 绕 Z 轴旋转的四元数表示 |
float4x4.LookAt | 由眼睛位置、目标点与单位上向量派生的视图矩阵 |
float4x4.Ortho | 正交投影矩阵 |
float4x4.OrthoOffCenter | 离轴正交投影矩阵 |
float4x4.PerspectiveFov | 基于视野角(FOV)的透视投影矩阵 |
float4x4.PerspectiveOffCenter | 离轴透视投影矩阵 |
float4x4.Scale | 表示缩放的变换矩阵 |
float4x4.Translate | 表示平移的变换矩阵 |
float4x4.TRS | 表示平移、旋转、缩放组合的变换矩阵 |
float3x3.Scale | 表示缩放的变换矩阵 |
RigidTransform.Translate | 表示平移的变换矩阵 |
RigidTransform、float3x3与float4x4也拥有与quaternion大部分相同的旋转构造方法。
实战印证一:HelloCube 的旋转系统用quaternion.RotateY构造每帧的角增量,再叠加到LocalTransform上(见 SpinSystem.cs):
Offset = quaternion.RotateY(SystemAPI.Time.DeltaTime * math.PI)math.PI保证每秒旋转半圈(π 弧度),RotateY生成绕 Y 轴的增量四元数,配合LocalTransform.Rotate(Offset)完成平滑自转。
实战印证二:Boids 的转向系统用float4x4.TRS一次性组合“位置平移 + 朝向旋转 + 单位缩放”写出新的LocalToWorld(见 BoidSystem.cs):
localToWorld = new LocalToWorld { Value = float4x4.TRS( new float3(localToWorld.Position + (nextHeading * MoveDistance)), quaternion.LookRotationSafe(nextHeading, math.up()), new float3(1.0f, 1.0f, 1.0f)) };其中LookRotationSafe把“新航向作为前向、math.up()作为上向”的安全版朝向构造与TRS平移/缩放组合,完成了整个群集转向的变换更新。
生成随机数
对应 Mathematics.cs 中的random()方法,Random是无状态可控的纯值 struct,可在 Burst Job 中安全复制与并行使用:
Random rand = new Random(123); // 种子为 123 // [-2147483647, 2147483647] int integer = rand.NextInt(); // [25, 100) 左闭右开 integer = rand.NextInt(25, 100); // x 为 [0, 1),y 为 [0, 1) float2 f2 = rand.NextFloat2(); // x 为 [0, 7.5),y 为 [0, 11) f2 = rand.NextFloat2(new float2(7.5f, 11f)); // x 为 [2, 7.5),y 为 [-4.6, 11) f2 = rand.NextFloat2(new float2(2f, -4.6f), new float2(7.5f, 11f)); // 均匀随机的单位长度方向向量。 double3 d3 = rand.NextDouble3Direction(); // 均匀随机的单位四元数。 quaternion q = rand.NextQuaternionRotation(); // 使用递增种子创建多个 Random 实例。 NativeArray<Random> rngs = new NativeArray<Random>(10, Allocator.Temp); for (int i = 0; i < 10; i++) { // 与 Random 构造函数不同,CreateFromIndex 会对种子做哈希。 // 若把递增种子直接传给构造函数,各 RNG 会生成彼此相似的随机序列; // 而改用 CreateFromIndex 后,各 RNG 生成的随机流彼此充分独立、互不相关。 rngs[i] = Random.CreateFromIndex((uint)(i + 123)); }工程要点:
- 区间规则均为左闭右开(
[min, max)),即包含下限、不包含上限,设计随机索引时要留意(配合rand.NextInt(0, array.Length)是安全的)。 - 多 RNG 场景务必使用
Random.CreateFromIndex:直接对构造函数传入递增种子会得到高度相关的序列(同族随机流),而CreateFromIndex通过哈希扩散种子,使并行实体各自拿到真正独立的随机流。这是 DOTS 中“每实体一个 RNG”的标准做法。 - 初始化批量 RNG 时通常配合
NativeArray<Random>与Allocator.Temp(或Allocator.TempJob)在系统 OnUpdate 内短生命周期使用。
生成噪声
noise类提供静态噪声生成方法,覆盖细胞噪声(Worley)与 Perlin/Simplex 两大体系:
| 方法 | 说明 |
|---|---|
noise.cellular(float2) | 2D 细胞噪声(Worley noise),使用标准 3x3 搜索窗口以获得较好的特征点数值 |
noise.cellular(float3) | 3D 细胞噪声(Worley noise),使用 3x3x3 搜索区域,F2 效果更好,但明显慢于 2x2x2 版本 |
noise.cellular2x2 | 2D 细胞噪声(Worley noise),2x2 搜索窗口 |
noise.cellular2x2x2 | 3D 细胞噪声(Worley noise),2x2x2 搜索窗口 |
noise.cnoise | 经典 Perlin 噪声 |
noise.pnoise | 经典 Perlin 噪声的周期化变体 |
noise.psrdoise | 2D 可平铺 simplex 噪声,支持固定或旋转梯度,附带解析导数 |
noise.psrnoise | 2D 可平铺 simplex 噪声,支持固定或旋转梯度,但不含解析导数 |
noise.snoise | Simplex 噪声 |
noise.srdnoise | 2D 不可平铺 simplex 噪声,支持固定或旋转梯度,附带解析导数 |
noise.srnoise | 2D 不可平铺 simplex 噪声,支持固定或旋转梯度,但不含解析导数 |
选型要点:
- 需要无缝平铺地形/纹理:选
pnoise或psrnoise/psrdoise(周期化/可平铺版本),并传入周期参数; - 需要导数做光照/变形:选
*doise(带 analytical derivative)系列; - 追求速度:用 2x2x2 的
cellular2x2x2或snoise;需要高质量 F2 距离特征时再升级到 3x3x3 的cellular(float3)。
仓库源码级应用总结
Unity.Mathematics在本仓库并非孤立存在,而是贯穿所有 DOTS 样例的核心计算层。以下对照表汇总了本文涉及的 API 在仓库中的真实调用点,可直接跳转阅读上下文:
| API | 仓库调用点 | 用途 |
|---|---|---|
math.min、math.select、math.normalizesafe、math.lengthsq、math.sqrt | BoidSystem.cs | 群集最近邻搜索与转向力计算 |
math.hash、math.floor | BoidSystem.cs | 空间网格哈希构建邻域桶 |
float4x4.TRS、quaternion.LookRotationSafe、math.up | BoidSystem.cs | 每 Boid 的 LocalToWorld 变换更新 |
quaternion.RotateY、math.PI | SpinSystem.cs | 实体自转的角增量构造 |
Random.CreateFromIndex、NativeArray<Random> | Mathematics.cs | 并行随机流的种子派生 |
更完整的“纯示例”版本位于 EntitiesSamples/Assets/ExampleCode/Mathematics.cs,其vectorCreation、matrixCreation、vectorMatrixOperators、random四个方法正是本文所有代码块的可编译来源。
延伸阅读
数学库只是 DOTS 的一个切面,本仓库 EntitiesSamples/Docs/cheatsheet 目录还提供了一系列配套速查文档,可作为系统学习的下一站:
- transforms.src.md:
LocalTransform、LocalToWorld、Parent等变换组件的速查,与本文的矩阵/四元数内容直接衔接; - blob_assets.src.md:Blob 资产(不可变共享数据)的创建与引用;
- collections.md:
NativeArray、NativeParallelMultiHashMap等集合的速查(Boids 的空间哈希即依赖于此); - mathematics.md:本文所依据的官方速查手册生成版;
- 若要观察数学库在完整游戏系统里的综合运用,Boids 样例(含 README)与 HelloCube 系列 是最佳阅读起点。
在开始编写自己的 ECS 系统前,建议把本文的速查表与Unity.Mathematics程序集 API 结合使用:先用速查表确定“有没有现成方法”,再通过重载列表确认具体签名,最后用本仓库的 Boids 与 HelloCube 样例验证性能与正确性。
【免费下载链接】EntityComponentSystemSamples项目地址: https://gitcode.com/GitHub_Trending/en/EntityComponentSystemSamples
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考