Files
o3de/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Material/MaterialComponentController.h
T
santorac 60d137c5b6 Merge pull request #2746 from aws-lumberyard-dev/Atom/santorac/OptionalSceneApiMaterialConversion3
Made Model Material Conversion Optional

Added a new registry setting that disables automatic conversion of materials from model files like FBX.

By default, processing of model files (like FBX) automatically convert the included materials to Atom materials, using StandardPBR. This adds a job dependency on StandardPBR.materialtype, which propagates to any related azsl files as well. Thus any change to azsl code will cause all model files in the project to rebuild.

Some game teams have no interest in using the auto-converted materials; they always use a Material Component to apply material overrides for every mesh. This new setting allows teams to disable material auto-conversion for the entire project, thus removing the job dependency on StandardPBR.materialtype. Instead, every mesh will be assigned the same default material. Any change to azsl code will cause that one default material to rebuild, but this will not trigger any models to rebuild.

Details:
- Added /O3DE/SceneAPI/MaterialConverter registry settings for configuring the scene material converter. It includes an enable flag, and a default material to use when conversion is disabled.
- Added SceneBuilderDependencyRequests::AddFingerprintInfo which allows SceneAPI components to modify the scene builder analysis fingerprint. We use this to reprocess scene files when the material converter settings change.
- Updated SceneAPI's material asset builder to skip the StandardPBR dependency when material conversion is disabled.
- Added some code to MaterialComponentController to handle an edge case that may when disabling material conversion on an existing project, and assigned materials disappear.

Testing:
- Changing the registry setting does trigger a rebuild of the fbx files.
- When material conversion is disabled, changing an azsl file does not cause fbx files to rebuild, but the shader still reloads as expected.
- Made a test level using multiple models with multiple meshes, made various adjustments to the material slots for each mesh, and tried switching the material conversion registry setting from true to false. (Details below)
- Merged this change to a customer's fork and tested on their existing content.

Details about my test level:
- Made a new test level AtomTest project
- Added two entities, both using multi-mat_mesh-groups_1m_cubes.fbx
- Added a material component to both entities
  - Entity 1 material assignments
    - Blue_Zaxis: left as-is
    - Green_Yaxis: exported the material
    - Red_Xaxis: exported the material, and changed the material instance color to pink
    - StingrayPBS1: exported the material, scaled the UVs in the exported material source, and changed the material instance color to green.
    - With_Texture: selected an existing brick material, changed the material instance color to red.
  - Entity 2 material assignments
    - Default Material: set to an existing brick material
    - Blue_Zaxis: manually assigned built-in material that was converted from fbx
    - Green_Yaxis: manually assigned built-in material that was converted from fbx, and changed the material instance color to orange
2021-08-23 15:24:21 -07:00

117 lines
8.2 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <AzCore/Component/TickBus.h>
#include <Atom/RPI.Public/Material/Material.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConfig.h>
namespace AZ
{
namespace Render
{
//! Can be paired with renderable components (MeshComponent for example)
//! to provide material overrides on a per-entity basis.
class MaterialComponentController final
: MaterialComponentRequestBus::Handler
, Data::AssetBus::MultiHandler
, TickBus::Handler
{
public:
friend class EditorMaterialComponent;
AZ_CLASS_ALLOCATOR(MaterialComponentController, AZ::SystemAllocator, 0);
AZ_RTTI(MaterialComponentController, "{34AD7ED0-9866-44CD-93B6-E86840214B91}");
static void Reflect(ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
MaterialComponentController() = default;
MaterialComponentController(const MaterialComponentConfig& config);
void Activate(AZ::EntityId entityId);
void Deactivate();
void SetConfiguration(const MaterialComponentConfig& config);
const MaterialComponentConfig& GetConfiguration() const;
//! MaterialComponentRequestBus overrides...
MaterialAssignmentMap GetOriginalMaterialAssignments() const override;
MaterialAssignmentId FindMaterialAssignmentId(const MaterialAssignmentLodIndex lod, const AZStd::string& label) const override;
void SetMaterialOverrides(const MaterialAssignmentMap& materials) override;
const MaterialAssignmentMap& GetMaterialOverrides() const override;
void ClearAllMaterialOverrides() override;
void SetDefaultMaterialOverride(const AZ::Data::AssetId& materialAssetId) override;
const AZ::Data::AssetId GetDefaultMaterialOverride() const override;
void ClearDefaultMaterialOverride() override;
void SetMaterialOverride(const MaterialAssignmentId& materialAssignmentId, const AZ::Data::AssetId& materialAssetId) override;
const AZ::Data::AssetId GetMaterialOverride(const MaterialAssignmentId& materialAssignmentId) const override;
void ClearMaterialOverride(const MaterialAssignmentId& materialAssignmentId) override;
void SetPropertyOverride(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZStd::any& value) override;
void SetPropertyOverrideBool(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const bool& value) override;
void SetPropertyOverrideInt32(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const int32_t& value) override;
void SetPropertyOverrideUInt32(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const uint32_t& value) override;
void SetPropertyOverrideFloat(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const float& value) override;
void SetPropertyOverrideVector2(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Vector2& value) override;
void SetPropertyOverrideVector3(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Vector3& value) override;
void SetPropertyOverrideVector4(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Vector4& value) override;
void SetPropertyOverrideColor(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Color& value) override;
void SetPropertyOverrideImageAsset(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Data::Asset<AZ::RPI::ImageAsset>& value) override;
void SetPropertyOverrideImageInstance(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZ::Data::Instance<AZ::RPI::Image>& value) override;
void SetPropertyOverrideString(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName, const AZStd::string& value) override;
AZStd::any GetPropertyOverride(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
bool GetPropertyOverrideBool(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
int32_t GetPropertyOverrideInt32(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
uint32_t GetPropertyOverrideUInt32(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
float GetPropertyOverrideFloat(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
AZ::Vector2 GetPropertyOverrideVector2(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
AZ::Vector3 GetPropertyOverrideVector3(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
AZ::Vector4 GetPropertyOverrideVector4(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
AZ::Color GetPropertyOverrideColor(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
AZ::Data::Asset<AZ::RPI::ImageAsset> GetPropertyOverrideImageAsset(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
AZ::Data::Instance<AZ::RPI::Image> GetPropertyOverrideImageInstance(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
AZStd::string GetPropertyOverrideString(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) const override;
void ClearPropertyOverride(const MaterialAssignmentId& materialAssignmentId, const AZStd::string& propertyName) override;
void ClearPropertyOverrides(const MaterialAssignmentId& materialAssignmentId) override;
void ClearAllPropertyOverrides() override;
MaterialPropertyOverrideMap GetPropertyOverrides(const MaterialAssignmentId& materialAssignmentId) const override;
private:
AZ_DISABLE_COPY(MaterialComponentController);
//! Data::AssetBus overrides...
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
void OnAssetReloaded(Data::Asset<Data::AssetData> asset) override;
// AZ::TickBus overrides...
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
void LoadMaterials();
void InitializeMaterialInstance(const Data::Asset<Data::AssetData>& asset);
void ReleaseMaterials();
//! Queue applying property overrides to material instances until tick
void QueuePropertyChanges(const MaterialAssignmentId& materialAssignmentId);
//! Queue material instance recreation notifiucations until tick
void QueueMaterialUpdateNotification();
EntityId m_entityId;
MaterialComponentConfig m_configuration;
AZStd::unordered_set<MaterialAssignmentId> m_queuedPropertyOverrides;
bool m_queuedMaterialUpdateNotification = false;
};
} // namespace Render
} // namespace AZ