mirror of
https://github.com/lubosz/overte.git
synced 2025-04-08 04:42:20 +02:00
working with texture transform fallthrough
This commit is contained in:
parent
a2fe8ef9e7
commit
ff3545beab
7 changed files with 159 additions and 50 deletions
|
@ -125,13 +125,18 @@ void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
|
|||
}
|
||||
});
|
||||
|
||||
_color = entity->getColor();
|
||||
_alpha = entity->getAlpha();
|
||||
_material->setAlbedo(toGlm(_color));
|
||||
_material->setOpacity(_alpha);
|
||||
auto materials = _materials.find("0");
|
||||
if (materials != _materials.end()) {
|
||||
materials->second.setNeedsUpdate(true);
|
||||
glm::u8vec3 color = entity->getColor();
|
||||
float alpha = entity->getAlpha();
|
||||
if (_color != color || _alpha != alpha) {
|
||||
_color = color;
|
||||
_alpha = alpha;
|
||||
_material->setAlbedo(toGlm(_color));
|
||||
_material->setOpacity(_alpha);
|
||||
|
||||
auto materials = _materials.find("0");
|
||||
if (materials != _materials.end()) {
|
||||
materials->second.setNeedsUpdate(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,7 +284,7 @@ scriptable::ScriptableModelBase ShapeEntityRenderer::getScriptableModel() {
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(_materialsLock);
|
||||
result.appendMaterials(_materials);
|
||||
auto& materials = _materials.find("0");
|
||||
auto materials = _materials.find("0");
|
||||
if (materials != _materials.end()) {
|
||||
vertexColor = materials->second.getSchemaBuffer().get<graphics::MultiMaterial::Schema>()._albedo;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,10 @@ namespace scriptable {
|
|||
* @property {string} occlusionMap
|
||||
* @property {string} lightmapMap
|
||||
* @property {string} scatteringMap
|
||||
* @property {string} texCoordTransform0
|
||||
* @property {string} texCoordTransform1
|
||||
* @property {string} lightmapParams
|
||||
* @property {string} materialParams
|
||||
* @property {boolean} defaultFallthrough
|
||||
*/
|
||||
class ScriptableMaterial {
|
||||
|
@ -91,7 +95,7 @@ namespace scriptable {
|
|||
QString scatteringMap;
|
||||
|
||||
bool defaultFallthrough;
|
||||
std::unordered_map<graphics::MaterialKey::FlagBit, bool> propertyFallthroughs; // not actually exposed to script
|
||||
std::unordered_map<uint, bool> propertyFallthroughs; // not actually exposed to script
|
||||
};
|
||||
|
||||
/**jsdoc
|
||||
|
|
|
@ -404,6 +404,20 @@ namespace scriptable {
|
|||
obj.setProperty("bumpMap", material.bumpMap);
|
||||
}
|
||||
|
||||
// These need to be implemented, but set the fallthrough for now
|
||||
if (material.propertyFallthroughs.at(graphics::Material::TEXCOORDTRANSFORM0)) {
|
||||
obj.setProperty("texCoordTransform0", FALLTHROUGH);
|
||||
}
|
||||
if (material.propertyFallthroughs.at(graphics::Material::TEXCOORDTRANSFORM1)) {
|
||||
obj.setProperty("texCoordTransform1", FALLTHROUGH);
|
||||
}
|
||||
if (material.propertyFallthroughs.at(graphics::Material::LIGHTMAP_PARAMS)) {
|
||||
obj.setProperty("lightmapParams", FALLTHROUGH);
|
||||
}
|
||||
if (material.propertyFallthroughs.at(graphics::Material::MATERIAL_PARAMS)) {
|
||||
obj.setProperty("materialParams", FALLTHROUGH);
|
||||
}
|
||||
|
||||
obj.setProperty("defaultFallthrough", material.defaultFallthrough);
|
||||
|
||||
return obj;
|
||||
|
|
|
@ -25,8 +25,8 @@ const float Material::DEFAULT_ROUGHNESS { 1.0f };
|
|||
const float Material::DEFAULT_SCATTERING { 0.0f };
|
||||
|
||||
Material::Material() {
|
||||
for (int i = 0; i < graphics::MaterialKey::NUM_FLAGS; i++) {
|
||||
_propertyFallthroughs[graphics::MaterialKey::FlagBit(i)] = false;
|
||||
for (int i = 0; i < NUM_TOTAL_FLAGS; i++) {
|
||||
_propertyFallthroughs[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ void MultiMaterial::calculateMaterialInfo() const {
|
|||
_textureSize = 0;
|
||||
_textureCount = 0;
|
||||
|
||||
auto& textures = _textureTable->getTextures();
|
||||
auto textures = _textureTable->getTextures();
|
||||
for (auto const &texture : textures) {
|
||||
if (texture && texture->isDefined()) {
|
||||
auto size = texture->getSize();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <QMutex>
|
||||
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <queue>
|
||||
|
||||
|
@ -176,7 +177,6 @@ public:
|
|||
bool isTexelOpaque() const { return isOpaque() && isOpacityMaskMap(); }
|
||||
};
|
||||
|
||||
|
||||
class MaterialFilter {
|
||||
public:
|
||||
MaterialKey::Flags _value{ 0 };
|
||||
|
@ -267,7 +267,7 @@ public:
|
|||
class Material {
|
||||
public:
|
||||
typedef MaterialKey::MapChannel MapChannel;
|
||||
typedef std::unordered_map<MapChannel, TextureMapPointer> TextureMaps;
|
||||
typedef std::map<MapChannel, TextureMapPointer> TextureMaps;
|
||||
|
||||
Material();
|
||||
Material(const Material& material);
|
||||
|
@ -322,17 +322,30 @@ public:
|
|||
const std::string& getModel() const { return _model; }
|
||||
void setModel(const std::string& model) { _model = model; }
|
||||
|
||||
glm::mat4 getTexCoordTransform(uint i) const { return _texcoordTransforms[i]; }
|
||||
glm::vec2 getLightmapParams() const { return _lightmapParams; }
|
||||
glm::vec2 getMaterialParams() const { return _materialParams; }
|
||||
|
||||
bool getDefaultFallthrough() const { return _defaultFallthrough; }
|
||||
void setDefaultFallthrough(bool defaultFallthrough) { _defaultFallthrough = defaultFallthrough; }
|
||||
|
||||
std::unordered_map<MaterialKey::FlagBit, bool> getPropertyFallthroughs() { return _propertyFallthroughs; }
|
||||
bool getPropertyFallthrough(MaterialKey::FlagBit property) { return _propertyFallthroughs[property]; }
|
||||
void setPropertyDoesFallthrough(MaterialKey::FlagBit property) { _propertyFallthroughs[property] = true; }
|
||||
enum ExtraFlagBit {
|
||||
TEXCOORDTRANSFORM0 = MaterialKey::NUM_FLAGS,
|
||||
TEXCOORDTRANSFORM1,
|
||||
LIGHTMAP_PARAMS,
|
||||
MATERIAL_PARAMS,
|
||||
|
||||
NUM_TOTAL_FLAGS
|
||||
};
|
||||
std::unordered_map<uint, bool> getPropertyFallthroughs() { return _propertyFallthroughs; }
|
||||
bool getPropertyFallthrough(uint property) { return _propertyFallthroughs[property]; }
|
||||
void setPropertyDoesFallthrough(uint property) { _propertyFallthroughs[property] = true; }
|
||||
|
||||
protected:
|
||||
std::string _name { "" };
|
||||
|
||||
private:
|
||||
std::string _model { "hifi_pbr" };
|
||||
mutable MaterialKey _key { 0 };
|
||||
|
||||
// Material properties
|
||||
|
@ -348,11 +361,9 @@ private:
|
|||
TextureMaps _textureMaps;
|
||||
|
||||
bool _defaultFallthrough { false };
|
||||
std::unordered_map<MaterialKey::FlagBit, bool> _propertyFallthroughs;
|
||||
std::unordered_map<uint, bool> _propertyFallthroughs { NUM_TOTAL_FLAGS };
|
||||
|
||||
mutable QMutex _textureMapsMutex { QMutex::Recursive };
|
||||
|
||||
std::string _model { "hifi_pbr" };
|
||||
};
|
||||
typedef std::shared_ptr<Material> MaterialPointer;
|
||||
|
||||
|
@ -434,7 +445,11 @@ public:
|
|||
// y: 1 for texture repeat, 0 for discard outside of 0 - 1
|
||||
glm::vec2 _materialParams { 0.0, 1.0 };
|
||||
|
||||
Schema() {}
|
||||
Schema() {
|
||||
for (auto& transform : _texcoordTransforms) {
|
||||
transform = glm::mat4();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gpu::BufferView& getSchemaBuffer() { return _schemaBuffer; }
|
||||
|
|
|
@ -153,6 +153,14 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
|
|||
* <code>bumpMap</code> is specified. Set to <code>"fallthrough"</code> to fallthrough to the material below. "hifi_pbr" model only.
|
||||
* @property {string} lightMap - URL of light map texture image. <em>Currently not used.</em>. Set to <code>"fallthrough"</code>
|
||||
* to fallthrough to the material below. "hifi_pbr" model only.
|
||||
* @property {string} texCoordTransform0 - The transform to use for all of the maps besides occlusionMap and lightMap. Currently unused. Set to
|
||||
* <code>"fallthrough"</code> to fallthrough to the material below. "hifi_pbr" model only.
|
||||
* @property {string} texCoordTransform1 - The transform to use for occlusionMap and lightMap. Currently unused. Set to <code>"fallthrough"</code>
|
||||
* to fallthrough to the material below. "hifi_pbr" model only.
|
||||
* @property {string} lightmapParams - Parameters for controlling how lightMap is used. Currently unused. Set to <code>"fallthrough"</code>
|
||||
* to fallthrough to the material below. "hifi_pbr" model only.
|
||||
* @property {string} materialParams - Parameters for controlling the material projection and repition. Currently unused. Set to <code>"fallthrough"</code>
|
||||
* to fallthrough to the material below. "hifi_pbr" model only.
|
||||
* @property {bool} defaultFallthrough=false - If <code>true</code>, all properties will fallthrough to the material below unless they are set. If
|
||||
* <code>false</code>, they will respect the individual properties' fallthrough state. "hifi_pbr" model only.
|
||||
*/
|
||||
|
@ -356,6 +364,42 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
|||
material->setLightmapMap(baseUrl.resolved(valueString));
|
||||
}
|
||||
}
|
||||
} else if (key == "texCoordTransform0") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::Material::ExtraFlagBit::TEXCOORDTRANSFORM0);
|
||||
}
|
||||
}
|
||||
// TODO: implement texCoordTransform0
|
||||
} else if (key == "texCoordTransform1") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::Material::ExtraFlagBit::TEXCOORDTRANSFORM1);
|
||||
}
|
||||
}
|
||||
// TODO: implement texCoordTransform1
|
||||
} else if (key == "lightmapParams") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::Material::ExtraFlagBit::LIGHTMAP_PARAMS);
|
||||
}
|
||||
}
|
||||
// TODO: implement lightmapParams
|
||||
} else if (key == "materialParams") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isString()) {
|
||||
auto valueString = value.toString();
|
||||
if (valueString == FALLTHROUGH) {
|
||||
material->setPropertyDoesFallthrough(graphics::Material::ExtraFlagBit::MATERIAL_PARAMS);
|
||||
}
|
||||
}
|
||||
// TODO: implement materialParams
|
||||
} else if (key == "defaultFallthrough") {
|
||||
auto value = materialJSON.value(key);
|
||||
if (value.isBool()) {
|
||||
|
|
|
@ -392,15 +392,14 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
|||
auto& drawMaterialTextures = multiMaterial.getTextureTable();
|
||||
|
||||
// The total list of things we need to look for
|
||||
static std::set<graphics::MaterialKey::FlagBit> allFlagBits;
|
||||
static std::set<uint> allFlags;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [textureCache] {
|
||||
for (int i = 0; i < graphics::MaterialKey::NUM_FLAGS; i++) {
|
||||
auto flagBit = graphics::MaterialKey::FlagBit(i);
|
||||
for (int i = 0; i < graphics::Material::NUM_TOTAL_FLAGS; i++) {
|
||||
// The opacity mask/map are derived from the albedo map
|
||||
if (flagBit != graphics::MaterialKey::OPACITY_MASK_MAP_BIT &&
|
||||
flagBit != graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT) {
|
||||
allFlagBits.insert(flagBit);
|
||||
if (i != graphics::MaterialKey::OPACITY_MASK_MAP_BIT &&
|
||||
i != graphics::MaterialKey::OPACITY_TRANSLUCENT_MAP_BIT) {
|
||||
allFlags.insert(i);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -409,21 +408,28 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
|||
graphics::MultiMaterial::Schema schema;
|
||||
graphics::MaterialKey schemaKey;
|
||||
|
||||
std::set<graphics::MaterialKey::FlagBit> flagBitsToCheck = allFlagBits;
|
||||
std::set<graphics::MaterialKey::FlagBit> flagBitsToSetDefault;
|
||||
std::set<uint> flagsToCheck = allFlags;
|
||||
std::set<uint> flagsToSetDefault;
|
||||
|
||||
while (!materials.empty()) {
|
||||
auto material = materials.top().material;
|
||||
if (!material) {
|
||||
break;
|
||||
}
|
||||
materials.pop();
|
||||
|
||||
auto material = materials.top().material;
|
||||
while (material) {
|
||||
bool defaultFallthrough = material->getDefaultFallthrough();
|
||||
const auto& materialKey = material->getKey();
|
||||
const auto& textureMaps = material->getTextureMaps();
|
||||
|
||||
auto it = flagBitsToCheck.begin();
|
||||
while (it != flagBitsToCheck.end()) {
|
||||
auto flagBit = *it;
|
||||
auto it = flagsToCheck.begin();
|
||||
while (it != flagsToCheck.end()) {
|
||||
auto flag = *it;
|
||||
bool fallthrough = defaultFallthrough || material->getPropertyFallthrough(flag);
|
||||
|
||||
bool wasSet = false;
|
||||
bool forceDefault = false;
|
||||
switch (flagBit) {
|
||||
switch (flag) {
|
||||
case graphics::MaterialKey::EMISSIVE_VAL_BIT:
|
||||
if (materialKey.isEmissive()) {
|
||||
schema._emissive = material->getEmissive(false);
|
||||
|
@ -574,36 +580,56 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
|||
schemaKey.setLightmapMap(true);
|
||||
}
|
||||
break;
|
||||
case graphics::Material::TEXCOORDTRANSFORM0:
|
||||
if (!fallthrough) {
|
||||
schema._texcoordTransforms[0] = material->getTexCoordTransform(0);
|
||||
wasSet = true;
|
||||
}
|
||||
break;
|
||||
case graphics::Material::TEXCOORDTRANSFORM1:
|
||||
if (!fallthrough) {
|
||||
schema._texcoordTransforms[1] = material->getTexCoordTransform(1);
|
||||
wasSet = true;
|
||||
}
|
||||
break;
|
||||
case graphics::Material::LIGHTMAP_PARAMS:
|
||||
if (!fallthrough) {
|
||||
schema._lightmapParams = material->getLightmapParams();
|
||||
wasSet = true;
|
||||
}
|
||||
break;
|
||||
case graphics::Material::MATERIAL_PARAMS:
|
||||
if (!fallthrough) {
|
||||
schema._materialParams = material->getMaterialParams();
|
||||
wasSet = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool fallthrough = defaultFallthrough || material->getPropertyFallthrough(flagBit);
|
||||
if (wasSet) {
|
||||
flagBitsToCheck.erase(it++);
|
||||
flagsToCheck.erase(it++);
|
||||
} else if (forceDefault || !fallthrough) {
|
||||
flagBitsToSetDefault.insert(flagBit);
|
||||
flagBitsToCheck.erase(it++);
|
||||
flagsToSetDefault.insert(flag);
|
||||
flagsToCheck.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
if (flagBitsToCheck.empty()) {
|
||||
if (flagsToCheck.empty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
materials.pop();
|
||||
material = materials.top().material;
|
||||
}
|
||||
|
||||
for (auto flagBit : flagBitsToCheck) {
|
||||
flagBitsToSetDefault.insert(flagBit);
|
||||
for (auto flagBit : flagsToCheck) {
|
||||
flagsToSetDefault.insert(flagBit);
|
||||
}
|
||||
|
||||
// Handle defaults
|
||||
for (auto flagBit : flagBitsToSetDefault) {
|
||||
switch (flagBit) {
|
||||
for (auto flag : flagsToSetDefault) {
|
||||
switch (flag) {
|
||||
case graphics::MaterialKey::EMISSIVE_VAL_BIT:
|
||||
case graphics::MaterialKey::UNLIT_VAL_BIT:
|
||||
case graphics::MaterialKey::ALBEDO_VAL_BIT:
|
||||
|
@ -611,6 +637,10 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
|||
case graphics::MaterialKey::GLOSSY_VAL_BIT:
|
||||
case graphics::MaterialKey::OPACITY_VAL_BIT:
|
||||
case graphics::MaterialKey::SCATTERING_VAL_BIT:
|
||||
case graphics::Material::TEXCOORDTRANSFORM0:
|
||||
case graphics::Material::TEXCOORDTRANSFORM1:
|
||||
case graphics::Material::LIGHTMAP_PARAMS:
|
||||
case graphics::Material::MATERIAL_PARAMS:
|
||||
// these are initialized to the correct default values in Schema()
|
||||
break;
|
||||
case graphics::MaterialKey::ALBEDO_MAP_BIT:
|
||||
|
@ -658,9 +688,6 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME:
|
||||
// set transforms and params
|
||||
|
||||
schema._key = (uint32_t)schemaKey._flags.to_ulong();
|
||||
schemaBuffer.edit<graphics::MultiMaterial::Schema>() = schema;
|
||||
multiMaterial.setNeedsUpdate(false);
|
||||
|
|
Loading…
Reference in a new issue