From 3b746384caec01614c1de0a56a350edc42ad756d Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 23 Apr 2019 15:47:12 -0700 Subject: [PATCH] really fix texture baking, and turn off irradiance generation during baking --- libraries/baking/src/FBXBaker.cpp | 1 - libraries/baking/src/FBXBaker.h | 4 ---- libraries/baking/src/MaterialBaker.cpp | 2 +- libraries/baking/src/OBJBaker.h | 4 ---- libraries/baking/src/TextureBaker.cpp | 13 ++++++------- libraries/baking/src/TextureBaker.h | 5 ++--- libraries/gpu/src/gpu/Texture.cpp | 2 +- libraries/gpu/src/gpu/Texture.h | 4 +++- libraries/image/src/image/TextureProcessing.cpp | 6 +++--- libraries/image/src/image/TextureProcessing.h | 2 +- .../src/material-networking/TextureCache.cpp | 4 ++-- .../src/material-networking/TextureCache.h | 2 +- tools/oven/src/DomainBaker.cpp | 14 +++++++++----- tools/oven/src/DomainBaker.h | 1 + tools/oven/src/Oven.cpp | 3 +++ tools/oven/src/ui/SkyboxBakeWidget.cpp | 2 +- 16 files changed, 34 insertions(+), 35 deletions(-) diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp index 9b80041bcf..eb02ac2241 100644 --- a/libraries/baking/src/FBXBaker.cpp +++ b/libraries/baking/src/FBXBaker.cpp @@ -31,7 +31,6 @@ #include #include "ModelBakingLoggingCategory.h" -#include "TextureBaker.h" FBXBaker::FBXBaker(const QUrl& inputModelURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory, bool hasBeenBaked) : ModelBaker(inputModelURL, bakedOutputDirectory, originalOutputDirectory, hasBeenBaked) { diff --git a/libraries/baking/src/FBXBaker.h b/libraries/baking/src/FBXBaker.h index 5daf8a8adf..a528de512d 100644 --- a/libraries/baking/src/FBXBaker.h +++ b/libraries/baking/src/FBXBaker.h @@ -18,15 +18,11 @@ #include #include "Baker.h" -#include "TextureBaker.h" #include "ModelBaker.h" #include "ModelBakingLoggingCategory.h" -#include - #include -using TextureBakerThreadGetter = std::function; class FBXBaker : public ModelBaker { Q_OBJECT diff --git a/libraries/baking/src/MaterialBaker.cpp b/libraries/baking/src/MaterialBaker.cpp index 69e19224dd..7c9a5c10c1 100644 --- a/libraries/baking/src/MaterialBaker.cpp +++ b/libraries/baking/src/MaterialBaker.cpp @@ -138,7 +138,7 @@ void MaterialBaker::processMaterial() { auto baseTextureFileName = _textureFileNamer.createBaseTextureFileName(textureURL.fileName(), type); QSharedPointer textureBaker { - new TextureBaker(textureURL, type, _textureOutputDir, "", baseTextureFileName, content), + new TextureBaker(textureURL, type, _textureOutputDir, baseTextureFileName, content), &TextureBaker::deleteLater }; textureBaker->setMapChannel(mapChannel); diff --git a/libraries/baking/src/OBJBaker.h b/libraries/baking/src/OBJBaker.h index 9bd1431d28..9d0fe53e3c 100644 --- a/libraries/baking/src/OBJBaker.h +++ b/libraries/baking/src/OBJBaker.h @@ -13,13 +13,9 @@ #define hifi_OBJBaker_h #include "Baker.h" -#include "TextureBaker.h" #include "ModelBaker.h" - #include "ModelBakingLoggingCategory.h" -using TextureBakerThreadGetter = std::function; - using NodeID = qlonglong; class OBJBaker : public ModelBaker { diff --git a/libraries/baking/src/TextureBaker.cpp b/libraries/baking/src/TextureBaker.cpp index 54d304b7d8..e4b0abcef6 100644 --- a/libraries/baking/src/TextureBaker.cpp +++ b/libraries/baking/src/TextureBaker.cpp @@ -33,14 +33,13 @@ const QString BAKED_META_TEXTURE_SUFFIX = ".texmeta.json"; bool TextureBaker::_compressionEnabled = true; TextureBaker::TextureBaker(const QUrl& textureURL, image::TextureUsage::Type textureType, - const QDir& outputDirectory, const QString& metaTexturePathPrefix, - const QString& baseFilename, const QByteArray& textureContent) : + const QDir& outputDirectory, const QString& baseFilename, + const QByteArray& textureContent) : _textureURL(textureURL), _originalTexture(textureContent), _textureType(textureType), _baseFilename(baseFilename), - _outputDirectory(outputDirectory), - _metaTexturePathPrefix(metaTexturePathPrefix) + _outputDirectory(outputDirectory) { if (baseFilename.isEmpty()) { // figure out the baked texture filename @@ -151,7 +150,7 @@ void TextureBaker::processTexture() { // IMPORTANT: _originalTexture is empty past this point _originalTexture.clear(); _outputFiles.push_back(originalCopyFilePath); - meta.original = _metaTexturePathPrefix + _originalCopyFilePath.fileName(); + meta.original = _originalCopyFilePath.fileName(); } // Load the copy of the original file from the baked output directory. New images will be created using the original as the source data. @@ -204,7 +203,7 @@ void TextureBaker::processTexture() { return; } _outputFiles.push_back(filePath); - meta.availableTextureTypes[memKTX->_header.getGLInternaFormat()] = _metaTexturePathPrefix + fileName; + meta.availableTextureTypes[memKTX->_header.getGLInternaFormat()] = fileName; } } @@ -240,7 +239,7 @@ void TextureBaker::processTexture() { return; } _outputFiles.push_back(filePath); - meta.uncompressed = _metaTexturePathPrefix + fileName; + meta.uncompressed = fileName; } else { buffer.reset(); } diff --git a/libraries/baking/src/TextureBaker.h b/libraries/baking/src/TextureBaker.h index 13ad82cff4..5fda05e9b4 100644 --- a/libraries/baking/src/TextureBaker.h +++ b/libraries/baking/src/TextureBaker.h @@ -32,8 +32,8 @@ class TextureBaker : public Baker { public: TextureBaker(const QUrl& textureURL, image::TextureUsage::Type textureType, - const QDir& outputDirectory, const QString& metaTexturePathPrefix = "", - const QString& baseFilename = QString(), const QByteArray& textureContent = QByteArray()); + const QDir& outputDirectory, const QString& baseFilename = QString(), + const QByteArray& textureContent = QByteArray()); const QByteArray& getOriginalTexture() const { return _originalTexture; } @@ -74,7 +74,6 @@ private: QString _baseFilename; QDir _outputDirectory; QString _metaTextureFileName; - QString _metaTexturePathPrefix; QUrl _originalCopyFilePath; std::atomic _abortProcessing { false }; diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 5c2e181810..c884191995 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -37,11 +37,11 @@ ContextMetricCount Texture::_textureCPUCount; ContextMetricSize Texture::_textureCPUMemSize; std::atomic Texture::_allowedCPUMemoryUsage { 0 }; - #define MIN_CORES_FOR_INCREMENTAL_TEXTURES 5 bool recommendedSparseTextures = (QThread::idealThreadCount() >= MIN_CORES_FOR_INCREMENTAL_TEXTURES); std::atomic Texture::_enableSparseTextures { recommendedSparseTextures }; +bool Texture::_generateIrradiance { true }; void Texture::setEnableSparseTextures(bool enabled) { #ifdef Q_OS_WIN diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 26ff86af9c..63cbd0bfed 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -550,7 +550,7 @@ public: void setUsage(const Usage& usage) { _usage = usage; } Usage getUsage() const { return _usage; } - // For Cube Texture, it's possible to generate the irradiance spherical harmonics and make them availalbe with the texture + // For Cube Texture, it's possible to generate the irradiance spherical harmonics and make them available with the texture bool generateIrradiance(gpu::BackendTarget target); const SHPointer& getIrradiance(uint16 slice = 0) const { return _irradiance; } void overrideIrradiance(SHPointer irradiance) { _irradiance = irradiance; } @@ -583,6 +583,8 @@ public: static bool evalTextureFormat(const ktx::Header& header, Element& mipFormat, Element& texelFormat); static bool getCompressedFormat(khronos::gl::texture::InternalFormat format, Element& elFormat); + static bool _generateIrradiance; + protected: const TextureUsageType _usageType; diff --git a/libraries/image/src/image/TextureProcessing.cpp b/libraries/image/src/image/TextureProcessing.cpp index 5b3d546f8e..edbe71a619 100644 --- a/libraries/image/src/image/TextureProcessing.cpp +++ b/libraries/image/src/image/TextureProcessing.cpp @@ -103,7 +103,7 @@ gpu::Element getHDRTextureFormatForTarget(BackendTarget target, bool compressed) } } -TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type, const QVariantMap& options) { +TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type) { switch (type) { case ALBEDO_TEXTURE: return image::TextureUsage::createAlbedoTextureFromImage; @@ -114,7 +114,7 @@ TextureUsage::TextureLoader TextureUsage::getTextureLoaderForType(Type type, con case SKY_TEXTURE: return image::TextureUsage::createCubeTextureFromImage; case AMBIENT_TEXTURE: - if (options.value("generateIrradiance", true).toBool()) { + if (Texture::_generateIrradiance) { return image::TextureUsage::createAmbientCubeTextureAndIrradianceFromImage; } else { return image::TextureUsage::createAmbientCubeTextureFromImage; @@ -388,7 +388,7 @@ gpu::TexturePointer processImage(std::shared_ptr content, const std:: if (sourceChannel != ColorChannel::NONE) { mapToRedChannel(image, sourceChannel); } - + auto loader = TextureUsage::getTextureLoaderForType(textureType); auto texture = loader(std::move(image), filename, compress, target, abortProcessing); diff --git a/libraries/image/src/image/TextureProcessing.h b/libraries/image/src/image/TextureProcessing.h index 6f93af1b29..a46a933d5a 100644 --- a/libraries/image/src/image/TextureProcessing.h +++ b/libraries/image/src/image/TextureProcessing.h @@ -76,7 +76,7 @@ enum Type { }; using TextureLoader = std::function&)>; -TextureLoader getTextureLoaderForType(Type type, const QVariantMap& options = QVariantMap()); +TextureLoader getTextureLoaderForType(Type type); gpu::TexturePointer create2DTextureFromImage(Image&& image, const std::string& srcImageName, bool compress, gpu::BackendTarget target, const std::atomic& abortProcessing); diff --git a/libraries/material-networking/src/material-networking/TextureCache.cpp b/libraries/material-networking/src/material-networking/TextureCache.cpp index 6ceb5d328a..05fda7b8cb 100644 --- a/libraries/material-networking/src/material-networking/TextureCache.cpp +++ b/libraries/material-networking/src/material-networking/TextureCache.cpp @@ -311,13 +311,13 @@ gpu::BackendTarget getBackendTarget() { } /// Returns a texture version of an image file -gpu::TexturePointer TextureCache::getImageTexture(const QString& path, image::TextureUsage::Type type, QVariantMap options) { +gpu::TexturePointer TextureCache::getImageTexture(const QString& path, image::TextureUsage::Type type) { QImage image = QImage(path); if (image.isNull()) { qCWarning(networking) << "Unable to load required resource texture" << path; return nullptr; } - auto loader = image::TextureUsage::getTextureLoaderForType(type, options); + auto loader = image::TextureUsage::getTextureLoaderForType(type); #ifdef USE_GLES constexpr bool shouldCompress = true; diff --git a/libraries/material-networking/src/material-networking/TextureCache.h b/libraries/material-networking/src/material-networking/TextureCache.h index f8ddd77412..a328622885 100644 --- a/libraries/material-networking/src/material-networking/TextureCache.h +++ b/libraries/material-networking/src/material-networking/TextureCache.h @@ -176,7 +176,7 @@ public: const gpu::TexturePointer& getBlackTexture(); /// Returns a texture version of an image file - static gpu::TexturePointer getImageTexture(const QString& path, image::TextureUsage::Type type = image::TextureUsage::DEFAULT_TEXTURE, QVariantMap options = QVariantMap()); + static gpu::TexturePointer getImageTexture(const QString& path, image::TextureUsage::Type type = image::TextureUsage::DEFAULT_TEXTURE); /// Loads a texture from the specified URL. NetworkTexturePointer getTexture(const QUrl& url, image::TextureUsage::Type type = image::TextureUsage::DEFAULT_TEXTURE, diff --git a/tools/oven/src/DomainBaker.cpp b/tools/oven/src/DomainBaker.cpp index 12e2a1bafb..b39d433693 100644 --- a/tools/oven/src/DomainBaker.cpp +++ b/tools/oven/src/DomainBaker.cpp @@ -198,10 +198,11 @@ void DomainBaker::addTextureBaker(const QString& property, const QString& url, i // setup a texture baker for this URL, as long as we aren't baking a texture already if (!_textureBakers.contains(key)) { + auto baseTextureFileName = _textureFileNamer.createBaseTextureFileName(textureURL.fileName(), type); // setup a baker for this texture QSharedPointer textureBaker { - new TextureBaker(textureURL, type, _contentOutputPath), + new TextureBaker(textureURL, type, _contentOutputPath, baseTextureFileName), &TextureBaker::deleteLater }; @@ -221,7 +222,8 @@ void DomainBaker::addTextureBaker(const QString& property, const QString& url, i // add this QJsonValueRef to our multi hash so that it can re-write the texture URL // to the baked version once the baker is complete - _entitiesNeedingRewrite.insert(textureURL, { property, jsonRef }); + // it doesn't really matter what this key is as long as it's consistent + _entitiesNeedingRewrite.insert(textureURL.toDisplayString() + type, { property, jsonRef }); } else { qDebug() << "Texture extension not supported: " << extension; } @@ -498,9 +500,11 @@ void DomainBaker::handleFinishedTextureBaker() { auto baker = qobject_cast(sender()); if (baker) { + QUrl rewriteKey = baker->getTextureURL().toDisplayString() + baker->getTextureType(); + if (!baker->hasErrors()) { // this TextureBaker is done and everything went according to plan - qDebug() << "Re-writing entity references to" << baker->getTextureURL(); + qDebug() << "Re-writing entity references to" << baker->getTextureURL() << "with usage" << baker->getTextureType(); // setup a new URL using the prefix we were passed auto relativeTextureFilePath = QDir(_contentOutputPath).relativeFilePath(baker->getMetaTextureFileName()); @@ -511,7 +515,7 @@ void DomainBaker::handleFinishedTextureBaker() { // enumerate the QJsonRef values for the URL of this texture from our multi hash of // entity objects needing a URL re-write - for (auto propertyEntityPair : _entitiesNeedingRewrite.values(baker->getTextureURL())) { + for (auto propertyEntityPair : _entitiesNeedingRewrite.values(rewriteKey)) { QString property = propertyEntityPair.first; // convert the entity QJsonValueRef to a QJsonObject so we can modify its URL auto entity = propertyEntityPair.second.toObject(); @@ -555,7 +559,7 @@ void DomainBaker::handleFinishedTextureBaker() { } // remove the baked URL from the multi hash of entities needing a re-write - _entitiesNeedingRewrite.remove(baker->getTextureURL()); + _entitiesNeedingRewrite.remove(rewriteKey); // drop our shared pointer to this baker so that it gets cleaned up _textureBakers.remove({ baker->getTextureURL(), baker->getTextureType() }); diff --git a/tools/oven/src/DomainBaker.h b/tools/oven/src/DomainBaker.h index 5887838f5c..b8903c5189 100644 --- a/tools/oven/src/DomainBaker.h +++ b/tools/oven/src/DomainBaker.h @@ -63,6 +63,7 @@ private: QHash> _modelBakers; QHash> _textureBakers; + TextureFileNamer _textureFileNamer; QHash> _scriptBakers; QHash> _materialBakers; diff --git a/tools/oven/src/Oven.cpp b/tools/oven/src/Oven.cpp index a680dd1f89..2dcf632867 100644 --- a/tools/oven/src/Oven.cpp +++ b/tools/oven/src/Oven.cpp @@ -52,6 +52,9 @@ Oven::Oven() { modelFormatRegistry->addFormat(FBXSerializer()); modelFormatRegistry->addFormat(OBJSerializer()); } + + // We only need to generate irradiance at runtime + gpu::Texture::_generateIrradiance = false; } Oven::~Oven() { diff --git a/tools/oven/src/ui/SkyboxBakeWidget.cpp b/tools/oven/src/ui/SkyboxBakeWidget.cpp index 6c6e0340ac..8ce62e9292 100644 --- a/tools/oven/src/ui/SkyboxBakeWidget.cpp +++ b/tools/oven/src/ui/SkyboxBakeWidget.cpp @@ -202,7 +202,7 @@ void SkyboxBakeWidget::bakeButtonClicked() { ambientMapBaseFilename = QUrl(urlParts.front()).fileName(); // we need to bake the corresponding ambient map too - addBaker(new TextureBaker(skyboxToBakeURL, image::TextureUsage::AMBIENT_TEXTURE, outputDirectory.absolutePath(), QString(), ambientMapBaseFilename), + addBaker(new TextureBaker(skyboxToBakeURL, image::TextureUsage::AMBIENT_TEXTURE, outputDirectory.absolutePath(), ambientMapBaseFilename), outputDirectory); } }