From 899528e087bead777440cc2f179ca1c307c6c53c Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 30 Dec 2024 21:27:03 -0600 Subject: [PATCH] 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.