Changes driven by the alpha mode

This commit is contained in:
Sam Gateau 2019-09-12 17:01:16 -07:00
parent 133a8b7d5e
commit 68b754fc0c
9 changed files with 103 additions and 34 deletions

View file

@ -79,6 +79,7 @@ namespace scriptable {
float roughness;
float metallic;
float scattering;
float alphaCutoff;
bool unlit;
glm::vec3 emissive;
glm::vec3 albedo;

View file

@ -382,7 +382,8 @@ namespace scriptable {
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_VAL_BIT)) {
obj.setProperty("scattering", FALLTHROUGH);
} else if (material.key.isScattering()) {
}
else if (material.key.isScattering()) {
obj.setProperty("scattering", material.scattering);
}
@ -428,8 +429,11 @@ namespace scriptable {
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OPACITY_MASK_MAP_BIT)) {
obj.setProperty("opacityMapMode", FALLTHROUGH);
obj.setProperty("alphaCutoff", FALLTHROUGH);
} else if (material.key.isGlossy()) {
obj.setProperty("opacityMapMode", material.opacityMode);
obj.setProperty("alphaCutoff", material.alphaCutoff);
}
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::OCCLUSION_MAP_BIT)) {

View file

@ -26,6 +26,7 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const
roughness = material.roughness;
metallic = material.metallic;
scattering = material.scattering;
alphaCutoff = material.alphaCutoff;
unlit = material.unlit;
emissive = material.emissive;
albedo = material.albedo;
@ -63,6 +64,7 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint
roughness = material->getRoughness();
metallic = material->getMetallic();
scattering = material->getScattering();
alphaCutoff = material->getAlphaCutoff();
unlit = material->isUnlit();
emissive = material->getEmissive();
albedo = material->getAlbedo();

View file

@ -22,7 +22,8 @@ const float Material::DEFAULT_OPACITY { 1.0f };
const float Material::DEFAULT_ALBEDO { 0.5f };
const float Material::DEFAULT_METALLIC { 0.0f };
const float Material::DEFAULT_ROUGHNESS { 1.0f };
const float Material::DEFAULT_SCATTERING { 0.0f };
const float Material::DEFAULT_SCATTERING{ 0.0f };
const float Material::DEFAULT_ALPHA_CUTOFF { 0.5f };
Material::Material() {
for (int i = 0; i < NUM_TOTAL_FLAGS; i++) {
@ -40,6 +41,7 @@ Material::Material(const Material& material) :
_roughness(material._roughness),
_metallic(material._metallic),
_scattering(material._scattering),
_alphaCutoff(material._alphaCutoff),
_texcoordTransforms(material._texcoordTransforms),
_lightmapParams(material._lightmapParams),
_materialParams(material._materialParams),
@ -50,7 +52,7 @@ Material::Material(const Material& material) :
}
Material& Material::operator=(const Material& material) {
QMutexLocker locker(&_textureMapsMutex);
std::lock_guard<std::recursive_mutex> locker(_textureMapsMutex);
_name = material._name;
_model = material._model;
@ -61,6 +63,7 @@ Material& Material::operator=(const Material& material) {
_roughness = material._roughness;
_metallic = material._metallic;
_scattering = material._scattering;
_alphaCutoff = material._alphaCutoff;
_texcoordTransforms = material._texcoordTransforms;
_lightmapParams = material._lightmapParams;
_materialParams = material._materialParams;
@ -109,8 +112,22 @@ void Material::setScattering(float scattering) {
_scattering = scattering;
}
void Material::setAlphaCutoff(float alphaCutoff) {
alphaCutoff = glm::clamp(alphaCutoff, 0.0f, 1.0f);
// _key.setAlphaCutoff(alphaCutoff != DEFAULT_ALPHA_CUTOFF);
_alphaCutoff = alphaCutoff;
}
void Material::setAlphaMapMode(MaterialKey::AlphaMapMode alphaMode) {
_key.setAlphaMapMode(alphaMode);
}
MaterialKey::AlphaMapMode Material::getAlphaMapMode() const {
return _key.getAlphaMapMode();
}
void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textureMap) {
QMutexLocker locker(&_textureMapsMutex);
std::lock_guard<std::recursive_mutex> locker(_textureMapsMutex);
if (textureMap) {
_key.setMapChannel(channel, true);
@ -166,7 +183,7 @@ void Material::resetOpacityMap() const {
}
const TextureMapPointer Material::getTextureMap(MapChannel channel) const {
QMutexLocker locker(&_textureMapsMutex);
std::lock_guard<std::recursive_mutex> locker(_textureMapsMutex);
auto result = _textureMaps.find(channel);
if (result != _textureMaps.end()) {

View file

@ -11,8 +11,7 @@
#ifndef hifi_model_Material_h
#define hifi_model_Material_h
#include <QMutex>
#include <mutex>
#include <bitset>
#include <map>
#include <unordered_map>
@ -73,6 +72,12 @@ public:
NUM_MAP_CHANNELS,
};
enum AlphaMapMode {
ALPHA_MAP_OPAQUE = 0,
ALPHA_MAP_MASK,
ALPHA_MAP_BLEND,
};
// The signature is the Flags
Flags _flags;
@ -104,6 +109,23 @@ public:
Builder& withTranslucentMap() { _flags.set(OPACITY_TRANSLUCENT_MAP_BIT); return (*this); }
Builder& withMaskMap() { _flags.set(OPACITY_MASK_MAP_BIT); return (*this); }
Builder& withAlphaMapMode(AlphaMapMode mode) {
switch (mode) {
case ALPHA_MAP_OPAQUE:
_flags.reset(OPACITY_TRANSLUCENT_MAP_BIT);
_flags.reset(OPACITY_MASK_MAP_BIT);
break;
case ALPHA_MAP_MASK:
_flags.reset(OPACITY_TRANSLUCENT_MAP_BIT);
_flags.set(OPACITY_MASK_MAP_BIT);
break;
case ALPHA_MAP_BLEND:
_flags.set(OPACITY_TRANSLUCENT_MAP_BIT);
_flags.reset(OPACITY_MASK_MAP_BIT);
break;
};
return (*this);
}
Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
Builder& withOcclusionMap() { _flags.set(OCCLUSION_MAP_BIT); return (*this); }
@ -171,6 +193,25 @@ public:
// Translucency and Opacity Heuristics are combining several flags:
void setAlphaMapMode(AlphaMapMode mode) {
switch (mode) {
case ALPHA_MAP_OPAQUE:
_flags.reset(OPACITY_TRANSLUCENT_MAP_BIT);
_flags.reset(OPACITY_MASK_MAP_BIT);
break;
case ALPHA_MAP_MASK:
_flags.reset(OPACITY_TRANSLUCENT_MAP_BIT);
_flags.set(OPACITY_MASK_MAP_BIT);
break;
case ALPHA_MAP_BLEND:
_flags.set(OPACITY_TRANSLUCENT_MAP_BIT);
_flags.reset(OPACITY_MASK_MAP_BIT);
break;
};
}
AlphaMapMode getAlphaMapMode() const { return (_flags[OPACITY_MASK_MAP_BIT] ? ALPHA_MAP_MASK : (_flags[OPACITY_TRANSLUCENT_MAP_BIT] ? ALPHA_MAP_BLEND : ALPHA_MAP_OPAQUE)); }
bool isTranslucent() const { return isTranslucentFactor() || isTranslucentMap(); }
bool isOpaque() const { return !isTranslucent(); }
bool isSurfaceOpaque() const { return isOpaque() && !isOpacityMaskMap(); }
@ -283,6 +324,13 @@ public:
void setOpacity(float opacity);
float getOpacity() const { return _opacity; }
void setAlphaMapMode(MaterialKey::AlphaMapMode alphaMode);
MaterialKey::AlphaMapMode getAlphaMapMode() const;
static const float DEFAULT_ALPHA_CUTOFF;
void setAlphaCutoff(float alphaCutoff);
float getAlphaCutoff() const { return _alphaCutoff; }
void setUnlit(bool value);
bool isUnlit() const { return _key.isUnlit(); }
@ -357,6 +405,7 @@ private:
float _roughness { DEFAULT_ROUGHNESS };
float _metallic { DEFAULT_METALLIC };
float _scattering { DEFAULT_SCATTERING };
float _alphaCutoff { DEFAULT_ALPHA_CUTOFF };
std::array<glm::mat4, NUM_TEXCOORD_TRANSFORMS> _texcoordTransforms;
glm::vec2 _lightmapParams { 0.0, 1.0 };
glm::vec2 _materialParams { 0.0, 1.0 };
@ -365,7 +414,7 @@ private:
bool _defaultFallthrough { false };
std::unordered_map<uint, bool> _propertyFallthroughs { NUM_TOTAL_FLAGS };
mutable QMutex _textureMapsMutex { QMutex::Recursive };
mutable std::recursive_mutex _textureMapsMutex;
};
typedef std::shared_ptr<Material> MaterialPointer;
@ -425,18 +474,8 @@ public:
float _metallic { Material::DEFAULT_METALLIC }; // Not Metallic
float _scattering { Material::DEFAULT_SCATTERING }; // Scattering info
#if defined(__clang__)
__attribute__((unused))
#endif
glm::vec2 _spare { 0.0f }; // Padding
float _alphaCutoff { Material::DEFAULT_ALPHA_CUTOFF }; // Alpha cutoff applyed when using alphaMa as Mask
uint32_t _key { 0 }; // a copy of the materialKey
#if defined(__clang__)
__attribute__((unused))
#endif
glm::vec3 _spare2 { 0.0f };
// for alignment beauty, Material size == Mat4x4
// Texture Coord Transform Array
glm::mat4 _texcoordTransforms[Material::NUM_TEXCOORD_TRANSFORMS];

View file

@ -49,8 +49,7 @@ struct TexMapArray {
struct Material {
vec4 _emissiveOpacity;
vec4 _albedoRoughness;
vec4 _metallicScatteringSpare2;
vec4 _keySpare3;
vec4 _metallicScatteringAlphaCutoffKey;
};
LAYOUT_STD140(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
@ -72,10 +71,11 @@ vec3 getMaterialAlbedo(Material m) { return m._albedoRoughness.rgb; }
float getMaterialRoughness(Material m) { return m._albedoRoughness.a; }
float getMaterialShininess(Material m) { return 1.0 - getMaterialRoughness(m); }
float getMaterialMetallic(Material m) { return m._metallicScatteringSpare2.x; }
float getMaterialScattering(Material m) { return m._metallicScatteringSpare2.y; }
float getMaterialMetallic(Material m) { return m._metallicScatteringAlphaCutoffKey.x; }
float getMaterialScattering(Material m) { return m._metallicScatteringAlphaCutoffKey.y; }
float getMaterialAlphaCutoff(Material m) { return m._metallicScatteringAlphaCutoffKey.z; }
BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._keySpare3.x); }
BITFIELD getMaterialKey(Material m) { return floatBitsToInt(m._metallicScatteringAlphaCutoffKey.w); }
const BITFIELD EMISSIVE_VAL_BIT = 0x00000001;
const BITFIELD UNLIT_VAL_BIT = 0x00000002;

View file

@ -214,6 +214,13 @@ vec3 fetchLightMap(vec2 uv) {
}
<@endfunc@>
<@func evalMaterialOpacityMask(fetchedOpacity, materialAlphaCutoff, opacity)@>
{
<$opacity$> = step(<$materialAlphaCutoff$>, <$fetchedOpacity$>);
}
<@endfunc@>
<@func evalMaterialOpacity(fetchedOpacity, materialOpacity, matKey, opacity)@>
{
const float OPACITY_MASK_THRESHOLD = 0.5;

View file

@ -486,6 +486,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
schemaKey.setAlbedoMap(true);
schemaKey.setOpacityMaskMap(material->getKey().isOpacityMaskMap());
schemaKey.setTranslucentMap(material->getKey().isTranslucentMap());
schema._alphaCutoff = material->getAlphaCutoff();
}
break;
case graphics::MaterialKey::METALLIC_MAP_BIT:

View file

@ -104,13 +104,12 @@ void main(void) {
<@if HIFI_USE_TRANSLUCENT@>
float opacity = getMaterialOpacity(mat) * _color.a;
<@else@>
float opacity = 1.0;
<@endif@>
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
<@if HIFI_USE_TRANSLUCENT@>
<$discardInvisible(opacity)$>;
<@else@>
float cutoff = getMaterialAlphaCutoff(mat);
float opacity = 1.0;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>;
<$discardTransparent(opacity)$>;
<@endif@>
@ -156,14 +155,13 @@ void main(void) {
<@if HIFI_USE_TRANSLUCENT@>
float opacity = getMaterialOpacity(mat) * _color.a;
<@else@>
float opacity = 1.0;
<@endif@>
<$evalMaterialOpacity(albedoTex.a, opacity, matKey, opacity)$>;
<@if HIFI_USE_TRANSLUCENT@>
<$discardInvisible(opacity)$>;
<$discardInvisible(opacity)$>;
<@else@>
<$discardTransparent(opacity)$>;
float cutoff = getMaterialAlphaCutoff(mat);
float opacity = 1.0;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity)$>;
<$discardTransparent(opacity)$>;
<@endif@>
vec3 albedo = getMaterialAlbedo(mat);