From 899528e087bead777440cc2f179ca1c307c6c53c Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 30 Dec 2024 21:27:03 -0600 Subject: [PATCH 1/4] Add invert options for texture imports for Red, Blue, and Alpha channels. --- .../TextureTool/TextureTool.DirectXTex.cpp | 83 ++++++++++++++++++- Source/Engine/Tools/TextureTool/TextureTool.h | 18 +++- 2 files changed, 96 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp index dc2b20778..f3515ebfb 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp @@ -730,6 +730,9 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path if (!options.FlipY && !options.FlipX && !options.InvertGreenChannel && + !options.InvertRedChannel && + !options.InvertAlphaChannel && + !options.InvertBlueChannel && !options.ReconstructZChannel && options.Compress && type == ImageType::DDS && @@ -831,9 +834,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; - const DirectX::XMVECTOR inverty = DirectX::XMVectorSubtract(DirectX::g_XMOne, value); - outPixels[j] = DirectX::XMVectorSelect(value, inverty, s_selecty); } }, timage); @@ -844,6 +845,84 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path } SET_CURRENT_IMG(timage); } + + // Check if invert red channel + if (!keepAsIs && options.InvertRedChannel) + { + auto& timage = GET_TMP_IMG(); + result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), + [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) + { + static const DirectX::XMVECTORU32 s_selectx = { { { DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; + + UNREFERENCED_PARAMETER(y); + + for (size_t j = 0; j < w; ++j) + { + const DirectX::XMVECTOR value = inPixels[j]; + const DirectX::XMVECTOR inverty = DirectX::XMVectorSubtract(DirectX::g_XMOne, value); + outPixels[j] = DirectX::XMVectorSelect(value, inverty, s_selectx); + } + }, timage); + if (FAILED(result)) + { + errorMsg = String::Format(TEXT("Cannot invert red channel in texture, error: {0:x}"), static_cast(result)); + return true; + } + SET_CURRENT_IMG(timage); + } + + // Check if invert red channel + if (!keepAsIs && options.InvertBlueChannel) + { + auto& timage = GET_TMP_IMG(); + result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), + [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) + { + static const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; + + UNREFERENCED_PARAMETER(y); + + for (size_t j = 0; j < w; ++j) + { + const DirectX::XMVECTOR value = inPixels[j]; + const DirectX::XMVECTOR inverty = DirectX::XMVectorSubtract(DirectX::g_XMOne, value); + outPixels[j] = DirectX::XMVectorSelect(value, inverty, s_selectz); + } + }, timage); + if (FAILED(result)) + { + errorMsg = String::Format(TEXT("Cannot invert blue channel in texture, error: {0:x}"), static_cast(result)); + return true; + } + SET_CURRENT_IMG(timage); + } + + // Check if invert alpha channel + if (!keepAsIs && options.InvertAlphaChannel) + { + auto& timage = GET_TMP_IMG(); + result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), + [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) + { + static const DirectX::XMVECTORU32 s_selectw = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1 } } }; + + UNREFERENCED_PARAMETER(y); + + for (size_t j = 0; j < w; ++j) + { + const DirectX::XMVECTOR value = inPixels[j]; + const DirectX::XMVECTOR inverty = DirectX::XMVectorSubtract(DirectX::g_XMOne, value); + outPixels[j] = DirectX::XMVectorSelect(value, inverty, s_selectw); + } + }, timage); + if (FAILED(result)) + { + errorMsg = String::Format(TEXT("Cannot invert alpha channel in texture, error: {0:x}"), static_cast(result)); + return true; + } + SET_CURRENT_IMG(timage); + } // Reconstruct Z Channel if (!keepAsIs & options.ReconstructZChannel) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.h b/Source/Engine/Tools/TextureTool/TextureTool.h index 13bac0dc5..cfca9aec5 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.h +++ b/Source/Engine/Tools/TextureTool/TextureTool.h @@ -61,12 +61,24 @@ API_CLASS(Namespace="FlaxEngine.Tools", Static) class FLAXENGINE_API TextureTool API_FIELD(Attributes="EditorOrder(71)") bool FlipX = false; - // True if to invert the green channel on a normal map. Good for OpenGL to DirectX conversion. - API_FIELD(Attributes = "EditorOrder(72)") + // Invert the red channel. + API_FIELD(Attributes = "EditorOrder(72), EditorDisplay(\"Invert Channels\"), ExpandGroups") + bool InvertRedChannel = false; + + // Invert the green channel. Good for OpenGL to DirectX conversion. + API_FIELD(Attributes = "EditorOrder(73), EditorDisplay(\"Invert Channels\")") bool InvertGreenChannel = false; + // Invert the blue channel. + API_FIELD(Attributes = "EditorOrder(74), EditorDisplay(\"Invert Channels\")") + bool InvertBlueChannel = false; + + // Invert the alpha channel. + API_FIELD(Attributes = "EditorOrder(75), EditorDisplay(\"Invert Channels\")") + bool InvertAlphaChannel = false; + // Rebuild Z (blue) channel assuming X/Y are normals. - API_FIELD(Attributes = "EditorOrder(73)") + API_FIELD(Attributes = "EditorOrder(76)") bool ReconstructZChannel = false; // Texture size scale. Allows increasing or decreasing the imported texture resolution. Default is 1. From cb6ab6a6478b3c299f0e818c505225d0f456ec77 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 30 Dec 2024 22:14:18 -0600 Subject: [PATCH 2/4] Fix comment --- Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp index f3515ebfb..683bcc292 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp @@ -872,7 +872,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path SET_CURRENT_IMG(timage); } - // Check if invert red channel + // Check if invert blue channel if (!keepAsIs && options.InvertBlueChannel) { auto& timage = GET_TMP_IMG(); From f71e731e54be8401527a82510fd0f0b9f482b9e4 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 30 Dec 2024 23:42:32 -0600 Subject: [PATCH 3/4] Add saving and loading. --- Source/Engine/Tools/TextureTool/TextureTool.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.cpp b/Source/Engine/Tools/TextureTool/TextureTool.cpp index 550e26699..bc4c544d7 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.cpp @@ -27,7 +27,7 @@ namespace String TextureTool::Options::ToString() const { - return String::Format(TEXT("Type: {}, IsAtlas: {}, NeverStream: {}, IndependentChannels: {}, sRGB: {}, GenerateMipMaps: {}, FlipY: {}, InvertGreen: {} Scale: {}, MaxSize: {}, Resize: {}, PreserveAlphaCoverage: {}, PreserveAlphaCoverageReference: {}, SizeX: {}, SizeY: {}"), + return String::Format(TEXT("Type: {}, IsAtlas: {}, NeverStream: {}, IndependentChannels: {}, sRGB: {}, GenerateMipMaps: {}, FlipY: {}, InvertRed: {}, InvertGreen: {}, InvertBlue {}, Invert Alpha {}, Scale: {}, MaxSize: {}, Resize: {}, PreserveAlphaCoverage: {}, PreserveAlphaCoverageReference: {}, SizeX: {}, SizeY: {}"), ScriptingEnum::ToString(Type), IsAtlas, NeverStream, @@ -35,7 +35,10 @@ String TextureTool::Options::ToString() const sRGB, GenerateMipMaps, FlipY, + InvertRedChannel, InvertGreenChannel, + InvertBlueChannel, + InvertAlphaChannel, Scale, MaxSize, MaxSize, @@ -76,9 +79,18 @@ void TextureTool::Options::Serialize(SerializeStream& stream, const void* otherO stream.JKEY("FlipX"); stream.Bool(FlipX); + stream.JKEY("InvertRedChannel"); + stream.Bool(InvertRedChannel); + stream.JKEY("InvertGreenChannel"); stream.Bool(InvertGreenChannel); + stream.JKEY("InvertBlueChannel"); + stream.Bool(InvertBlueChannel); + + stream.JKEY("InvertAlphaChannel"); + stream.Bool(InvertAlphaChannel); + stream.JKEY("ReconstructZChannel"); stream.Bool(ReconstructZChannel); @@ -143,7 +155,10 @@ void TextureTool::Options::Deserialize(DeserializeStream& stream, ISerializeModi GenerateMipMaps = JsonTools::GetBool(stream, "GenerateMipMaps", GenerateMipMaps); FlipY = JsonTools::GetBool(stream, "FlipY", FlipY); FlipX = JsonTools::GetBool(stream, "FlipX", FlipX); + InvertRedChannel = JsonTools::GetBool(stream, "InvertRedChannel", InvertRedChannel); InvertGreenChannel = JsonTools::GetBool(stream, "InvertGreenChannel", InvertGreenChannel); + InvertBlueChannel = JsonTools::GetBool(stream, "InvertBlueChannel", InvertBlueChannel); + InvertAlphaChannel = JsonTools::GetBool(stream, "InvertAlphaChannel", InvertAlphaChannel); ReconstructZChannel = JsonTools::GetBool(stream, "ReconstructZChannel", ReconstructZChannel); Resize = JsonTools::GetBool(stream, "Resize", Resize); KeepAspectRatio = JsonTools::GetBool(stream, "KeepAspectRatio", KeepAspectRatio); From 90316dfa52995453a67c4830a48e84a69dcb94c2 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 13 Jan 2025 15:46:35 +0100 Subject: [PATCH 4/4] Minor code changes to PR --- .../TextureTool/TextureTool.DirectXTex.cpp | 20 +++++-------------- .../Tools/TextureTool/TextureTool.stb.cpp | 4 ++-- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp index 683bcc292..37b914e9c 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.DirectXTex.cpp @@ -827,10 +827,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selecty = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; - + const DirectX::XMVECTORU32 s_selecty = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; @@ -853,10 +851,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selectx = { { { DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; - + const DirectX::XMVECTORU32 s_selectx = { { { DirectX::XM_SELECT_1, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; @@ -879,10 +875,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; - + const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; @@ -905,10 +899,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selectw = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1 } } }; - + const DirectX::XMVECTORU32 s_selectw = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; @@ -932,10 +924,8 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), [&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y) { - static const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; - + const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } }; UNREFERENCED_PARAMETER(y); - for (size_t j = 0; j < w; ++j) { const DirectX::XMVECTOR value = inPixels[j]; diff --git a/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp b/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp index 8ca585c32..0bb2deec2 100644 --- a/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp +++ b/Source/Engine/Tools/TextureTool/TextureTool.stb.cpp @@ -541,10 +541,10 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu // TODO: impl this LOG(Warning, "Option 'Flip X' is not supported"); } - if (options.InvertGreenChannel) + if (options.InvertRedChannel || options.InvertGreenChannel || options.InvertBlueChannel || options.InvertAlphaChannel) { // TODO: impl this - LOG(Warning, "Option 'Invert Green Channel' is not supported"); + LOG(Warning, "Option to invert channels is not supported"); } if (options.ReconstructZChannel) {