diff --git a/AssetStudio/Classes/Texture2D.cs b/AssetStudio/Classes/Texture2D.cs index 655368a..5dbb984 100644 --- a/AssetStudio/Classes/Texture2D.cs +++ b/AssetStudio/Classes/Texture2D.cs @@ -13,6 +13,7 @@ namespace AssetStudio public bool m_MipMap; public int m_MipCount; public GLTextureSettings m_TextureSettings; + public int m_LightmapFormat; public int m_ImageCount; public byte[] m_PlatformBlob; [JsonPropertyName("image data")] @@ -70,6 +71,7 @@ namespace AssetStudio m_MipCount = parsedTex2d.m_MipCount; m_ImageCount = parsedTex2d.m_ImageCount; m_TextureSettings = parsedTex2d.m_TextureSettings; + m_LightmapFormat = parsedTex2d.m_LightmapFormat; m_StreamData = parsedTex2d.m_StreamData; m_PlatformBlob = parsedTex2d.m_PlatformBlob ?? Array.Empty(); @@ -137,7 +139,7 @@ namespace AssetStudio var m_IgnoreMasterTextureLimit = reader.ReadBoolean(); } } - if (version.IsInRange(3, (5, 5))) //3.0.0 - 5.4 + if (version.IsInRange(3, (5, 5))) //3.0.0 - 5.5 down { var m_ReadAllowed = reader.ReadBoolean(); } @@ -162,7 +164,7 @@ namespace AssetStudio m_TextureSettings = new GLTextureSettings(reader); if (version >= 3) //3.0 and up { - var m_LightmapFormat = reader.ReadInt32(); + m_LightmapFormat = reader.ReadInt32(); } if (version >= (3, 5)) //3.5.0 and up { diff --git a/AssetStudioUtility/Texture2DConverter.cs b/AssetStudioUtility/Texture2DConverter.cs index fe6df56..1eb53f2 100644 --- a/AssetStudioUtility/Texture2DConverter.cs +++ b/AssetStudioUtility/Texture2DConverter.cs @@ -120,6 +120,7 @@ namespace AssetStudio { image.Mutate(x => x.Flip(FlipMode.Vertical)); } + return true; } finally @@ -334,6 +335,13 @@ namespace AssetStudio BigArrayPool.Shared.Return(buff, clearArray: true); } + //src: https://github.com/AssetRipper/AssetRipper/blob/master/Source/AssetRipper.Export.Modules.Textures/TextureConverter.cs + // despite the name, this packing works for different formats + if (m_Texture2D.m_LightmapFormat == 3) //NormalmapDXT5nm + { + UnpackNormal(destSpan); + } + return flag; } @@ -844,5 +852,23 @@ namespace AssetStudio } return !result.IsEmpty; } + + private void UnpackNormal(Span bgraImageData) + { + for (var i = 0; i < outputDataSize; i += 4) + { + (bgraImageData[i + 2], bgraImageData[i + 3]) = (bgraImageData[i + 3], bgraImageData[i + 2]); //Alpha and red are swapped + var g = bgraImageData[i + 1]; + var r = bgraImageData[i + 2]; + + //Blue needs calculated + const double magnitudeSqr = 255 * 255; + var vr = r * 2.0 - 255.0; + var vg = g * 2.0 - 255.0; + var hypotenuseSqr = Math.Min(vr * vr + vg * vg, magnitudeSqr); + var b = (Math.Sqrt(magnitudeSqr - hypotenuseSqr) + 255.0) / 2.0; + bgraImageData[i] = (byte)b; + } + } } }