diff --git a/src/esp/assets/ResourceManager.cpp b/src/esp/assets/ResourceManager.cpp index 09058b17e9..d60563fea1 100644 --- a/src/esp/assets/ResourceManager.cpp +++ b/src/esp/assets/ResourceManager.cpp @@ -1186,33 +1186,39 @@ std::vector ResourceManager::computeAbsoluteTransformations( void ResourceManager::buildPrimitiveAssetData( const std::string& primTemplateHandle) { - // retrieves -actual- template, not a copy - esp::metadata::attributes::AbstractPrimitiveAttributes::ptr primTemplate = - getAssetAttributesManager()->getObjectByHandle(primTemplateHandle); + // use metallic material for primitives + buildPrimitiveAssetData(primTemplateHandle, METALLIC_MATERIAL_KEY); + +} // ResourceManager::buildPrimitiveAssetData +void ResourceManager::buildPrimitiveAssetData( + const std::string& primTemplateHandle, + const std::string& materialKey) { + // retrieves -actual- template, not a copy + esp::metadata::attributes::AbstractPrimitiveAttributes::cptr primTemplate = + getAssetAttributesManager()->getOrCreateTemplateFromHandle( + primTemplateHandle); + // If nullptr then template was not correct format for primitive attributes if (primTemplate == nullptr) { - // Template does not yet exist, create it using its name - primitive - // template names encode all the pertinent template settings and cannot be - // changed by the user, so the template name can be used to recreate the - // template itself. - auto newTemplate = getAssetAttributesManager()->createTemplateFromHandle( - primTemplateHandle); - // if still null, fail. - if (newTemplate == nullptr) { - ESP_ERROR(Mn::Debug::Flag::NoSpace) - << "Attempting to reference or build a " - "primitive template from an unknown/malformed handle : `" - << primTemplateHandle << "`, so aborting build."; - return; - } - // we do not want a copy of the newly created template, but the actual - // template - primTemplate = getAssetAttributesManager()->getObjectByHandle( - newTemplate->getHandle()); + ESP_ERROR(Mn::Debug::Flag::NoSpace) + << "Attempting to reference or build a " + "primitive template from an unknown/malformed handle : `" + << primTemplateHandle << "`, so aborting build."; + return; } + // check if unique name of attributes describing primitive asset is present // already - don't remake if so - auto primAssetHandle = primTemplate->getHandle(); + + // TODO need to support customization of primitive materials in the + // RenderAssetCreationInfo structure, so that queries of resourceDict_ using + // RenderAssetCreationInfo will work properly. + auto primAssetHandle = + // Default metallic primitive material + (materialKey == METALLIC_MATERIAL_KEY) + ? primTemplate->getHandle() + : Cr::Utility::formatString("{}_{}", primTemplate->getHandle(), + materialKey); if (resourceDict_.count(primAssetHandle) > 0) { ESP_DEBUG(Mn::Debug::Flag::NoSpace) << "Primitive Asset exists already : `" << primAssetHandle << "`."; @@ -1233,9 +1239,6 @@ void ResourceManager::buildPrimitiveAssetData( *cfgGroup = newCfgGroup; } - // make assetInfo - AssetInfo info{AssetType::PRIMITIVE}; - info.forceFlatShading = false; // set up primitive mesh // make primitive mesh structure auto primMeshData = std::make_unique(false); @@ -1249,24 +1252,17 @@ void ResourceManager::buildPrimitiveAssetData( primMeshData->uploadBuffersToGPU(false); } + // make assetInfo + AssetInfo info{AssetType::PRIMITIVE}; + info.forceFlatShading = false; + // make MeshMetaData int meshStart = nextMeshID_++; int meshEnd = meshStart; MeshMetaData meshMetaData{meshStart, meshEnd}; meshes_.emplace(meshStart, std::move(primMeshData)); - meshMetaData.root.materialID = std::to_string(nextMaterialID_++); - - // default material for now - // Populate with defaults from sim's gfx::PhongMaterialData - Mn::Trade::MaterialData materialData = buildDefaultPhongMaterial(); - - // Set expected user-defined attributes - materialData = setMaterialDefaultUserAttributes( - materialData, ObjectInstanceShaderType::Phong); - - shaderManager_.set(meshMetaData.root.materialID, - std::move(materialData)); + meshMetaData.root.materialID = materialKey; meshMetaData.root.meshIDLocal = 0; meshMetaData.root.componentID = 0; @@ -1834,22 +1830,30 @@ bool ResourceManager::buildTrajectoryVisualization( meshes_.emplace(meshStart, std::move(visMeshData)); - // default material for now - // Populate with defaults from sim's gfx::PhongMaterialData - Mn::Trade::MaterialData materialData = buildDefaultPhongMaterial(); - // Override default values - materialData.mutableAttribute( + // default material + Mn::Trade::MaterialData trajMaterialData = buildDefaultMaterial(); + // Override default values. These values will in turn be overridden by the + // vertex colors derived from the colorVec values passed to the function. + trajMaterialData.mutableAttribute( Mn::Trade::MaterialAttribute::AmbientColor) = Mn::Color4{1.0}; - materialData.mutableAttribute( + trajMaterialData.mutableAttribute( Mn::Trade::MaterialAttribute::SpecularColor) = Mn::Color4{1.0}; - materialData.mutableAttribute( + trajMaterialData.mutableAttribute( Mn::Trade::MaterialAttribute::Shininess) = 160.0f; + trajMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::BaseColor) = Mn::Color4{1.0}; + trajMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::Metalness) = 0.50f; + trajMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::Roughness) = 0.0f; + // Set expected user-defined attributes - materialData = setMaterialDefaultUserAttributes( - materialData, ObjectInstanceShaderType::Phong, true); + trajMaterialData = setMaterialDefaultUserAttributes( + trajMaterialData, getDefaultMaterialShaderType(), true); + meshMetaData.root.materialID = std::to_string(nextMaterialID_++); shaderManager_.set(meshMetaData.root.materialID, - std::move(materialData)); + std::move(trajMaterialData)); meshMetaData.root.meshIDLocal = 0; meshMetaData.root.componentID = 0; @@ -2001,8 +2005,8 @@ Mn::Trade::MaterialData createUniversalMaterial( // calculate Phong values from PBR material values //////////////// - // derive ambient color from pbr baseColor - const Mn::Color4 ambientColor = pbrMaterial.baseColor(); + // derive diffuse color from pbr baseColor + const Mn::Color4 diffuseColor = pbrMaterial.baseColor(); // If there's a roughness texture, we have no way to use it here. The safest // fallback is to assume roughness == 1, thus producing no spec highlights. @@ -2041,16 +2045,17 @@ Mn::Trade::MaterialData createUniversalMaterial( const float specIntensity = Mn::Math::pow(1.0f - roughness, 2.5f) * 1.4f * specIntensityScale; - const Mn::Color4 diffuseColor = ambientColor; + // Set ambient color to be diffuse color + const Mn::Color4 ambientColor = diffuseColor; // Set spec base color to white or material base color, depending on // metalness. const Mn::Color4 specBaseColor = (metalness > 0.0f ? (metalness < 1.0f - ? Mn::Math::lerp(0xffffffff_rgbaf, ambientColor, + ? Mn::Math::lerp(0xffffffff_rgbaf, diffuseColor, Mn::Math::pow(metalness, 0.5f)) - : ambientColor) + : diffuseColor) : 0xffffffff_rgbaf); const Mn::Color4 specColor = specBaseColor * specIntensity; @@ -2123,8 +2128,10 @@ Mn::Trade::MaterialData createUniversalMaterial( // normal mapping is already present in copied array if present in // original material. - arrayAppend(newAttributes, {{MaterialAttribute::BaseColor, baseColor}, - {MaterialAttribute::Metalness, metalness}}); + arrayAppend(newAttributes, + {{MaterialAttribute::BaseColor, baseColor}, + {MaterialAttribute::Metalness, metalness}, + {MaterialAttribute::Roughness, 1.0f - metalness}}); // if diffuse texture is present, use as base color texture in pbr. if (phongMaterial.hasAttribute(MaterialAttribute::DiffuseTexture)) { @@ -2160,15 +2167,19 @@ Mn::Trade::MaterialData createUniversalMaterial( } // namespace // Specifically for building materials that relied on old defaults -Mn::Trade::MaterialData ResourceManager::buildDefaultPhongMaterial() { +Mn::Trade::MaterialData ResourceManager::buildDefaultMaterial() { Mn::Trade::MaterialData materialData{ - Mn::Trade::MaterialType::Phong, + Mn::Trade::MaterialType::Phong | + Mn::Trade::MaterialType::PbrMetallicRoughness, {{Mn::Trade::MaterialAttribute::AmbientColor, Mn::Color4{0.1}}, {Mn::Trade::MaterialAttribute::DiffuseColor, Mn::Color4{0.7}}, {Mn::Trade::MaterialAttribute::SpecularColor, Mn::Color4{0.2}}, - {Mn::Trade::MaterialAttribute::Shininess, 80.0f}}}; + {Mn::Trade::MaterialAttribute::Shininess, 80.0f}, + {Mn::Trade::MaterialAttribute::BaseColor, Mn::Color4{1.0}}, + {Mn::Trade::MaterialAttribute::Metalness, 0.3f}, + {Mn::Trade::MaterialAttribute::Roughness, 0.3f}}}; return materialData; -} // ResourceManager::buildDefaultPhongMaterial +} // ResourceManager::buildDefaultMaterial Mn::Trade::MaterialData ResourceManager::setMaterialDefaultUserAttributes( const Mn::Trade::MaterialData& material, @@ -2207,7 +2218,7 @@ std::string ResourceManager::createColorMaterial( if (materialResource.state() == Mn::ResourceState::NotLoadedFallback) { // Build a new default phong material - Mn::Trade::MaterialData materialData = buildDefaultPhongMaterial(); + Mn::Trade::MaterialData materialData = buildDefaultMaterial(); materialData.mutableAttribute( Mn::Trade::MaterialAttribute::AmbientColor) = materialColor.ambientColor; @@ -2227,29 +2238,57 @@ std::string ResourceManager::createColorMaterial( return newMaterialID; } // ResourceManager::createColorMaterial +ObjectInstanceShaderType ResourceManager::getDefaultMaterialShaderType() { + return metadataMediator_->getDefaultMaterialShaderType(); +} + void ResourceManager::initDefaultMaterials() { - // Build default phong materials - Mn::Trade::MaterialData dfltMaterialData = buildDefaultPhongMaterial(); + const auto defaultMaterialShader = getDefaultMaterialShaderType(); + // Build default materials + Mn::Trade::MaterialData dfltMaterialData = buildDefaultMaterial(); // Set expected user-defined attributes - dfltMaterialData = setMaterialDefaultUserAttributes( - dfltMaterialData, ObjectInstanceShaderType::Phong); + dfltMaterialData = + setMaterialDefaultUserAttributes(dfltMaterialData, defaultMaterialShader); // Add to shaderManager at specified key location shaderManager_.set(DEFAULT_MATERIAL_KEY, std::move(dfltMaterialData)); // Build white material - Mn::Trade::MaterialData whiteMaterialData = buildDefaultPhongMaterial(); + Mn::Trade::MaterialData whiteMaterialData = buildDefaultMaterial(); whiteMaterialData.mutableAttribute( Mn::Trade::MaterialAttribute::AmbientColor) = Mn::Color4{1.0}; + whiteMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::Metalness) = 0.0f; + whiteMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::Roughness) = 0.5f; // Set expected user-defined attributes - whiteMaterialData = setMaterialDefaultUserAttributes( - whiteMaterialData, ObjectInstanceShaderType::Phong); + whiteMaterialData = setMaterialDefaultUserAttributes(whiteMaterialData, + defaultMaterialShader); // Add to shaderManager at specified key location shaderManager_.set(WHITE_MATERIAL_KEY, std::move(whiteMaterialData)); + + // Build metallic material + Mn::Trade::MaterialData metalMaterialData = buildDefaultMaterial(); + metalMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::SpecularColor) = Mn::Color4{1.0}; + metalMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::Shininess) = 250.0f; + metalMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::Metalness) = 0.7f; + // Set expected user-defined attributes + metalMaterialData = setMaterialDefaultUserAttributes(metalMaterialData, + defaultMaterialShader); + // Add to shaderManager at specified key location + shaderManager_.set(METALLIC_MATERIAL_KEY, + std::move(metalMaterialData)); // Build white vertex ID material - Mn::Trade::MaterialData vertIdMaterialData = buildDefaultPhongMaterial(); + Mn::Trade::MaterialData vertIdMaterialData = buildDefaultMaterial(); vertIdMaterialData.mutableAttribute( Mn::Trade::MaterialAttribute::AmbientColor) = Mn::Color4{1.0}; + vertIdMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::Metalness) = 0.0f; + vertIdMaterialData.mutableAttribute( + Mn::Trade::MaterialAttribute::Roughness) = 1.0f; // Set expected user-defined attributes vertIdMaterialData = setMaterialDefaultUserAttributes( vertIdMaterialData, ObjectInstanceShaderType::Phong, true); @@ -2258,10 +2297,10 @@ void ResourceManager::initDefaultMaterials() { std::move(vertIdMaterialData)); // Build default material for fallback material - auto fallBackMaterial = buildDefaultPhongMaterial(); + auto fallBackMaterial = buildDefaultMaterial(); // Set expected user-defined attributes - fallBackMaterial = setMaterialDefaultUserAttributes( - fallBackMaterial, ObjectInstanceShaderType::Phong); + fallBackMaterial = + setMaterialDefaultUserAttributes(fallBackMaterial, defaultMaterialShader); // Add to shaderManager as fallback material shaderManager_.setFallback( std::move(fallBackMaterial)); @@ -2288,6 +2327,8 @@ void ResourceManager::loadMaterials(Importer& importer, int textureBaseIndex = loadedAssetData.meshMetaData.textureIndex.first; if (loadedAssetData.assetInfo.hasSemanticTextures) { + // Assumes if semantic textures are present then only semantic rendering is + // processed. for (int iMaterial = 0; iMaterial < numMaterials; ++iMaterial) { // Build material key std::string materialKey = std::to_string(nextMaterialID_++); @@ -2303,17 +2344,18 @@ void ResourceManager::loadMaterials(Importer& importer, } // Semantic texture-based mapping - // Build a phong material for semantics. TODO: Should this be a - // FlatMaterialData? Populate with defaults from deprecated - // gfx::PhongMaterialData - Mn::Trade::MaterialData newMaterialData = buildDefaultPhongMaterial(); - // Override default values - newMaterialData.mutableAttribute( - Mn::Trade::MaterialAttribute::AmbientColor) = Mn::Color4{1.0}; - newMaterialData.mutableAttribute( - Mn::Trade::MaterialAttribute::DiffuseColor) = Mn::Color4{}; - newMaterialData.mutableAttribute( - Mn::Trade::MaterialAttribute::SpecularColor) = Mn::Color4{}; + // Build a phong material for semantic textures. Should this be a + // FlatMaterialData? + Mn::Trade::MaterialData newMaterialData{ + Mn::Trade::MaterialType::Phong | + Mn::Trade::MaterialType::PbrMetallicRoughness, + {{Mn::Trade::MaterialAttribute::AmbientColor, Mn::Color4{1.0}}, + {Mn::Trade::MaterialAttribute::DiffuseColor, Mn::Color4{}}, + {Mn::Trade::MaterialAttribute::SpecularColor, Mn::Color4{}}, + {Mn::Trade::MaterialAttribute::Shininess, 1.0f}, + {Mn::Trade::MaterialAttribute::BaseColor, Mn::Color4{1.0}}, + {Mn::Trade::MaterialAttribute::Metalness, 0.0f}, + {Mn::Trade::MaterialAttribute::Roughness, 1.0f}}}; // Set expected user-defined attributes - force to use phong shader for // semantics @@ -2350,7 +2392,7 @@ void ResourceManager::loadMaterials(Importer& importer, if ((shaderTypeToUse != ObjectInstanceShaderType::Material) && (shaderTypeToUse != ObjectInstanceShaderType::Flat) && !(compareShaderTypeToMnMatType(shaderTypeToUse, *materialData))) { - // Only create this string if veryverbose logging is enabled + // Only create this string if debug logging is enabled if (ESP_LOG_LEVEL_ENABLED(logging::LoggingLevel::Debug)) { materialExpandStr = Cr::Utility::formatString( "Forcing to {} shader (material requires expansion to support it " @@ -3262,6 +3304,11 @@ void ResourceManager::initDefaultLightSetups() { std::shared_ptr ResourceManager::getOrBuildPBRIBLHelper( const std::shared_ptr& pbrShaderAttr) { + // Don't attempt to retrieve or create IBL maps if no gl context is available + if (!getCreateRenderer()) { + return nullptr; + } + auto helperKey = pbrShaderAttr->getPbrShaderHelperKey(); ESP_DEBUG(Mn::Debug::Flag::NoSpace) diff --git a/src/esp/assets/ResourceManager.h b/src/esp/assets/ResourceManager.h index a794b97fee..44ab46b8e8 100644 --- a/src/esp/assets/ResourceManager.h +++ b/src/esp/assets/ResourceManager.h @@ -699,20 +699,33 @@ class ResourceManager { bool forceFlatShading); /** - * @brief Build a primitive asset based on passed template parameters. If - * exists already, does nothing. Will use primitiveImporter_ to call - * appropriate method to construct asset. + * @brief Build a primitive asset based on the template parameters encoded in + * @p primTemplateHandle , using the predefined material referenced by + * DEFAULT_MATERIAL_KEY. If primitive asset exists already, does nothing. Will + * use primitiveImporter_ to call appropriate method to construct asset. * @param primTemplateHandle the handle referring to the attributes describing * primitive to instantiate */ void buildPrimitiveAssetData(const std::string& primTemplateHandle); /** - * @brief this will build a Phong @ref Magnum::Trade::MaterialData using - * default attributes from deprecated/removed esp::gfx::PhongMaterialData. - * @return The new phong color populated with default values + * @brief Build a primitive asset based on passed template parameters and + * passed material key. If exists already, does nothing. Will use + * primitiveImporter_ to call appropriate method to construct asset. + * @param primTemplateHandle the handle referring to the attributes describing + * primitive to instantiate + * @param materialKey The key to the existing material being used for this + * primitive. + */ + void buildPrimitiveAssetData(const std::string& primTemplateHandle, + const std::string& materialKey); + /** + * @brief this will build a MaterialData compatible with Flat, Phong and + * PBR @ref Magnum::Trade::MaterialData, using default attributes + * from deprecated/removed habitat material default values. + * @return The new material populated with default values */ - Mn::Trade::MaterialData buildDefaultPhongMaterial(); + Mn::Trade::MaterialData buildDefaultMaterial(); /** * @brief Define and set user-defined attributes for the passed @@ -1116,6 +1129,11 @@ class ResourceManager { */ void initDefaultMaterials(); + /** + * @brief Retrieve the shader type to use for the various default materials. + */ + ObjectInstanceShaderType getDefaultMaterialShaderType(); + /** * @brief Checks if light setup is compatible with loaded asset */ diff --git a/src/esp/core/Esp.h b/src/esp/core/Esp.h index 02cf57f2ff..d0082bddfe 100644 --- a/src/esp/core/Esp.h +++ b/src/esp/core/Esp.h @@ -102,10 +102,16 @@ constexpr char DEFAULT_MATERIAL_KEY[] = ""; /** *@brief The @ref esp::gfx::ShaderManager key for full ambient white @ref - *esp::gfx::MaterialInfo used for primitive wire-meshes + *esp::gfx::MaterialInfo */ constexpr char WHITE_MATERIAL_KEY[] = "ambient_white"; +/** + *@brief The @ref esp::gfx::ShaderManager key for shiny metallic @ref + *esp::gfx::MaterialInfo + */ +constexpr char METALLIC_MATERIAL_KEY[] = "metallic_gray"; + /** *@brief The @ref ShaderManager key for @ref MaterialInfo with per-vertex * object ID diff --git a/src/esp/gfx/PbrDrawable.cpp b/src/esp/gfx/PbrDrawable.cpp index bc2bda3d31..b2798f8734 100644 --- a/src/esp/gfx/PbrDrawable.cpp +++ b/src/esp/gfx/PbrDrawable.cpp @@ -327,6 +327,12 @@ void PbrDrawable::setMaterialValuesInternal( matCache.volumeLayer.attenuationColor = *attenuationColor; } } // has KHR_materials_volume layer + + // Vertex colors (for synth assets) + if (meshAttributeFlags_ & Drawable::Flag::HasVertexColor) { + flags_ |= PbrShader::Flag::VertexColor; + } + // If not reset then make sure the same shader is used if (!reset) { flags_ = oldFlags; diff --git a/src/esp/gfx/PbrShader.cpp b/src/esp/gfx/PbrShader.cpp index 0ab1ba191f..a5ed4bcb93 100644 --- a/src/esp/gfx/PbrShader.cpp +++ b/src/esp/gfx/PbrShader.cpp @@ -107,6 +107,11 @@ PbrShader::PbrShader(Flags originalFlags, attributeLocationsStream << Cr::Utility::formatString( "#define ATTRIBUTE_LOCATION_TANGENT4 {}\n", Tangent4::Location); } + if (flags_ >= Flag::VertexColor) { + attributeLocationsStream << Cr::Utility::formatString( + "#define ATTRIBUTE_LOCATION_COLOR {}\n", Color4::Location); + } + // TODO: Occlusion texture to be added. if (isTextured_) { @@ -126,6 +131,7 @@ PbrShader::PbrShader(Flags originalFlags, .addSource(isTextured_ && (flags_ >= Flag::TextureTransformation) ? "#define TEXTURE_TRANSFORMATION\n" : "") + .addSource(flags_ >= Flag::VertexColor ? "#define VERTEX_COLOR\n" : "") .addSource(rs.getString("pbr.vert")); std::stringstream outputAttributeLocationsStream; @@ -146,6 +152,7 @@ PbrShader::PbrShader(Flags originalFlags, .addSource(flags_ >= Flag::NormalTexture ? "#define NORMAL_TEXTURE\n" : "") .addSource(flags_ >= Flag::ObjectId ? "#define OBJECT_ID\n" : "") + .addSource(flags_ >= Flag::VertexColor ? "#define VERTEX_COLOR\n" : "") // Clearcoat layer .addSource(flags_ >= Flag::ClearCoatLayer ? "#define CLEAR_COAT\n" : "") diff --git a/src/esp/gfx/PbrShader.h b/src/esp/gfx/PbrShader.h index 80902226bf..79f9d5730a 100644 --- a/src/esp/gfx/PbrShader.h +++ b/src/esp/gfx/PbrShader.h @@ -53,6 +53,11 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { */ typedef Magnum::Shaders::GenericGL3D::Tangent4 Tangent4; + /** + * @brief Four-component vertex color + */ + typedef Magnum::Shaders::GenericGL3D::Color4 Color4; + enum : Magnum::UnsignedInt { /** * Color shader output. @ref shaders-generic "Generic output", @@ -108,6 +113,11 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { */ EmissiveTexture = 1ULL << 4, + /** + * Support mesh vertex colors + */ + VertexColor = 1ULL << 5, + /** * Enable texture coordinate transformation. If this flag is set, * the shader expects that at least one of @@ -118,7 +128,7 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * @ref Flag::OcclusionRoughnessMetallicTexture is enabled as well. * @see @ref setTextureMatrix() */ - TextureTransformation = 1ULL << 5, + TextureTransformation = 1ULL << 6, /** * TODO: Do we need instanced object? (instanced texture, instanced id etc.) @@ -136,86 +146,84 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * see PBR fragment shader code for more details * Requires the @ref Tangent4 attribute to be present. */ - PrecomputedTangent = 1ULL << 6, + PrecomputedTangent = 1ULL << 7, /** * Enable object ID output for this shader. */ - ObjectId = 1ULL << 7, + ObjectId = 1ULL << 8, /** * Support Instanced object ID. Retrieves a per-instance / per-vertex * object ID from the @ref ObjectId attribute. If this is false, the shader * will use the node's semantic ID */ - InstancedObjectId = (1ULL << 8) | ObjectId, + InstancedObjectId = (1ULL << 9) | ObjectId, /** * Has ClearCoat layer. */ - ClearCoatLayer = 1ULL << 9, + ClearCoatLayer = 1ULL << 10, /** * Has ClearCoat Texture in ClearCoat layer */ - ClearCoatTexture = (1ULL << 10) | ClearCoatLayer, + ClearCoatTexture = (1ULL << 11) | ClearCoatLayer, /** * Has Roughness Texture in ClearCoat layer */ - ClearCoatRoughnessTexture = (1ULL << 11) | ClearCoatLayer, + ClearCoatRoughnessTexture = (1ULL << 12) | ClearCoatLayer, /** * Has Normal Texture in ClearCoat layer */ - ClearCoatNormalTexture = (1ULL << 12) | ClearCoatLayer, + ClearCoatNormalTexture = (1ULL << 13) | ClearCoatLayer, /** * Has KHR_materials_specular layer */ - SpecularLayer = 1ULL << 13, + SpecularLayer = 1ULL << 14, /** * Has Specular Texture in KHR_materials_specular layer */ - SpecularLayerTexture = (1ULL << 14) | SpecularLayer, + SpecularLayerTexture = (1ULL << 15) | SpecularLayer, /** * Has Specular Color Texture in KHR_materials_specular layer */ - SpecularLayerColorTexture = (1ULL << 15) | SpecularLayer, + SpecularLayerColorTexture = (1ULL << 16) | SpecularLayer, /** * Has KHR_materials_anisotropy layer */ - AnisotropyLayer = 1ULL << 16, + AnisotropyLayer = 1ULL << 17, /** * Has Anisotropy Texture in KHR_materials_anisotropy layer */ - AnisotropyLayerTexture = (1ULL << 17) | AnisotropyLayer, + AnisotropyLayerTexture = (1ULL << 18) | AnisotropyLayer, /** * Has KHR_materials_transmission layer */ - TransmissionLayer = 1ULL << 18, + TransmissionLayer = 1ULL << 19, /** * Has transmission texture in KHR_materials_transmission layer */ - TransmissionLayerTexture = (1ULL << 19) | TransmissionLayer, + TransmissionLayerTexture = (1ULL << 20) | TransmissionLayer, /** * Has KHR_materials_volume layer */ - VolumeLayer = 1ULL << 20, + VolumeLayer = 1ULL << 21, /** * Has Thickness texture in KHR_materials_volume layer */ - VolumeLayerThicknessTexture = (1ULL << 21) | VolumeLayer, + VolumeLayerThicknessTexture = (1ULL << 22) | VolumeLayer, /** * Enable double-sided rendering. - * (Temporarily STOP supporting this functionality. See comments in - * the PbrDrawable::draw() function) */ - DoubleSided = 1ULL << 22, + DoubleSided = 1ULL << 23, /////////////////////////////// // PbrShaderAttributes provides these values to configure the shader @@ -224,12 +232,12 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * If not set, disable direct lighting regardless of presence of lights. * Ignored if no direct lights present. */ - DirectLighting = 1ULL << 23, + DirectLighting = 1ULL << 24, /** * Enable image based lighting */ - ImageBasedLighting = 1ULL << 24, + ImageBasedLighting = 1ULL << 25, /** * Whether or not the direct lighting diffuse calculation should use the @@ -238,7 +246,7 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf * Lambertian is simpler and quicker to calculate but may not look as 'nice' */ - UseBurleyDiffuse = 1ULL << 25, + UseBurleyDiffuse = 1ULL << 26, /** * If set, skip TBN frame calculation in fragment shader. This calculation @@ -246,7 +254,7 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * provided. * TODO : implement in shader. */ - SkipMissingTBNCalc = 1ULL << 26, + SkipMissingTBNCalc = 1ULL << 27, /** * Use the Mikkelsen algorithm to calculate TBN, as per @@ -256,7 +264,7 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * https://github.com/KhronosGroup/Vulkan-Samples/blob/main/shaders/pbr.frag, * which empirically seems to give equivalent results. */ - UseMikkelsenTBN = 1ULL << 27, + UseMikkelsenTBN = 1ULL << 28, /** * Whether we should use shader-based srgb->linear approx remapping of @@ -264,7 +272,7 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * and IBL. This field should be removed/ignored when Magnum fully supports * sRGB texture conversion on load. */ - MapMatTxtrToLinear = 1ULL << 28, + MapMatTxtrToLinear = 1ULL << 29, /** * Whether we should use shader-based srgb->linear approx remapping of @@ -272,7 +280,7 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * calculations. This field should be removed/ignored when Magnum fully * supports sRGB texture conversion on load. */ - MapIBLTxtrToLinear = 1ULL << 29, + MapIBLTxtrToLinear = 1ULL << 30, /** * Whether we should use shader-based linear->srgb approx remapping of @@ -280,17 +288,17 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * field should be removed/ignored when an appropriate framebuffer is used * for output to handle this conversion. */ - MapOutputToSRGB = 1ULL << 30, + MapOutputToSRGB = 1ULL << 31, /** * Whether or not to use tonemappping for direct lighting. */ - UseDirectLightTonemap = 1ULL << 31, + UseDirectLightTonemap = 1ULL << 32, /** * Whether or not to use tonemappping for image-based lighting. */ - UseIBLTonemap = 1ULL << 32, + UseIBLTonemap = 1ULL << 33, //////////////// // Testing and debugging @@ -299,25 +307,25 @@ class PbrShader : public Magnum::GL::AbstractShaderProgram { * sent to the shader, but no actual calcuations will be performed if this * is set. */ - SkipClearCoatLayer = 1ULL << 33, + SkipClearCoatLayer = 1ULL << 34, /** * Whether we should skip all specular layer calcs. Values will still be * sent to the shader, but no actual calcuations will be performed if this * is set. */ - SkipSpecularLayer = 1ULL << 34, + SkipSpecularLayer = 1ULL << 35, /** * Whether we should skip all anisotropy layer calcs. Values will still be * sent to the shader, but no actual calcuations will be performed if this * is set. */ - SkipAnisotropyLayer = 1ULL << 35, + SkipAnisotropyLayer = 1ULL << 36, /** * Enable shader debug mode. Then developer can set the uniform * PbrDebugDisplay in the fragment shader for debugging */ - DebugDisplay = 1ULL << 36, + DebugDisplay = 1ULL << 37, /* * TODO: alphaMask */ diff --git a/src/esp/metadata/MetadataMediator.h b/src/esp/metadata/MetadataMediator.h index 582dbbcdc9..85c0bd9ed4 100644 --- a/src/esp/metadata/MetadataMediator.h +++ b/src/esp/metadata/MetadataMediator.h @@ -241,6 +241,13 @@ class MetadataMediator { currDefaultPbrAttributesHandle_); } + /** + * @brief Retrieve the shader type to use for the various default materials. + */ + attributes::ObjectInstanceShaderType getDefaultMaterialShaderType() { + return getActiveDSAttribs()->getDefaultMaterialShaderType(); + } + /** * @brief Get a list of all scene instances available in the currently active * dataset diff --git a/src/esp/metadata/attributes/SceneDatasetAttributes.cpp b/src/esp/metadata/attributes/SceneDatasetAttributes.cpp index b183f199d4..aa772032b3 100644 --- a/src/esp/metadata/attributes/SceneDatasetAttributes.cpp +++ b/src/esp/metadata/attributes/SceneDatasetAttributes.cpp @@ -24,6 +24,8 @@ SceneDatasetAttributes::SceneDatasetAttributes( stageAttributesManager_ = managers::StageAttributesManager::create(physAttrMgr); stageAttributesManager_->setAssetAttributesManager(assetAttributesManager_); + // Use PBR as default materials.Override this in SceneDataset config + setDefaultMaterialIsPBR(true); } // ctor bool SceneDatasetAttributes::addNewSceneInstanceToDataset( diff --git a/src/esp/metadata/attributes/SceneDatasetAttributes.h b/src/esp/metadata/attributes/SceneDatasetAttributes.h index fadf53e684..1ea0a7b549 100644 --- a/src/esp/metadata/attributes/SceneDatasetAttributes.h +++ b/src/esp/metadata/attributes/SceneDatasetAttributes.h @@ -90,6 +90,24 @@ class SceneDatasetAttributes : public AbstractAttributes { return stageAttributesManager_; } + /** + * @brief Retrieve the shader type to use for the various default materials, + * either Phong of PBR + */ + ObjectInstanceShaderType getDefaultMaterialShaderType() const { + return get("default_material_is_pbr") + ? ObjectInstanceShaderType::PBR + : ObjectInstanceShaderType::Phong; + } + + /** + * @brief Set whether to use PBR or Phong for the default material values + * defined in resource Manager. + */ + void setDefaultMaterialIsPBR(bool default_material_is_pbr) { + set("default_material_is_pbr", default_material_is_pbr); + } + /** * @brief Return the map for navmesh file locations */ diff --git a/src/esp/metadata/managers/AssetAttributesManager.cpp b/src/esp/metadata/managers/AssetAttributesManager.cpp index e624ed9a12..9699a4a4cf 100644 --- a/src/esp/metadata/managers/AssetAttributesManager.cpp +++ b/src/esp/metadata/managers/AssetAttributesManager.cpp @@ -173,6 +173,20 @@ AssetAttributesManager::createTemplateFromHandle( registerTemplate); } // AssetAttributesManager::createTemplateFromHandle +attributes::AbstractPrimitiveAttributes::cptr +AssetAttributesManager::getOrCreateTemplateFromHandle( + const std::string& templateHandle, + bool registerTemplate) { + if (!getObjectLibHasHandle(templateHandle)) { + // If doesn't exist, create template from handle + createTemplateFromHandle(templateHandle, registerTemplate); + } + // Returns the actual template, not a copy + attributes::AbstractPrimitiveAttributes::cptr resTemplate = + getObjectByHandle(templateHandle); + return resTemplate; +} // AssetAttributesManager::createTemplateFromHandle + int AssetAttributesManager::registerObjectFinalize( AbstractPrimitiveAttributes::ptr primAttributesTemplate, const std::string&, diff --git a/src/esp/metadata/managers/AssetAttributesManager.h b/src/esp/metadata/managers/AssetAttributesManager.h index fa8596be7a..42ab45572e 100644 --- a/src/esp/metadata/managers/AssetAttributesManager.h +++ b/src/esp/metadata/managers/AssetAttributesManager.h @@ -152,6 +152,23 @@ class AssetAttributesManager const std::string& templateHandle, bool registerTemplate = true); + /** + * @brief Retrieves the template specified by the supplied handle, creating + * the template if none exists. Since the primitive asset attributes templates + * encode their structure in their handles, and these handles are not user + * editable, a properly configured handle can be used to build a template. + * @param templateHandle The template handle to use to create the attributes. + * @param registerTemplate whether to add this template to the library. + * If the user is going to edit this template, this should be false - any + * subsequent editing will require re-registration. Defaults to true. If + * specified as true, then this function returns a copy of the registered + * template. + * @return The attributes that most closely matches the given handle. + */ + attributes::AbstractPrimitiveAttributes::cptr getOrCreateTemplateFromHandle( + const std::string& templateHandle, + bool registerTemplate = true); + /** * @brief Should only be called internally. Creates an instance of a * primtive asset attributes template described by passed enum value. For diff --git a/src/shaders/gfx/pbr.vert b/src/shaders/gfx/pbr.vert index 01b6a71776..8f1677257d 100644 --- a/src/shaders/gfx/pbr.vert +++ b/src/shaders/gfx/pbr.vert @@ -15,6 +15,10 @@ layout(location = ATTRIBUTE_LOCATION_TEXCOORD) in highp vec2 vertexTexCoord; layout(location = ATTRIBUTE_LOCATION_TANGENT4) in highp vec4 vertexTangent; #endif +#ifdef VERTEX_COLOR +layout(location = ATTRIBUTE_LOCATION_COLOR) in highp vec4 vertexColor; +#endif + // -------------- output --------------------- // position, normal, tangent in *world* space, NOT camera space! out highp vec3 position; @@ -33,7 +37,9 @@ uniform highp mat3 uTextureMatrix out highp vec3 tangent; out highp vec3 biTangent; #endif - +#ifdef VERTEX_COLOR +out highp vec4 interpolatedVertexColor; +#endif // ------------ uniform ---------------------- uniform highp mat4 uViewMatrix; uniform highp mat3 uNormalMatrix; // inverse transpose of 3x3 model matrix, NOT @@ -64,6 +70,10 @@ void main() { // (read from normal map) from tangent space to world space, // NOT camera space #endif +#ifdef VERTEX_COLOR + /* Vertex colors, if enabled */ + interpolatedVertexColor = vertexColor; +#endif gl_Position = uProjectionMatrix * uViewMatrix * vertexWorldPosition; } diff --git a/src/shaders/gfx/pbrMaterials.glsl b/src/shaders/gfx/pbrMaterials.glsl index 24e35c069e..de6188709c 100644 --- a/src/shaders/gfx/pbrMaterials.glsl +++ b/src/shaders/gfx/pbrMaterials.glsl @@ -150,7 +150,11 @@ PBRData buildPBRData() { pbrInfo.n_dot_v = clamp(dot(pbrInfo.n, pbrInfo.view), 0.0, 1.0); ////////////////////// // colors - pbrInfo.baseColor = uMaterial.baseColor; + pbrInfo.baseColor = uMaterial.baseColor +#ifdef VERTEX_COLOR + * interpolatedVertexColor +#endif + ; #if defined(BASECOLOR_TEXTURE) #if defined(MAP_MAT_TXTRS_TO_LINEAR) diff --git a/src/shaders/gfx/pbrUniforms.glsl b/src/shaders/gfx/pbrUniforms.glsl index 6fdb6fbecf..fa4a1d6e29 100644 --- a/src/shaders/gfx/pbrUniforms.glsl +++ b/src/shaders/gfx/pbrUniforms.glsl @@ -16,7 +16,9 @@ in highp vec2 texCoord; in highp vec3 tangent; in highp vec3 biTangent; #endif - +#ifdef VERTEX_COLOR +in highp vec4 interpolatedVertexColor; +#endif // -------------- uniforms ---------------- #if defined(OBJECT_ID) uniform highp uint uObjectId;