Version: Unity 6.0 (6000.0)
语言 : 中文
访问自定义着色器中的 DOTS Instancing 属性
URP 中 DOTS 实例化着色器示例

在 URP 中应用 DOTS 实例化着色器的最佳实践

最佳做法是将所有 unity_DOTSInstanceData 缓冲区的前 64 个字节初始化为零,并保留未使用状态。这是因为批处理创建期间 Unity 中,未指定的所有元数据值的默认元数据值为零。具体而言,当着色器从 UNITY_ACCESS_DOTS_INSTANCED_PROP 宏加载零元数据值时,着色器将从地址 zero 加载此值,因为将忽略实例索引。确保前 64 个字节(即最大值类型(float4x4 矩阵)的大小)为零可以保证此类加载能够以可预测的方式返回零结果。否则,着色器可能会加载一些不可预测的内容,具体取决于地址零所处的位置。

使用 DOTS 实例化时,Unity 提供的 Shader Graph 和 Shader 对变换矩阵使用特殊约定。为节省 GPU 内存和带宽,它们仅使用 12 个浮点数而非全部 16 个浮点数来存储矩阵,因为四个浮点数始终是常量。此类着色器希望浮点数的格式能够按顺序存储矩阵中每列的 x、y 和 z。也就是说,前三个浮点数是第一列的 x、y 和 z,接下来的三个浮点数是第二列的 x、y 和 z,依此类推。矩阵不会存储每列的 w 元素。这会影响的变换矩阵为:

  • unity_ObjectToWorld
  • unity_WorldToObject
  • unity_MatrixPreviousM
  • unity_MatrixPreviousMI

以下代码示例包含一个将常规四乘四矩阵转换为 12 浮点数的规范形式。

struct PackedMatrix
{
    public float c0x;
    public float c0y;
    public float c0z;
    public float c1x;
    public float c1y;
    public float c1z;
    public float c2x;
    public float c2y;
    public float c2z;
    public float c3x;
    public float c3y;
    public float c3z;

    public PackedMatrix(Matrix4x4 m)
    {
        c0x = m.m00;
        c0y = m.m10;
        c0z = m.m20;
        c1x = m.m01;
        c1y = m.m11;
        c1z = m.m21;
        c2x = m.m02;
        c2y = m.m12;
        c2z = m.m22;
        c3x = m.m03;
        c3y = m.m13;
        c3z = m.m23;
    }
}
访问自定义着色器中的 DOTS Instancing 属性
URP 中 DOTS 实例化着色器示例