TextureBufferObjects: Unterschied zwischen den Versionen
K-bal (Diskussion | Beiträge) (Artikel erstellt!) |
K (Transform-Feedback korrekt verlinkt) |
||
(4 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | + | Shader Model 4.0 führt mit der Extension [[GL_ARB_texture_buffer_object]] einen zusätzlichen Texturtyp ein: Das TextureBufferObject, oftmals abgekürzt mit TBO. Dabei handelt es sich um eine eindimensionale Textur, welche ihren Speicherbereich nicht selbst enthält, sondern auf den Speicher eines verknüpften BufferObjects zugreift. Bei einem solchen BufferObject kann es sich beispielsweise um ein [[VBO|VertexBufferObject]] (VBO) handeln. Es steht somit die Flexibilität von Bufferobjekten auch für Texturen zur Verfügung (fast) ohne zusätzliche Schnittstellen. | |
+ | Im Zusammenhang mit [[Transform-Feedback]] aber auch mit [[Instancing]] und bei anderen Gelegenheiten erweisen sich TextureBufferObjects als sehr nützlich. Mit Transform-Feedback kann in einen Vertexbuffer geschrieben werden, welcher dann im nächsten Renderpass ohne zusätzliche Kopiervorgänge als Textur benutzt werden kann. Dies wird unter anderem beim [[GLSL_Partikel_2|Shader Model 4.0 Partikelsystem]] exzessiv benutzt. Ein [[shader_Instancing|Beispiel zu Instancing]] findet sich in der [[Shadersammlung]]. | ||
− | + | Im Shader können TextureBufferObjects ausschließlich mit Integer-Koordinaten adressiert werden. Daher findet auch keine Interpolation zwischen Texeln statt. Wer eine Interpolation benötigt kann diese aber einfach selbst im Shader implementieren. | |
− | |||
+ | Für TextureBufferObjects muss keine Größe angegeben werden. Die Größe der Textur berechnet sich aus der Gesamtgröße des zugehörigen Bufferobjektes geteilt durch die Größe eines Texels. Die maximale Größe eines TextureBufferObjects beträgt dabei 2^27 = 134.217.728 Texel im Gegensatz zu normalen eindimensionalen Texturen, welche eine maximale Größe von 2^13 = 8.192 Texeln haben. In Kombination mit einem 4x32bit Texelformat (z.B. RGBA32F) bedeutet dies, dass ein TBO theoretisch bis zu 2 GB groß werden darf. Praktisch ist die Größe natürlich durch den Speicher der Grafikkarte begrenzt. | ||
− | + | ==Verwendung== | |
− | === | + | ===Verwendung im Programm=== |
− | + | Um unser TextureBufferObject zu Erstellen benutzen wir wie bei gewöhnlichen Texturen die Funktion [[glGenTextures]]: | |
− | |||
− | Um unser | ||
− | |||
<source lang="cpp"> | <source lang="cpp"> | ||
GLuint myTBO; | GLuint myTBO; | ||
Zeile 17: | Zeile 15: | ||
</source> | </source> | ||
− | Das Löschen geschieht mit | + | Das Löschen geschieht genauso gewohnt mit [[glDeleteTextures]]: |
− | |||
<source lang="cpp"> | <source lang="cpp"> | ||
glDeleteTextures(1, &myTBO); | glDeleteTextures(1, &myTBO); | ||
</source> | </source> | ||
− | + | Um das TextureBufferObject zu verwenden muss es wie eine normale Textur mit [[glBindTexture]] gebunden werden. Wir übergeben dabei allerdings die Konstante <tt>GL_TEXTURE_BUFFER_ARB</tt> als ersten Parameter: | |
− | |||
− | |||
− | |||
− | |||
− | |||
<source lang="cpp"> | <source lang="cpp"> | ||
glBindTexture(GL_TEXTURE_BUFFER_ARB, myTBO); | glBindTexture(GL_TEXTURE_BUFFER_ARB, myTBO); | ||
</source> | </source> | ||
− | Anschließend geben wir mit '' | + | Anschließend geben wir mit [[glTexBufferARB]]''(enum target, enum internalformat, uint buffer)'' |
− | an, welches | + | an, welches BufferObject mit dem TextureBufferObject verknüpft werden soll. Bei diesem BufferObject kann es sich zum Beispiel um ein [[VBO|VertexBufferObject]] handeln. |
− | |||
<source lang="cpp"> | <source lang="cpp"> | ||
− | glTexBufferARB(GL_TEXTURE_BUFFER_ARB GL_RGBA32F_ARB, myVBO); | + | glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_RGBA32F_ARB, myVBO); |
</source> | </source> | ||
− | Der zweite Parameter gibt hierbei den Datentyp unserer Textur an. Als Beispiel | + | Der zweite Parameter gibt hierbei den Datentyp unserer Textur an. Als Beispiel wurde hier ''GL_RGBA32F_ARB'' gewählt. Damit wird unsere Textur als vierelementiger 32-bit-float-Vektor benutzt (4*4 = 16 Byte pro Texel). Die Tabelle im [[#Texelformate|Abschnitt Texelformate]] gibt eine Übersicht über die möglichen Formate, welche als zweiter Parameter angegeben werden können. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | ===Verwendung im Shader=== | ||
+ | Unser TextureBufferObject ist nun erstellt und gebunden. Nun ist es an der Zeit, es im Shader auszulesen. Dafür brauchen wir neue Textursampler-Typen: <tt>samplerBuffer</tt>, <tt>usamplerBuffer</tt> oder <tt>isamplerBuffer</tt>, je nachdem, was unser TextureBufferObject für einen Datentyp repräsentiert: <tt>float</tt>, <tt>unsigned int</tt> oder <tt>int</tt>. Über diesen Sampler greifen wir mit der Funktion <tt>texelFetchBuffer(samplerBuffer sampler, uint index)</tt> auf unser TextureBufferObject zu: | ||
− | = | + | <source lang="glsl"> |
+ | #extension GL_EXT_gpu_shader4 : require | ||
+ | // ... | ||
− | + | uniform samplerBuffer tbo; // Unser Sampler, wir benutzen floats => samplerBuffer | |
− | |||
− | |||
− | |||
− | |||
− | uniform samplerBuffer tbo; // Unser | ||
void main() | void main() | ||
{ | { | ||
// Wir brauchen einen Array-Index um einen Texel zum Auslesen zu bestimmen. | // Wir brauchen einen Array-Index um einen Texel zum Auslesen zu bestimmen. | ||
− | |||
unsigned int index; | unsigned int index; | ||
// Wir berechnen unseren Index. | // Wir berechnen unseren Index. | ||
− | + | // ... | |
− | // | ||
− | // Wir holen einen Texel aus unserem | + | // Wir holen einen Texel aus unserem TextureBufferObject. |
− | |||
vec4 tmp = texelFetchBuffer(tbo, index); | vec4 tmp = texelFetchBuffer(tbo, index); | ||
// Wir machen etwas mit tmp | // Wir machen etwas mit tmp | ||
− | + | // ... | |
− | // | ||
} | } | ||
</source> | </source> | ||
+ | == Texelformate == | ||
+ | Die folgende Tabelle aus der [http://www.opengl.org/registry/specs/ARB/texture_buffer_object.txt Extension-Spezifikation] gibt eine Übersicht über die möglichen Texelformate. | ||
− | + | {{Hinweis|Es gibt nur ein-, zwei- und vier-elementige Typen. Will man also drei-elementige Daten benutzen, so muss man eine vierte Komponente ergänzen (zusätzlicher Speicherverbrauch) oder die Komponenten-Indizes im Shader zurückrechnen (zusätzlicher Rechenaufwand).}} | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | {| {{Prettytable_B1}} | ||
+ | |- style="background:#CCCCCC;" | ||
+ | ! rowspan=2 | Sized Internal Format | ||
+ | ! rowspan=2 | Base Type | ||
+ | ! rowspan=2 | Components | ||
+ | ! rowspan=2 | Norm | ||
+ | ! colspan=4 | Component | ||
+ | |- style="background:#CCCCCC;" | ||
+ | ! 0 !! 1 !! 2 !! 3 | ||
+ | |- | ||
+ | | GL_ALPHA8 || ubyte || 1 || Y || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA16 || ushort || 1 || Y || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA16F_ARB || half || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA32F_ARB || float || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA8I_EXT || byte || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA16I_EXT || short || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA32I_EXT || int || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA8UI_EXT || ubyte || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA16UI_EXT || ushort || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_ALPHA32UI_EXT || uint || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE8 || ubyte || 1 || Y || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE16 || ushort || 1 || Y || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE16F_ARB || half || 1 || N || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE32F_ARB || float || 1 || N || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE8I_EXT || byte || 1 || N || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE16I_EXT || short || 1 || N || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE32I_EXT || int || 1 || N || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE8UI_EXT || ubyte || 1 || N || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE16UI_EXT || ushort || 1 || N || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE32UI_EXT || uint || 1 || N || L || . || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE8_ALPHA8 || ubyte || 2 || Y || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE16_ALPHA16 || ushort || 2 || Y || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE_ALPHA16F_ARB || half || 2 || N || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE_ALPHA32F_ARB || float || 2 || N || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE_ALPHA8I_EXT || byte || 2 || N || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE_ALPHA16I_EXT || short || 2 || N || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE_ALPHA32I_EXT || int || 2 || N || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE_ALPHA8UI_EXT || ubyte || 2 || N || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE_ALPHA16UI_EXT || ushort || 2 || N || L || A || . || . | ||
+ | |- | ||
+ | | GL_LUMINANCE_ALPHA32UI_EXT || uint || 2 || N || L || A || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY8 || ubyte || 1 || Y || I || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY16 || ushort || 1 || Y || I || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY16F_ARB || half || 1 || N || I || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY32F_ARB || float || 1 || N || I || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY8I_EXT || byte || 1 || N || I || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY16I_EXT || short || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY32I_EXT || int || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY8UI_EXT || ubyte || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY16UI_EXT || ushort || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_INTENSITY32UI_EXT || uint || 1 || N || A || . || . || . | ||
+ | |- | ||
+ | | GL_RGBA8 || ubyte || 4 || Y || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA16 || ushort || 4 || Y || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA16F_ARB || half || 4 || N || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA32F_ARB || float || 4 || N || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA8I_EXT || byte || 4 || N || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA16I_EXT || short || 4 || N || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA32I_EXT || int || 4 || N || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA8UI_EXT || ubyte || 4 || N || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA16UI_EXT || ushort || 4 || N || R || G || B || A | ||
+ | |- | ||
+ | | GL_RGBA32UI_EXT || uint || 4 || N || R || G || B || A | ||
+ | |} | ||
− | http://www.opengl.org/registry/specs/ARB/texture_buffer_object.txt | + | == Literatur == |
+ | * [http://www.opengl.org/registry/specs/ARB/texture_buffer_object.txt ARB_texture_buffer_object] (Englisch) |
Aktuelle Version vom 10. Januar 2010, 14:37 Uhr
Shader Model 4.0 führt mit der Extension GL_ARB_texture_buffer_object einen zusätzlichen Texturtyp ein: Das TextureBufferObject, oftmals abgekürzt mit TBO. Dabei handelt es sich um eine eindimensionale Textur, welche ihren Speicherbereich nicht selbst enthält, sondern auf den Speicher eines verknüpften BufferObjects zugreift. Bei einem solchen BufferObject kann es sich beispielsweise um ein VertexBufferObject (VBO) handeln. Es steht somit die Flexibilität von Bufferobjekten auch für Texturen zur Verfügung (fast) ohne zusätzliche Schnittstellen.
Im Zusammenhang mit Transform-Feedback aber auch mit Instancing und bei anderen Gelegenheiten erweisen sich TextureBufferObjects als sehr nützlich. Mit Transform-Feedback kann in einen Vertexbuffer geschrieben werden, welcher dann im nächsten Renderpass ohne zusätzliche Kopiervorgänge als Textur benutzt werden kann. Dies wird unter anderem beim Shader Model 4.0 Partikelsystem exzessiv benutzt. Ein Beispiel zu Instancing findet sich in der Shadersammlung.
Im Shader können TextureBufferObjects ausschließlich mit Integer-Koordinaten adressiert werden. Daher findet auch keine Interpolation zwischen Texeln statt. Wer eine Interpolation benötigt kann diese aber einfach selbst im Shader implementieren.
Für TextureBufferObjects muss keine Größe angegeben werden. Die Größe der Textur berechnet sich aus der Gesamtgröße des zugehörigen Bufferobjektes geteilt durch die Größe eines Texels. Die maximale Größe eines TextureBufferObjects beträgt dabei 2^27 = 134.217.728 Texel im Gegensatz zu normalen eindimensionalen Texturen, welche eine maximale Größe von 2^13 = 8.192 Texeln haben. In Kombination mit einem 4x32bit Texelformat (z.B. RGBA32F) bedeutet dies, dass ein TBO theoretisch bis zu 2 GB groß werden darf. Praktisch ist die Größe natürlich durch den Speicher der Grafikkarte begrenzt.
Inhaltsverzeichnis
Verwendung
Verwendung im Programm
Um unser TextureBufferObject zu Erstellen benutzen wir wie bei gewöhnlichen Texturen die Funktion glGenTextures:
GLuint myTBO;
glGenTextures(1, &myTBO);
Das Löschen geschieht genauso gewohnt mit glDeleteTextures:
glDeleteTextures(1, &myTBO);
Um das TextureBufferObject zu verwenden muss es wie eine normale Textur mit glBindTexture gebunden werden. Wir übergeben dabei allerdings die Konstante GL_TEXTURE_BUFFER_ARB als ersten Parameter:
glBindTexture(GL_TEXTURE_BUFFER_ARB, myTBO);
Anschließend geben wir mit glTexBufferARB(enum target, enum internalformat, uint buffer) an, welches BufferObject mit dem TextureBufferObject verknüpft werden soll. Bei diesem BufferObject kann es sich zum Beispiel um ein VertexBufferObject handeln.
glTexBufferARB(GL_TEXTURE_BUFFER_ARB, GL_RGBA32F_ARB, myVBO);
Der zweite Parameter gibt hierbei den Datentyp unserer Textur an. Als Beispiel wurde hier GL_RGBA32F_ARB gewählt. Damit wird unsere Textur als vierelementiger 32-bit-float-Vektor benutzt (4*4 = 16 Byte pro Texel). Die Tabelle im Abschnitt Texelformate gibt eine Übersicht über die möglichen Formate, welche als zweiter Parameter angegeben werden können.
Verwendung im Shader
Unser TextureBufferObject ist nun erstellt und gebunden. Nun ist es an der Zeit, es im Shader auszulesen. Dafür brauchen wir neue Textursampler-Typen: samplerBuffer, usamplerBuffer oder isamplerBuffer, je nachdem, was unser TextureBufferObject für einen Datentyp repräsentiert: float, unsigned int oder int. Über diesen Sampler greifen wir mit der Funktion texelFetchBuffer(samplerBuffer sampler, uint index) auf unser TextureBufferObject zu:
#extension GL_EXT_gpu_shader4 : require
// ...
uniform samplerBuffer tbo; // Unser Sampler, wir benutzen floats => samplerBuffer
void main()
{
// Wir brauchen einen Array-Index um einen Texel zum Auslesen zu bestimmen.
unsigned int index;
// Wir berechnen unseren Index.
// ...
// Wir holen einen Texel aus unserem TextureBufferObject.
vec4 tmp = texelFetchBuffer(tbo, index);
// Wir machen etwas mit tmp
// ...
}
Texelformate
Die folgende Tabelle aus der Extension-Spezifikation gibt eine Übersicht über die möglichen Texelformate.
Sized Internal Format | Base Type | Components | Norm | Component | |||
---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | ||||
GL_ALPHA8 | ubyte | 1 | Y | A | . | . | . |
GL_ALPHA16 | ushort | 1 | Y | A | . | . | . |
GL_ALPHA16F_ARB | half | 1 | N | A | . | . | . |
GL_ALPHA32F_ARB | float | 1 | N | A | . | . | . |
GL_ALPHA8I_EXT | byte | 1 | N | A | . | . | . |
GL_ALPHA16I_EXT | short | 1 | N | A | . | . | . |
GL_ALPHA32I_EXT | int | 1 | N | A | . | . | . |
GL_ALPHA8UI_EXT | ubyte | 1 | N | A | . | . | . |
GL_ALPHA16UI_EXT | ushort | 1 | N | A | . | . | . |
GL_ALPHA32UI_EXT | uint | 1 | N | A | . | . | . |
GL_LUMINANCE8 | ubyte | 1 | Y | L | . | . | . |
GL_LUMINANCE16 | ushort | 1 | Y | L | . | . | . |
GL_LUMINANCE16F_ARB | half | 1 | N | L | . | . | . |
GL_LUMINANCE32F_ARB | float | 1 | N | L | . | . | . |
GL_LUMINANCE8I_EXT | byte | 1 | N | L | . | . | . |
GL_LUMINANCE16I_EXT | short | 1 | N | L | . | . | . |
GL_LUMINANCE32I_EXT | int | 1 | N | L | . | . | . |
GL_LUMINANCE8UI_EXT | ubyte | 1 | N | L | . | . | . |
GL_LUMINANCE16UI_EXT | ushort | 1 | N | L | . | . | . |
GL_LUMINANCE32UI_EXT | uint | 1 | N | L | . | . | . |
GL_LUMINANCE8_ALPHA8 | ubyte | 2 | Y | L | A | . | . |
GL_LUMINANCE16_ALPHA16 | ushort | 2 | Y | L | A | . | . |
GL_LUMINANCE_ALPHA16F_ARB | half | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA32F_ARB | float | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA8I_EXT | byte | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA16I_EXT | short | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA32I_EXT | int | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA8UI_EXT | ubyte | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA16UI_EXT | ushort | 2 | N | L | A | . | . |
GL_LUMINANCE_ALPHA32UI_EXT | uint | 2 | N | L | A | . | . |
GL_INTENSITY8 | ubyte | 1 | Y | I | . | . | . |
GL_INTENSITY16 | ushort | 1 | Y | I | . | . | . |
GL_INTENSITY16F_ARB | half | 1 | N | I | . | . | . |
GL_INTENSITY32F_ARB | float | 1 | N | I | . | . | . |
GL_INTENSITY8I_EXT | byte | 1 | N | I | . | . | . |
GL_INTENSITY16I_EXT | short | 1 | N | A | . | . | . |
GL_INTENSITY32I_EXT | int | 1 | N | A | . | . | . |
GL_INTENSITY8UI_EXT | ubyte | 1 | N | A | . | . | . |
GL_INTENSITY16UI_EXT | ushort | 1 | N | A | . | . | . |
GL_INTENSITY32UI_EXT | uint | 1 | N | A | . | . | . |
GL_RGBA8 | ubyte | 4 | Y | R | G | B | A |
GL_RGBA16 | ushort | 4 | Y | R | G | B | A |
GL_RGBA16F_ARB | half | 4 | N | R | G | B | A |
GL_RGBA32F_ARB | float | 4 | N | R | G | B | A |
GL_RGBA8I_EXT | byte | 4 | N | R | G | B | A |
GL_RGBA16I_EXT | short | 4 | N | R | G | B | A |
GL_RGBA32I_EXT | int | 4 | N | R | G | B | A |
GL_RGBA8UI_EXT | ubyte | 4 | N | R | G | B | A |
GL_RGBA16UI_EXT | ushort | 4 | N | R | G | B | A |
GL_RGBA32UI_EXT | uint | 4 | N | R | G | B | A |
Literatur
- ARB_texture_buffer_object (Englisch)