2017-07-10 2 views
3

Ich versuche zu verstehen Fragment Shader-Eingabeposition von Vertex-Shader. Erhält jedes Fragment seine Position vom Vertex-Shader?Verständnis der Fragment-Shader-Eingabe aus dem Vertex-Shader

Hier ist meine 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;  
} 

Farbe

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

color computed in vertex shader

Farbe berechnet in Fragment-Shader in Vertex-Shader berechnet

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

color computed in fragment shader

warum sind sie anders gemacht? Welchen Wert hat die Vertexposition an jedes Fragment? Es scheint, dass alle Fragmente eines Dreiecks den Schwerpunkt des Dreiecks erhalten. Wie berechnet man die Position jedes Fragments im Fragmentpuffer?

--EDIT--

Teilungsposition mit in Fragment-Shader-Fenstergröße; immer noch ist das Dreieck gelb.

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 
} 

Antwort

3

Die Eckpunktpositionen der Perspektive Teilung und Ansichtsfenster durch verwandeln, nachdem sie den Vertex-Shader lassen. Das transformiert sie von Clipkoordinaten (-1, 1 in x, y, 0..1 in z) zu Framebufferkoordinaten (x = 0..width-1, y = 0..height-1, z = 0..1). Der Fragment-Shader empfängt interpolierte Positionen im Framebuffer-Koordinatenraum.

Da sich die Positionskoordinaten der Fragmente im Framebuffer-Raum befinden, sind fast alle xy-Werte größer als 1,0, so dass Ihre Farbe nur maximal rot, maximal grün und dann unabhängig von Ihrem z-Wert ist. Wahrscheinlich wollen Sie sie wieder normalisieren, d. H. Den Wert der Position x durch die Framebufferbreite und die Position y durch die Framebufferhöhe teilen.

+0

Es hat nicht funktioniert. die Frage mit Vorschlägen bearbeitet – neckTwi

Verwandte Themen