GLSL: Wert auf mehrere Farbkanäle verteilen



  • Hallo!

    Ich habe RGBA-Texturen (momentan 8 Bit pro Kanal). Ist es möglich, zwei Farbkanäle direkt als einzelnen Wert anzusprechen, wie in C? Eine Farbe wäre dann so aufgebaut:

    +------+------+-------------+
    | 8bit | 8bit |    16bit    |
    +------+------+-------------+
    

    Das würde mir erlauben, andere Daten mitzuspeichern. Ich habe zwar gesehen, dass OpenGL spezielle Texturformate anbietet, aber dieses spezielle (8/8/16) habe ich nicht gefunden. Die Reihenfolge der Felder spielt hier keine Rolle.

    Könnte man also color.ba nicht als vec2, sondern als float oder uint ansprechen? Oder müsste man das manuell handhaben (bei ints mit Bitshift), oder wie würdet ihr hier vorgehen?



  • color.b = dot(color.ba,vec2(1,1.f/256f));
    

    Geht nur mit Nearest filtering.



  • Wenn ich das nur dem Kanal b zuweise, wird der Wert doch einfach abgeschnitten und nicht auf ba verteilt, oder? Ich habe leider kein Texturformat gefunden, wo man mit b gleich 16 Bit ansprechen kann...



  • Da wird nichts geschnitten, im Shader sind r,g,b,a 32bit float werte. R,g,b,a liest du aus der Textur und berechnest b aus b und a.



  • Ja, aber beim Zurückspeichern geht Information verloren, da ein einzelner Kanal meiner Textur nur 8bit halten kann. Oder B und A zusammen 16bit.

    Dein Code macht ja das gleiche wie

    color.b += color.a/256.f;
    

    was nur den B-Kanal füllt (Konvertierung zu 8bit). Der A-Kanal ist ja noch nicht zugewiesen... Ich habe aber ein RGBA8-Format, da ich R8G8B16 nicht gefunden habe. Oder verstehe ich dich falsch?



  • GLSLer hat den Variablennamen color.b einfach weiter verwendet, da dieser innerhalb des Shaders ein float ist. So ist es etwas Verständlicher:

    float mein16BitGenauerWert = dot(color.ba,vec2(1,1.f/256f));
    

    und zum speichern, wenn man z.b. in einen FBO rendert:

    float value;
    outputColor.b = value;
    outputColor.a = mod( value, ( 1.0f / 256.0f ) );
    

Anmelden zum Antworten