mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-07 19:23:04 +02:00
Fixed gamma with ETC SRGB8
This commit is contained in:
commit
150508dc18
4 changed files with 57 additions and 26 deletions
|
@ -15,13 +15,14 @@
|
|||
#include <tbb/blocked_range2d.h>
|
||||
|
||||
#include "RandomAndNoise.h"
|
||||
#include "TextureProcessing.h"
|
||||
#include "ImageLogging.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265359
|
||||
#endif
|
||||
|
||||
#include <nvtt/nvtt.h>
|
||||
|
||||
using namespace image;
|
||||
|
||||
static const glm::vec3 FACE_NORMALS[24] = {
|
||||
|
@ -321,7 +322,7 @@ CubeMap::CubeMap(int width, int height, int mipCount) {
|
|||
reset(width, height, mipCount);
|
||||
}
|
||||
|
||||
CubeMap::CubeMap(const std::vector<Image>& faces, gpu::Element srcTextureFormat, int mipCount, const std::atomic<bool>& abortProcessing) {
|
||||
CubeMap::CubeMap(const std::vector<Image>& faces, int mipCount, const std::atomic<bool>& abortProcessing) {
|
||||
reset(faces.front().getWidth(), faces.front().getHeight(), mipCount);
|
||||
|
||||
int face;
|
||||
|
@ -330,13 +331,11 @@ CubeMap::CubeMap(const std::vector<Image>& faces, gpu::Element srcTextureFormat,
|
|||
surface.setAlphaMode(nvtt::AlphaMode_None);
|
||||
surface.setWrapMode(nvtt::WrapMode_Mirror);
|
||||
|
||||
std::vector<glm::vec4> floatPixels;
|
||||
floatPixels.resize(_width * _height);
|
||||
|
||||
// Compute mips
|
||||
for (face = 0; face < 6; face++) {
|
||||
convertToFloatFromPacked(faces[face].getBits(), _width, _height, faces[face].getBytesPerLineCount(), srcTextureFormat, floatPixels.data(), _width);
|
||||
surface.setImage(nvtt::InputFormat_RGBA_32F, _width, _height, 1, &floatPixels.front().x);
|
||||
Image faceImage = faces[face].getConvertedToFormat(Image::Format_RGBAF);
|
||||
|
||||
surface.setImage(nvtt::InputFormat_RGBA_32F, _width, _height, 1, faceImage.editBits());
|
||||
|
||||
auto mipLevel = 0;
|
||||
copySurface(surface, editFace(0, face), getMipLineStride(0));
|
||||
|
@ -359,6 +358,18 @@ CubeMap::CubeMap(const std::vector<Image>& faces, gpu::Element srcTextureFormat,
|
|||
}
|
||||
}
|
||||
|
||||
void CubeMap::applyGamma(float value) {
|
||||
for (auto& mip : _mips) {
|
||||
for (auto& face : mip) {
|
||||
for (auto& pixel : face) {
|
||||
pixel.r = std::pow(pixel.r, value);
|
||||
pixel.g = std::pow(pixel.g, value);
|
||||
pixel.b = std::pow(pixel.b, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CubeMap::copyFace(int width, int height, const glm::vec4* source, size_t srcLineStride, glm::vec4* dest, size_t dstLineStride) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
std::copy(source, source + width, dest);
|
||||
|
|
|
@ -31,11 +31,13 @@ namespace image {
|
|||
public:
|
||||
|
||||
CubeMap(int width, int height, int mipCount);
|
||||
CubeMap(const std::vector<Image>& faces, gpu::Element faceFormat, int mipCount, const std::atomic<bool>& abortProcessing = false);
|
||||
CubeMap(const std::vector<Image>& faces, int mipCount, const std::atomic<bool>& abortProcessing = false);
|
||||
|
||||
void reset(int width, int height, int mipCount);
|
||||
void copyTo(CubeMap& other) const;
|
||||
|
||||
void applyGamma(float value);
|
||||
|
||||
gpu::uint16 getMipCount() const { return (gpu::uint16)_mips.size(); }
|
||||
int getMipWidth(gpu::uint16 mipLevel) const {
|
||||
return std::max(1, _width >> mipLevel);
|
||||
|
|
|
@ -75,8 +75,8 @@ Image Image::getScaled(glm::uvec2 dstSize, AspectRatioMode ratioMode, Transforma
|
|||
glm::vec4* floatPixels = new glm::vec4[getWidth()*getHeight()];
|
||||
auto unpackFunc = getHDRUnpackingFunction();
|
||||
auto floatDataIt = floatPixels;
|
||||
for (auto lineNb = 0; lineNb < getHeight(); lineNb++) {
|
||||
const glm::uint32* srcPixelIt = reinterpret_cast<const glm::uint32*>(getScanLine(lineNb));
|
||||
for (glm::uint32 lineNb = 0; lineNb < getHeight(); lineNb++) {
|
||||
const glm::uint32* srcPixelIt = reinterpret_cast<const glm::uint32*>(getScanLine((int)lineNb));
|
||||
const glm::uint32* srcPixelEnd = srcPixelIt + getWidth();
|
||||
|
||||
while (srcPixelIt < srcPixelEnd) {
|
||||
|
@ -96,7 +96,7 @@ Image Image::getScaled(glm::uvec2 dstSize, AspectRatioMode ratioMode, Transforma
|
|||
if (transformMode == Qt::TransformationMode::FastTransformation) {
|
||||
filter = nvtt::ResizeFilter_Box;
|
||||
}
|
||||
surface.resize(dstSize.x, dstSize.y, 1, nvtt::ResizeFilter_Box);
|
||||
surface.resize(dstSize.x, dstSize.y, 1, filter);
|
||||
|
||||
auto srcRedIt = reinterpret_cast<const float*>(surface.channel(0));
|
||||
auto srcGreenIt = reinterpret_cast<const float*>(surface.channel(1));
|
||||
|
@ -124,8 +124,8 @@ Image Image::getScaled(glm::uvec2 dstSize, AspectRatioMode ratioMode, Transforma
|
|||
QImage resizedImage((int)dstSize.x, (int)dstSize.y, (QImage::Format)Image::Format_PACKED_FLOAT);
|
||||
|
||||
auto packFunc = getHDRPackingFunction();
|
||||
for (auto lineNb = 0; lineNb < dstSize.y; lineNb++) {
|
||||
glm::uint32* dstPixelIt = reinterpret_cast<glm::uint32*>(resizedImage.scanLine(lineNb));
|
||||
for (glm::uint32 lineNb = 0; lineNb < dstSize.y; lineNb++) {
|
||||
glm::uint32* dstPixelIt = reinterpret_cast<glm::uint32*>(resizedImage.scanLine((int)lineNb));
|
||||
glm::uint32* dstPixelEnd = dstPixelIt + dstSize.x;
|
||||
|
||||
while (dstPixelIt < dstPixelEnd) {
|
||||
|
|
|
@ -615,7 +615,7 @@ nvtt::OutputHandler* getNVTTCompressionOutputHandler(gpu::Texture* outputTexture
|
|||
}
|
||||
}
|
||||
|
||||
void convertToHDRTexture(gpu::Texture* texture, Image&& image, BackendTarget target, int baseMipLevel, bool buildMips, const std::atomic<bool>& abortProcessing, int face) {
|
||||
void convertImageToHDRTexture(gpu::Texture* texture, Image&& image, BackendTarget target, int baseMipLevel, bool buildMips, const std::atomic<bool>& abortProcessing, int face) {
|
||||
assert(image.hasFloatFormat());
|
||||
|
||||
Image localCopy = image.getConvertedToFormat(Image::Format_RGBAF);
|
||||
|
@ -658,21 +658,20 @@ void convertToHDRTexture(gpu::Texture* texture, Image&& image, BackendTarget tar
|
|||
}
|
||||
}
|
||||
|
||||
void convertToLDRTexture(gpu::Texture* texture, Image&& image, BackendTarget target, int baseMipLevel, bool buildMips, const std::atomic<bool>& abortProcessing, int face) {
|
||||
void convertImageToLDRTexture(gpu::Texture* texture, Image&& image, BackendTarget target, int baseMipLevel, bool buildMips, const std::atomic<bool>& abortProcessing, int face) {
|
||||
// Take a local copy to force move construction
|
||||
// https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f18-for-consume-parameters-pass-by-x-and-stdmove-the-parameter
|
||||
Image localCopy = std::move(image);
|
||||
|
||||
assert(localCopy.getFormat() != Image::Format_PACKED_FLOAT);
|
||||
if (localCopy.getFormat() != Image::Format_ARGB32) {
|
||||
localCopy = localCopy.getConvertedToFormat(Image::Format_ARGB32);
|
||||
}
|
||||
|
||||
const int width = localCopy.getWidth(), height = localCopy.getHeight();
|
||||
auto mipFormat = texture->getStoredMipFormat();
|
||||
int mipLevel = baseMipLevel;
|
||||
|
||||
if (target != BackendTarget::GLES32) {
|
||||
if (localCopy.getFormat() != Image::Format_ARGB32) {
|
||||
localCopy = localCopy.getConvertedToFormat(Image::Format_ARGB32);
|
||||
}
|
||||
|
||||
const void* data = static_cast<const void*>(localCopy.getBits());
|
||||
nvtt::TextureType textureType = nvtt::TextureType_2D;
|
||||
nvtt::InputFormat inputFormat = nvtt::InputFormat_BGRA_8UB;
|
||||
|
@ -864,12 +863,12 @@ void convertImageToTexture(gpu::Texture* texture, Image& image, BackendTarget ta
|
|||
PROFILE_RANGE(resource_parse, "convertToTextureWithMips");
|
||||
|
||||
if (target == BackendTarget::GLES32) {
|
||||
convertToLDRTexture(texture, std::move(image), target, baseMipLevel, buildMips, abortProcessing, face);
|
||||
convertImageToLDRTexture(texture, std::move(image), target, baseMipLevel, buildMips, abortProcessing, face);
|
||||
} else {
|
||||
if (image.hasFloatFormat()) {
|
||||
convertToHDRTexture(texture, std::move(image), target, baseMipLevel, buildMips, abortProcessing, face);
|
||||
convertImageToHDRTexture(texture, std::move(image), target, baseMipLevel, buildMips, abortProcessing, face);
|
||||
} else {
|
||||
convertToLDRTexture(texture, std::move(image), target, baseMipLevel, buildMips, abortProcessing, face);
|
||||
convertImageToLDRTexture(texture, std::move(image), target, baseMipLevel, buildMips, abortProcessing, face);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1487,12 +1486,31 @@ Image convertToHDRFormat(Image&& srcImage, gpu::Element format) {
|
|||
return hdrImage;
|
||||
}
|
||||
|
||||
void convolveForGGX(const std::vector<Image>& faces, gpu::Element faceFormat, gpu::Texture* texture, BackendTarget target, const std::atomic<bool>& abortProcessing = false) {
|
||||
static bool isLinearTextureFormat(gpu::Element format) {
|
||||
return !((format == gpu::Element::COLOR_SRGBA_32)
|
||||
|| (format == gpu::Element::COLOR_SBGRA_32)
|
||||
|| (format == gpu::Element::COLOR_SR_8)
|
||||
|| (format == gpu::Element::COLOR_COMPRESSED_BCX_SRGB)
|
||||
|| (format == gpu::Element::COLOR_COMPRESSED_BCX_SRGBA_MASK)
|
||||
|| (format == gpu::Element::COLOR_COMPRESSED_BCX_SRGBA)
|
||||
|| (format == gpu::Element::COLOR_COMPRESSED_BCX_SRGBA_HIGH)
|
||||
|| (format == gpu::Element::COLOR_COMPRESSED_ETC2_SRGB)
|
||||
|| (format == gpu::Element::COLOR_COMPRESSED_ETC2_SRGBA)
|
||||
|| (format == gpu::Element::COLOR_COMPRESSED_ETC2_SRGB_PUNCHTHROUGH_ALPHA));
|
||||
}
|
||||
|
||||
void convolveForGGX(const std::vector<Image>& faces, gpu::Texture* texture, BackendTarget target, const std::atomic<bool>& abortProcessing = false) {
|
||||
PROFILE_RANGE(resource_parse, "convolveForGGX");
|
||||
CubeMap source(faces, faceFormat, texture->getNumMips(), abortProcessing);
|
||||
CubeMap source(faces, texture->getNumMips(), abortProcessing);
|
||||
CubeMap output(texture->getWidth(), texture->getHeight(), texture->getNumMips());
|
||||
|
||||
if (!faces.front().hasFloatFormat()) {
|
||||
source.applyGamma(2.2f);
|
||||
}
|
||||
source.convolveForGGX(output, abortProcessing);
|
||||
if (!isLinearTextureFormat(texture->getTexelFormat())) {
|
||||
output.applyGamma(1.0f/2.2f);
|
||||
}
|
||||
|
||||
for (int face = 0; face < 6; face++) {
|
||||
for (gpu::uint16 mipLevel = 0; mipLevel < output.getMipCount(); mipLevel++) {
|
||||
|
@ -1601,7 +1619,7 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(Image&& srcIm
|
|||
|
||||
if (options & CUBE_GGX_CONVOLVE) {
|
||||
// Performs and convolution AND mip map generation
|
||||
convolveForGGX(faces, GPU_CUBEMAP_HDR_FORMAT, theTexture.get(), target, abortProcessing);
|
||||
convolveForGGX(faces, theTexture.get(), target, abortProcessing);
|
||||
} else {
|
||||
// Create mip maps and compress to final format in one go
|
||||
for (uint8 face = 0; face < faces.size(); ++face) {
|
||||
|
|
Loading…
Reference in a new issue