针对所有 unity_DOTSInstanceData
缓冲区的最初 64 个字节进行初始化并保持其未使用的状态是一种最佳实践。其原因在于,Unity 为批处理创建期间未指定的所有元数据值所使用的默认元数据值是零。具体而言,当着色器在 GPU 上运行的程序。 了解更多信息
参见 词汇表从 UNITY_ACCESS_DOTS_INSTANCED_PROP
宏加载零元数据值时,该着色器从地址 zero
加载此值,因为实例索引将被忽略。确保前 64 个字节(即最大值类型的字节数(float4x4 矩阵))为零,可保证此类加载可预测地返回零结果。否则,着色器可能会加载某些不可预测的内容,具体取决于地址 zero 处的内容。
使用 DOTS 实例化时,Unity 提供的着色器图和着色器使用变换矩阵特殊约定。为了节省 GPU 内存和带宽,他们使用仅 12 个浮点数(而不是完整的 16 个浮点数)存储这些矩阵,因为其中四个浮点数始终是常量。这些着色器预期的浮点数格式是这样的:矩阵中每列的 x、y 和 z 按顺序存储。换句话说,前三个浮点数是第一列的 x、y 和 z,后三个浮点数是第二列的 x、y 和 z,依此类推。矩阵不会存储每列的 w
元素。这会影响以下变换矩阵
unity_ObjectToWorld
unity_WorldToObject
unity_MatrixPreviousM
unity_MatrixPreviousMI
以下代码示例包含将常规 4x4 矩阵转换为 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;
}
}