diff --git a/libs/image/include/image/ImageOps.h b/libs/image/include/image/ImageOps.h index 8ff69d0298..e62a206f3a 100644 --- a/libs/image/include/image/ImageOps.h +++ b/libs/image/include/image/ImageOps.h @@ -37,6 +37,7 @@ LinearImage verticalFlip(const LinearImage& image); // Transforms normals (components live in [-1,+1]) into colors (components live in [0,+1]). LinearImage vectorsToColors(const LinearImage& image); +LinearImage colorsToVectors(const LinearImage& image); // Creates a single-channel image by extracting the selected channel. LinearImage extractChannel(const LinearImage& image, uint32_t channel); diff --git a/libs/image/src/ImageOps.cpp b/libs/image/src/ImageOps.cpp index 96e7ab1148..6ad88e62ec 100644 --- a/libs/image/src/ImageOps.cpp +++ b/libs/image/src/ImageOps.cpp @@ -123,12 +123,24 @@ LinearImage vectorsToColors(const LinearImage& image) { LinearImage result(width, height, 3); auto src = (float3 const*) image.getPixelRef(); auto dst = (float3*) result.getPixelRef(); - for (uint32_t n = 0; n < width * height; ++n) { + for (uint32_t n = 0, end = width * height; n < end; ++n) { dst[n] = 0.5f * (src[n] + float3(1)); } return result; } +LinearImage colorsToVectors(const LinearImage& image) { + ASSERT_PRECONDITION(image.getChannels() == 3, "Must be a 3-channel image."); + const uint32_t width = image.getWidth(), height = image.getHeight(); + LinearImage result(width, height, 3); + auto src = (float3 const*) image.getPixelRef(); + auto dst = (float3*) result.getPixelRef(); + for (uint32_t n = 0, end = width * height; n < end; ++n) { + dst[n] = 2.0f * src[n] - float3(1); + } + return result; +} + LinearImage extractChannel(const LinearImage& source, uint32_t channel) { const uint32_t width = source.getWidth(), height = source.getHeight(); const uint32_t nchan = source.getChannels(); diff --git a/tools/mipgen/src/main.cpp b/tools/mipgen/src/main.cpp index f6dab35192..774e6b7ff2 100644 --- a/tools/mipgen/src/main.cpp +++ b/tools/mipgen/src/main.cpp @@ -253,6 +253,10 @@ int main(int argc, char* argv[]) { sourceImage = extractChannel(sourceImage, 0); } + if (g_filter == Filter::GAUSSIAN_NORMALS) { + sourceImage = colorsToVectors(sourceImage); + } + puts("Generating miplevels..."); uint32_t count = getMipmapCount(sourceImage); vector miplevels(count); @@ -306,7 +310,10 @@ int main(int argc, char* argv[]) { info.glBaseInternalFormat = KtxBundle::RGBA; } uint32_t mip = 0; - auto addLevel = [&](const LinearImage& image) { + auto addLevel = [&](LinearImage image) { + if (g_filter == Filter::GAUSSIAN_NORMALS) { + image = vectorsToColors(image); + } std::unique_ptr data; if (astcConfig.blocksize[0] > 0) { // The ASTC encoder calls exit(1) if it fails, so it's very useful to print some