properly implement alphaModes

This commit is contained in:
HifiExperiments 2019-11-22 00:37:27 -08:00
parent cb5d881bd8
commit 5371fd613a
7 changed files with 90 additions and 83 deletions

View file

@ -265,17 +265,17 @@ int GLTFSerializer::getAccessorType(const QString& type) {
return GLTFAccessorType::SCALAR; return GLTFAccessorType::SCALAR;
} }
int GLTFSerializer::getMaterialAlphaMode(const QString& type) { graphics::MaterialKey::OpacityMapMode GLTFSerializer::getMaterialAlphaMode(const QString& type) {
if (type == "OPAQUE") { if (type == "OPAQUE") {
return GLTFMaterialAlphaMode::OPAQUE; return graphics::MaterialKey::OPACITY_MAP_OPAQUE;
} }
if (type == "MASK") { if (type == "MASK") {
return GLTFMaterialAlphaMode::MASK; return graphics::MaterialKey::OPACITY_MAP_MASK;
} }
if (type == "BLEND") { if (type == "BLEND") {
return GLTFMaterialAlphaMode::BLEND; return graphics::MaterialKey::OPACITY_MAP_BLEND;
} }
return GLTFMaterialAlphaMode::OPAQUE; return graphics::MaterialKey::OPACITY_MAP_BLEND;
} }
int GLTFSerializer::getCameraType(const QString& type) { int GLTFSerializer::getCameraType(const QString& type) {
@ -523,9 +523,9 @@ bool GLTFSerializer::addMaterial(const QJsonObject& object) {
getIndexFromObject(object, "normalTexture", material.normalTexture, material.defined); getIndexFromObject(object, "normalTexture", material.normalTexture, material.defined);
getIndexFromObject(object, "occlusionTexture", material.occlusionTexture, material.defined); getIndexFromObject(object, "occlusionTexture", material.occlusionTexture, material.defined);
getBoolVal(object, "doubleSided", material.doubleSided, material.defined); getBoolVal(object, "doubleSided", material.doubleSided, material.defined);
QString alphamode; QString alphaMode;
if (getStringVal(object, "alphaMode", alphamode, material.defined)) { if (getStringVal(object, "alphaMode", alphaMode, material.defined)) {
material.alphaMode = getMaterialAlphaMode(alphamode); material.alphaMode = getMaterialAlphaMode(alphaMode);
} }
getDoubleVal(object, "alphaCutoff", material.alphaCutoff, material.defined); getDoubleVal(object, "alphaCutoff", material.alphaCutoff, material.defined);
QJsonObject jsMetallicRoughness; QJsonObject jsMetallicRoughness;
@ -1704,57 +1704,67 @@ HFMTexture GLTFSerializer::getHFMTexture(const GLTFTexture& texture) {
return fbxtex; return fbxtex;
} }
void GLTFSerializer::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material) { void GLTFSerializer::setHFMMaterial(HFMMaterial& hfmMat, const GLTFMaterial& material) {
if (material.defined["alphaMode"]) {
hfmMat._material->setOpacityMapMode(material.alphaMode);
} else {
hfmMat._material->setOpacityMapMode(graphics::MaterialKey::OPACITY_MAP_OPAQUE); // GLTF defaults to opaque
}
if (material.defined["alphaCutoff"]) {
hfmMat._material->setOpacityCutoff(material.alphaCutoff);
}
if (material.defined["emissiveFactor"] && material.emissiveFactor.size() == 3) { if (material.defined["emissiveFactor"] && material.emissiveFactor.size() == 3) {
glm::vec3 emissive = glm::vec3(material.emissiveFactor[0], material.emissiveFactor[1], material.emissiveFactor[2]); glm::vec3 emissive = glm::vec3(material.emissiveFactor[0], material.emissiveFactor[1], material.emissiveFactor[2]);
fbxmat._material->setEmissive(emissive); hfmMat._material->setEmissive(emissive);
} }
if (material.defined["emissiveTexture"]) { if (material.defined["emissiveTexture"]) {
fbxmat.emissiveTexture = getHFMTexture(_file.textures[material.emissiveTexture]); hfmMat.emissiveTexture = getHFMTexture(_file.textures[material.emissiveTexture]);
fbxmat.useEmissiveMap = true; hfmMat.useEmissiveMap = true;
} }
if (material.defined["normalTexture"]) { if (material.defined["normalTexture"]) {
fbxmat.normalTexture = getHFMTexture(_file.textures[material.normalTexture]); hfmMat.normalTexture = getHFMTexture(_file.textures[material.normalTexture]);
fbxmat.useNormalMap = true; hfmMat.useNormalMap = true;
} }
if (material.defined["occlusionTexture"]) { if (material.defined["occlusionTexture"]) {
fbxmat.occlusionTexture = getHFMTexture(_file.textures[material.occlusionTexture]); hfmMat.occlusionTexture = getHFMTexture(_file.textures[material.occlusionTexture]);
fbxmat.useOcclusionMap = true; hfmMat.useOcclusionMap = true;
} }
if (material.defined["pbrMetallicRoughness"]) { if (material.defined["pbrMetallicRoughness"]) {
fbxmat.isPBSMaterial = true; hfmMat.isPBSMaterial = true;
if (material.pbrMetallicRoughness.defined["metallicFactor"]) { if (material.pbrMetallicRoughness.defined["metallicFactor"]) {
fbxmat.metallic = material.pbrMetallicRoughness.metallicFactor; hfmMat.metallic = material.pbrMetallicRoughness.metallicFactor;
} }
if (material.pbrMetallicRoughness.defined["baseColorTexture"]) { if (material.pbrMetallicRoughness.defined["baseColorTexture"]) {
fbxmat.opacityTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); hfmMat.opacityTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
fbxmat.albedoTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); hfmMat.albedoTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
fbxmat.useAlbedoMap = true; hfmMat.useAlbedoMap = true;
} }
if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) { if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) {
fbxmat.roughnessTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); hfmMat.roughnessTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
fbxmat.roughnessTexture.sourceChannel = image::ColorChannel::GREEN; hfmMat.roughnessTexture.sourceChannel = image::ColorChannel::GREEN;
fbxmat.useRoughnessMap = true; hfmMat.useRoughnessMap = true;
fbxmat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); hfmMat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
fbxmat.metallicTexture.sourceChannel = image::ColorChannel::BLUE; hfmMat.metallicTexture.sourceChannel = image::ColorChannel::BLUE;
fbxmat.useMetallicMap = true; hfmMat.useMetallicMap = true;
} }
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) { if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
fbxmat._material->setRoughness(material.pbrMetallicRoughness.roughnessFactor); hfmMat._material->setRoughness(material.pbrMetallicRoughness.roughnessFactor);
} }
if (material.pbrMetallicRoughness.defined["baseColorFactor"] && if (material.pbrMetallicRoughness.defined["baseColorFactor"] &&
material.pbrMetallicRoughness.baseColorFactor.size() == 4) { material.pbrMetallicRoughness.baseColorFactor.size() == 4) {
glm::vec3 dcolor = glm::vec3 dcolor =
glm::vec3(material.pbrMetallicRoughness.baseColorFactor[0], material.pbrMetallicRoughness.baseColorFactor[1], glm::vec3(material.pbrMetallicRoughness.baseColorFactor[0], material.pbrMetallicRoughness.baseColorFactor[1],
material.pbrMetallicRoughness.baseColorFactor[2]); material.pbrMetallicRoughness.baseColorFactor[2]);
fbxmat.diffuseColor = dcolor; hfmMat.diffuseColor = dcolor;
fbxmat._material->setAlbedo(dcolor); hfmMat._material->setAlbedo(dcolor);
fbxmat._material->setOpacity(material.pbrMetallicRoughness.baseColorFactor[3]); hfmMat._material->setOpacity(material.pbrMetallicRoughness.baseColorFactor[3]);
} }
} }
} }

View file

@ -418,21 +418,13 @@ struct GLTFpbrMetallicRoughness {
} }
}; };
namespace GLTFMaterialAlphaMode {
enum Values {
OPAQUE = 0,
MASK,
BLEND
};
};
struct GLTFMaterial { struct GLTFMaterial {
QString name; QString name;
QVector<double> emissiveFactor; QVector<double> emissiveFactor;
int emissiveTexture; int emissiveTexture;
int normalTexture; int normalTexture;
int occlusionTexture; int occlusionTexture;
int alphaMode; graphics::MaterialKey::OpacityMapMode alphaMode;
double alphaCutoff; double alphaCutoff;
bool doubleSided; bool doubleSided;
GLTFpbrMetallicRoughness pbrMetallicRoughness; GLTFpbrMetallicRoughness pbrMetallicRoughness;
@ -453,6 +445,12 @@ struct GLTFMaterial {
if (defined["emissiveFactor"]) { if (defined["emissiveFactor"]) {
qCDebug(modelformat) << "emissiveFactor: " << emissiveFactor; qCDebug(modelformat) << "emissiveFactor: " << emissiveFactor;
} }
if (defined["alphaMode"]) {
qCDebug(modelformat) << "alphaMode: " << alphaMode;
}
if (defined["alphaCutoff"]) {
qCDebug(modelformat) << "alphaCutoff: " << alphaCutoff;
}
if (defined["pbrMetallicRoughness"]) { if (defined["pbrMetallicRoughness"]) {
pbrMetallicRoughness.dump(); pbrMetallicRoughness.dump();
} }
@ -850,7 +848,7 @@ private:
hifi::ByteArray setGLBChunks(const hifi::ByteArray& data); hifi::ByteArray setGLBChunks(const hifi::ByteArray& data);
int getMaterialAlphaMode(const QString& type); graphics::MaterialKey::OpacityMapMode getMaterialAlphaMode(const QString& type);
int getAccessorType(const QString& type); int getAccessorType(const QString& type);
int getAnimationSamplerInterpolation(const QString& interpolation); int getAnimationSamplerInterpolation(const QString& interpolation);
int getCameraType(const QString& type); int getCameraType(const QString& type);
@ -907,7 +905,7 @@ private:
bool doesResourceExist(const QString& url); bool doesResourceExist(const QString& url);
void setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material); void setHFMMaterial(HFMMaterial& hfmMat, const GLTFMaterial& material);
HFMTexture getHFMTexture(const GLTFTexture& texture); HFMTexture getHFMTexture(const GLTFTexture& texture);
void glTFDebugDump(); void glTFDebugDump();
void hfmDebugDump(const HFMModel& hfmModel); void hfmDebugDump(const HFMModel& hfmModel);

View file

@ -209,8 +209,7 @@ bool Material::resetOpacityMap() const {
} }
} }
} }
auto newious = _key.getOpacityMapMode(); if (previous != _key.getOpacityMapMode()) {
if (previous != newious) {
//opacity change detected for this material //opacity change detected for this material
return true; return true;
} }

View file

@ -214,22 +214,19 @@ vec3 fetchLightMap(vec2 uv) {
} }
<@endfunc@> <@endfunc@>
<@func evalMaterialOpacityMask(fetchedOpacity, materialOpacityCutoff, opacity)@> <@func evalMaterialOpacityMask(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@>
{ {
// This path only valid for opaque or texel opaque material // This path only valid for opaque or texel opaque material
<$opacity$> = step(<$materialOpacityCutoff$>, <$fetchedOpacity$>); <$opacity$> = mix(<$materialOpacity$>,
step(<$materialOpacityCutoff$>, <$fetchedOpacity$>),
float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0));
} }
<@endfunc@> <@endfunc@>
<@func evalMaterialOpacity(fetchedOpacity, materialOpacity, opacity)@>
<@func evalMaterialOpacity(fetchedOpacity, materialOpacityCutoff, materialOpacity, matKey, opacity)@>
{ {
// This path only valid for transparent material // This path only valid for transparent material
// Assert that float((<$matKey$> & (OPACITY_TRANSLUCENT_MAP_BIT | OPACITY_MASK_MAP_BIT)) != 0)) == 1.0 <$opacity$> = <$materialOpacity$> * <$fetchedOpacity$>;
<$opacity$> = mix(<$fetchedOpacity$>,
step(<$materialOpacityCutoff$>, <$fetchedOpacity$>),
float((<$matKey$> & OPACITY_MASK_MAP_BIT) != 0))
* <$materialOpacity$>;
} }
<@endfunc@> <@endfunc@>

View file

@ -176,24 +176,27 @@ public:
void getTextureNames(QSet<QString>& textureList) const; void getTextureNames(QSet<QString>& textureList) const;
void setMaxNumPixelsPerTexture(int maxNumPixels); void setMaxNumPixelsPerTexture(int maxNumPixels);
glm::vec3 diffuseColor{ 1.0f }; glm::vec3 diffuseColor { 1.0f };
float diffuseFactor{ 1.0f }; float diffuseFactor { 1.0f };
glm::vec3 specularColor{ 0.02f }; glm::vec3 specularColor { 0.02f };
float specularFactor{ 1.0f }; float specularFactor { 1.0f };
glm::vec3 emissiveColor{ 0.0f }; glm::vec3 emissiveColor { 0.0f };
float emissiveFactor{ 0.0f }; float emissiveFactor { 0.0f };
float shininess{ 23.0f }; float shininess { 23.0f };
float opacity{ 1.0f }; float opacity { 1.0f };
float metallic{ 0.0f }; float metallic { 0.0f };
float roughness{ 1.0f }; float roughness { 1.0f };
float emissiveIntensity{ 1.0f }; float emissiveIntensity { 1.0f };
float ambientFactor{ 1.0f }; float ambientFactor { 1.0f };
float bumpMultiplier { 1.0f }; // TODO: to be implemented float bumpMultiplier { 1.0f }; // TODO: to be implemented
graphics::MaterialKey::OpacityMapMode alphaMode { graphics::MaterialKey::OPACITY_MAP_BLEND };
float alphaCutoff { 0.5f };
QString materialID; QString materialID;
QString name; QString name;
QString shadingModel; QString shadingModel;
@ -210,19 +213,19 @@ public:
Texture occlusionTexture; Texture occlusionTexture;
Texture scatteringTexture; Texture scatteringTexture;
Texture lightmapTexture; Texture lightmapTexture;
glm::vec2 lightmapParams{ 0.0f, 1.0f }; glm::vec2 lightmapParams { 0.0f, 1.0f };
bool isPBSMaterial{ false }; bool isPBSMaterial { false };
// THe use XXXMap are not really used to drive which map are going or not, debug only // THe use XXXMap are not really used to drive which map are going or not, debug only
bool useNormalMap{ false }; bool useNormalMap { false };
bool useAlbedoMap{ false }; bool useAlbedoMap { false };
bool useOpacityMap{ false }; bool useOpacityMap { false };
bool useRoughnessMap{ false }; bool useRoughnessMap { false };
bool useSpecularMap{ false }; bool useSpecularMap { false };
bool useMetallicMap{ false }; bool useMetallicMap { false };
bool useEmissiveMap{ false }; bool useEmissiveMap { false };
bool useOcclusionMap{ false }; bool useOcclusionMap { false };
bool needTangentSpace() const; bool needTangentSpace() const;
}; };

View file

@ -387,8 +387,10 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
std::call_once(once, [] { std::call_once(once, [] {
for (int i = 0; i < graphics::Material::NUM_TOTAL_FLAGS; i++) { for (int i = 0; i < graphics::Material::NUM_TOTAL_FLAGS; i++) {
// The opacity mask/map are derived from the albedo map // The opacity mask/map are derived from the albedo map
// FIXME: OPACITY_MAP_MODE_BIT is supposed to support fallthrough
if (i != graphics::MaterialKey::OPACITY_MASK_MAP_BIT && if (i != graphics::MaterialKey::OPACITY_MASK_MAP_BIT &&
i != graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT) { i != graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT &&
i != graphics::MaterialKey::OPACITY_MAP_MODE_BIT) {
allFlags.insert(i); allFlags.insert(i);
} }
} }

View file

@ -103,14 +103,13 @@ void main(void) {
<$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$> <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$>
<@if HIFI_USE_TRANSLUCENT@> <@if HIFI_USE_TRANSLUCENT@>
float cutoff = getMaterialOpacityCutoff(mat);
float opacity = getMaterialOpacity(mat) * _color.a; float opacity = getMaterialOpacity(mat) * _color.a;
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>; <$evalMaterialOpacity(albedoTex.a, opacity, opacity)$>;
<$discardInvisible(opacity)$>; <$discardInvisible(opacity)$>;
<@else@> <@else@>
float cutoff = getMaterialOpacityCutoff(mat); float cutoff = getMaterialOpacityCutoff(mat);
float opacity = 1.0; float opacity = 1.0;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>; <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
<$discardTransparent(opacity)$>; <$discardTransparent(opacity)$>;
<@endif@> <@endif@>
@ -155,14 +154,13 @@ void main(void) {
<@endif@> <@endif@>
<@if HIFI_USE_TRANSLUCENT@> <@if HIFI_USE_TRANSLUCENT@>
float cutoff = getMaterialOpacityCutoff(mat);
float opacity = getMaterialOpacity(mat) * _color.a; float opacity = getMaterialOpacity(mat) * _color.a;
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>; <$evalMaterialOpacity(albedoTex.a, opacity, opacity)$>;
<$discardInvisible(opacity)$>; <$discardInvisible(opacity)$>;
<@else@> <@else@>
float cutoff = getMaterialOpacityCutoff(mat); float cutoff = getMaterialOpacityCutoff(mat);
float opacity = 1.0; float opacity = 1.0;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>; <$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
<$discardTransparent(opacity)$>; <$discardTransparent(opacity)$>;
<@endif@> <@endif@>