Vertex Shader Data Misalignment

I am having a problem with the data I am sending from CPU to the Metal Vertex Function. I send a Vertex Model to the Vertex Function but the data seems to be misaligned for the color values.


When showing the input values in the debugger in "Vertex Attributes" I see the following for the input.

Positions (float3)

V0 0.000000 1.000000 0.000000

V1 -1.000000 -1.000000 0.000000

V2 1.000000 -1.000000 0.000000


Colors (float4)

V0 3.860822e-38 1.401298e-45 3.860853e-38 1.401298e-45

V1 3.164020e-39 3.452799e-41 3.159805e-39 3.452799e-41

V2 8.283131e-40 3.452799e-41 9.716267e-40 3.452799e-41


I have included my code below on how I create my buffer data and the attribute bindings I apply.

What am I doing wrong to get the wrong color data information.


1) I created a basic Vertex model

    struct Vertex{
        var position: float3!
        var color: float4!
    }


2) I then created my triangle using that model.

var vertices: [Vertex] = [
            Vertex(position: float3( 0, 1, 0), color: float4(1,0,0,1)), //Top Middle (Red)
            Vertex(position: float3(-1,-1, 0), color: float4(0,1,0,1)), //Bottom Left (Green)
            Vertex(position: float3( 1,-1, 0), color: float4(0,0,1,1))  //Bottom Right (Blue)
        ]


3) I then create an MTLBuffer with the vertices data.

var vertexBuffer: MTLBuffer  = device?.makeBuffer(bytes: vertices, length: MemoryLayout<Vertex>.stride * vertices.count, options: [])


4) I set my vertex descriptor for my render pipeline state to have these attributes

        let vertexDescriptor = MTLVertexDescriptor()

        //Position Attribute
        vertexDescriptor.attributes[0].format = .float3
        vertexDescriptor.attributes[0].bufferIndex = 0
        vertexDescriptor.attributes[0].offset = 0

        //Color Attribute
        vertexDescriptor.attributes[1].format = .float4
        vertexDescriptor.attributes[1].bufferIndex = 0
        vertexDescriptor.attributes[1].offset = MemoryLayout<float3>.size

        vertexDescriptor.layouts[0].stride = MemoryLayout<Vertex>.stride


5) Now that the data is set up, I send the data to my metal file with the following code.

struct VertexIn{
    float3 position [[ attribute(0) ]];
    float4 color [[ attribute(1) ]];
};
struct VertexOut{
    float4 position [[ position ]];
    float4 color;
};
vertex VertexOut basic_vertex_shader(VertexIn vIn [[ stage_in ]]){
    VertexOut vOut;

    vOut.position = float4(vIn.position, 1);
    vOut.color = vIn.color;

    return vOut;
}
fragment half4 basic_fragment_shader(VertexOut vIn [[ stage_in ]]){
    float4 color = vIn.color;

    return half4(color.r, color.g, color.b, color.a);
}


I have done this in other projects and not had this result. Can you please let me know why the data is misaligned?

Accepted Reply

Hi,


I'm wondering about the "!" after the types in your vertex struct. I think that T! means Optional<T>, which may not have the same memory layout as T. Shouldn't your struct be:


struct Vertex {

var position: float3

var color: float4

}


Ie, `float3`, not `float3!`. It might work for float3 but not float4, by luck, because of low level details about how the compiler lays out the Optional<float3> and Optional<float4> in memory.


Rob

Replies

Hi,


I'm wondering about the "!" after the types in your vertex struct. I think that T! means Optional<T>, which may not have the same memory layout as T. Shouldn't your struct be:


struct Vertex {

var position: float3

var color: float4

}


Ie, `float3`, not `float3!`. It might work for float3 but not float4, by luck, because of low level details about how the compiler lays out the Optional<float3> and Optional<float4> in memory.


Rob

Oh man were you correct! Thanks for the help. I removed the !'s and my triangle was full of radiant color. I new it was something silly.