The size of this struct is 36 bytes:
struct Mat
{
enum Type { Lam, Met, Dia };
int type;
packed_float3 albedo;
packed_float3 emissive;
float roughness;
float ri;
};
That makes sense when float
s and int
s are 4 bytes each and a packed_float3
is 12 bytes.
The size of this is 88 bytes:
struct Cam
{
packed_float3 origin;
packed_float3 lowerLeftCorner;
packed_float3 horizontal;
packed_float3 vertical;
packed_float3 u, v, w;
float lensRadius;
};
That makes sense when float
s are 8 bytes and the packed_float3
is 16 bytes.
These are in the same Metal shader. What is happening with the alignment here that would cause this to be true?
I can only get the match to work if a packed_float3
must fit within a contiguous 16-byte space, so in the first example it fits right after the first int
, but in the second example each must start its own. Is that it? If so, this magic number 16
does not appear to be documented anywhere I can find in the Metal Shading guide.
I think you're just counting wrong. This:
struct Cam
{
packed_float3 origin;
packed_float3 lowerLeftCorner;
packed_float3 horizontal;
packed_float3 vertical;
packed_float3 u, v, w;
float lensRadius;
};
is equivalent to:
struct Cam
{
packed_float3 origin;
packed_float3 lowerLeftCorner;
packed_float3 horizontal;
packed_float3 vertical;
packed_float3 u;
packed_float3 v;
packed_float3 w;
float lensRadius;
};
That's 7 packed_float3
s, for 21 float
s, plus a lone float
for a total of 22 float
s. When float
is 4 bytes, that's 88 bytes. There's no contradiction.