Unity.Mathematics Documentation

repository·master·Indexed 23 days ago

https://github.com/unity-technologies/unity.mathematics

A high-performance C# SIMD math library providing vector types (floatN), matrices (float3x3, float4x4), and quaternions with a shader-like syntax following HLSL conventions. Optimized for the Burst compiler and data-oriented programming, it includes a lightweight xor-shift based Random number generator and specialized utility functions like csum, compress, and lengthsq.

Tokens
3.6K
Snippets
8
Records
19
Agent score
81%

What's inside Unity.Mathematics

  1. Overview of Unity Mathematics types and functions

    master

    Unity Mathematics is a C# math library designed with a shader-like syntax (similar to HLSL or SIMD) to facilitate high-performance math operations. It is optimized for use with the Burst compiler to compile C# into efficient native code.

    Supported Vector and Matrix Types:

    • floatN (e.g., float2, float3, float4)
    • quaternion
    • float3x3
    • float4x4

    Supported Elementary Functions:

    • Basic: min, max, fabs, etc.
    • Trigonometric/Geometric: sin, cos, sqrt, normalize, dot, cross, etc.
  2. Use the quaternion type for rotations and transforms

    master

    The quaternion type is a core component of Unity.Mathematics designed as a drop-in replacement for float3x3 in many contexts.

    Key features include:

    • Matrix Compatibility: quaternion can be used to initialize matrices and supports the mul function just like float3x3.
    • Named Constructors: It provides the same set of named constructors as the equivalent float3x3 type for common transform operations.
    • Inversion: Use inverse or fastinverse for inverting quaternions.
  3. Understand Unity.Mathematics naming conventions

    master

    Unity Mathematics uses lowercase names for its core types and intrinsic operators to align with HLSL shader code and Burst compiler built-in types.

    • Types: Vectors (typeN), matrices (typeNxN), and quaternions (quaternion) are written in all lowercase.
    • Operators: Mathematical functions in Unity.Mathematics.math are intrinsics and are always lowercase.

    This convention facilitates frictionless code sharing between C# (via Burst) and shader code.

  4. Understand the differences between Unity.Mathematics and HLSL

    master

    Unity.Mathematics follows HLSL conventions (swizzles, free functions, succinct syntax) to allow for easy code porting, but differs from HLSL in several ways due to C# language constraints:

    1. Type Conversion: Unlike HLSL, which allows implicit narrowing conversions (e.g., float2 to int2), Unity.Mathematics requires explicit casts for potentially lossy conversions to remain consistent with C# conventions.
    2. Floating Point Literals: In HLSL, the default is float. In Unity.Mathematics (C#), the default is double. Use 1.5f for float and 3.2 for double.
    3. Half Precision (half/halfN): These are supported only as storage types. They implicitly convert to float/double and can be explicitly converted back, but no arithmetic operations are defined directly on them to avoid expensive implicit conversions.
    4. Implicit Truncation: HLSL allows assigning a float4 to a float2 (truncating extra components). Unity.Mathematics does not support this; assignments must match dimensions to avoid error-prone behavior.
  5. Use the Random Number Generator (Random)

    master

    The Random type is a basic PRNG based on the xor-shift algorithm. It is designed to be lightweight with a small state and avoids integer multiplication, making it efficient on lower-tier vector instruction sets.

    Capabilities:

    • Drawing uniformly random values for basic scalar and vector types.
    • Generating uniformly random directions and rotations.

    Warning: Because Random is implemented as a struct to support Burst, you must ensure it is properly initialized. A zero-initialized Random instance (e.g., default(Random)) will perpetually generate only zeros due to the nature of the xor-shift algorithm.

  6. Understand float4x4 operator multiplication

    master

    In Unity.Mathematics, the * operator for float4x4 performs componentwise multiplication, which differs from the behavior in UnityEngine. Multiplying two matrices with the * operator multiplies each corresponding element together.

    void OperatorMultiply4x4UnityMathematics()
    {
       float4x4 result = f4x4_Ones * f4x4_HalfIdentity;
       // result:
       // 0.5, 0.0, 0.0, 0.0,
       // 0.0, 0.5, 0.0, 0.0,
       // 0.0, 0.0, 0.5, 0.0,
       // 0.0, 0.0, 0.0, 0.5
    }
  7. Generate random numbers with the Random struct

    master

    To generate random numbers in Unity.Mathematics, you must manually create and manage the state of a random number generator using the Unity.Mathematics.Random struct. This explicit state management allows for deterministic behavior, which is essential for parallel code or when you need multiple independent sources of randomness with different seeds.

    To obtain random values, use the NextFloat method. By default, NextFloat() returns a value in the range [0, 1) (exclusive). You can also specify a custom range [min, max) (exclusive) by passing two arguments.

    // Unity Mathematics example
    void RandomNumberUnityMathematics()
    {
       // Choose some non-zero seed and set up the random number generator state.
       uint seed = 1;
       Unity.Mathematics.Random rng = new Unity.Mathematics.Random(seed);
    
       // [0, 1) exclusive
       float randomFloat1 = rng.NextFloat();
    
       // [-5, 5) exclusive
       float randomFloat2 = rng.NextFloat(-5.0f, 5.0f);
    }
  8. Porting UnityEngine code to Unity.Mathematics

    master

    When migrating code from UnityEngine to Unity.Mathematics, you must account for differences in types, operator behavior, and mathematical conventions:

    1. Type Mapping: Replace UnityEngine types with their Unity.Mathematics equivalents. Common mappings include:
      • Vector4 $\rightarrow$ float4
      • Quaternion $\rightarrow$ quaternion
    2. Operator Behavior: Be aware that operators behave differently. For example, while Matrix4x4 multiplication in UnityEngine implements matrix multiplication, the float4x4 multiplication operator in Unity.Mathematics implements componentwise multiplication.
    3. Angle Units: Ensure you convert between degrees and radians where necessary, as Unity.Mathematics typically expects radians.
    4. Random Number Generation: Unity.Mathematics.Random is an instanced object (not static) and behaves differently than UnityEngine.Random. Specifically, it is exclusive with its upper bound. If your existing logic is sensitive to bounds, you must adjust your implementation.
  9. Use Unity Mathematics in your C# code

    master

    To use the library, add using Unity.Mathematics; to your namespace. For easier access to the math functions, you can also use using static Unity.Mathematics.math; to call functions like float3(), normalize(), and dot() directly without a class prefix.

    using static Unity.Mathematics.math;
    namespace MyNamespace
    {
        using Unity.Mathematics;
        
        ...
        var v1 = float3(1,2,3);
        var v2 = float3(4,5,6);
        v1 = normalize(v1);
        v2 = normalize(v2);
        var v3 = dot(v1, v2);
        ...
    }
  10. Rotate a quaternion using AxisAngle and math.mul

    master

    To apply a rotation to an existing quaternion, you can create a rotation quaternion using quaternion.AxisAngle and then combine it with your target orientation using math.mul.

    Note that quaternion.AxisAngle expects the angle in radians, not degrees. You can use math.radians() to convert from degrees. math.mul performs quaternion multiplication, which is the standard way to compose rotations, similar to how matrices and vectors are multiplied.

    // Unity Mathematics example
    void QuaternionMultiplicationUnityMathematics()
    {
       var axis = new float3(0.0f, 1.0f, 0.0f);
       var q = quaternion.AxisAngle(axis,math.radians(45.0f));
       var orientation = quaternion.Euler(
           math.radians(45.0f),
           math.radians(90.0f),
           math.radians(180.0f));
       var result = math.mul(q, orientation);
    }
  11. When to use Unity.Mathematics vs UnityEngine.Mathf

    master

    To optimize for Burst compilation, use the Unity.Mathematics package by default and only use Mathf when necessary.

    Performance Warning:

    • Burst Compilation: Use Unity.Mathematics for best performance with Burst.
    • Mono Compiler: If your project uses the Mono compiler (and not Burst), continue using Mathf for mathematical operations, as Unity.Mathematics may not provide performance benefits in that context.
    • Type Conversions: Avoid frequent conversions between UnityEngine types (e.g., Vector3) and Unity.Mathematics types (e.g., float3), as these conversions are performance-intensive.