OpenGL: uniform oder buffer?



  • Hallo,

    in meinem Vertex Shader brauche ich einen Puffer für mein Model, der 65536 x 2uints hält (=0,5MiB). Der Shader wird nur mit den nötigen Indices gefüttert, dessen Model er zeichnen soll.

    Meine Frage lautet, ob ich das mit einem Uniform realisieren kann oder einem Buffer. Mich stört schon alleine bei Uniform, dass ich keine Arrays von structs im Shader anlegen kann, deshalb der Versuch:

    im Shader

    #define BLOCKS 65536
    // ...
    uniform uint  u_model_id[BLOCKS];
    uniform uint  u_model_data[BLOCKS];
    

    error C5041: cannot locate suitable resource to bind variable "u_model_id". Possibly large array.

    Ich vermute, es sind zu viele, wobei pro Item keine neue location erstellt wird dachte ich.

    Lieber wäre es mir natürlich, dass mein Buffer auf dem Host wie im Shader wie folgt aussieht:

    struct model
    {
      uint id, data;
    }
    
    buffer model b_blocks[];
    

    Ist das so möglich oder auch schlecht? Ich hab gelesen, dass die buffer wohl Mindestgrößen haben und solange der Shader in den Puffer nicht schreiben können muss, sollte man Uniforms nehmen.



  • Storage Buffer gibt's anscheinend ja erst ab GLSL 4.3. Muss ja irgendwie schon früher eine Lösung gegeben haben struct's vom Host in den VRAM zu stopfen, ohne großartig die Struktur zu verändern und in den Shadern darauf zugreifen zu können. Größenordnung im Megabyte-Bereich.



  • Angeblich soll ein Texture Buffer helfen. hmm klingt schon wieder nach einem Workaround.

    http://stackoverflow.com/questions/7954927/glsl-passing-a-list-of-values-to-fragment-shader
    http://www.opengl.org/wiki/Buffer_Texture



  • PhilippHToner schrieb:

    Angeblich soll ein Texture Buffer helfen. hmm klingt schon wieder nach einem Workaround.

    Eine Textur ist ja nichts anderes als ein 1D-, 2D- oder 3D-Array.
    Wenn man also ein Array möchte, dessen Grösse den Uniform-Speicherplatz überschreitet, gibt es dafür keine bessere Lösung als eine Textur.
    Man muss sich aber eben mit der Einschränkung abfinden, dass man seine Daten in einem Format unterbringen muss, dass eigentlich mal für Farben gedacht war.

    Alternativen sind Compute Shader und OpenCL.



  • Einmal gibt es Uniform buffer objects. Diese haben nur eine garantierte Unterstützung für 16 KiB (GL_MAX_UNIFORM_BLOCK_SIZE).
    Die meisten Treiber unterstüzen 64 KiB.

    Texture Buffer ist ein einfaches Proxy Objekt mit welchem der Shader auf den Speicher von einem Buffer Objekte zugreifen kann.
    Ein Texture Buffer wird wie eine Texture gebunden und im Shader als 1D-Texture mit einem bestimmten Datentype benutzt.

    Texture Buffer haben zwar nur eine garantierte Unterstützung von 65536 Elementen. (GL_MAX_TEXTURE_BUFFER_SIZE)
    Daraus ergibt sich: Elemente * sizeof(Type) = größe in Byte
    Jedoch haben die meisten Treiber Unterstützung für sehr viel größere Buffer! Hiernach oft 128-256 Millionen Elemente.

    Ansonsten halt Shader Storage Buffer Objects(nicht zu verwechseln mit Buffer Storage), welche jedoch ein 4.3 Feature sind.


Anmelden zum Antworten