Support occlusion texture all the way.

By oversight we had not included occlusionTexture in the core
MaterialData. While we're at it, bake occlusion into the red channel of
the merged metallic/roughness texture.
This commit is contained in:
Par Winzell 2018-02-25 18:33:11 -08:00
parent 6732ba4a6e
commit 3fdc41843b
3 changed files with 39 additions and 11 deletions

View File

@ -635,8 +635,9 @@ ModelData *Raw2Gltf(
return (material.textures[usage] >= 0) ? getSimpleTexture(material.textures[usage], "simple") : nullptr;
};
TextureData *normalTexture = simpleTex(RAW_TEXTURE_USAGE_NORMAL).get();
TextureData *normalTexture = simpleTex(RAW_TEXTURE_USAGE_NORMAL).get();
TextureData *emissiveTexture = simpleTex(RAW_TEXTURE_USAGE_EMISSIVE).get();
TextureData *occlusionTexture = nullptr;
// acquire derived texture of two RawTextureUsage as *TextData, or nullptr if neither exists
auto merge2Tex = [&](
@ -651,10 +652,24 @@ ModelData *Raw2Gltf(
combine, tag, outputHasAlpha);
};
// acquire derived texture of two RawTextureUsage as *TextData, or nullptr if neither exists
auto merge3Tex = [&](
const std::string tag,
RawTextureUsage u1,
RawTextureUsage u2,
RawTextureUsage u3,
const pixel_merger &combine,
bool outputHasAlpha
) -> std::shared_ptr<TextureData> {
return getDerivedTexture(
{ material.textures[u1], material.textures[u2], material.textures[u3] },
combine, tag, outputHasAlpha);
};
std::shared_ptr<PBRMetallicRoughness> pbrMetRough;
if (options.usePBRMetRough) {
// albedo is a basic texture, no merging needed
std::shared_ptr<TextureData> baseColorTex, metRoughTex;
std::shared_ptr<TextureData> baseColorTex, aoMetRoughTex;
Vec4f diffuseFactor;
float metallic, roughness;
@ -667,9 +682,11 @@ ModelData *Raw2Gltf(
*/
RawMetRoughMatProps *props = (RawMetRoughMatProps *) material.info.get();
// merge metallic into the blue channel and roughness into the green, of a new combinatory texture
metRoughTex = merge2Tex("met_rough",
RAW_TEXTURE_USAGE_METALLIC, RAW_TEXTURE_USAGE_ROUGHNESS,
[&](const std::vector<const pixel *> pixels) -> pixel { return { 0, (*pixels[1])[0], (*pixels[0])[0], 0 }; },
aoMetRoughTex = merge3Tex("ao_met_rough",
RAW_TEXTURE_USAGE_OCCLUSION, RAW_TEXTURE_USAGE_METALLIC, RAW_TEXTURE_USAGE_ROUGHNESS,
[&](const std::vector<const pixel *> pixels) -> pixel {
return { (*pixels[0])[0], (*pixels[2])[0], (*pixels[1])[0], 0 };
},
false);
baseColorTex = simpleTex(RAW_TEXTURE_USAGE_ALBEDO);
diffuseFactor = props->diffuseFactor;
@ -677,6 +694,10 @@ ModelData *Raw2Gltf(
roughness = props->roughness;
emissiveFactor = props->emissiveFactor;
emissiveIntensity = props->emissiveIntensity;
// add the occlusion texture only if actual occlusion pixels exist in the aoNetRough texture.
if (material.textures[RAW_TEXTURE_USAGE_OCCLUSION] >= 0) {
occlusionTexture = aoMetRoughTex.get();
}
} else {
/**
* Traditional FBX Material -> PBR Met/Rough glTF.
@ -697,10 +718,9 @@ ModelData *Raw2Gltf(
emissiveFactor = props->emissiveFactor;
emissiveIntensity = 1.0f;
}
pbrMetRough.reset(new PBRMetallicRoughness(baseColorTex.get(), metRoughTex.get(), diffuseFactor, metallic, roughness));
pbrMetRough.reset(new PBRMetallicRoughness(baseColorTex.get(), aoMetRoughTex.get(), diffuseFactor, metallic, roughness));
}
std::shared_ptr<KHRCmnUnlitMaterial> khrCmnUnlitMat;
if (options.useKHRMatUnlit) {
normalTexture = nullptr;
@ -725,13 +745,14 @@ ModelData *Raw2Gltf(
khrCmnUnlitMat.reset(new KHRCmnUnlitMaterial());
}
if (!occlusionTexture) {
occlusionTexture = simpleTex(RAW_TEXTURE_USAGE_OCCLUSION).get();
}
std::shared_ptr<MaterialData> mData = gltf->materials.hold(
new MaterialData(
material.name, isTransparent,
normalTexture, emissiveTexture,
emissiveFactor * emissiveIntensity,
khrCmnUnlitMat, pbrMetRough));
material.name, isTransparent, normalTexture, occlusionTexture, emissiveTexture,
emissiveFactor * emissiveIntensity, khrCmnUnlitMat, pbrMetRough));
materialsByName[materialHash(material)] = mData;
}

View File

@ -80,6 +80,7 @@ void to_json(json &j, const PBRMetallicRoughness &d)
MaterialData::MaterialData(
std::string name, bool isTransparent, const TextureData *normalTexture,
const TextureData *occlusionTexture,
const TextureData *emissiveTexture, const Vec3f & emissiveFactor,
std::shared_ptr<KHRCmnUnlitMaterial> const khrCmnConstantMaterial,
std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness)
@ -87,6 +88,7 @@ MaterialData::MaterialData(
name(std::move(name)),
isTransparent(isTransparent),
normalTexture(Tex::ref(normalTexture)),
occlusionTexture(Tex::ref(occlusionTexture)),
emissiveTexture(Tex::ref(emissiveTexture)),
emissiveFactor(clamp(emissiveFactor)),
khrCmnConstantMaterial(khrCmnConstantMaterial),
@ -102,6 +104,9 @@ json MaterialData::serialize() const
if (normalTexture != nullptr) {
result["normalTexture"] = *normalTexture;
}
if (occlusionTexture != nullptr) {
result["occlusionTexture"] = *occlusionTexture;
}
if (emissiveTexture != nullptr) {
result["emissiveTexture"] = *emissiveTexture;
}

View File

@ -45,6 +45,7 @@ struct MaterialData : Holdable
{
MaterialData(
std::string name, bool isTransparent, const TextureData *normalTexture,
const TextureData *occlusionTexture,
const TextureData *emissiveTexture, const Vec3f &emissiveFactor,
std::shared_ptr<KHRCmnUnlitMaterial> const khrCmnConstantMaterial,
std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness);
@ -54,6 +55,7 @@ struct MaterialData : Holdable
const std::string name;
const bool isTransparent;
const std::unique_ptr<const Tex> normalTexture;
const std::unique_ptr<const Tex> occlusionTexture;
const std::unique_ptr<const Tex> emissiveTexture;
const Vec3f emissiveFactor;