mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 23:09:52 +02:00
Merge pull request #7281 from zzmp/fix/png-opacity
Fix materials to honor png texture opacity
This commit is contained in:
commit
f30e8e9e0c
8 changed files with 70 additions and 27 deletions
|
@ -135,6 +135,8 @@ bool NetworkGeometry::isLoadedWithTextures() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_isLoadedWithTextures) {
|
if (!_isLoadedWithTextures) {
|
||||||
|
_hasTransparentTextures = true;
|
||||||
|
|
||||||
for (auto&& material : _materials) {
|
for (auto&& material : _materials) {
|
||||||
if ((material->albedoTexture && !material->albedoTexture->isLoaded()) ||
|
if ((material->albedoTexture && !material->albedoTexture->isLoaded()) ||
|
||||||
(material->normalTexture && !material->normalTexture->isLoaded()) ||
|
(material->normalTexture && !material->normalTexture->isLoaded()) ||
|
||||||
|
@ -145,7 +147,16 @@ bool NetworkGeometry::isLoadedWithTextures() const {
|
||||||
(material->lightmapTexture && !material->lightmapTexture->isLoaded())) {
|
(material->lightmapTexture && !material->lightmapTexture->isLoaded())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (material->albedoTexture) {
|
||||||
|
// 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);
|
||||||
|
// FIXME: Materials with *some* transparent textures seem to give all *other* textures alphas of 0.
|
||||||
|
_hasTransparentTextures = isTransparentTexture && _hasTransparentTextures;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_isLoadedWithTextures = true;
|
_isLoadedWithTextures = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -75,6 +75,10 @@ public:
|
||||||
// true when the requested geometry and its textures are loaded.
|
// true when the requested geometry and its textures are loaded.
|
||||||
bool isLoadedWithTextures() const;
|
bool isLoadedWithTextures() const;
|
||||||
|
|
||||||
|
// true if the albedo texture has a non-masking alpha channel.
|
||||||
|
// This can only be known after isLoadedWithTextures().
|
||||||
|
bool hasTransparentTextures() const { return _hasTransparentTextures; }
|
||||||
|
|
||||||
// WARNING: only valid when isLoaded returns true.
|
// WARNING: only valid when isLoaded returns true.
|
||||||
const FBXGeometry& getFBXGeometry() const { return *_geometry; }
|
const FBXGeometry& getFBXGeometry() const { return *_geometry; }
|
||||||
const std::vector<std::unique_ptr<NetworkMesh>>& getMeshes() const { return _meshes; }
|
const std::vector<std::unique_ptr<NetworkMesh>>& getMeshes() const { return _meshes; }
|
||||||
|
@ -151,6 +155,7 @@ protected:
|
||||||
|
|
||||||
// cache for isLoadedWithTextures()
|
// cache for isLoadedWithTextures()
|
||||||
mutable bool _isLoadedWithTextures = false;
|
mutable bool _isLoadedWithTextures = false;
|
||||||
|
mutable bool _hasTransparentTextures = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Reads geometry in a worker thread.
|
/// Reads geometry in a worker thread.
|
||||||
|
|
|
@ -80,6 +80,10 @@ void Material::setMetallic(float metallic) {
|
||||||
_schemaBuffer.edit<Schema>()._metallic = 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) {
|
void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
|
||||||
if (textureMap) {
|
if (textureMap) {
|
||||||
|
@ -92,6 +96,3 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur
|
||||||
_textureMaps.erase(channel);
|
_textureMaps.erase(channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
METALLIC_VAL_BIT,
|
METALLIC_VAL_BIT,
|
||||||
GLOSSY_VAL_BIT,
|
GLOSSY_VAL_BIT,
|
||||||
TRANSPARENT_VAL_BIT,
|
TRANSPARENT_VAL_BIT,
|
||||||
|
TRANSPARENT_TEX_VAL_BIT,
|
||||||
|
|
||||||
EMISSIVE_MAP_BIT,
|
EMISSIVE_MAP_BIT,
|
||||||
ALBEDO_MAP_BIT,
|
ALBEDO_MAP_BIT,
|
||||||
|
@ -101,6 +102,9 @@ public:
|
||||||
void setAlbedo(bool value) { _flags.set(ALBEDO_VAL_BIT, value); }
|
void setAlbedo(bool value) { _flags.set(ALBEDO_VAL_BIT, value); }
|
||||||
bool isAlbedo() const { return _flags[ALBEDO_VAL_BIT]; }
|
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); }
|
void setAlbedoMap(bool value) { _flags.set(ALBEDO_MAP_BIT, value); }
|
||||||
bool isAlbedoMap() const { return _flags[ALBEDO_MAP_BIT]; }
|
bool isAlbedoMap() const { return _flags[ALBEDO_MAP_BIT]; }
|
||||||
|
|
||||||
|
@ -164,6 +168,9 @@ public:
|
||||||
Builder& withoutAlbedo() { _value.reset(MaterialKey::ALBEDO_VAL_BIT); _mask.set(MaterialKey::ALBEDO_VAL_BIT); return (*this); }
|
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& 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& 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); }
|
Builder& withAlbedoMap() { _value.set(MaterialKey::ALBEDO_MAP_BIT); _mask.set(MaterialKey::ALBEDO_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
|
@ -248,6 +255,8 @@ public:
|
||||||
void setRoughness(float roughness);
|
void setRoughness(float roughness);
|
||||||
float getRoughness() const { return _schemaBuffer.get<Schema>()._roughness; }
|
float getRoughness() const { return _schemaBuffer.get<Schema>()._roughness; }
|
||||||
|
|
||||||
|
void setTransparentTexture(bool isTransparent);
|
||||||
|
|
||||||
// Schema to access the attribute values of the material
|
// Schema to access the attribute values of the material
|
||||||
class Schema {
|
class Schema {
|
||||||
public:
|
public:
|
||||||
|
@ -260,8 +269,7 @@ public:
|
||||||
glm::vec3 _fresnel{ 0.03f }; // Fresnel value for a default non metallic
|
glm::vec3 _fresnel{ 0.03f }; // Fresnel value for a default non metallic
|
||||||
float _metallic{ 0.0f }; // Not Metallic
|
float _metallic{ 0.0f }; // Not Metallic
|
||||||
|
|
||||||
|
glm::vec3 _spare{ 0.0f };
|
||||||
glm::vec3 _spare0{ 0.0f };
|
|
||||||
|
|
||||||
uint32_t _key{ 0 }; // a copy of the materialKey
|
uint32_t _key{ 0 }; // a copy of the materialKey
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct Material {
|
||||||
vec4 _emissiveOpacity;
|
vec4 _emissiveOpacity;
|
||||||
vec4 _albedoRoughness;
|
vec4 _albedoRoughness;
|
||||||
vec4 _fresnelMetallic;
|
vec4 _fresnelMetallic;
|
||||||
vec4 _spare;
|
vec4 _spareKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform materialBuffer {
|
uniform materialBuffer {
|
||||||
|
@ -37,25 +37,23 @@ float getMaterialMetallic(Material m) { return m._fresnelMetallic.a; }
|
||||||
|
|
||||||
float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); }
|
float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); }
|
||||||
|
|
||||||
int getMaterialKey(Material m) { return floatBitsToInt(m._spare.w); }
|
int getMaterialKey(Material m) { return floatBitsToInt(m._spareKey.w); }
|
||||||
|
|
||||||
const int EMISSIVE_VAL_BIT = 0x00000001;
|
const int EMISSIVE_VAL_BIT = 0x00000001;
|
||||||
const int ALBEDO_VAL_BIT = 0x00000002;
|
const int ALBEDO_VAL_BIT = 0x00000002;
|
||||||
const int METALLIC_VAL_BIT = 0x00000004;
|
const int METALLIC_VAL_BIT = 0x00000004;
|
||||||
const int GLOSSY_VAL_BIT = 0x00000008;
|
const int GLOSSY_VAL_BIT = 0x00000008;
|
||||||
const int TRANSPARENT_VAL_BIT = 0x00000010;
|
const int TRANSPARENT_VAL_BIT = 0x00000010;
|
||||||
|
const int TRANSPARENT_TEX_VAL_BIT = 0x00000020;
|
||||||
|
|
||||||
|
const int EMISSIVE_MAP_BIT = 0x00000040;
|
||||||
|
const int ALBEDO_MAP_BIT = 0x00000080;
|
||||||
|
const int METALLIC_MAP_BIT = 0x00000100;
|
||||||
|
const int ROUGHNESS_MAP_BIT = 0x00000200;
|
||||||
|
const int TRANSPARENT_MAP_BIT = 0x00000400;
|
||||||
|
const int NORMAL_MAP_BIT = 0x00000800;
|
||||||
|
const int OCCLUSION_MAP_BIT = 0x00001000;
|
||||||
|
|
||||||
const int EMISSIVE_MAP_BIT = 0x00000020;
|
const int LIGHTMAP_MAP_BIT = 0x00002000;
|
||||||
const int ALBEDO_MAP_BIT = 0x00000040;
|
|
||||||
const int METALLIC_MAP_BIT = 0x00000080;
|
|
||||||
const int ROUGHNESS_MAP_BIT = 0x00000100;
|
|
||||||
const int TRANSPARENT_MAP_BIT = 0x00000200;
|
|
||||||
const int NORMAL_MAP_BIT = 0x00000400;
|
|
||||||
const int OCCLUSION_MAP_BIT = 0x00000800;
|
|
||||||
|
|
||||||
const int LIGHTMAP_MAP_BIT = 0x00001000;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -81,7 +81,7 @@ ItemKey MeshPartPayload::getKey() const {
|
||||||
|
|
||||||
if (_drawMaterial) {
|
if (_drawMaterial) {
|
||||||
auto matKey = _drawMaterial->getKey();
|
auto matKey = _drawMaterial->getKey();
|
||||||
if (matKey.isTransparent() || matKey.isTransparentMap()) {
|
if (matKey.isTransparent() || matKey.isTransparentTexture() || matKey.isTransparentMap()) {
|
||||||
builder.withTransparent();
|
builder.withTransparent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ ShapeKey MeshPartPayload::getShapeKey() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeKey::Builder builder;
|
ShapeKey::Builder builder;
|
||||||
if (drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap()) {
|
if (drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentTexture() || drawMaterialKey.isTransparentMap()) {
|
||||||
builder.withTranslucent();
|
builder.withTranslucent();
|
||||||
}
|
}
|
||||||
if (drawMaterialKey.isNormalMap()) {
|
if (drawMaterialKey.isNormalMap()) {
|
||||||
|
@ -365,7 +365,7 @@ ItemKey ModelMeshPartPayload::getKey() const {
|
||||||
|
|
||||||
if (_drawMaterial) {
|
if (_drawMaterial) {
|
||||||
auto matKey = _drawMaterial->getKey();
|
auto matKey = _drawMaterial->getKey();
|
||||||
if (matKey.isTransparent() || matKey.isTransparentMap()) {
|
if (matKey.isTransparent() || matKey.isTransparentTexture() || matKey.isTransparentMap()) {
|
||||||
builder.withTransparent();
|
builder.withTransparent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,7 +412,8 @@ ShapeKey ModelMeshPartPayload::getShapeKey() const {
|
||||||
drawMaterialKey = _drawMaterial->getKey();
|
drawMaterialKey = _drawMaterial->getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap();
|
bool isTranslucent =
|
||||||
|
drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentTexture() || drawMaterialKey.isTransparentMap();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
||||||
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
bool hasSpecular = drawMaterialKey.isMetallicMap();
|
||||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
||||||
|
|
|
@ -74,6 +74,21 @@ Model::~Model() {
|
||||||
|
|
||||||
AbstractViewStateInterface* Model::_viewState = NULL;
|
AbstractViewStateInterface* Model::_viewState = NULL;
|
||||||
|
|
||||||
|
bool Model::needsFixupInScene() {
|
||||||
|
if (readyToAddToScene()) {
|
||||||
|
// Once textures are loaded, fixup if they are now transparent
|
||||||
|
if (!_needsReload && _needsUpdateTransparentTextures && _geometry->isLoadedWithTextures()) {
|
||||||
|
_needsUpdateTransparentTextures = false;
|
||||||
|
if (_hasTransparentTextures != _geometry->hasTransparentTextures()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_readyWhenAdded) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Model::setTranslation(const glm::vec3& translation) {
|
void Model::setTranslation(const glm::vec3& translation) {
|
||||||
_translation = translation;
|
_translation = translation;
|
||||||
|
@ -728,6 +743,8 @@ void Model::setURL(const QUrl& url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_needsReload = true;
|
_needsReload = true;
|
||||||
|
_needsUpdateTransparentTextures = true;
|
||||||
|
_hasTransparentTextures = false;
|
||||||
_meshGroupsKnown = false;
|
_meshGroupsKnown = false;
|
||||||
invalidCalculatedMeshBoxes();
|
invalidCalculatedMeshBoxes();
|
||||||
deleteGeometry();
|
deleteGeometry();
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
|
|
||||||
// new Scene/Engine rendering support
|
// new Scene/Engine rendering support
|
||||||
void setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scene);
|
void setVisibleInScene(bool newValue, std::shared_ptr<render::Scene> scene);
|
||||||
bool needsFixupInScene() { return !_readyWhenAdded && readyToAddToScene(); }
|
bool needsFixupInScene();
|
||||||
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) {
|
bool readyToAddToScene(RenderArgs* renderArgs = nullptr) {
|
||||||
return !_needsReload && isRenderable() && isActive() && isLoaded();
|
return !_needsReload && isRenderable() && isActive() && isLoaded();
|
||||||
}
|
}
|
||||||
|
@ -365,10 +365,12 @@ protected:
|
||||||
|
|
||||||
QSet<std::shared_ptr<MeshPartPayload>> _renderItemsSet;
|
QSet<std::shared_ptr<MeshPartPayload>> _renderItemsSet;
|
||||||
QMap<render::ItemID, render::PayloadPointer> _renderItems;
|
QMap<render::ItemID, render::PayloadPointer> _renderItems;
|
||||||
bool _readyWhenAdded = false;
|
bool _readyWhenAdded { false };
|
||||||
bool _needsReload = true;
|
bool _needsReload { true };
|
||||||
bool _needsUpdateClusterMatrices = true;
|
bool _needsUpdateClusterMatrices { true };
|
||||||
bool _showCollisionHull = false;
|
bool _needsUpdateTransparentTextures { true };
|
||||||
|
bool _hasTransparentTextures { false };
|
||||||
|
bool _showCollisionHull { false };
|
||||||
|
|
||||||
friend class ModelMeshPartPayload;
|
friend class ModelMeshPartPayload;
|
||||||
RigPointer _rig;
|
RigPointer _rig;
|
||||||
|
|
Loading…
Reference in a new issue