Repository navigation
Expand file tree
/
Copy paths3tc.txt
More file actions
336 lines (273 loc) · 12.5 KB
/
Copy paths3tc.txt
File metadata and controls
336 lines (273 loc) · 12.5 KB
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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
// Copyright (C) 2008-2025 The Khronos Group Inc. All Rights Reserved.
// Copyright notice at https://www.khronos.org/registry/speccopyright.html
[[S3TC]]
== S3TC Compressed Texture Image Formats
_This description is derived from the
link:https://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt[EXT_texture_compression_s3tc] extension._
// Contact S3 Incorporated (http://www.s3.com) regarding any intellectual
// property issues associated with implementing this extension.
// Note: www.s3.com is no longer valid (nor is s3graphics.com. The company
// is currently owned by HTC.
Compressed texture images stored using the S3TC compressed image formats
are represented as a collection of 4{times}4 texel blocks, where each block
contains 64 or 128 bits of texel data. The image is encoded as a normal
2D raster image in which each 4{times}4 block is treated as a single pixel.
If an S3TC image has a width or height that is not a multiple of four, the
data corresponding to texels outside the image are irrelevant and
undefined.
When an S3TC image with a width of _w_, height of _h_, and block size of
_blocksize_ (8 or 16 bytes) is decoded, the corresponding image size (in
bytes) is:
[latexmath]
++++++++++++++++
\begin{align*}
\left\lceil { w \over 4 } \right\rceil \times
\left\lceil { h \over 4 } \right\rceil \times
blocksize
\end{align*}
++++++++++++++++
When decoding an S3TC image, the block containing the texel at offset
(_x_, _y_) begins at an offset (in bytes) relative to the base of the
image of:
[latexmath]
++++++++++++++
\begin{align*}
blocksize \times
\left( { \left\lceil { w \over 4 } \right\rceil \times
\left\lfloor { y \over 4 } \right\rfloor +
\left\lfloor { x \over 4 } \right\rfloor } \right)
\end{align*}
++++++++++++++
The data corresponding to a specific texel (_x_, _y_) are extracted from a
4{times}4 texel block using a relative (_x_, _y_) value of
[latexmath]
++++++++++++++
\begin{align*}
(x \bmod 4,y \bmod 4)
\end{align*}
++++++++++++++
[NOTE]
====
There is an analysis of the precise conversions performed by a
range of real-world GPU hardware in
link:https://fgiesen.wordpress.com/2021/10/04/gpu-bcn-decoding/[Fabian ``ryg'' Giesen's blog].
====
There are four distinct S3TC image formats:
[[s3tc_bc1_noalpha]]
=== BC1 with no alpha
Each 4{times}4 block of texels consists of 64
bits of _RGB_ image data.
Each _RGB_ image data block is encoded as a sequence of 8 bytes, called (in
order of increasing address):
[latexmath]
++++++
\begin{align*}
c0_{\mathit{lo}}, c0_{\mathit{hi}}, c1_{\mathit{lo}}, c1_{\mathit{hi}}, \mathit{bits}_0, \mathit{bits}_1, \mathit{bits}_2, \mathit{bits}_3
\end{align*}
++++++
The 8 bytes of the block are decoded into three quantities:
[latexmath]
++++++
\begin{align*}
\mathit{color}_0 & = c0_{\mathit{lo}} + c0_{\mathit{hi}} \times 256 \\
\mathit{color}_1 & = c1_{\mathit{lo}} + c1_{\mathit{hi}} \times 256 \\
\mathit{bits} & = \mathit{bits}_0 + 256 \times (\mathit{bits}_1 + 256 \times (\mathit{bits}_2 + 256 \times \mathit{bits}_3))
\end{align*}
++++++
_color_~0~ and _color_~1~ are 16-bit unsigned integers that
are unpacked to _RGB_ colors _RGB_~0~ and _RGB_~1~ as though they were 16-bit
unsigned packed pixels with the _R_ channel in the high 5 bits, _G_ in the
next 6 bits and _B_ in the low 5 bits:
[latexmath]
++++++
\begin{align*}
\mathit{R}_n & = {{\mathit{color}_n^{15..11}}\over 31} \\
\mathit{G}_n & = {{\mathit{color}_n^{10..5}}\over 63} \\
\mathit{B}_n & = {{\mathit{color}_n^{4..0}}\over 31}
\end{align*}
++++++
_bits_ is a 32-bit unsigned integer, from which a two-bit control code
is extracted for a texel at position (_x_, _y_) in the block using:
[latexmath]
++++++
\begin{align*}
\mathit{code}(x,y) & = \mathit{bits}[2\times (4\times y+x)+1\ \dots\ 2\times(4\times y+x)+0]
\end{align*}
++++++
where _bits_[31] is the most significant and _bits_[0] is the least
significant bit.
The _RGB_ color for a texel at position (_x_, _y_) in the block is given
in <<BC1blocks>>.
[[BC1blocks]]
.Block decoding for BC1
[options="header",cols="1,2",width="60%"]
|==========
^| Texel value ^| Condition
^.^| _RGB_~0~ ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 0
^.^| _RGB_~1~ ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 1
^| latexmath:[$(2\times \mathit{RGB}_0 + \mathit{RGB}_1)\over 3$] ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 2
^| latexmath:[$(\mathit{RGB}_0 + 2\times RGB_1)\over 3$] ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 3
^.^| _RGB_~0~ ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 0
^.^| _RGB_~1~ ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 1
^| latexmath:[$(\mathit{RGB}_0+\mathit{RGB}_1)\over 2$] ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 2
^.^| BLACK ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 3
|==========
Arithmetic operations are done per component, and BLACK refers to an
_RGB_ color where red, green, and blue are all zero.
Since this image has an _RGB_ format, there is no alpha component and the
image is considered fully opaque.
[[s3tc_bc1_alpha]]
=== BC1 with alpha
Each 4{times}4 block of texels consists of 64
bits of _RGB_ image data and minimal alpha information.
The _RGB_ components of a texel are extracted in the same way as BC1
with no alpha.
The alpha component for a texel at position (_x_, _y_) in the block is
given by <<BC1alpha>>.
[[BC1alpha]]
.BC1 with alpha
[options="header",cols="1,2",width="60%"]
|==========
^| Alpha value ^| Condition
^| 0.0 ^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 3
^| 1.0 ^| otherwise
|==========
// This is a discussion of the behavior of the encoder, not of the
// format itself.
//
// IMPORTANT: When encoding an RGBA image into a format using 1-bit
// alpha, any texels with an alpha component less than 0.5 end up with an
// alpha of 0.0 and any texels with an alpha component greater than or
// equal to 0.5 end up with an alpha of 1.0. When encoding an RGBA image
// into the COMPRESSED_RGBA_S3TC_DXT1_EXT format, the resulting red,
// green, and blue components of any texels with a final alpha of 0.0
// will automatically be zero (black). If this behavior is not desired
// by an application, it should not use COMPRESSED_RGBA_S3TC_DXT1_EXT.
// This format will never be used when a generic compressed internal
// format (Table 3.16.2) is specified, although the nearly identical
// format COMPRESSED_RGB_S3TC_DXT1_EXT (above) may be.
The red, green, and blue components of any texels with a final alpha
of 0 should be encoded as zero (black).
[NOTE]
====
<<Figure-bc1>> shows an example BC1 texel block:
_color_~0~, encoded as latexmath:[$\left({{29}\over{31}}, {{60}\over{63}}, {{1}\over{31}}\right)$],
and _color_~1~, encoded as latexmath:[$\left({{20}\over{31}}, {{2}\over{63}}, {{30}\over{31}}\right)$],
are shown as circles. The interpolated values are shown as small diamonds.
Since 29 > 20, there are two interpolated values, accessed when
_code_(_x_, _y_) = 2 and _code_(_x_, _y_) = 3.
[[Figure-bc1]]
.BC1 two interpolated colors
image::images/bc1.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"]
<<Figure-bc1a>> shows the example BC1 texel block with the colors swapped:
_color_~0~, encoded as latexmath:[$\left({{20}\over{31}}, {{2}\over{63}}, {{30}\over{31}}\right)$],
and _color_~1~, encoded as latexmath:[$\left({{29}\over{31}}, {{60}\over{63}}, {{1}\over{31}}\right)$],
are shown as circles. The interpolated value is shown as a small diamonds.
Since 20 {leq} 29, there is one interpolated value for
_code_(_x_, _y_) = 2, and _code_(_x_, _y_) = 3 represents
(_R_,_ G_,_ B_) = (0, 0, 0).
[[Figure-bc1a]]
.BC1 one interpolated color {plus} black
image::images/bc1a.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"]
If the format is BC1 with alpha, _code_(_x_, _y_) = 3 is transparent
(alpha = 0).
If the format is BC1 with no alpha, _code_(_x_, _y_) = 3 represents
opaque black.
====
<<<
[[s3tc_bc2]]
=== BC2
Each 4{times}4 block of texels consists of 64 bits of uncompressed alpha
image data followed by 64 bits of _RGB_ image data.
Each _RGB_ image data block is encoded according to the
BC1 formats, with the exception that the two code
bits always use the non-transparent encodings.
In other words, they are treated as though _color_~0~ > _color_~1~,
regardless of the actual values of _color_~0~ and _color_~1~.
Each alpha image data block is encoded as a sequence of 8 bytes, called
(in order of increasing address):
[latexmath]
++++++
\begin{align*}
a_0, a_1, a_2, a_3, a_4, a_5, a_6, a_7
\end{align*}
++++++
The 8 bytes of the block are decoded into one 64-bit integer:
[latexmath]
++++++
\begin{align*}
\mathit{alpha} & = a_0 + 256 \times (a_1 + 256 \times (a_2 + 256 \times (a_3 +
256 \times (a_4 + 256 \times (a_5 + 256 \times (a_6 + 256 \times a_7))))))
\end{align*}
++++++
_alpha_ is a 64-bit unsigned integer, from which a four-bit alpha value
is extracted for a texel at position (_x_, _y_) in the block using:
[latexmath]
++++++
\begin{align*}
\mathit{alpha}(x,y) & = \mathit{bits}[4\times(4\times y+x)+3 \dots 4\times(4\times y+x)+0]
\end{align*}
++++++
where _bits_[63] is the most significant and _bits_[0] is the least
significant bit.
The alpha component for a texel at position (_x_, _y_) in the block is
given by latexmath:[$\mathit{alpha}(x,y)\over 15$].
[[s3tc_bc3]]
=== BC3
Each 4{times}4 block of texels consists of 64 bits of compressed
alpha image data followed by 64 bits of _RGB_ image data.
Each _RGB_ image data block is encoded according to the
BC1 formats, with the exception that the two code
bits always use the non-transparent encodings. In other words, they are
treated as though _color_~0~ > _color_~1~, regardless of the actual values of
_color_~0~ and _color_~1~.
Each alpha image data block is encoded as a sequence of 8 bytes, called
(in order of increasing address):
[latexmath]
++++++
\begin{align*}
\mathit{alpha}_0, \mathit{alpha}_1, \mathit{bits}_0, \mathit{bits}_1, \mathit{bits}_2, \mathit{bits}_3, \mathit{bits}_4, \mathit{bits}_5
\end{align*}
++++++
The _alpha_~0~ and _alpha_~1~ are 8-bit unsigned bytes converted to alpha
components by multiplying by latexmath:[$1\over 255$].
The 6 _bits_ bytes of the block are decoded into one 48-bit integer:
[latexmath]
++++++
\begin{align*}
\mathit{bits} & = \mathit{bits}_0 + 256 \times (\mathit{bits}_1 + 256 \times (\mathit{bits}_2 +
256 \times (\mathit{bits}_3 + 256 \times (\mathit{bits}_4 + 256 \times \mathit{bits}_5))))
\end{align*}
++++++
_bits_ is a 48-bit unsigned integer, from which a three-bit control code
is extracted for a texel at position (_x_, _y_) in the block using:
[latexmath]
++++++
\begin{align*}
\mathit{code}(x,y) & = \mathit{bits}[3\times(4\times y+x)+2 \dots 3\times(4\times y+x)+0]
\end{align*}
++++++
where _bits_[47] is the most-significant and _bits_[0] is the least-significant bit.
<<<
The alpha component for a texel at position (_x_, _y_) in the block is
given by <<BC3alpha>>.
[[BC3alpha]]
.Alpha encoding for BC3 blocks
[options="header",cols="2,3",width="70%"]
|=================
^| Alpha value ^| Condition
^.^| _alpha_~0~ ^.^| _code_(_x_, _y_) = 0
^.^| _alpha_~1~ ^.^| _code_(_x_, _y_) = 1
^| latexmath:[$(6\times\mathit{alpha}_0 + 1\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 2
^| latexmath:[$(5\times\mathit{alpha}_0 + 2\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 3
^| latexmath:[$(4\times\mathit{alpha}_0 + 3\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 4
^| latexmath:[$(3\times\mathit{alpha}_0 + 4\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 5
^| latexmath:[$(2\times\mathit{alpha}_0 + 5\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 6
^| latexmath:[$(1\times\mathit{alpha}_0 + 6\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 7
^| latexmath:[$(4\times\mathit{alpha}_0 + 1\times\mathit{alpha}_1)\over 5$] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 2
^| latexmath:[$(3\times\mathit{alpha}_0 + 2\times\mathit{alpha}_1)\over 5$] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 3
^| latexmath:[$(2\times\mathit{alpha}_0 + 3\times\mathit{alpha}_1)\over 5$] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 4
^| latexmath:[$(1\times\mathit{alpha}_0 + 4\times\mathit{alpha}_1)\over 5$] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 5
^.^| 0.0 ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 6
^.^| 1.0 ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 7
|=================