mirror of
https://github.com/AssetRipper/AssetRipper.git
synced 2025-12-11 20:15:29 +01:00
Improve texture export performance
This commit is contained in:
parent
58d0496f3c
commit
39f9ea7592
@ -3,7 +3,6 @@
|
||||
<PropertyGroup>
|
||||
<OutputPath>..\0Bins\Other\AssetRipper.Export.Modules.Textures\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>..\0Bins\obj\AssetRipper.Export.Modules.Textures\$(Configuration)\</IntermediateOutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -14,7 +13,7 @@
|
||||
<PackageReference Include="AssetRipper.Conversions.Crunch" Version="1.0.3" />
|
||||
<PackageReference Include="AssetRipper.Conversions.FastPng" Version="1.1.0" />
|
||||
<PackageReference Include="AssetRipper.Conversions.UnityCrunch" Version="1.0.3" />
|
||||
<PackageReference Include="AssetRipper.TextureDecoder" Version="2.3.0" />
|
||||
<PackageReference Include="AssetRipper.TextureDecoder" Version="2.4.0" />
|
||||
<PackageReference Include="AssetRipper.Tpk" Version="1.1.0" />
|
||||
<PackageReference Include="StbImageWriteSharp" Version="1.16.7" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -9,25 +9,25 @@ public static class TerrainHeatmap
|
||||
{
|
||||
public static DirectBitmap GetBitmap(ITerrainData terrain)
|
||||
{
|
||||
DirectBitmap bitmap = new DirectBitmap<ColorBGRA32, byte>(
|
||||
DirectBitmap bitmap = new DirectBitmap<ColorRGBA<byte>, byte>(
|
||||
Math.Max(terrain.Heightmap.Width, terrain.Heightmap.Resolution),
|
||||
Math.Max(terrain.Heightmap.Height, terrain.Heightmap.Resolution),
|
||||
1,
|
||||
GetBGRA32Data(terrain));
|
||||
GetRGBA32Data(terrain));
|
||||
bitmap.FlipY();
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static byte[] GetBGRA32Data(ITerrainData terrain)
|
||||
public static byte[] GetRGBA32Data(ITerrainData terrain)
|
||||
{
|
||||
AssetList<short> heights = terrain.Heightmap.Heights;
|
||||
byte[] result = new byte[heights.Count * 4];
|
||||
for (int y = 0; y < heights.Count; y++)
|
||||
{
|
||||
Color32 color = (Color32)ConvertToColor((float)heights[y] / short.MaxValue);
|
||||
result[4 * y] = color.B;
|
||||
result[4 * y] = color.R;
|
||||
result[4 * y + 1] = color.G;
|
||||
result[4 * y + 2] = color.R;
|
||||
result[4 * y + 2] = color.B;
|
||||
result[4 * y + 3] = byte.MaxValue; //small optimization
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -224,7 +224,7 @@ public static class TextureConverter
|
||||
TextureFormat.RG32_SIGNED => TryConvertToBitmap<ColorRG<short>, short>(textureFormat, width, height, depth, imageSize, version, data, out bitmap),
|
||||
TextureFormat.RGB48_SIGNED => TryConvertToBitmap<ColorRGB<short>, short>(textureFormat, width, height, depth, imageSize, version, data, out bitmap),
|
||||
TextureFormat.RGBA64_SIGNED => TryConvertToBitmap<ColorRGBA<short>, short>(textureFormat, width, height, depth, imageSize, version, data, out bitmap),
|
||||
_ => TryConvertToBitmap<ColorBGRA32, byte>(textureFormat, width, height, depth, imageSize, version, data, out bitmap),
|
||||
_ => TryConvertToBitmap<ColorRGBA<byte>, byte>(textureFormat, width, height, depth, imageSize, version, data, out bitmap),
|
||||
};
|
||||
}
|
||||
|
||||
@ -289,149 +289,75 @@ public static class TextureConverter
|
||||
ReadOnlySpan<byte> inputSpan = uncompressedSpan.Slice(i * bytesPerLayer, bytesPerLayer);
|
||||
Span<byte> outputSpan = bitmap.Bits.Slice(i * outputSize, outputSize);
|
||||
|
||||
if (typeof(TColor) == typeof(ColorBGRA32))
|
||||
if (!TryDecodeTexture<TColor, TChannelValue>(textureFormat, width, height, inputSpan, outputSpan))
|
||||
{
|
||||
if (!TryDecodeTexture(textureFormat, width, height, inputSpan, outputSpan))
|
||||
{
|
||||
bitmap = DirectBitmap.Empty;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TryDecodeTexture<TColor, TChannelValue>(textureFormat, width, height, inputSpan, outputSpan))
|
||||
{
|
||||
bitmap = DirectBitmap.Empty;
|
||||
return false;
|
||||
}
|
||||
bitmap = DirectBitmap.Empty;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryDecodeTexture(TextureFormat textureFormat, int width, int height, ReadOnlySpan<byte> inputSpan, Span<byte> outputSpan)
|
||||
{
|
||||
switch (textureFormat)
|
||||
{
|
||||
//ASTC
|
||||
case TextureFormat.ASTC_RGB_4x4:
|
||||
case TextureFormat.ASTC_RGBA_4x4:
|
||||
AstcDecoder.DecodeASTC(inputSpan, width, height, 4, 4, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_5x5:
|
||||
case TextureFormat.ASTC_RGBA_5x5:
|
||||
AstcDecoder.DecodeASTC(inputSpan, width, height, 5, 5, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_6x6:
|
||||
case TextureFormat.ASTC_RGBA_6x6:
|
||||
AstcDecoder.DecodeASTC(inputSpan, width, height, 6, 6, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_8x8:
|
||||
case TextureFormat.ASTC_RGBA_8x8:
|
||||
AstcDecoder.DecodeASTC(inputSpan, width, height, 8, 8, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_10x10:
|
||||
case TextureFormat.ASTC_RGBA_10x10:
|
||||
AstcDecoder.DecodeASTC(inputSpan, width, height, 10, 10, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_12x12:
|
||||
case TextureFormat.ASTC_RGBA_12x12:
|
||||
AstcDecoder.DecodeASTC(inputSpan, width, height, 12, 12, outputSpan);
|
||||
return true;
|
||||
|
||||
//ATC
|
||||
case TextureFormat.ATC_RGB4:
|
||||
AtcDecoder.DecompressAtcRgb4(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ATC_RGBA8:
|
||||
AtcDecoder.DecompressAtcRgba8(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
//BC
|
||||
case TextureFormat.BC4:
|
||||
Bc4.Decompress(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
case TextureFormat.BC5:
|
||||
Bc5.Decompress(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
case TextureFormat.BC6H:
|
||||
Bc6h.Decompress(inputSpan, width, height, false, outputSpan);
|
||||
return true;
|
||||
case TextureFormat.BC7:
|
||||
Bc7.Decompress(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
//ETC
|
||||
case TextureFormat.ETC_RGB4:
|
||||
case TextureFormat.ETC_RGB4_3DS:
|
||||
case TextureFormat.ETC_RGB4Crunched:
|
||||
EtcDecoder.DecompressETC(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.EAC_R:
|
||||
EtcDecoder.DecompressEACRUnsigned(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.EAC_R_SIGNED:
|
||||
EtcDecoder.DecompressEACRSigned(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.EAC_RG:
|
||||
EtcDecoder.DecompressEACRGUnsigned(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.EAC_RG_SIGNED:
|
||||
EtcDecoder.DecompressEACRGSigned(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ETC2_RGB:
|
||||
EtcDecoder.DecompressETC2(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ETC2_RGBA1:
|
||||
EtcDecoder.DecompressETC2A1(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ETC2_RGBA8:
|
||||
case TextureFormat.ETC_RGBA8_3DS:
|
||||
case TextureFormat.ETC2_RGBA8Crunched:
|
||||
EtcDecoder.DecompressETC2A8(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
//PVRTC
|
||||
case TextureFormat.PVRTC_RGB2:
|
||||
case TextureFormat.PVRTC_RGBA2:
|
||||
PvrtcDecoder.DecompressPVRTC(inputSpan, width, height, true, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.PVRTC_RGB4:
|
||||
case TextureFormat.PVRTC_RGBA4:
|
||||
PvrtcDecoder.DecompressPVRTC(inputSpan, width, height, false, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.BGRA32_14:
|
||||
case TextureFormat.BGRA32_37:
|
||||
//This needs sliced because the inputSpan can have mips.
|
||||
inputSpan[..outputSpan.Length].CopyTo(outputSpan);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return TryDecodeTexture<ColorBGRA32, byte>(textureFormat, width, height, inputSpan, outputSpan);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryDecodeTexture<TColor, TChannelValue>(TextureFormat textureFormat, int width, int height, ReadOnlySpan<byte> inputSpan, Span<byte> outputSpan)
|
||||
where TColor : unmanaged, IColor<TChannelValue>
|
||||
where TChannelValue : unmanaged
|
||||
{
|
||||
switch (textureFormat)
|
||||
{
|
||||
//ASTC
|
||||
case TextureFormat.ASTC_RGB_4x4:
|
||||
case TextureFormat.ASTC_RGBA_4x4:
|
||||
AstcDecoder.DecodeASTC<TColor, TChannelValue>(inputSpan, width, height, 4, 4, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_5x5:
|
||||
case TextureFormat.ASTC_RGBA_5x5:
|
||||
AstcDecoder.DecodeASTC<TColor, TChannelValue>(inputSpan, width, height, 5, 5, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_6x6:
|
||||
case TextureFormat.ASTC_RGBA_6x6:
|
||||
AstcDecoder.DecodeASTC<TColor, TChannelValue>(inputSpan, width, height, 6, 6, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_8x8:
|
||||
case TextureFormat.ASTC_RGBA_8x8:
|
||||
AstcDecoder.DecodeASTC<TColor, TChannelValue>(inputSpan, width, height, 8, 8, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_10x10:
|
||||
case TextureFormat.ASTC_RGBA_10x10:
|
||||
AstcDecoder.DecodeASTC<TColor, TChannelValue>(inputSpan, width, height, 10, 10, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ASTC_RGB_12x12:
|
||||
case TextureFormat.ASTC_RGBA_12x12:
|
||||
AstcDecoder.DecodeASTC<TColor, TChannelValue>(inputSpan, width, height, 12, 12, outputSpan);
|
||||
return true;
|
||||
|
||||
//ATC
|
||||
case TextureFormat.ATC_RGB4:
|
||||
AtcDecoder.DecompressAtcRgb4<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ATC_RGBA8:
|
||||
AtcDecoder.DecompressAtcRgba8<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
//BC
|
||||
case TextureFormat.BC4:
|
||||
Bc4.Decompress<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
case TextureFormat.BC5:
|
||||
Bc5.Decompress<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
case TextureFormat.BC6H:
|
||||
Bc6h.Decompress<TColor, TChannelValue>(inputSpan, width, height, false, outputSpan);
|
||||
return true;
|
||||
case TextureFormat.BC7:
|
||||
Bc7.Decompress<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
//DXT
|
||||
case TextureFormat.DXT1:
|
||||
case TextureFormat.DXT1Crunched:
|
||||
@ -447,6 +373,54 @@ public static class TextureConverter
|
||||
DxtDecoder.DecompressDXT5<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
//ETC
|
||||
case TextureFormat.ETC_RGB4:
|
||||
case TextureFormat.ETC_RGB4_3DS:
|
||||
case TextureFormat.ETC_RGB4Crunched:
|
||||
EtcDecoder.DecompressETC<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.EAC_R:
|
||||
EtcDecoder.DecompressEACRUnsigned<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.EAC_R_SIGNED:
|
||||
EtcDecoder.DecompressEACRSigned<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.EAC_RG:
|
||||
EtcDecoder.DecompressEACRGUnsigned<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.EAC_RG_SIGNED:
|
||||
EtcDecoder.DecompressEACRGSigned<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ETC2_RGB:
|
||||
EtcDecoder.DecompressETC2<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ETC2_RGBA1:
|
||||
EtcDecoder.DecompressETC2A1<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.ETC2_RGBA8:
|
||||
case TextureFormat.ETC_RGBA8_3DS:
|
||||
case TextureFormat.ETC2_RGBA8Crunched:
|
||||
EtcDecoder.DecompressETC2A8<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
return true;
|
||||
|
||||
//PVRTC
|
||||
case TextureFormat.PVRTC_RGB2:
|
||||
case TextureFormat.PVRTC_RGBA2:
|
||||
PvrtcDecoder.DecompressPVRTC<TColor, TChannelValue>(inputSpan, width, height, true, outputSpan);
|
||||
return true;
|
||||
|
||||
case TextureFormat.PVRTC_RGB4:
|
||||
case TextureFormat.PVRTC_RGBA4:
|
||||
PvrtcDecoder.DecompressPVRTC<TColor, TChannelValue>(inputSpan, width, height, false, outputSpan);
|
||||
return true;
|
||||
|
||||
//YUY2
|
||||
case TextureFormat.YUY2:
|
||||
Yuy2Decoder.DecompressYUY2<TColor, TChannelValue>(inputSpan, width, height, outputSpan);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user