Skip to content

Commit 54e60db

Browse files
Add BC3 compressed texture support
Signed-off-by: Aleksander Kamiński <[email protected]>
1 parent 3f7fa26 commit 54e60db

File tree

4 files changed

+139
-5
lines changed

4 files changed

+139
-5
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/* Copyright 2024, Robotec.ai sp. z o.o.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
#include <Utilities/BlockCompression.h>
16+
17+
namespace RGL::Utils
18+
{
19+
AZStd::pair<size_t, size_t> BC3Block::GetBlockIndices(uint32_t width, uint32_t x, uint32_t y)
20+
{
21+
return AZ::RPI::BC1Block::GetBlockIndices(width, x, y);
22+
}
23+
24+
AZ::Color BC3Block::GetBlockColor(size_t pixelIndex) const
25+
{
26+
AZ::Color color = m_bc1.GetBlockColor(pixelIndex);
27+
color.SetA8(GetAlpha(pixelIndex));
28+
return color;
29+
}
30+
31+
static AZ::u8 LerpU8(AZ::u8 val0, AZ::u8 val1, AZ::u8 i, AZ::u8 n)
32+
{
33+
return (val0 * i + val1 * (n - i)) / n;
34+
}
35+
36+
AZ::u8 BC3Block::GetAlpha(size_t pixelIndex) const
37+
{
38+
AZ_Assert(pixelIndex < 16, "Unsupported pixel index for BC3: %zu", pixelIndex);
39+
static constexpr AZ::u8 IndexBitShift = 16U;
40+
static constexpr AZ::u8 IndexBitCount = 3U;
41+
42+
const AZ::u8 valueBitShift = pixelIndex * IndexBitCount + IndexBitShift;
43+
const AZ::u8 index = (m_alphaData >> valueBitShift) & 0b111;
44+
if (m_referenceAlpha[0] > m_referenceAlpha[1])
45+
{
46+
switch (index)
47+
{
48+
case 0:
49+
case 1:
50+
return m_referenceAlpha[index];
51+
case 2:
52+
case 3:
53+
case 4:
54+
case 5:
55+
case 6:
56+
case 7:
57+
return LerpU8(m_referenceAlpha[1], m_referenceAlpha[0], index - 1U, 7U);
58+
}
59+
}
60+
else
61+
{
62+
switch (index)
63+
{
64+
case 0:
65+
case 1:
66+
return m_referenceAlpha[index];
67+
case 2:
68+
case 3:
69+
case 4:
70+
case 5:
71+
return LerpU8(m_referenceAlpha[1], m_referenceAlpha[0], index - 1U, 5U);
72+
case 6:
73+
return 0U;
74+
case 7:
75+
return 255U;
76+
}
77+
}
78+
79+
return 0U;
80+
}
81+
} // namespace RGL::Utils
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* Copyright 2024, Robotec.ai sp. z o.o.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#pragma once
17+
#include <AzCore/Math/Color.h>
18+
#include <Atom/RPI.Public/BlockCompression.h>
19+
#include <AzCore/base.h>
20+
21+
namespace RGL::Utils
22+
{
23+
struct BC3Block
24+
{
25+
static AZStd::pair<size_t, size_t> GetBlockIndices(uint32_t width, uint32_t x, uint32_t y);
26+
27+
[[nodiscard]] AZ::Color GetBlockColor(size_t pixelIndex) const;
28+
[[nodiscard]] AZ::u8 GetAlpha(size_t pixelIndex) const;
29+
30+
union
31+
{
32+
AZ::u64 m_alphaData;
33+
struct
34+
{
35+
AZ::u8 m_referenceAlpha[2];
36+
AZ::u8 m_alphaIndices[6];
37+
};
38+
};
39+
AZ::RPI::BC1Block m_bc1;
40+
};
41+
} // namespace RGL::Utils

Code/Source/Wrappers/RglTexture.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515
#include <Atom/RPI.Public/BlockCompression.h>
1616
#include <AzCore/Name/NameDictionary.h>
17+
#include <Utilities/BlockCompression.h>
1718
#include <Utilities/RGLUtils.h>
1819
#include <Wrappers/RglTexture.h>
1920

@@ -86,7 +87,7 @@ namespace RGL::Wrappers
8687

8788
float RglTexture::CreateGrayFromColor(const AZ::Color& color)
8889
{
89-
return RedGrayMultiplier * color.GetR() + GreenGrayMultiplier * color.GetG() + BlueGrayMultiplier * color.GetB();
90+
return (RedGrayMultiplier * color.GetR() + GreenGrayMultiplier * color.GetG() + BlueGrayMultiplier * color.GetB()) * color.GetA();
9091
}
9192

9293
uint8_t RglTexture::CreateGray8FromColor(const AZ::Color& color)
@@ -119,7 +120,10 @@ namespace RGL::Wrappers
119120
using Format = AZ::RHI::Format;
120121
const auto format = imageDescriptor.m_format;
121122
const auto& size = imageDescriptor.m_size;
122-
if (format == Format::BC1_UNORM || format == Format::BC1_UNORM_SRGB || format == Format::BC4_UNORM)
123+
static AZStd::set<AZ::RHI::Format> SupportedFormats{
124+
Format::BC1_UNORM, Format::BC1_UNORM_SRGB, Format::BC3_UNORM, Format::BC3_UNORM_SRGB, Format::BC4_UNORM,
125+
};
126+
if (SupportedFormats.contains(format))
123127
{
124128
tempRglTextureData.resize(size.m_width * size.m_height);
125129

@@ -135,13 +139,18 @@ namespace RGL::Wrappers
135139
LoadBlockToGrays(
136140
reinterpret_cast<const AZ::RPI::BC4Block*>(imageData.data() + srcIdx), tempRglTextureData, x, y, size.m_width);
137141
}
138-
else
142+
else if (format == Format::BC1_UNORM || format == Format::BC1_UNORM_SRGB)
139143
{
140144
LoadBlockToGrays(
141145
reinterpret_cast<const AZ::RPI::BC1Block*>(imageData.data() + srcIdx), tempRglTextureData, x, y, size.m_width);
142146
}
147+
else if (format == Format::BC3_UNORM || format == Format::BC3_UNORM_SRGB)
148+
{
149+
LoadBlockToGrays(
150+
reinterpret_cast<const Utils::BC3Block*>(imageData.data() + srcIdx), tempRglTextureData, x, y, size.m_width);
151+
}
143152

144-
srcIdx += 8;
153+
srcIdx += GetFormatSize(format);
145154
if (srcIdx == imageData.size() && ++sliceIdx < imageDescriptor.m_arraySize)
146155
{
147156
imageData = imageAsset->GetSubImageData(0, sliceIdx);
@@ -157,7 +166,8 @@ namespace RGL::Wrappers
157166
AZ_Warning(
158167
ConstructTraceWindowName(__func__).c_str(),
159168
false,
160-
"Image is of unsupported type: %s. Only BC1 and BC4 formats are currently supported. Skipping...",
169+
"Image \"%s\" is of unsupported type: %s. Only BC1 and BC4 formats are currently supported. Skipping...",
170+
imageAsset.ToString<AZStd::string>().c_str(),
161171
ToString(imageDescriptor.m_format));
162172
}
163173

Code/rgl_files.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ set(FILES
3636
Source/Model/ModelLibrary.h
3737
Source/RGLSystemComponent.cpp
3838
Source/RGLSystemComponent.h
39+
Source/Utilities/BlockCompression.cpp
40+
Source/Utilities/BlockCompression.h
3941
Source/Utilities/RGLUtils.cpp
4042
Source/Utilities/RGLUtils.h
4143
Source/Wrappers/RglEntity.cpp

0 commit comments

Comments
 (0)