모든 unity_DOTSInstanceData 버퍼의 첫 64바이트를 0으로 초기화하고 사용하지 않는 것이 가장 좋습니다. 이는 배치 생성 시 지정되지 않은 모든 메타데이터 값에 대해 Unity가 사용하는 기본 메타데이터 값이 0이기 때문입니다. 특히 셰이더가 UNITY_ACCESS_DOTS_INSTANCED_PROP 매크로에서 메타데이터 값 0을 로드할 때 인스턴스 인덱스가 무시되므로 셰이더는 이 값을 주소 zero에서 로드합니다. 가장 큰 값 유형(float4x4 매트릭스)의 크기인 첫 64바이트가 0이인지 확인하면 이러한 로드에서 예측한 대로 0의 결과가 반환됩니다. 그렇지 않으면 셰이더는 주소 0에 발생하는 상황에 따라 예측할 수 없는 것을 로드할 수 있습니다.
DOTS 인스턴싱을 사용할 때 Unity가 제공하는 Shader Graph와 셰이더는 트랜스폼 매트릭스에 대해 특별한 규칙을 사용합니다. GPU 메모리와 대역폭을 절약하기 위하여 16개 전체가 아닌 12개의 플로트만 사용해 이러한 매트릭스를 저장합니다. 이는 4개의 플로트는 항상 일정하기 때문입니다. 이러한 셰이더는 매트릭스에서 각 열의 x, y, z가 순서대로 저장되는 포맷의 플로트를 예상합니다. 즉, 첫 3개의 플로트는 첫 번째 열의 x, y, z이고, 그 다음 3개의 플로트는 두 번째 열의 x, y, z인 식입니다. 매트릭스는 각 열의 w 요소를 저장하지 않습니다. 이에 영향을 받는 트랜스폼 매트릭스는 다음과 같습니다.
unity_ObjectToWorldunity_WorldToObjectunity_MatrixPreviousMunity_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;
}
}