File: texture_formats.rst

package info (click to toggle)
python-moderngl 5.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,700 kB
  • sloc: python: 15,758; cpp: 14,665; makefile: 14
file content (296 lines) | stat: -rw-r--r-- 14,425 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
.. _texture-format-label:

Texture Format
==============

.. py:currentmodule:: moderngl

Description
-----------

The format of a texture can be described by the ``dtype`` parameter
during texture creation. For example the :py:meth:`moderngl.Context.texture`.
The default ``dtype`` is ``f1``. Each component is an unsigned byte (0-255)
that is normalized when read in a shader into a value from 0.0 to 1.0.

The formats are based on the string formats used in numpy.

Some quick example of texture creation::

    # RGBA (4 component) f1 texture
    texture = ctx.texture((100, 100), 4)  # dtype f1 is default

    # R (1 component) f4 texture (32 bit float)
    texture = ctx.texture((100, 100), 1, dype="f4")

    # RG (2 component) u2 texture (16 bit unsigned integer)
    texture = ctx.texture((100, 100), 2, dtype="u2")


Texture contents can be passed in using the ``data`` parameter during
creation or by using the ``write()`` method. The object passed in
``data`` can be bytes or any object supporting the buffer protocol.

When writing data to texture the data type can be derived from
the internal format in the tables below. ``f1`` textures takes
unsigned bytes (``u1`` or ``numpy.uint8`` in numpy) while
``f2`` textures takes 16 bit floats (``f2`` or ``numpy.float16`` in numpy).


Float Textures
--------------

``f1`` textures are just unsigned bytes (8 bits per component) (``GL_UNSIGNED_BYTE``)

The ``f1`` texture is the most commonly used textures in OpenGL
and is currently the default. Each component takes 1 byte (4 bytes for RGBA).
This is not really a "real" float format, but a shader will read
normalized values from these textures. ``0-255`` (byte range) is read
as a value from ``0.0`` to ``1.0`` in shaders.

In shaders the sampler type should be ``sampler2D``, ``sampler2DArray``
``sampler3D``, ``samplerCube`` etc.

+----------+---------------+---------------+-------------------+
| **dtype**|  *Components* | *Base Format* | *Internal Format* |
+==========+===============+===============+===================+
| f1       |  1            | GL_RED        | GL_R8             |
+----------+---------------+---------------+-------------------+
| f1       |  2            | GL_RG         | GL_RG8            |
+----------+---------------+---------------+-------------------+
| f1       |  3            | GL_RGB        | GL_RGB8           |
+----------+---------------+---------------+-------------------+
| f1       |  4            | GL_RGBA       | GL_RGBA8          |
+----------+---------------+---------------+-------------------+

``f2`` textures stores 16 bit float values (``GL_HALF_FLOAT``).

+----------+---------------+---------------+-------------------+
| **dtype**|  *Components* | *Base Format* | *Internal Format* |
+==========+===============+===============+===================+
| f2       |  1            | GL_RED        | GL_R16F           |
+----------+---------------+---------------+-------------------+
| f2       |  2            | GL_RG         | GL_RG16F          |
+----------+---------------+---------------+-------------------+
| f2       |  3            | GL_RGB        | GL_RGB16F         |
+----------+---------------+---------------+-------------------+
| f2       |  4            | GL_RGBA       | GL_RGBA16F        |
+----------+---------------+---------------+-------------------+

``f4`` textures store 32 bit float values. (``GL_FLOAT``)
Note that some drivers do not like 3 components because of alignment.

+----------+---------------+---------------+-------------------+
| **dtype**|  *Components* | *Base Format* | *Internal Format* |
+==========+===============+===============+===================+
| f4       |  1            | GL_RED        | GL_R32F           |
+----------+---------------+---------------+-------------------+
| f4       |  2            | GL_RG         | GL_RG32F          |
+----------+---------------+---------------+-------------------+
| f4       |  3            | GL_RGB        | GL_RGB32F         |
+----------+---------------+---------------+-------------------+
| f4       |  4            | GL_RGBA       | GL_RGBA32F        |
+----------+---------------+---------------+-------------------+

Integer Textures
----------------

Integer textures come in a signed and unsigned version. The advantage
with integer textures is that shader can read the raw integer values
from them using for example ``usampler*`` (unsigned) or ``isampler*``
(signed).

Integer textures do not support ``LINEAR`` filtering (only ``NEAREST``).

Unsigned
~~~~~~~~

``u1`` textures store unsigned byte values (``GL_UNSIGNED_BYTE``).

In shaders the sampler type should be ``usampler2D``, ``usampler2DArray``
``usampler3D``, ``usamplerCube`` etc.

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| u1       |  1            | GL_RED_INTEGER  | GL_R8UI           |
+----------+---------------+-----------------+-------------------+
| u1       |  2            | GL_RG_INTEGER   | GL_RG8UI          |
+----------+---------------+-----------------+-------------------+
| u1       |  3            | GL_RGB_INTEGER  | GL_RGB8UI         |
+----------+---------------+-----------------+-------------------+
| u1       |  4            | GL_RGBA_INTEGER | GL_RGBA8UI        |
+----------+---------------+-----------------+-------------------+

``u2`` textures store 16 bit unsigned integers (``GL_UNSIGNED_SHORT``).

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| u2       |  1            | GL_RED_INTEGER  | GL_R16UI          |
+----------+---------------+-----------------+-------------------+
| u2       |  2            | GL_RG_INTEGER   | GL_RG16UI         |
+----------+---------------+-----------------+-------------------+
| u2       |  3            | GL_RGB_INTEGER  | GL_RGB16UI        |
+----------+---------------+-----------------+-------------------+
| u2       |  4            | GL_RGBA_INTEGER | GL_RGBA16UI       |
+----------+---------------+-----------------+-------------------+

``u4`` textures store 32 bit unsigned integers (``GL_UNSIGNED_INT``)

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| u4       |  1            | GL_RED_INTEGER  | GL_R32UI          |
+----------+---------------+-----------------+-------------------+
| u4       |  2            | GL_RG_INTEGER   | GL_RG32UI         |
+----------+---------------+-----------------+-------------------+
| u4       |  3            | GL_RGB_INTEGER  | GL_RGB32UI        |
+----------+---------------+-----------------+-------------------+
| u4       |  4            | GL_RGBA_INTEGER | GL_RGBA32UI       |
+----------+---------------+-----------------+-------------------+

Signed
~~~~~~

``i1`` textures store signed byte values (``GL_BYTE``).

In shaders the sampler type should be ``isampler2D``, ``isampler2DArray``
``isampler3D``, ``isamplerCube`` etc.

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| i1       |  1            | GL_RED_INTEGER  | GL_R8I            |
+----------+---------------+-----------------+-------------------+
| i1       |  2            | GL_RG_INTEGER   | GL_RG8I           |
+----------+---------------+-----------------+-------------------+
| i1       |  3            | GL_RGB_INTEGER  | GL_RGB8I          |
+----------+---------------+-----------------+-------------------+
| i1       |  4            | GL_RGBA_INTEGER | GL_RGBA8I         |
+----------+---------------+-----------------+-------------------+

``i2`` textures store 16 bit integers (``GL_SHORT``).

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| i2       |  1            | GL_RED_INTEGER  | GL_R16I           |
+----------+---------------+-----------------+-------------------+
| i2       |  2            | GL_RG_INTEGER   | GL_RG16I          |
+----------+---------------+-----------------+-------------------+
| i2       |  3            | GL_RGB_INTEGER  | GL_RGB16I         |
+----------+---------------+-----------------+-------------------+
| i2       |  4            | GL_RGBA_INTEGER | GL_RGBA16I        |
+----------+---------------+-----------------+-------------------+

``i4`` textures store 32 bit integers (``GL_INT``)

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| i4       |  1            | GL_RED_INTEGER  | GL_R32I           |
+----------+---------------+-----------------+-------------------+
| i4       |  2            | GL_RG_INTEGER   | GL_RG32I          |
+----------+---------------+-----------------+-------------------+
| i4       |  3            | GL_RGB_INTEGER  | GL_RGB32I         |
+----------+---------------+-----------------+-------------------+
| i4       |  4            | GL_RGBA_INTEGER | GL_RGBA32I        |
+----------+---------------+-----------------+-------------------+

Normalized Integer Textures
---------------------------

Normalized integers are integer texture, but texel reads in a shader
returns normalized values (``[0.0, 1.0]``). For example an unsigned 16
bit fragment with the value ``2**16-1`` will be read as ``1.0``.

Normalized integer textures should use the `sampler2D` sampler
type. Also note that there's no standard for normalized 32 bit
integer textures because a float32 doesn't have enough precision
to express a 32 bit integer as a number between 0.0 and 1.0.

Unsigned
~~~~~~~~

``nu1`` textures is really the same as an ``f1``. Each component
is a ``GL_UNSIGNED_BYTE``, but are read by the shader in normalized
form ``[0.0, 1.0]``.

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| nu1      |  1            | GL_RED          | GL_R8             |
+----------+---------------+-----------------+-------------------+
| nu1      |  2            | GL_RG           | GL_RG8            |
+----------+---------------+-----------------+-------------------+
| nu1      |  3            | GL_RGB          | GL_RGB8           |
+----------+---------------+-----------------+-------------------+
| nu1      |  4            | GL_RGBA         | GL_RGBA8          |
+----------+---------------+-----------------+-------------------+

``nu2`` textures store 16 bit unsigned integers (``GL_UNSIGNED_SHORT``).
The value range ``[0, 2**16-1]`` will be normalized into ``[0.0, 1.0]``.

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| nu2      |  1            | GL_RED          | GL_R16            |
+----------+---------------+-----------------+-------------------+
| nu2      |  2            | GL_RG           | GL_RG16           |
+----------+---------------+-----------------+-------------------+
| nu2      |  3            | GL_RGB          | GL_RGB16          |
+----------+---------------+-----------------+-------------------+
| nu2      |  4            | GL_RGBA         | GL_RGBA16         |
+----------+---------------+-----------------+-------------------+

Signed
~~~~~~

``ni1`` textures store 8 bit signed integers (``GL_BYTE``).
The value range ``[0, 127]`` will be normalized into ``[0.0, 1.0]``.
Negative values will be clamped.

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| ni1      |  1            | GL_RED          | GL_R8             |
+----------+---------------+-----------------+-------------------+
| ni1      |  2            | GL_RG           | GL_RG8            |
+----------+---------------+-----------------+-------------------+
| ni1      |  3            | GL_RGB          | GL_RGB8           |
+----------+---------------+-----------------+-------------------+
| ni1      |  4            | GL_RGBA         | GL_RGBA8          |
+----------+---------------+-----------------+-------------------+

``ni2`` textures store 16 bit signed integers (``GL_SHORT``).
The value range ``[0, 2**15-1]`` will be normalized into ``[0.0, 1.0]``.
Negative values will be clamped.

+----------+---------------+-----------------+-------------------+
| **dtype**|  *Components* | *Base Format*   | *Internal Format* |
+==========+===============+=================+===================+
| ni2      |  1            | GL_RED          | GL_R16            |
+----------+---------------+-----------------+-------------------+
| ni2      |  2            | GL_RG           | GL_RG16           |
+----------+---------------+-----------------+-------------------+
| ni2      |  3            | GL_RGB          | GL_RGB16          |
+----------+---------------+-----------------+-------------------+
| ni2      |  4            | GL_RGBA         | GL_RGBA16         |
+----------+---------------+-----------------+-------------------+

Overriding internalformat
-------------------------

:py:meth:`Context.texture` supports overriding the internalformat
of the texture. This is only necessary when needing a different
internal formats from the tables above. This can for
example be ``GL_SRGB8 = 0x8C41`` or some compressed format.
You may also need to look up in :py:attr:`Context.extensions`
to ensure the context supports internalformat you are using.
We do not provide the enum values for these alternative internalformats.
They can be looked up in the registry : https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/gl.xml

Example::

    texture = ctx.texture(image.size, 3, data=srbg_data, internal_format=GL_SRGB8)