mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 01:48:59 +02:00
Trying to better load aand detect the case for transparent textures oor opacity mask
This commit is contained in:
parent
5ca1598572
commit
225b330d41
6 changed files with 88 additions and 34 deletions
|
@ -147,11 +147,12 @@ bool NetworkGeometry::isLoadedWithTextures() const {
|
|||
(material->lightmapTexture && !material->lightmapTexture->isLoaded())) {
|
||||
return false;
|
||||
}
|
||||
if (material->albedoTexture && material->albedoTexture->getGPUTexture()) {
|
||||
if (material->useAlbedoMapOpacity && material->albedoTexture && material->albedoTexture->getGPUTexture()) {
|
||||
material->_material->setTextureMap(model::MaterialKey::ALBEDO_MAP, material->_material->getTextureMap(model::MaterialKey::ALBEDO_MAP));
|
||||
// Reset the materialKey transparentTexture key only, as it is albedoTexture-dependent
|
||||
const auto& usage = material->albedoTexture->getGPUTexture()->getUsage();
|
||||
bool isTransparentTexture = usage.isAlpha() && !usage.isAlphaMask();
|
||||
material->_material->setTransparentTexture(isTransparentTexture);
|
||||
// material->_material->setTransparentTexture(isTransparentTexture);
|
||||
// FIXME: Materials with *some* transparent textures seem to give all *other* textures alphas of 0.
|
||||
_hasTransparentTextures = isTransparentTexture && _hasTransparentTextures;
|
||||
}
|
||||
|
@ -376,9 +377,21 @@ static NetworkMaterial* buildNetworkMaterial(NetworkGeometry* geometry, const FB
|
|||
auto albedoMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.albedoTexture, DEFAULT_TEXTURE,
|
||||
networkMaterial->albedoTexture, networkMaterial->albedoTextureName);
|
||||
albedoMap->setTextureTransform(material.albedoTexture.transform);
|
||||
|
||||
if (!material.opacityTexture.filename.isEmpty()) {
|
||||
if (material.albedoTexture.filename == material.opacityTexture.filename) {
|
||||
// Best case scenario, just indicating that the albedo map contains transparency
|
||||
networkMaterial->useAlbedoMapOpacity;
|
||||
albedoMap->setUseAlphaChannel(true);
|
||||
} else {
|
||||
// Opacity Map is different from the Abledo map, not supported
|
||||
}
|
||||
}
|
||||
|
||||
material._material->setTextureMap(model::MaterialKey::ALBEDO_MAP, albedoMap);
|
||||
}
|
||||
|
||||
|
||||
if (!material.normalTexture.filename.isEmpty()) {
|
||||
auto normalMap = setupNetworkTextureMap(geometry, textureBaseUrl, material.normalTexture,
|
||||
(material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE),
|
||||
|
|
|
@ -199,6 +199,7 @@ public:
|
|||
QSharedPointer<NetworkTexture> occlusionTexture;
|
||||
QString lightmapTextureName;
|
||||
QSharedPointer<NetworkTexture> lightmapTexture;
|
||||
bool useAlbedoMapOpacity{ false };
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ void Material::setEmissive(const Color& emissive, bool isSRGB) {
|
|||
}
|
||||
|
||||
void Material::setOpacity(float opacity) {
|
||||
_key.setTransparent((opacity < 1.0f));
|
||||
_key.setTransparentFactor((opacity < 1.0f));
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_schemaBuffer.edit<Schema>()._opacity = opacity;
|
||||
}
|
||||
|
@ -80,19 +80,52 @@ void Material::setMetallic(float metallic) {
|
|||
_schemaBuffer.edit<Schema>()._metallic = metallic;
|
||||
}
|
||||
|
||||
void Material::setTransparentTexture(bool isTransparent) {
|
||||
_key.setTransparentTexture(isTransparent);
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
}
|
||||
|
||||
void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
|
||||
if (textureMap) {
|
||||
_key.setMapChannel(channel, (true));
|
||||
|
||||
if (channel == MaterialKey::ALBEDO_MAP) {
|
||||
if (textureMap->useAlphaChannel()) {
|
||||
if (textureMap->isDefined()) {
|
||||
if (textureMap->getTextureView().isValid()) {
|
||||
auto usage = textureMap->getTextureView()._texture->getUsage();
|
||||
if (usage.isAlpha()) {
|
||||
// Texture has alpha, is nut just a mask or a true transparent channel
|
||||
if (!usage.isAlphaMask()) {
|
||||
_key.setOpacityMaskMap(true);
|
||||
_key.setTransparentMap(false);
|
||||
} else {
|
||||
_key.setOpacityMaskMap(false);
|
||||
_key.setTransparentMap(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_textureMaps[channel] = textureMap;
|
||||
} else {
|
||||
_key.setMapChannel(channel, (false));
|
||||
|
||||
if (channel == MaterialKey::ALBEDO_MAP) {
|
||||
_key.setOpacityMaskMap(false);
|
||||
_key.setTransparentMap(false);
|
||||
}
|
||||
|
||||
_schemaBuffer.edit<Schema>()._key = (uint32)_key._flags.to_ulong();
|
||||
_textureMaps.erase(channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const TextureMapPointer Material::getTextureMap(MapChannel channel) const {
|
||||
auto result = _textureMaps.find(channel);
|
||||
if (result != _textureMaps.end()) {
|
||||
return (result->second);
|
||||
} else {
|
||||
return TextureMapPointer();
|
||||
}
|
||||
}
|
|
@ -31,14 +31,14 @@ public:
|
|||
ALBEDO_VAL_BIT,
|
||||
METALLIC_VAL_BIT,
|
||||
GLOSSY_VAL_BIT,
|
||||
TRANSPARENT_VAL_BIT,
|
||||
TRANSPARENT_TEX_VAL_BIT,
|
||||
OPACITY_VAL_BIT,
|
||||
|
||||
EMISSIVE_MAP_BIT,
|
||||
ALBEDO_MAP_BIT,
|
||||
OPACITY_MASK_MAP_BIT, // OPacity Map and Opacity MASK map are mutually exclusive
|
||||
OPACITY_TRANSPARENT_MAP_BIT,
|
||||
METALLIC_MAP_BIT,
|
||||
ROUGHNESS_MAP_BIT,
|
||||
TRANSPARENT_MAP_BIT,
|
||||
NORMAL_MAP_BIT,
|
||||
OCCLUSION_MAP_BIT,
|
||||
LIGHTMAP_MAP_BIT,
|
||||
|
@ -52,7 +52,6 @@ public:
|
|||
ALBEDO_MAP,
|
||||
METALLIC_MAP,
|
||||
ROUGHNESS_MAP,
|
||||
TRANSPARENT_MAP,
|
||||
NORMAL_MAP,
|
||||
OCCLUSION_MAP,
|
||||
LIGHTMAP_MAP,
|
||||
|
@ -77,13 +76,15 @@ public:
|
|||
Builder& withAlbedo() { _flags.set(ALBEDO_VAL_BIT); return (*this); }
|
||||
Builder& withMetallic() { _flags.set(METALLIC_VAL_BIT); return (*this); }
|
||||
Builder& withGlossy() { _flags.set(GLOSSY_VAL_BIT); return (*this); }
|
||||
Builder& withTransparent() { _flags.set(TRANSPARENT_VAL_BIT); return (*this); }
|
||||
Builder& withOpacity() { _flags.set(OPACITY_VAL_BIT); return (*this); }
|
||||
|
||||
Builder& withEmissiveMap() { _flags.set(EMISSIVE_MAP_BIT); return (*this); }
|
||||
Builder& withAlbedoMap() { _flags.set(ALBEDO_MAP_BIT); return (*this); }
|
||||
Builder& withMetallicMap() { _flags.set(METALLIC_MAP_BIT); return (*this); }
|
||||
Builder& withRoughnessMap() { _flags.set(ROUGHNESS_MAP_BIT); return (*this); }
|
||||
Builder& withTransparentMap() { _flags.set(TRANSPARENT_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withTransparentMap() { _flags.set(OPACITY_TRANSPARENT_MAP_BIT); return (*this); }
|
||||
Builder& withMaskMap() { _flags.set(OPACITY_MASK_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
|
||||
Builder& withOcclusionMap() { _flags.set(OCCLUSION_MAP_BIT); return (*this); }
|
||||
|
@ -102,9 +103,6 @@ public:
|
|||
void setAlbedo(bool value) { _flags.set(ALBEDO_VAL_BIT, value); }
|
||||
bool isAlbedo() const { return _flags[ALBEDO_VAL_BIT]; }
|
||||
|
||||
void setTransparentTexture(bool value) { _flags.set(TRANSPARENT_TEX_VAL_BIT, value); }
|
||||
bool isTransparentTexture() const { return _flags[TRANSPARENT_TEX_VAL_BIT]; }
|
||||
|
||||
void setAlbedoMap(bool value) { _flags.set(ALBEDO_MAP_BIT, value); }
|
||||
bool isAlbedoMap() const { return _flags[ALBEDO_MAP_BIT]; }
|
||||
|
||||
|
@ -121,13 +119,16 @@ public:
|
|||
void setRoughnessMap(bool value) { _flags.set(ROUGHNESS_MAP_BIT, value); }
|
||||
bool isRoughnessMap() const { return _flags[ROUGHNESS_MAP_BIT]; }
|
||||
|
||||
void setTransparent(bool value) { _flags.set(TRANSPARENT_VAL_BIT, value); }
|
||||
bool isTransparent() const { return _flags[TRANSPARENT_VAL_BIT]; }
|
||||
bool isOpaque() const { return !_flags[TRANSPARENT_VAL_BIT]; }
|
||||
void setTransparentFactor(bool value) { _flags.set(OPACITY_VAL_BIT, value); }
|
||||
bool isTransparentFactor() const { return _flags[OPACITY_VAL_BIT]; }
|
||||
bool isOpaqueFactor() const { return !_flags[OPACITY_VAL_BIT]; }
|
||||
|
||||
void setTransparentMap(bool value) { _flags.set(TRANSPARENT_MAP_BIT, value); }
|
||||
bool isTransparentMap() const { return _flags[TRANSPARENT_MAP_BIT]; }
|
||||
void setTransparentMap(bool value) { _flags.set(OPACITY_TRANSPARENT_MAP_BIT, value); }
|
||||
bool isTransparentMap() const { return _flags[OPACITY_TRANSPARENT_MAP_BIT]; }
|
||||
|
||||
void setOpacityMaskMap(bool value) { _flags.set(OPACITY_MASK_MAP_BIT, value); }
|
||||
bool isOpacityMaskMap() const { return _flags[OPACITY_MASK_MAP_BIT]; }
|
||||
|
||||
void setNormalMap(bool value) { _flags.set(NORMAL_MAP_BIT, value); }
|
||||
bool isNormalMap() const { return _flags[NORMAL_MAP_BIT]; }
|
||||
|
||||
|
@ -168,9 +169,6 @@ public:
|
|||
Builder& withoutAlbedo() { _value.reset(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
||||
Builder& withAlbedo() { _value.set(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
||||
|
||||
Builder& withoutTransparentTexture() { _value.reset(MaterialKey::TRANSPARENT_TEX_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_TEX_VAL_BIT); return (*this); }
|
||||
Builder& withTransparentTexture() { _value.set(MaterialKey::TRANSPARENT_TEX_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_TEX_VAL_BIT); return (*this); }
|
||||
|
||||
Builder& withoutAlbedoMap() { _value.reset(MaterialKey::ALBEDO_MAP_BIT); _mask.set(MaterialKey::ALBEDO_MAP_BIT); return (*this); }
|
||||
Builder& withAlbedoMap() { _value.set(MaterialKey::ALBEDO_MAP_BIT); _mask.set(MaterialKey::ALBEDO_MAP_BIT); return (*this); }
|
||||
|
||||
|
@ -186,11 +184,15 @@ public:
|
|||
Builder& withoutRoughnessMap() { _value.reset(MaterialKey::ROUGHNESS_MAP_BIT); _mask.set(MaterialKey::ROUGHNESS_MAP_BIT); return (*this); }
|
||||
Builder& withRoughnessMap() { _value.set(MaterialKey::ROUGHNESS_MAP_BIT); _mask.set(MaterialKey::ROUGHNESS_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutTransparent() { _value.reset(MaterialKey::TRANSPARENT_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_VAL_BIT); return (*this); }
|
||||
Builder& withTransparent() { _value.set(MaterialKey::TRANSPARENT_VAL_BIT); _mask.set(MaterialKey::TRANSPARENT_VAL_BIT); return (*this); }
|
||||
Builder& withoutTransparentFactor() { _value.reset(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); }
|
||||
Builder& withTransparentFactor() { _value.set(MaterialKey::OPACITY_VAL_BIT); _mask.set(MaterialKey::OPACITY_VAL_BIT); return (*this); }
|
||||
Builder& withOpaqueFactor() { return withoutTransparentFactor(); }
|
||||
|
||||
Builder& withoutTransparentMap() { _value.reset(MaterialKey::TRANSPARENT_MAP_BIT); _mask.set(MaterialKey::TRANSPARENT_MAP_BIT); return (*this); }
|
||||
Builder& withTransparentMap() { _value.set(MaterialKey::TRANSPARENT_MAP_BIT); _mask.set(MaterialKey::TRANSPARENT_MAP_BIT); return (*this); }
|
||||
Builder& withoutTransparentMap() { _value.reset(MaterialKey::OPACITY_TRANSPARENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSPARENT_MAP_BIT); return (*this); }
|
||||
Builder& withTransparentMap() { _value.set(MaterialKey::OPACITY_TRANSPARENT_MAP_BIT); _mask.set(MaterialKey::OPACITY_TRANSPARENT_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutMaskMap() { _value.reset(MaterialKey::OPACITY_MASK_MAP_BIT); _mask.set(MaterialKey::OPACITY_MASK_MAP_BIT); return (*this); }
|
||||
Builder& withMaskMap() { _value.set(MaterialKey::OPACITY_MASK_MAP_BIT); _mask.set(MaterialKey::OPACITY_MASK_MAP_BIT); return (*this); }
|
||||
|
||||
Builder& withoutNormalMap() { _value.reset(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
|
||||
Builder& withNormalMap() { _value.set(MaterialKey::NORMAL_MAP_BIT); _mask.set(MaterialKey::NORMAL_MAP_BIT); return (*this); }
|
||||
|
@ -202,7 +204,7 @@ public:
|
|||
Builder& withLightmapMap() { _value.set(MaterialKey::LIGHTMAP_MAP_BIT); _mask.set(MaterialKey::LIGHTMAP_MAP_BIT); return (*this); }
|
||||
|
||||
// Convenient standard keys that we will keep on using all over the place
|
||||
static MaterialFilter opaqueAlbedo() { return Builder().withAlbedo().withoutTransparent().build(); }
|
||||
static MaterialFilter opaqueAlbedo() { return Builder().withAlbedo().withOpaqueFactor().build(); }
|
||||
};
|
||||
|
||||
// Item Filter operator testing if a key pass the filter
|
||||
|
@ -255,7 +257,6 @@ public:
|
|||
void setRoughness(float roughness);
|
||||
float getRoughness() const { return _schemaBuffer.get<Schema>()._roughness; }
|
||||
|
||||
void setTransparentTexture(bool isTransparent);
|
||||
|
||||
// Schema to access the attribute values of the material
|
||||
class Schema {
|
||||
|
@ -283,6 +284,7 @@ public:
|
|||
// The texture map to channel association
|
||||
void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap);
|
||||
const TextureMaps& getTextureMaps() const { return _textureMaps; }
|
||||
const TextureMapPointer getTextureMap(MapChannel channel) const;
|
||||
|
||||
// conversion from legacy material properties to PBR equivalent
|
||||
static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; }
|
||||
|
|
|
@ -56,6 +56,9 @@ public:
|
|||
void setTextureTransform(const Transform& texcoordTransform);
|
||||
const Transform& getTextureTransform() const { return _texcoordTransform; }
|
||||
|
||||
void setUseAlphaChannel(bool useAlpha) { _useAlphaChannel = useAlpha; }
|
||||
bool useAlphaChannel() const { return _useAlphaChannel; }
|
||||
|
||||
void setLightmapOffsetScale(float offset, float scale);
|
||||
const glm::vec2& getLightmapOffsetScale() const { return _lightmapOffsetScale; }
|
||||
|
||||
|
@ -64,6 +67,8 @@ protected:
|
|||
|
||||
Transform _texcoordTransform;
|
||||
glm::vec2 _lightmapOffsetScale{ 0.0f, 1.0f };
|
||||
|
||||
bool _useAlphaChannel{ false };
|
||||
};
|
||||
typedef std::shared_ptr< TextureMap > TextureMapPointer;
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ ItemKey MeshPartPayload::getKey() const {
|
|||
|
||||
if (_drawMaterial) {
|
||||
auto matKey = _drawMaterial->getKey();
|
||||
if (matKey.isTransparent() || matKey.isTransparentTexture() || matKey.isTransparentMap()) {
|
||||
if (matKey.isTransparentFactor() || matKey.isTransparentMap()) {
|
||||
builder.withTransparent();
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ ShapeKey MeshPartPayload::getShapeKey() const {
|
|||
}
|
||||
|
||||
ShapeKey::Builder builder;
|
||||
if (drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentTexture() || drawMaterialKey.isTransparentMap()) {
|
||||
if (drawMaterialKey.isTransparentFactor() || drawMaterialKey.isTransparentMap()) {
|
||||
builder.withTranslucent();
|
||||
}
|
||||
if (drawMaterialKey.isNormalMap()) {
|
||||
|
@ -365,7 +365,7 @@ ItemKey ModelMeshPartPayload::getKey() const {
|
|||
|
||||
if (_drawMaterial) {
|
||||
auto matKey = _drawMaterial->getKey();
|
||||
if (matKey.isTransparent() || matKey.isTransparentTexture() || matKey.isTransparentMap()) {
|
||||
if (matKey.isTransparentFactor() || matKey.isTransparentMap()) {
|
||||
builder.withTransparent();
|
||||
}
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
|||
}
|
||||
|
||||
bool isTranslucent =
|
||||
drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentTexture() || drawMaterialKey.isTransparentMap();
|
||||
drawMaterialKey.isTransparentFactor() || drawMaterialKey.isTransparentMap();
|
||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
||||
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||
|
|
Loading…
Reference in a new issue