texassemble: -tonemap option

This commit is contained in:
Chuck Walbourn 2017-02-25 23:57:13 -08:00
parent 7245687c6c
commit 209a5b4a54
3 changed files with 168 additions and 78 deletions

View File

@ -4,6 +4,8 @@
// DirectX Texture assembler for cube maps, volume maps, and arrays // DirectX Texture assembler for cube maps, volume maps, and arrays
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=248926
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
#pragma warning(push) #pragma warning(push)
@ -71,6 +73,7 @@ enum OPTIONS
OPT_DEMUL_ALPHA, OPT_DEMUL_ALPHA,
OPT_TA_WRAP, OPT_TA_WRAP,
OPT_TA_MIRROR, OPT_TA_MIRROR,
OPT_TONEMAP,
OPT_MAX OPT_MAX
}; };
@ -122,6 +125,7 @@ const SValue g_pOptions [] =
{ L"alpha", OPT_DEMUL_ALPHA }, { L"alpha", OPT_DEMUL_ALPHA },
{ L"wrap", OPT_TA_WRAP }, { L"wrap", OPT_TA_WRAP },
{ L"mirror", OPT_TA_MIRROR }, { L"mirror", OPT_TA_MIRROR },
{ L"tonemap", OPT_TONEMAP },
{ nullptr, 0 } { nullptr, 0 }
}; };
@ -490,6 +494,7 @@ namespace
wprintf(L" -alpha convert premultiplied alpha to straight alpha\n"); wprintf(L" -alpha convert premultiplied alpha to straight alpha\n");
wprintf(L" -dx10 Force use of 'DX10' extended header\n"); wprintf(L" -dx10 Force use of 'DX10' extended header\n");
wprintf(L" -nologo suppress copyright message\n"); wprintf(L" -nologo suppress copyright message\n");
wprintf(L" -tonemap Apply a tonemap operator based on maximum luminance\n");
wprintf(L"\n <format>: "); wprintf(L"\n <format>: ");
PrintList(13, g_pFormats); PrintList(13, g_pFormats);
@ -1055,6 +1060,84 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
image.swap(timage); image.swap(timage);
} }
// --- Tonemap (if requested) --------------------------------------------------
if (dwOptions & (1 << OPT_TONEMAP))
{
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
if (!timage)
{
wprintf(L"\nERROR: Memory allocation failed\n");
return 1;
}
// Compute max luminosity across all images
XMVECTOR maxLum = XMVectorZero();
hr = EvaluateImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
[&](const XMVECTOR* pixels, size_t width, size_t y)
{
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < width; ++j)
{
static const XMVECTORF32 s_luminance = { 0.3f, 0.59f, 0.11f, 0.f };
XMVECTOR v = *pixels++;
v = XMVector3Dot(v, s_luminance);
maxLum = XMVectorMax(v, maxLum);
}
});
if (FAILED(hr))
{
wprintf(L" FAILED [tonemap maxlum] (%x)\n", hr);
return 1;
}
// Reinhard et al, "Photographic Tone Reproduction for Digital Images"
// http://www.cs.utah.edu/~reinhard/cdrom/
maxLum = XMVectorMultiply(maxLum, maxLum);
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
[&](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
{
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < width; ++j)
{
XMVECTOR value = inPixels[j];
XMVECTOR scale = XMVectorDivide(
XMVectorAdd(g_XMOne, XMVectorDivide(value, maxLum)),
XMVectorAdd(g_XMOne, value));
XMVECTOR nvalue = XMVectorMultiply(value, scale);
value = XMVectorSelect(value, nvalue, g_XMSelect1110);
outPixels[j] = value;
}
}, *timage);
if (FAILED(hr))
{
wprintf(L" FAILED [tonemap apply] (%x)\n", hr);
return 1;
}
auto& tinfo = timage->GetMetadata();
tinfo;
assert(info.width == tinfo.width);
assert(info.height == tinfo.height);
assert(info.depth == tinfo.depth);
assert(info.arraySize == tinfo.arraySize);
assert(info.mipLevels == tinfo.mipLevels);
assert(info.miscFlags == tinfo.miscFlags);
assert(info.format == tinfo.format);
assert(info.dimension == tinfo.dimension);
image.swap(timage);
}
// --- Convert ----------------------------------------------------------------- // --- Convert -----------------------------------------------------------------
if (format == DXGI_FORMAT_UNKNOWN) if (format == DXGI_FORMAT_UNKNOWN)
{ {

View File

@ -4,6 +4,8 @@
// DirectX Texture Converter // DirectX Texture Converter
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=248926
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
#pragma warning(push) #pragma warning(push)
@ -1715,6 +1717,85 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
cimage.reset(); cimage.reset();
} }
// --- Tonemap (if requested) --------------------------------------------------
if (dwOptions & DWORD64(1) << OPT_TONEMAP)
{
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
if (!timage)
{
wprintf(L"\nERROR: Memory allocation failed\n");
return 1;
}
// Compute max luminosity across all images
XMVECTOR maxLum = XMVectorZero();
hr = EvaluateImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
[&](const XMVECTOR* pixels, size_t width, size_t y)
{
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < width; ++j)
{
static const XMVECTORF32 s_luminance = { 0.3f, 0.59f, 0.11f, 0.f };
XMVECTOR v = *pixels++;
v = XMVector3Dot(v, s_luminance);
maxLum = XMVectorMax(v, maxLum);
}
});
if (FAILED(hr))
{
wprintf(L" FAILED [tonemap maxlum] (%x)\n", hr);
return 1;
}
// Reinhard et al, "Photographic Tone Reproduction for Digital Images"
// http://www.cs.utah.edu/~reinhard/cdrom/
maxLum = XMVectorMultiply(maxLum, maxLum);
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
[&](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
{
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < width; ++j)
{
XMVECTOR value = inPixels[j];
XMVECTOR scale = XMVectorDivide(
XMVectorAdd(g_XMOne, XMVectorDivide(value, maxLum)),
XMVectorAdd(g_XMOne, value));
XMVECTOR nvalue = XMVectorMultiply(value, scale);
value = XMVectorSelect(value, nvalue, g_XMSelect1110);
outPixels[j] = value;
}
}, *timage);
if (FAILED(hr))
{
wprintf(L" FAILED [tonemap apply] (%x)\n", hr);
return 1;
}
auto& tinfo = timage->GetMetadata();
tinfo;
assert(info.width == tinfo.width);
assert(info.height == tinfo.height);
assert(info.depth == tinfo.depth);
assert(info.arraySize == tinfo.arraySize);
assert(info.mipLevels == tinfo.mipLevels);
assert(info.miscFlags == tinfo.miscFlags);
assert(info.format == tinfo.format);
assert(info.dimension == tinfo.dimension);
image.swap(timage);
cimage.reset();
}
// --- Convert ----------------------------------------------------------------- // --- Convert -----------------------------------------------------------------
if (dwOptions & (DWORD64(1) << OPT_NORMAL_MAP)) if (dwOptions & (DWORD64(1) << OPT_NORMAL_MAP))
{ {
@ -1838,6 +1919,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
assert(info.arraySize == tinfo.arraySize); assert(info.arraySize == tinfo.arraySize);
assert(info.mipLevels == tinfo.mipLevels); assert(info.mipLevels == tinfo.mipLevels);
assert(info.miscFlags == tinfo.miscFlags); assert(info.miscFlags == tinfo.miscFlags);
assert(info.format == tinfo.format);
assert(info.dimension == tinfo.dimension); assert(info.dimension == tinfo.dimension);
image.swap(timage); image.swap(timage);
@ -1986,84 +2068,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
assert(info.depth == tinfo.depth); assert(info.depth == tinfo.depth);
assert(info.arraySize == tinfo.arraySize); assert(info.arraySize == tinfo.arraySize);
assert(info.miscFlags == tinfo.miscFlags); assert(info.miscFlags == tinfo.miscFlags);
assert(info.dimension == tinfo.dimension); assert(info.format == tinfo.format);
image.swap(timage);
cimage.reset();
}
// --- Tonemap (if requested) --------------------------------------------------
if (dwOptions & DWORD64(1) << OPT_TONEMAP)
{
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
if (!timage)
{
wprintf(L"\nERROR: Memory allocation failed\n");
return 1;
}
// Compute max luminosity across all images
XMVECTOR maxLum = XMVectorZero();
hr = EvaluateImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
[&](const XMVECTOR* pixels, size_t width, size_t y)
{
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < width; ++j)
{
static const XMVECTORF32 s_luminance = { 0.3f, 0.59f, 0.11f, 0.f };
XMVECTOR v = *pixels++;
v = XMVector3Dot(v, s_luminance);
maxLum = XMVectorMax(v, maxLum);
}
});
if (FAILED(hr))
{
wprintf(L" FAILED [tonemap maxlum] (%x)\n", hr);
return 1;
}
// Reinhard et al, "Photographic Tone Reproduction for Digital Images"
// http://www.cs.utah.edu/~reinhard/cdrom/
maxLum = XMVectorMultiply(maxLum, maxLum);
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
[&](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t width, size_t y)
{
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < width; ++j)
{
XMVECTOR value = inPixels[j];
XMVECTOR scale = XMVectorDivide(
XMVectorAdd(g_XMOne, XMVectorDivide(value, maxLum)),
XMVectorAdd(g_XMOne, value));
XMVECTOR nvalue = XMVectorMultiply(value, scale);
value = XMVectorSelect(value, nvalue, g_XMSelect1110);
outPixels[j] = value;
}
}, *timage);
if (FAILED(hr))
{
wprintf(L" FAILED [tonemap apply] (%x)\n", hr);
return 1;
}
auto& tinfo = timage->GetMetadata();
tinfo;
assert(info.width == tinfo.width);
assert(info.height == tinfo.height);
assert(info.depth == tinfo.depth);
assert(info.arraySize == tinfo.arraySize);
assert(info.mipLevels == tinfo.mipLevels);
assert(info.miscFlags == tinfo.miscFlags);
assert(info.dimension == tinfo.dimension); assert(info.dimension == tinfo.dimension);
image.swap(timage); image.swap(timage);

View File

@ -4,6 +4,8 @@
// DirectX Texture diagnostic tool // DirectX Texture diagnostic tool
// //
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=248926
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
#pragma warning(push) #pragma warning(push)