simplifying material baker and support bump/gloss maps

This commit is contained in:
SamGondelman 2019-04-01 22:35:28 -07:00
parent cf4d864e7c
commit 75a246b82d
5 changed files with 27 additions and 49 deletions

View file

@ -27,15 +27,6 @@ std::function<QThread*()> MaterialBaker::_getNextOvenWorkerThreadOperator;
static int materialNum = 0;
namespace std {
template <>
struct hash<graphics::Material::MapChannel> {
size_t operator()(const graphics::Material::MapChannel& a) const {
return std::hash<size_t>()((size_t)a);
}
};
};
MaterialBaker::MaterialBaker(const QString& materialData, bool isURL, const QString& bakedOutputDir, const QUrl& destinationPath) :
_materialData(materialData),
_isURL(isURL),
@ -112,13 +103,15 @@ void MaterialBaker::processMaterial() {
for (auto networkMaterial : _materialResource->parsedMaterials.networkMaterials) {
if (networkMaterial.second) {
auto textureMaps = networkMaterial.second->getTextureMaps();
for (auto textureMap : textureMaps) {
if (textureMap.second && textureMap.second->getTextureSource()) {
graphics::Material::MapChannel mapChannel = textureMap.first;
auto texture = textureMap.second->getTextureSource();
auto textures = networkMaterial.second->getTextures();
for (auto texturePair : textures) {
auto mapChannel = texturePair.first;
auto textureMap = texturePair.second;
if (textureMap.texture && textureMap.texture->_textureSource) {
auto textureSource = textureMap.texture->_textureSource;
auto type = textureMap.texture->getTextureType();
QUrl url = texture->getUrl();
QUrl url = textureSource->getUrl();
QString cleanURL = url.adjusted(QUrl::RemoveQuery | QUrl::RemoveFragment).toDisplayString();
auto idx = cleanURL.lastIndexOf('.');
auto extension = idx >= 0 ? url.toDisplayString().mid(idx + 1).toLower() : "";
@ -126,41 +119,22 @@ void MaterialBaker::processMaterial() {
if (QImageReader::supportedImageFormats().contains(extension.toLatin1())) {
QUrl textureURL = url.adjusted(QUrl::RemoveQuery | QUrl::RemoveFragment);
// FIXME: this isn't properly handling bumpMaps or glossMaps
static std::unordered_map<graphics::Material::MapChannel, image::TextureUsage::Type> MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP;
if (MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP.empty()) {
MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP[graphics::Material::MapChannel::EMISSIVE_MAP] = image::TextureUsage::EMISSIVE_TEXTURE;
MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP[graphics::Material::MapChannel::ALBEDO_MAP] = image::TextureUsage::ALBEDO_TEXTURE;
MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP[graphics::Material::MapChannel::METALLIC_MAP] = image::TextureUsage::METALLIC_TEXTURE;
MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP[graphics::Material::MapChannel::ROUGHNESS_MAP] = image::TextureUsage::ROUGHNESS_TEXTURE;
MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP[graphics::Material::MapChannel::NORMAL_MAP] = image::TextureUsage::NORMAL_TEXTURE;
MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP[graphics::Material::MapChannel::OCCLUSION_MAP] = image::TextureUsage::OCCLUSION_TEXTURE;
MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP[graphics::Material::MapChannel::LIGHTMAP_MAP] = image::TextureUsage::LIGHTMAP_TEXTURE;
MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP[graphics::Material::MapChannel::SCATTERING_MAP] = image::TextureUsage::SCATTERING_TEXTURE;
}
auto it = MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP.find(mapChannel);
if (it == MAP_CHANNEL_TO_TEXTURE_USAGE_TYPE_MAP.end()) {
handleError("Unknown map channel");
return;
}
QPair<QUrl, image::TextureUsage::Type> textureKey(textureURL, it->second);
QPair<QUrl, image::TextureUsage::Type> textureKey(textureURL, type);
if (!_textureBakers.contains(textureKey)) {
auto baseTextureFileName = _textureFileNamer.createBaseTextureFileName(textureURL.fileName(), it->second);
auto baseTextureFileName = _textureFileNamer.createBaseTextureFileName(textureURL.fileName(), type);
QByteArray content;
{
auto textureContentMapIter = _textureContentMap.find(networkMaterial.second->getName());
if (textureContentMapIter != _textureContentMap.end()) {
auto textureUsageIter = textureContentMapIter->second.find(it->second);
auto textureUsageIter = textureContentMapIter->second.find(type);
if (textureUsageIter != textureContentMapIter->second.end()) {
content = textureUsageIter->second;
}
}
}
QSharedPointer<TextureBaker> textureBaker {
new TextureBaker(textureURL, it->second, _textureOutputDir, "", baseTextureFileName, content),
new TextureBaker(textureURL, type, _textureOutputDir, "", baseTextureFileName, content),
&TextureBaker::deleteLater
};
textureBaker->setMapChannel(mapChannel);
@ -169,7 +143,6 @@ void MaterialBaker::processMaterial() {
textureBaker->moveToThread(_getNextOvenWorkerThreadOperator ? _getNextOvenWorkerThreadOperator() : thread());
QMetaObject::invokeMethod(textureBaker.data(), "bake");
}
// FIXME: we need to detect when our material has opacity and output the opacityMap
_materialsNeedingRewrite.insert(textureKey, networkMaterial.second);
} else {
qCDebug(material_baking) << "Texture extension not supported: " << extension;

View file

@ -559,8 +559,7 @@ void NetworkMaterial::setLightmapMap(const QUrl& url) {
}
NetworkMaterial::NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl) :
graphics::Material(*material._material),
_textures(MapChannel::NUM_MAP_CHANNELS)
graphics::Material(*material._material)
{
_name = material.name.toStdString();
if (!material.albedoTexture.filename.isEmpty()) {
@ -709,7 +708,7 @@ void NetworkMaterial::setTextures(const QVariantMap& textureMap) {
bool NetworkMaterial::isMissingTexture() {
for (auto& networkTexture : _textures) {
auto& texture = networkTexture.texture;
auto& texture = networkTexture.second.texture;
if (!texture) {
continue;
}

View file

@ -36,15 +36,21 @@ public:
bool isMissingTexture();
void checkResetOpacityMap();
protected:
friend class Geometry;
class Texture {
public:
QString name;
NetworkTexturePointer texture;
};
using Textures = std::vector<Texture>;
struct MapChannelHash {
std::size_t operator()(MapChannel mapChannel) const {
return static_cast<std::size_t>(mapChannel);
}
};
using Textures = std::unordered_map<MapChannel, Texture, MapChannelHash>;
Textures getTextures() { return _textures; }
protected:
friend class Geometry;
Textures _textures;

View file

@ -437,8 +437,8 @@ const QVariantMap Geometry::getTextures() const {
QVariantMap textures;
for (const auto& material : _materials) {
for (const auto& texture : material->_textures) {
if (texture.texture) {
textures[texture.name] = texture.texture->getURL();
if (texture.second.texture) {
textures[texture.second.name] = texture.second.texture->getURL();
}
}
}
@ -467,7 +467,7 @@ void Geometry::setTextures(const QVariantMap& textureMap) {
for (auto& material : _materials) {
// Check if any material textures actually changed
if (std::any_of(material->_textures.cbegin(), material->_textures.cend(),
[&textureMap](const NetworkMaterial::Textures::value_type& it) { return it.texture && textureMap.contains(it.name); })) {
[&textureMap](const NetworkMaterial::Textures::value_type& it) { return it.second.texture && textureMap.contains(it.second.name); })) {
// FIXME: The Model currently caches the materials (waste of space!)
// so they must be copied in the Geometry copy-ctor