How can I copy a SIMD float4x4 matrix to a vertex shader by using the setVertexBytes:length:atIndex message of a render command encoder?
I'm not sure if you're using Swift or Objective-C, but here's an example for both. We'll assume there's a helper function matrix4x4_rotation
that creates a rotation matrix using the angle-axis formula that returns a matrix_float4x4
. We'll also assume that BufferIndexModelMatrix
is defined as the index you want to bind the matrix to.
In Swift, you'll create your matrix and then use the &
operator to get the pointer, and MemoryLayout<simd_float4x4>.size
to get the size of the matrix data type.
let rotationAxis = SIMD3<Float>(1, 1, 0)
let modelMatrix: matrix_float4x4 = matrix4x4_rotation(radians: rotation, axis: rotationAxis)
renderEncoder.setVertexBytes(&modelMatrix, length: MemoryLayout<simd_float4x4>.size, index: Int(BufferIndexModelMatrix.rawValue))
And in Objective-C, we can use the normal C &
operator to get the pointer, and sizeof(simd_float4x4)
to get the size of the matrix data type.
simd_float3 rotationAxis = {1, 1, 0};
simd_float4x4 modelMatrix = matrix4x4_rotation(_rotation, rotationAxis);
[renderEncoder setVertexBytes:&modelMatrix length:sizeof(simd_float4x4) atIndex:BufferIndexModelMatrix]
And in your Metal shader source, you would add a constant
parameter at the buffer index and use the matrix you encoded.
vertex ColorInOut vertexShader(Vertex in [[ stage_in ]],
constant FrameData & frameData [[ buffer(BufferIndexFrameData) ]],
constant float4x4 & modelMatrix [[ buffer(BufferIndexModelMatrix) ]])
{
ColorInOut out;
float4 position = float4(in.position, 1.0);
out.position = frameData.projectionViewMatrix * modelMatrix * position;
out.texCoord = in.texCoord;
return out;
}