Clean house in material extensions.

- KHR_materials_common never had a real life in the glTF 2.0 world. One
day we may see a new extension for Phong/Blinn/Lambert.
- PBR_specular_glossiness is a poor fit for PBS StingRay (the only real
source of PBR we have) and has no advantage over PBR_metallic_roughness.
- The conversion we were doing for traditional materials to PBR made no
sense. Revert to a very simple formula: diffuse -> baseColor, simple
reasonable constants for metallic & roughness.
This commit is contained in:
Par Winzell 2018-02-19 08:57:19 -08:00
parent 67bb9372d7
commit 7c0715c4ad
7 changed files with 44 additions and 421 deletions

View File

@ -624,13 +624,15 @@ ModelData *Raw2Gltf(
float emissiveIntensity;
const Vec3f dielectric(0.04f, 0.04f, 0.04f);
const float epsilon = 1e-6f;
// acquire the texture of a specific RawTextureUsage as *TextData, or nullptr if none exists
auto simpleTex = [&](RawTextureUsage usage) -> std::shared_ptr<TextureData> {
return (material.textures[usage] >= 0) ? getSimpleTexture(material.textures[usage], "simple") : nullptr;
};
TextureData *normalTexture = simpleTex(RAW_TEXTURE_USAGE_NORMAL).get();
TextureData *emissiveTexture = simpleTex(RAW_TEXTURE_USAGE_EMISSIVE).get();
// acquire derived texture of two RawTextureUsage as *TextData, or nullptr if neither exists
auto merge2Tex = [&](
const std::string tag,
@ -658,19 +660,6 @@ ModelData *Raw2Gltf(
combine, tag, outputHasAlpha);
};
auto getMaxComponent = [&](const Vec3f &color) {
return fmax(color.x, fmax(color.y, color.z));
};
auto getPerceivedBrightness = [&](const Vec3f &color) {
return sqrt(0.299 * color.x * color.x + 0.587 * color.y * color.y + 0.114 * color.z * color.z);
};
auto toVec3f = [&](const pixel &pix) -> const Vec3f {
return Vec3f(pix[0], pix[1], pix[2]);
};
auto toVec4f = [&](const pixel &pix) -> const Vec4f {
return Vec4f(pix[0], pix[1], pix[2], pix[3]);
};
std::shared_ptr<PBRMetallicRoughness> pbrMetRough;
if (options.usePBRMetRough) {
// albedo is a basic texture, no merging needed
@ -701,212 +690,25 @@ ModelData *Raw2Gltf(
/**
* Traditional FBX Material -> PBR Met/Rough glTF.
*
* Diffuse channel is used as base colour.
* Diffuse channel is used as base colour. Simple constants for metallic and roughness.
*/
const RawTraditionalMatProps *props = ((RawTraditionalMatProps *) material.info.get());
diffuseFactor = props->diffuseFactor;
// TODO: make configurable on the command line, or do a better job guessing from other, supplied params
if (material.info->shadingModel == RAW_SHADING_MODEL_LAMBERT) {
metallic = 0.6f;
roughness = 1.0f;
} else {
metallic = 0.2f;
roughness = 0.8f;
} else {
metallic = 0.4f;
roughness = 0.6f;
}
auto solveMetallic = [&](float pDiff, float pSpec, float oneMinusSpecularStrength)
{
if (pSpec < dielectric.x) {
return 0.0;
}
baseColorTex = simpleTex(RAW_TEXTURE_USAGE_DIFFUSE);
float a = dielectric.x;
float b = pDiff * oneMinusSpecularStrength / (1 - dielectric.x) + pSpec - 2 * dielectric.x;
float c = dielectric.x - pSpec;
float D = fmax(b * b - 4 * a * c, 0);
return fmax(0.0, fmin(1.0, (-b + sqrt(D)) / (2 * a)));
};
metRoughTex = merge3Tex("rough_met",
RAW_TEXTURE_USAGE_SPECULAR, RAW_TEXTURE_USAGE_SHININESS, RAW_TEXTURE_USAGE_DIFFUSE,
[&](const std::vector<const pixel *> pixels) -> pixel {
const Vec3f specular = Vec3f(0.4f, 0.4f, 0.4f) +
0.2f * (pixels[0] ? toVec3f(*pixels[0]) : props->specularFactor);
float shininess = pixels[1] ? (*pixels[1])[0] : props->shininess;
const Vec4f diffuse = pixels[2] ? toVec4f(*pixels[2]) : props->diffuseFactor;
float pixelMet = solveMetallic(
getPerceivedBrightness(diffuse.xyz()),
getPerceivedBrightness(specular),
1 - getMaxComponent(specular));
float pixelRough = 1 - shininess;
return { 0, pixelRough, pixelMet, 0 };
}, false);
if (material.textures[RAW_TEXTURE_USAGE_DIFFUSE] >= 0) {
const RawTexture &diffuseTex = raw.GetTexture(material.textures[RAW_TEXTURE_USAGE_DIFFUSE]);
baseColorTex = merge2Tex("base_col", RAW_TEXTURE_USAGE_DIFFUSE, RAW_TEXTURE_USAGE_SPECULAR,
[&](const std::vector<const pixel *> pixels) -> pixel {
const Vec4f diffuse = pixels[0] ? toVec4f(*pixels[0]) : props->diffuseFactor;
const Vec3f specular = Vec3f(0.4f, 0.4f, 0.4f) +
0.2f * (pixels[1] ? toVec3f(*pixels[1]) : props->specularFactor);
float oneMinus = 1 - getMaxComponent(specular);
float pixelMet = solveMetallic(
getPerceivedBrightness(diffuse.xyz()),
getPerceivedBrightness(specular),
oneMinus);
Vec3f fromDiffuse = diffuse.xyz() * (oneMinus / (1.0f - dielectric.x) / fmax(1.0f - pixelMet, epsilon));
Vec3f fromSpecular = specular - dielectric * (1.0f - pixelMet) * (1.0f / fmax(pixelMet, epsilon));
Vec3f baseColor = Vec3f::Lerp(fromDiffuse, fromSpecular, pixelMet * pixelMet);
return { baseColor[0], baseColor[1], baseColor[2], diffuse[3] };
}, diffuseTex.occlusion == RAW_TEXTURE_OCCLUSION_TRANSPARENT);
}
emissiveFactor = props->emissiveFactor;
emissiveIntensity = 1.0f;
}
pbrMetRough.reset(new PBRMetallicRoughness(baseColorTex.get(), metRoughTex.get(), diffuseFactor, metallic, roughness));
}
std::shared_ptr<PBRSpecularGlossiness> pbrSpecGloss;
if (options.usePBRSpecGloss) {
Vec4f diffuseFactor;
Vec3f specularFactor;
float glossiness;
std::shared_ptr<TextureData> specGlossTex;
std::shared_ptr<TextureData> diffuseTex;
const Vec3f dielectric(0.04f, 0.04f, 0.04f);
const float epsilon = 1e-6f;
if (material.info->shadingModel == RAW_SHADING_MODEL_PBR_MET_ROUGH) {
/**
* PBR FBX Material -> PBR Spec/Gloss glTF.
*
* TODO: A complete mess. Low priority.
*/
RawMetRoughMatProps *props = (RawMetRoughMatProps *) material.info.get();
// we can estimate spec/gloss from met/rough by between Vec4f(0.04, 0.04, 0.04) and baseColor
// according to metalness, and then taking gloss to be the inverse of roughness
specGlossTex = merge3Tex("specgloss",
RAW_TEXTURE_USAGE_ALBEDO, RAW_TEXTURE_USAGE_METALLIC, RAW_TEXTURE_USAGE_ROUGHNESS,
[&](const std::vector<const pixel *> pixels) -> pixel {
Vec3f baseColor(1.0f);
if (pixels[0]) {
baseColor.x = (*pixels[0])[0];
baseColor.y = (*pixels[0])[1];
baseColor.z = (*pixels[0])[2];
}
float metallic = pixels[1] ? (*pixels[1])[0] : 1.0f;
float roughness = pixels[2] ? (*pixels[2])[0] : 1.0f;
Vec3f spec = Vec3f::Lerp(dielectric, baseColor, metallic);
return { spec[0], spec[1], spec[2], 1.0f - roughness };
}, false);
diffuseTex = merge2Tex("albedo",
RAW_TEXTURE_USAGE_ALBEDO, RAW_TEXTURE_USAGE_METALLIC,
[&](const std::vector<const pixel *> pixels) -> pixel {
Vec3f baseColor(1.0f);
float alpha = 1.0f;
if (pixels[0]) {
baseColor[0] = (*pixels[0])[0];
baseColor[1] = (*pixels[0])[1];
baseColor[2] = (*pixels[0])[2];
alpha = (*pixels[0])[3];
}
float metallic = pixels[1] ? (*pixels[1])[0] : 1.0f;
Vec3f spec = Vec3f::Lerp(dielectric, baseColor, metallic);
float maxSpecComp = fmax(fmax(spec.x, spec.y), spec.z);
// attenuate baseColor to get specgloss-compliant diffuse; for details consult
// https://github.com/KhronosGroup/glTF/tree/master/extensions/Khronos/KHR_materials_pbrSpecularGlossiness
Vec3f diffuse = baseColor * (1 - dielectric[0]) * (1 - metallic) * fmax(1.0f - maxSpecComp, epsilon);
return { diffuse[0], diffuse[1], diffuse[2], alpha };
}, true);
diffuseFactor = props->diffuseFactor;
specularFactor = Vec3f::Lerp(dielectric, props->diffuseFactor.xyz(), props->metallic);
glossiness = 1.0f - props->roughness;
} else {
/**
* Traditional FBX Material -> PBR Spec/Gloss glTF.
*
* TODO: A complete mess. Low priority.
*/
// TODO: this section a ludicrous over-simplifictation; we can surely do better.
const RawTraditionalMatProps *props = ((RawTraditionalMatProps *) material.info.get());
specGlossTex = merge2Tex("specgloss",
RAW_TEXTURE_USAGE_SPECULAR, RAW_TEXTURE_USAGE_SHININESS,
[&](const std::vector<const pixel *> pixels) -> pixel {
const auto &spec = *(pixels[0]);
const auto &shine = *(pixels[1]);
return { spec[0], spec[1], spec[2], shine[0] };
}, false);
diffuseTex = simpleTex(RAW_TEXTURE_USAGE_DIFFUSE);
diffuseFactor = props->diffuseFactor;
specularFactor = props->specularFactor;
glossiness = props->shininess;
}
pbrSpecGloss.reset(
new PBRSpecularGlossiness(
diffuseTex.get(), diffuseFactor, specGlossTex.get(), specularFactor, glossiness));
}
TextureData *normalTexture = simpleTex(RAW_TEXTURE_USAGE_NORMAL).get();
TextureData *emissiveTexture = simpleTex(RAW_TEXTURE_USAGE_EMISSIVE).get();
std::shared_ptr<KHRCommonMats> khrComMat;
if (options.useKHRMatCom) {
float shininess;
Vec3f ambientFactor, specularFactor;
Vec4f diffuseFactor;
std::shared_ptr<TextureData> diffuseTex;
auto type = KHRCommonMats::MaterialType::Constant;
if (material.info->shadingModel == RAW_SHADING_MODEL_PBR_MET_ROUGH) {
/**
* PBR FBX Material -> KHR Common Materials glTF.
*
* TODO: We can use the specularFactor calculation below to generate a reasonable specular map, too.
*/
const RawMetRoughMatProps *props = (RawMetRoughMatProps *) material.info.get();
shininess = 1.0f - props->roughness;
ambientFactor = Vec3f(0.0f, 0.0f, 0.0f);
diffuseTex = simpleTex(RAW_TEXTURE_USAGE_ALBEDO);
diffuseFactor = props->diffuseFactor;
specularFactor = Vec3f::Lerp(Vec3f(0.04f, 0.04f, 0.04f), props->diffuseFactor.xyz(), props->metallic);
// render as Phong if there's any specularity, otherwise Lambert
type = (specularFactor.LengthSquared() > 1e-4) ?
KHRCommonMats::MaterialType::Phong : KHRCommonMats::MaterialType::Lambert;
// TODO: convert textures
} else {
/**
* Traditional FBX Material -> KHR Common Materials glTF.
*
* Should be in good shape. Essentially pass-through.
*/
const RawTraditionalMatProps *props = (RawTraditionalMatProps *) material.info.get();
shininess = props->shininess;
ambientFactor = props->ambientFactor;
diffuseTex = simpleTex(RAW_TEXTURE_USAGE_DIFFUSE);
diffuseFactor = props->diffuseFactor;
specularFactor = props->specularFactor;
if (material.info->shadingModel == RAW_SHADING_MODEL_LAMBERT) {
type = KHRCommonMats::MaterialType::Lambert;
} else if (material.info->shadingModel == RAW_SHADING_MODEL_BLINN) {
type = KHRCommonMats::MaterialType::Blinn;
} else if (material.info->shadingModel == RAW_SHADING_MODEL_PHONG) {
type = KHRCommonMats::MaterialType::Phong;
}
}
khrComMat.reset(
new KHRCommonMats(type,
simpleTex(RAW_TEXTURE_USAGE_SHININESS).get(), shininess,
simpleTex(RAW_TEXTURE_USAGE_AMBIENT).get(), ambientFactor,
diffuseTex.get(), diffuseFactor,
simpleTex(RAW_TEXTURE_USAGE_SPECULAR).get(), specularFactor));
}
std::shared_ptr<KHRCmnUnlitMaterial> khrCmnUnlitMat;
if (options.useKHRMatUnlit) {
@ -938,7 +740,7 @@ ModelData *Raw2Gltf(
material.name, isTransparent,
normalTexture, emissiveTexture,
emissiveFactor * emissiveIntensity,
khrComMat, khrCmnUnlitMat, pbrMetRough, pbrSpecGloss));
khrCmnUnlitMat, pbrMetRough));
materialsByName[materialHash(material)] = mData;
}
@ -1209,21 +1011,9 @@ ModelData *Raw2Gltf(
{
std::vector<std::string> extensionsUsed, extensionsRequired;
if (options.useKHRMatCom) {
extensionsUsed.push_back(KHR_MATERIALS_COMMON);
if (!options.usePBRSpecGloss && !options.usePBRMetRough) {
extensionsRequired.push_back(KHR_MATERIALS_COMMON);
}
}
if (options.useKHRMatUnlit) {
extensionsUsed.push_back(KHR_MATERIALS_CMN_UNLIT);
}
if (options.usePBRSpecGloss) {
extensionsUsed.push_back(KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS);
if (!options.useKHRMatCom && !options.usePBRMetRough) {
extensionsRequired.push_back(KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS);
}
}
if (options.useDraco) {
extensionsUsed.push_back(KHR_DRACO_MESH_COMPRESSION);
extensionsRequired.push_back(KHR_DRACO_MESH_COMPRESSION);

View File

@ -28,12 +28,10 @@ using json = nlohmann::basic_json<workaround_fifo_map>;
#include "FBX2glTF.h"
#include "RawModel.h"
static const std::string KHR_DRACO_MESH_COMPRESSION = "KHR_draco_mesh_compression";
static const std::string KHR_MATERIALS_COMMON = "KHR_materials_common";
static const std::string KHR_MATERIALS_CMN_UNLIT = "KHR_materials_unlit";
static const std::string KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS = "KHR_materials_pbrSpecularGlossiness";
const std::string KHR_DRACO_MESH_COMPRESSION = "KHR_draco_mesh_compression";
const std::string KHR_MATERIALS_CMN_UNLIT = "KHR_materials_unlit";
static const std::string extBufferFilename = "buffer.bin";
const std::string extBufferFilename = "buffer.bin";
struct ComponentType {
// OpenGL Datatype enums
@ -52,8 +50,8 @@ struct ComponentType {
const unsigned int size;
};
static const ComponentType CT_USHORT = {ComponentType::GL_UNSIGNED_SHORT, 2};
static const ComponentType CT_FLOAT = {ComponentType::GL_FLOAT, 4};
const ComponentType CT_USHORT = {ComponentType::GL_UNSIGNED_SHORT, 2};
const ComponentType CT_FLOAT = {ComponentType::GL_FLOAT, 4};
// Map our low-level data types for glTF output
struct GLType {
@ -101,16 +99,16 @@ struct GLType {
const std::string dataType;
};
static const GLType GLT_FLOAT = {CT_FLOAT, 1, "SCALAR"};
static const GLType GLT_USHORT = {CT_USHORT, 1, "SCALAR"};
static const GLType GLT_VEC2F = {CT_FLOAT, 2, "VEC2"};
static const GLType GLT_VEC3F = {CT_FLOAT, 3, "VEC3"};
static const GLType GLT_VEC4F = {CT_FLOAT, 4, "VEC4"};
static const GLType GLT_VEC4I = {CT_USHORT, 4, "VEC4"};
static const GLType GLT_MAT2F = {CT_USHORT, 4, "MAT2"};
static const GLType GLT_MAT3F = {CT_USHORT, 9, "MAT3"};
static const GLType GLT_MAT4F = {CT_FLOAT, 16, "MAT4"};
static const GLType GLT_QUATF = {CT_FLOAT, 4, "VEC4"};
const GLType GLT_FLOAT = {CT_FLOAT, 1, "SCALAR"};
const GLType GLT_USHORT = {CT_USHORT, 1, "SCALAR"};
const GLType GLT_VEC2F = {CT_FLOAT, 2, "VEC2"};
const GLType GLT_VEC3F = {CT_FLOAT, 3, "VEC3"};
const GLType GLT_VEC4F = {CT_FLOAT, 4, "VEC4"};
const GLType GLT_VEC4I = {CT_USHORT, 4, "VEC4"};
const GLType GLT_MAT2F = {CT_USHORT, 4, "MAT2"};
const GLType GLT_MAT3F = {CT_USHORT, 9, "MAT3"};
const GLType GLT_MAT4F = {CT_FLOAT, 16, "MAT4"};
const GLType GLT_QUATF = {CT_FLOAT, 4, "VEC4"};
/**
* The base of any indexed glTF entity.

View File

@ -337,6 +337,8 @@ void RawModel::TransformGeometry(ComputeNormalsOption normals)
case BROKEN:
case ALWAYS:
size_t computedNormalsCount = this->CalculateNormals(normals == ComputeNormalsOption::BROKEN);
vertexAttributes |= RAW_VERTEX_ATTRIBUTE_NORMAL;
if (verboseOutput) {
if (normals == ComputeNormalsOption::BROKEN) {
fmt::printf("Repaired %lu empty normals.\n", computedNormalsCount);
@ -572,13 +574,18 @@ Vec3f RawModel::getFaceNormal(int verts[3]) const
const Vec3f e0 = vertices[verts[(index + 1) % 3]].position - vertices[verts[index]].position;
const Vec3f e1 = vertices[verts[(index + 2) % 3]].position - vertices[verts[index]].position;
auto result = Vec3f::CrossProduct(e0, e1);
if (result.LengthSquared() < FLT_MIN) {
if (e0.LengthSquared() < FLT_MIN || e1.LengthSquared() < FLT_MIN) {
return Vec3f { 0.0f };
}
result.Normalize();
return result;
auto result = Vec3f::CrossProduct(e0, e1);
auto resultLengthSquared = result.LengthSquared();
if (resultLengthSquared < FLT_MIN) {
return Vec3f { 0.0f };
}
float edgeDot = std::max(-1.0f, std::min(1.0f, Vec3f::DotProduct(e0, e1)));
float angle = acos(edgeDot);
float area = resultLengthSquared / 2.0f;
return result.Normalized() * angle * area;
}
size_t RawModel::CalculateNormals(bool onlyBroken)

View File

@ -42,14 +42,10 @@ struct GltfOptions
bool embedResources { false };
/** Whether to use KHR_draco_mesh_compression to minimize static geometry size. */
bool useDraco { false };
/** Whether to use KHR_materials_common to extend materials definitions. */
bool useKHRMatCom { false };
/** Whether to use KHR_materials_unlit to extend materials definitions. */
bool useKHRMatUnlit { false };
/** Whether to populate the pbrMetallicRoughness substruct in materials. */
bool usePBRMetRough { false };
/** Whether to use KHR_materials_pbrSpecularGlossiness to extend material definitions. */
bool usePBRSpecGloss { false };
/** Whether to include blend shape normals, if present according to the SDK. */
bool useBlendShapeNormals { false };
/** Whether to include blend shape tangents, if present according to the SDK. */

View File

@ -27,72 +27,6 @@ void to_json(json &j, const Tex &data) {
};
}
static inline Vec4f toRGBA(const Vec3f &colour, float alpha = 1) {
return { colour[0], colour[1], colour[2], alpha };
};
KHRCommonMats::KHRCommonMats(
MaterialType type,
const TextureData *shininessTexture, float shininess,
const TextureData *ambientTexture, const Vec3f &ambientFactor,
const TextureData *diffuseTexture, const Vec4f &diffuseFactor,
const TextureData *specularTexture, const Vec3f &specularFactor)
: type(type),
shininessTexture(Tex::ref(shininessTexture)),
shininess(shininess),
ambientTexture(Tex::ref(ambientTexture)),
ambientFactor(ambientFactor),
diffuseTexture(Tex::ref(diffuseTexture)),
diffuseFactor(diffuseFactor),
specularTexture(Tex::ref(specularTexture)),
specularFactor(specularFactor)
{
}
std::string KHRCommonMats::typeDesc(MaterialType type)
{
switch (type) {
case Blinn:
return "commonBlinn";
case Phong:
return "commonPhong";
case Lambert:
return "commonLambert";
case Constant:
return "commonConstant";
}
}
void to_json(json &j, const KHRCommonMats &d)
{
j = {{"type", KHRCommonMats::typeDesc(d.type)}};
if (d.shininessTexture != nullptr) {
j["shininessTexture"] = *d.shininessTexture;
}
if (d.shininess != 0) {
j["shininess"] = d.shininess;
}
if (d.ambientTexture != nullptr) {
j["ambientTexture"] = *d.ambientTexture;
}
if (d.ambientFactor.LengthSquared() > 0) {
j["ambientFactor"] = toStdVec(toRGBA(d.ambientFactor));
}
if (d.diffuseTexture != nullptr) {
j["diffuseTexture"] = *d.diffuseTexture;
}
if (d.diffuseFactor.LengthSquared() > 0) {
j["diffuseFactor"] = toStdVec(d.diffuseFactor);
}
if (d.specularTexture != nullptr) {
j["specularTexture"] = *d.specularTexture;
}
if (d.specularFactor.LengthSquared() > 0) {
j["specularFactor"] = toStdVec(toRGBA(d.specularFactor));
}
}
KHRCmnUnlitMaterial::KHRCmnUnlitMaterial()
{
}
@ -102,38 +36,6 @@ void to_json(json &j, const KHRCmnUnlitMaterial &d)
j = json({});
}
PBRSpecularGlossiness::PBRSpecularGlossiness(
const TextureData *diffuseTexture, const Vec4f &diffuseFactor,
const TextureData *specularGlossinessTexture, const Vec3f &specularFactor,
float glossinessFactor)
: diffuseTexture(Tex::ref(diffuseTexture)),
diffuseFactor(diffuseFactor),
specularGlossinessTexture(Tex::ref(specularGlossinessTexture)),
specularFactor(specularFactor),
glossinessFactor(glossinessFactor)
{
}
void to_json(json &j, const PBRSpecularGlossiness &d)
{
j = {};
if (d.diffuseTexture != nullptr) {
j["diffuseTexture"] = *d.diffuseTexture;
}
if (d.diffuseFactor.LengthSquared() > 0) {
j["diffuseFactor"] = toStdVec(d.diffuseFactor);
}
if (d.specularGlossinessTexture != nullptr) {
j["specularGlossinessTexture"] = *d.specularGlossinessTexture;
}
if (d.specularFactor.LengthSquared() > 0) {
j["specularFactor"] = toStdVec(d.specularFactor);
}
if (d.glossinessFactor != 0) {
j["glossinessFactor"] = d.glossinessFactor;
}
}
PBRMetallicRoughness::PBRMetallicRoughness(
const TextureData *baseColorTexture, const TextureData *metRoughTexture,
const Vec4f &baseColorFactor, float metallic, float roughness)
@ -169,20 +71,16 @@ void to_json(json &j, const PBRMetallicRoughness &d)
MaterialData::MaterialData(
std::string name, bool isTransparent, const TextureData *normalTexture,
const TextureData *emissiveTexture, const Vec3f & emissiveFactor,
std::shared_ptr<KHRCommonMats> const khrCommonMats,
std::shared_ptr<KHRCmnUnlitMaterial> const khrCmnConstantMaterial,
std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness,
std::shared_ptr<PBRSpecularGlossiness> const pbrSpecularGlossiness)
std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness)
: Holdable(),
name(std::move(name)),
isTransparent(isTransparent),
normalTexture(Tex::ref(normalTexture)),
emissiveTexture(Tex::ref(emissiveTexture)),
emissiveFactor(std::move(emissiveFactor)),
khrCommonMats(khrCommonMats),
emissiveFactor(emissiveFactor),
khrCmnConstantMaterial(khrCmnConstantMaterial),
pbrMetallicRoughness(pbrMetallicRoughness),
pbrSpecularGlossiness(pbrSpecularGlossiness) {}
pbrMetallicRoughness(pbrMetallicRoughness) {}
json MaterialData::serialize() const
{
@ -203,18 +101,9 @@ json MaterialData::serialize() const
if (pbrMetallicRoughness != nullptr) {
result["pbrMetallicRoughness"] = *pbrMetallicRoughness;
}
if (khrCommonMats != nullptr || khrCmnConstantMaterial != nullptr || pbrSpecularGlossiness != nullptr) {
if (khrCmnConstantMaterial != nullptr) {
json extensions = { };
if (khrCommonMats != nullptr) {
extensions[KHR_MATERIALS_COMMON] = *khrCommonMats;
}
if (khrCmnConstantMaterial != nullptr) {
extensions[KHR_MATERIALS_CMN_UNLIT] = *khrCmnConstantMaterial;
}
if (pbrSpecularGlossiness != nullptr) {
extensions[KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS] = *pbrSpecularGlossiness;
}
extensions[KHR_MATERIALS_CMN_UNLIT] = *khrCmnConstantMaterial;
result["extensions"] = extensions;
}
return result;

View File

@ -23,55 +23,11 @@ struct Tex
const uint32_t texCoord;
};
struct KHRCommonMats
{
enum MaterialType
{
Blinn,
Phong,
Lambert,
Constant,
};
KHRCommonMats(
MaterialType type,
const TextureData *shininessTexture, float shininess,
const TextureData *ambientTexture, const Vec3f &ambientFactor,
const TextureData *diffuseTexture, const Vec4f &diffuseFactor,
const TextureData *specularTexture, const Vec3f &specularFactor);
static std::string typeDesc(MaterialType type);
const MaterialType type;
const std::unique_ptr<Tex> shininessTexture;
const float shininess;
const std::unique_ptr<Tex> ambientTexture;
const Vec3f ambientFactor;
const std::unique_ptr<Tex> diffuseTexture;
const Vec4f diffuseFactor;
const std::unique_ptr<Tex> specularTexture;
const Vec3f specularFactor;
};
struct KHRCmnUnlitMaterial
{
KHRCmnUnlitMaterial();
};
struct PBRSpecularGlossiness
{
PBRSpecularGlossiness(
const TextureData *diffuseTexture, const Vec4f &diffuseFactor,
const TextureData *specularGlossinessTexture,
const Vec3f &specularFactor, float glossinessFactor);
std::unique_ptr<Tex> diffuseTexture;
const Vec4f diffuseFactor;
std::unique_ptr<Tex> specularGlossinessTexture;
const Vec3f specularFactor;
const float glossinessFactor;
};
struct PBRMetallicRoughness
{
PBRMetallicRoughness(
@ -90,10 +46,8 @@ struct MaterialData : Holdable
MaterialData(
std::string name, bool isTransparent, const TextureData *normalTexture,
const TextureData *emissiveTexture, const Vec3f &emissiveFactor,
std::shared_ptr<KHRCommonMats> const khrCommonMats,
std::shared_ptr<KHRCmnUnlitMaterial> const khrCmnConstantMaterial,
std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness,
std::shared_ptr<PBRSpecularGlossiness> const pbrSpecularGlossiness);
std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness);
json serialize() const override;
@ -103,16 +57,12 @@ struct MaterialData : Holdable
const std::unique_ptr<const Tex> emissiveTexture;
const Vec3f emissiveFactor;
const std::shared_ptr<const KHRCommonMats> khrCommonMats;
const std::shared_ptr<const KHRCmnUnlitMaterial> khrCmnConstantMaterial;
const std::shared_ptr<const KHRCmnUnlitMaterial> khrCmnConstantMaterial;
const std::shared_ptr<const PBRMetallicRoughness> pbrMetallicRoughness;
const std::shared_ptr<const PBRSpecularGlossiness> pbrSpecularGlossiness;
};
void to_json(json &j, const Tex &data);
void to_json(json &j, const KHRCommonMats &d);
void to_json(json &j, const KHRCmnUnlitMaterial &d);
void to_json(json &j, const PBRSpecularGlossiness &d);
void to_json(json &j, const PBRMetallicRoughness &d);
#endif //FBX2GLTF_MATERIALDATA_H

View File

@ -26,7 +26,6 @@
#include "utils/String_Utils.h"
#include "utils/File_Utils.h"
#include "Fbx2Raw.h"
#include "RawModel.h"
#include "Raw2Gltf.h"
bool verboseOutput = false;
@ -70,12 +69,6 @@ int main(int argc, char *argv[])
(
"khr-materials-unlit", "Use KHR_materials_unlit extension to specify Unlit shader.",
cxxopts::value<bool>(gltfOptions.useKHRMatUnlit))
(
"khr-materials-common", "(WIP) Use KHR_materials_common extensions to specify Lambert/Blinn/Phong shaders.",
cxxopts::value<bool>(gltfOptions.useKHRMatCom))
(
"pbr-specular-glossiness", "(WIP) Experimentally fill in the KHR_materials_pbrSpecularGlossiness extension.",
cxxopts::value<bool>(gltfOptions.usePBRSpecGloss))
(
"blend-shape-normals", "Include blend shape normals, if reported present by the FBX SDK.",
cxxopts::value<bool>(gltfOptions.useBlendShapeNormals))
@ -125,7 +118,7 @@ Copyright (c) 2016-2017 Oculus VR, LLC.
verboseOutput = true;
}
if (!gltfOptions.useKHRMatUnlit && !gltfOptions.useKHRMatCom && !gltfOptions.usePBRSpecGloss && !gltfOptions.usePBRMetRough) {
if (!gltfOptions.useKHRMatUnlit && !gltfOptions.usePBRMetRough) {
if (verboseOutput) {
fmt::printf("Defaulting to --pbr-metallic-roughness material support.\n");
}