understanding the fragment shader input from the vertex shader

Viewed 1189

I am trying to understand fragment shader input position from vertex shader. Does each fragment receives its position from the vertex shader?

Here is my shaders.metal

struct VertexOut{
    float4 position [[position]];
    float4 color;
};

vertex VertexOut basic_vertex(     
                           const device packed_float3* vertex_array [[ buffer(0) ]],
                           unsigned int vid [[ vertex_id ]]) {                 
    VertexOut vertexOut;
    vertexOut.position = float4(vertex_array[vid], 1.0);
    vertexOut.color = (vertexOut.position+1)/2;
    return vertexOut;      
}

color computed in vertex shader

fragment float4 basic_fragment(VertexOut vertexOut [[stage_in]]) {
    return vertexOut.color;             
}

color computed in vertex shader

color computed in fragment shader

fragment float4 basic_fragment(VertexOut vertexOut [[stage_in]]) {
    return (vertexOut.position+1)/2;       
}

color computed in fragment shader

why are they rendered differently? what is value of vertex position passed to each fragment? It seems the all the fragments of a triangle receive the centroid of the triangle. how to compute position of each fragment in the fragment buffer?

--EDIT--

Divided position with window size in fragment shader; still the triangle is yellow.

ViewController.swift

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let window = view.window
        if(window == nil) {return}
        let scale = view.window?.screen.nativeScale
        let layerSize = view.bounds.size
        //[640, 1136]
        frameSize = [UInt(layerSize.width * scale!), UInt(layerSize.height * scale!)]
        uniformBuffer = device.makeBuffer(bytes: frameSize, length: 2*MemoryLayout<UInt>.size, options: [])

    }
func render() {
    ...
    renderEncoder.setFragmentBuffer(uniformBuffer, offset: 0, index: 0)
    ...
}

shaders.metal

struct FrameSize{
    unsigned int x;
    unsigned int y;
};
fragment float4 basic_fragment(VertexOut vertexOut [[stage_in]],
                               const device FrameSize* frameSize [[ buffer(0) ]]
                               ) { // 1
    return float4(vertexOut.position.x/frameSize->x, vertexOut.position.y/frameSize->y, vertexOut.position.z, 1.0);              // 2
}
1 Answers
Related