GLSL Verständnisfrage



  • Hallo.

    In den meisten Buechern und Tutorials wird ein einfaches "Texturing" Shader-Programm so oder so aehnlich beschrieben:

    Vertex Shader:

    void main() {
    
    	gl_TexCoord[0] = gl_MultiTexCoord0;
    	gl_Position = ftransform();
    }
    

    Fragment Shader:

    uniform sampler2D tex;
    
    void main()
    {
    	vec4 color = texture2D(tex,gl_TexCoord[0].st);
    	gl_FragColor = color;
    }
    

    .

    Aber wieso funktioniert das? Ich dachte, der Vertex Shader wird nur 1x pro Vertex aufgerufen (wenn man ein Quad rendert, also 4 mal). Demnach werden nach und nach 4 Werte in gl_TexCoord[0] geschrieben, die direkt darauffolgend vom Fragment Shader bearbeitet werden.

    Müsste der Fragment Shader dann nicht allen Pixeln die durchgearbeitet werden einen von diesen 4 verschiedenen Farben geben? Wie kommen da beim Fragment Shader die ganzen haufen Texelkoordinaten an anstatt nur die 4 die man beim 4x aufrufen des Vertexshaders speichert?



  • Im Vertex-Shader ist "gl_TexCoord[0]" nicht die Texturkoordinate vom ersten Vertex sondern die erste Texturkoordinate des Vertex.
    Denn wie Du schon richtig erkannt hast, sieht der Vertex-Shader ja immer nur einen Vertex und weiss von den anderen gar nichts.

    Wenn der Vertex-Shader genug Vertizen fuer ein Polygon erzeugt hat, interpoliert der Rasterizer alle Vertex-Attribute und stellt sie pro Pixel dem Fragment-Shader zur Verfuegung.
    Dort enthaelt gl_TexCoord[0] dann die interpolierte Texturkoordinate.
    Auch der Fragment-Shader weiss nichts von den zugehoerigen Vertizen.



  • Achso. Das heisst, diese Zeile "gl_TexCoord[0] = gl_MultiTexCoord0" schreibt gar nicht wirklich etwas in dieses Attribut, sondern markiert es sozusagen nur für den Rasterizer zum interpolieren, und dieser führt den Fragment-Shader x mal auf (je nachdem wie viele Pixel zwischen dem Polygon sind) und schreibt dann x verschiedene Werte in dieses Attribut?



  • Prinzipiell richtig. gl_TexCoord[0] ist ein Varying. Ein Varying ist ein Wert der im VertexShader geschrieben und vom Rasterizer dann zwischen allen Vertices über das ganze Polygon interpoliert wird. Im FragmentShader kannst du dann den interpolierten Wert auslesen. Man sollte aber anmerken dass diese ganzen gl_ Dinger veraltet sind und praktisch nur existieren um Shader mit der FFP kompatibel zu machen. In modernem OpenGL würde das eher so aussehen:

    // VertexShader
    
    #version 150
    
    uniform mat4 Transform;
    
    in vec3 position;  // vertex attribut
    in vec2 texcoord;  // vertex attribut
    
    out vec2 t;  // interpolator
    
    void main()
    {
      gl_Position = Transform * vec4(position, 1.0);
      t = texcoord;
    }
    
    // FragmentShader
    
    #version 150
    
    uniform sampler2D tex;
    
    in vec2 t;  // interpolator
    
    out vec4 color;
    
    void main()
    {
      color = texture2D(tex, t.xy);
    }
    

Anmelden zum Antworten