Ergebnis 1 bis 16 von 16

Thema: GLSL Fragment Shader: Palette Swapping

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1

    GLSL Fragment Shader: Palette Swapping

    Guten Tag.
    Ich habe mich vor kurzem mit GLSL Fragment und Vertex Shadern auseinandergesetzt.
    Ich bin nun also dabei einen eigenen Fragment Shader zu schreiben um schnelles und effektives Palette Swapping in meiner OpenGL-Anwendung umsetzen zu können.
    Dabei handelt es sich jedoch nicht nur um simples Palette Swapping sondern mit einer kleinen Feinheit dabei: Ich will nämlich bestimmte Bereiche des Sprites voneinander trennen und eigenständigen Paletten zuordnen.
    Zum Beispiel Haut, Haar und Kleidungspaletten.
    Ich habe mir also gedacht die Pixel in der Sprite-Textur dazu zu verwenden Informationen zu verschlüsseln.
    Der grüne Farbwert gibt an welchen Index der Pixel in der Palette haben soll, der rote Farbwert gibt an um welchen Typ (Haut, Haar, Kleidung) es sich handelt. Der blaue wird (noch) nicht verwendet und Alpha wird einfach übernommen.

    Nun habe ich einen ersten naiven Ansatz für den Shader geschrieben (Im Moment noch ohne die Typen) und ihn auch erfolgreich kompilieren können:
    Code:
    // texture
    uniform sampler2D tex;
    
    // id of palette to be used
    uniform int palette = 0;
    
    // the offset for each type in a single palette, 0 - 10 => body, 11 - 14 => skin, 15 - ... => hair
    uniform int offset_array[3] = {0, 11, 15};
    
    // the palette
    uniform vec3 color_table[30] = {
        vec3(0, 0, 1), vec3(1, 0, 0), vec3(1, 0, 0), 
        vec3(1, 0, 0), vec3(1, 0, 0), vec3(1, 0, 0),
        vec3(1, 0, 0), vec3(1, 0, 0), vec3(1, 0, 0), 
        vec3(1, 0, 0), vec3(1, 0, 0),vec3(1, 0, 0), 
        vec3(1, 0, 0), vec3(1, 0, 0), vec3(1, 0, 0),
        vec3(1, 0, 0), vec3(32, 72, 49), vec3(72, 128, 126), 
        vec3(152, 192, 185), vec3(72, 232, 83), vec3(96, 248, 164), 
        vec3(248, 248, 248), vec3(66, 152, 56), vec3(56, 64, 144), 
        vec3(32, 42, 90), vec3(131, 120, 232), vec3(24, 24, 24), 
        vec3(82, 54, 32), vec3(172, 110, 76), vec3(204, 148, 96)
    };
    
    void main(){
        vec4 color = texture2D(tex, gl_TexCoord[0].st);
    
        // the red value of a fragment determines the type: body, skin, hair
        int type = int(color.r * 255);
    
        // the green value of a fragment determines the index in the palette
        int index = int(color.g * 255);
    
        // the type determines the offset in the palette
        int offset = offset_array[type];
    
        // the color is picked from the palette according to offset, index and palette id.
        vec3 final_color = color_table[int(offset + index + palette * 15)];
    
        gl_FragColor = vec4(final_color.r, final_color.g, final_color.b, color.a);
    }
    Und ich könnte auch damit weiterarbeiten und den Shader vervollständigen wenn da nicht ein kleines Problem wäre:
    Die Daten welche "gl_TexCoord[0].st" liefert sind alle zwischen 0.0 und 1.0 angesiedelt und nicht die reinen Byte-Daten.
    Das öffnet natürlich Tür und Tor für Rundungsfehler und macht dadurch das gesamte System kaputt.

    Gibt es also einen Weg auf die RGBA-Werte eines Fragments direkt in Byte-Form zugreifen zu können?
    Und gibt es vielleicht einen Vorschlag für eine bessere Methode dieses Ziel zu erreichen?

    Vielen Dank für die Hilfe.

    Geändert von Cornix (19.01.2013 um 12:13 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •