Skip to content

Commit

Permalink
Perfect DXT5nm normalmaps output
Browse files Browse the repository at this point in the history
  • Loading branch information
AveYo committed Sep 20, 2018
1 parent e14f7c7 commit 6ce57f5
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
6 changes: 5 additions & 1 deletion ValveResourceFormat/Resource/ResourceTypes/Texture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,20 @@ public SKBitmap GenerateBitmap()

case VTexFormat.DXT5:
var yCoCg = false;
var normalize = false;
var invert = false;

if (Resource.EditInfo.Structs.ContainsKey(ResourceEditInfo.REDIStruct.SpecialDependencies))
{
var specialDeps = (SpecialDependencies)Resource.EditInfo.Structs[ResourceEditInfo.REDIStruct.SpecialDependencies];

yCoCg = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image YCoCg Conversion");
normalize = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image NormalizeNormals");
invert = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version LegacySource1InvertNormals");
}

SkipMipmaps(16);
TextureDecompressors.UncompressDXT5(imageInfo, Reader, data, yCoCg, Width, Height);
TextureDecompressors.UncompressDXT5(imageInfo, Reader, data, Width, Height, yCoCg, normalize, invert);
break;

case VTexFormat.I8:
Expand Down
22 changes: 19 additions & 3 deletions ValveResourceFormat/Resource/ResourceTypes/TextureDecompressors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ private static void DecompressBlockDXT1(int x, int y, int width, byte[] blockSto
}
}

public static void UncompressDXT5(SKImageInfo imageInfo, BinaryReader r, Span<byte> data, bool yCoCg, int w, int h)
public static void UncompressDXT5(SKImageInfo imageInfo, BinaryReader r, Span<byte> data, int w, int h, bool yCoCg, bool normalize, bool invert)
{
var blockCountX = (w + 3) / 4;
var blockCountY = (h + 3) / 4;
Expand All @@ -401,12 +401,12 @@ public static void UncompressDXT5(SKImageInfo imageInfo, BinaryReader r, Span<by
for (var i = 0; i < blockCountX; i++)
{
var blockStorage = r.ReadBytes(16);
DecompressBlockDXT5(i * 4, j * 4, imageInfo.Width, blockStorage, data, imageInfo.RowBytes, yCoCg);
DecompressBlockDXT5(i * 4, j * 4, imageInfo.Width, blockStorage, data, imageInfo.RowBytes, yCoCg, normalize, invert);
}
}
}

private static void DecompressBlockDXT5(int x, int y, int width, byte[] blockStorage, Span<byte> pixels, int stride, bool yCoCg)
private static void DecompressBlockDXT5(int x, int y, int width, byte[] blockStorage, Span<byte> pixels, int stride, bool yCoCg, bool normalize, bool invert)
{
var alpha0 = blockStorage[0];
var alpha1 = blockStorage[1];
Expand Down Expand Up @@ -531,6 +531,22 @@ private static void DecompressBlockDXT5(int x, int y, int width, byte[] blockSto
finalAlpha = 255; // TODO: yCoCg should have an alpha too?
}

if (normalize)
{
var swizzleA = (finalAlpha * 2) - 255; // premul A
var swizzleG = (finalG * 2) - 255; // premul G
var deriveB = (int)System.Math.Sqrt((255 * 255) - (swizzleA * swizzleA) - (swizzleG * swizzleG));
finalR = ClampColor((swizzleA / 2) + 128); // unpremul A and normalize (128 = forward, or facing viewer)
finalG = ClampColor((swizzleG / 2) + 128); // unpremul G and normalize
finalB = ClampColor((deriveB / 2) + 128); // unpremul B and normalize
finalAlpha = 255;
}

if (invert)
{
finalG = (byte)(~finalG); // LegacySource1InvertNormals
}

pixels[pixelIndex] = finalB;
pixels[pixelIndex + 1] = finalG;
pixels[pixelIndex + 2] = finalR;
Expand Down

0 comments on commit 6ce57f5

Please sign in to comment.