Here is the vertex shader (in MSL)
v2f vertex vertex_main(device const packed_float3* pos_data [[buffer(0)]],
device const packed_float2* uv_data [[buffer(1)]],
device const packed_float3* normal_data [[buffer(2)]],
device const Camera_Data& camera_data [[buffer(3)]],
device const int4* bone_id [[buffer(6)]],
device const packed_float4* bone_weight [[buffer(7)]],
device const float4x4* bone_transforms [[buffer(8)]],
uint vertex_id [[vertex_id]]) {
v2f o;
float3 pos = pos_data[vertex_id];
float4 norm = float4(normal_data[vertex_id], 0);
float4 total_position = float4(0, 0, 0, 0);
float4 total_normal = float4(0, 0, 0, 0);
int4 bone_ids = bone_id[vertex_id];
float4 bone_weights = bone_weight[vertex_id];
if (all(bone_ids == int4(-1))) {
total_position = float4(pos, 1);
total_normal = norm;
} else {
for (int i = 0; i < 4; i++) {
if (bone_ids[i] == -1) {
continue;
}
if (bone_ids[i] >= 100) {
break;
}
float4 local_pos = bone_transforms[bone_ids[i]] * float4(pos, 1);
total_position += local_pos * bone_weights[i];
total_normal += bone_transforms[bone_ids[i]] * bone_weights[i] * norm;
}
}
o.position = camera_data.perspective_transform * camera_data.view_transform * camera_data.world_transform * total_position;
}