-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Hello! I am experiencing an interesting crash when working with large textures - in this case 2048x2048. I am using a function to restore the Z axis of normal maps when converting to PNG. It "works" for small images, but it doesn't for large. I am attaching the dds files I tested in various sizes. 4 of them should work (512x512, 1024x1024, 1024x2048, 2018x1024), the last one will crash (tile_roofShingles...dds)
Here's the code I used.
unsafe public static void SaveNormalMap(string ddsFilePath, string destinationDirectory, TextureType textureType, DDSConversionMode conversionMode = DDSConversionMode.DEFAULT)
{
GetDDSImage(ddsFilePath, out ScratchImage image, out TexMetadata metadata);
// Create path for new texture file
var path = Path.Combine(destinationDirectory, Path.GetFileNameWithoutExtension(ddsFilePath) + Converter.GetExtension(textureType)[0]);
ScratchImage rawImage = DirectXTex.CreateScratchImage();
// Decompress to R8G8B8A8
if (DirectXTex.IsCompressed(metadata.Format))
{
DirectXTex.Decompress2(image.GetImages(), image.GetImageCount(), image.GetMetadata(), (int)DXGIFormat.R8G8B8A8_UNORM, rawImage);
}
else
{
// Copy the Texture if it's not compressed
Rect rect = new() { X = 0, Y = 0, W = metadata.Width, H = metadata.Height };
DirectXTex.CopyRectangle(image.GetImage(0, 0, 0), rect, rawImage.GetImage(0, 0, 0), TexFilterFlags.Default, 0, 0);
}
image.Release();
// Select the TransformImage Function (in this case we use Restore_Z and we use the RestoreZUnorm function).
TransformImageFunc transformFunction = null;
if (conversionMode == DDSConversionMode.RESTORE_Z)
{
transformFunction = RestoreZ;
if (DirectXTex.FormatDataType(metadata.Format) == FormatType.Unorm)
{
transformFunction = RestoreZUnorm;
}
}
ScratchImage finalImage = DirectXTex.CreateScratchImage();
// Transform the image
if (transformFunction != null)
{
DirectXTex.TransformImage(rawImage.GetImage(0, 0, 0), transformFunction, finalImage);
}
rawImage.Release();
// Save the new image
Guid guid = DirectXTex.GetWICCodec(GetWicDecoder(textureType));
DirectXTex.SaveToWICFile2(finalImage.GetImages(), finalImage.GetImageCount(), 0, guid, path, null, default);
finalImage.Release();
}
unsafe public static void RestoreZUnorm(Vector4* outPixels, Vector4* inPixels, ulong width, ulong y)
{
for (ulong j = 0; j < width; ++j)
{
Vector4 value = inPixels[j];
Vector4 x2 = (value * 2.0f) - Vector4.One;
x2 = Vector4.SquareRoot(Vector4.One - Vector4.Multiply(x2, x2));
Vector4 z = Vector4.Multiply(x2, 0.5f) + Vector4.One * 0.5f;
outPixels[j] = value;
outPixels[j].Z = z.Z;
}
}
// Enums for the modes, ignore them.
public enum DDSConversionMode
{
DEFAULT = 0,
RESTORE_Z = 1,
SWIZZLE_MASK_RG00 = 2,
SWIZZLE_ABGR = 3,
}
public enum TextureType
{
Unknown,
D3DTX,
DDS,
KTX,
KTX2,
PNG,
JPEG,
BMP,
TIFF,
TGA
}
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working