// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Math/Color.h" #include "Engine/Core/Math/Vector2.h" #include "Engine/Core/Math/Vector3.h" #include "Engine/Core/Types/StringView.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Scripting/ScriptingObjectReference.h" #include "Engine/Content/Assets/Texture.h" #include "Engine/Content/AssetReference.h" class MaterialInstance; class MaterialParams; class GPUContext; class GPUTextureView; class RenderBuffers; struct MaterialParamsLink { MaterialParams* This; MaterialParamsLink* Up; MaterialParamsLink* Down; }; /// /// The material parameter types. /// API_ENUM() enum class MaterialParameterType : byte { /// /// The invalid type. /// Invalid = 0, /// /// The bool. /// Bool = 1, /// /// The integer. /// Integer = 2, /// /// The float. /// Float = 3, /// /// The vector2 /// Vector2 = 4, /// /// The vector3. /// Vector3 = 5, /// /// The vector4. /// Vector4 = 6, /// /// The color. /// Color = 7, /// /// The texture. /// Texture = 8, /// /// The cube texture. /// CubeTexture = 9, /// /// The normal map texture. /// NormalMap = 10, /// /// The scene texture. /// SceneTexture = 11, /// /// The GPU texture (created from code). /// GPUTexture = 12, /// /// The matrix. /// Matrix = 13, /// /// The GPU texture array (created from code). /// GPUTextureArray = 14, /// /// The GPU volume texture (created from code). /// GPUTextureVolume = 15, /// /// The GPU cube texture (created from code). /// GPUTextureCube = 16, /// /// The RGBA channel selection mask. /// ChannelMask = 17, /// /// The gameplay global. /// GameplayGlobal = 18, /// /// The texture sampler derived from texture group settings. /// TextureGroupSampler = 19, /// /// The Global SDF (textures and constants). /// GlobalSDF = 20, }; /// /// Structure of serialized material parameter data. /// struct SerializedMaterialParam { MaterialParameterType Type; Guid ID; bool IsPublic; bool Override; String Name; String ShaderName; union { bool AsBool; int32 AsInteger; float AsFloat; Float2 AsFloat2; Float3 AsFloat3; Color AsColor; Guid AsGuid; byte AsData[16 * 4]; }; byte RegisterIndex; uint16 Offset; SerializedMaterialParam() { } }; /// /// Material variable object. Allows to modify material parameter value at runtime. /// API_CLASS(NoSpawn) class FLAXENGINE_API MaterialParameter : public ScriptingObject { DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(MaterialParameter, ScriptingObject); friend MaterialParams; friend MaterialInstance; private: Guid _paramId; MaterialParameterType _type = MaterialParameterType::Invalid; bool _isPublic; bool _override; byte _registerIndex; uint16 _offset; union { bool _asBool; int32 _asInteger; float _asFloat; Float2 _asVector2; Float3 _asVector3; Color _asColor; byte AsData[16 * 4]; }; AssetReference _asAsset; ScriptingObjectReference _asGPUTexture; String _name; public: MaterialParameter(const MaterialParameter& other) : MaterialParameter() { #if !BUILD_RELEASE CRASH; // Not used #endif } MaterialParameter& operator=(const MaterialParameter& other) { #if !BUILD_RELEASE CRASH; // Not used #endif return *this; } public: /// /// Gets the parameter ID (not the parameter instance Id but the original parameter ID). /// API_PROPERTY() FORCE_INLINE Guid GetParameterID() const { return _paramId; } /// /// Gets the parameter type. /// API_PROPERTY() FORCE_INLINE MaterialParameterType GetParameterType() const { return _type; } /// /// Gets the parameter name. /// API_PROPERTY() FORCE_INLINE const String& GetName() const { return _name; } /// /// Returns true is parameter is public visible. /// API_PROPERTY() FORCE_INLINE bool IsPublic() const { return _isPublic; } /// /// Returns true is parameter is overriding the value. /// API_PROPERTY() FORCE_INLINE bool IsOverride() const { return _override; } /// /// Sets the value override mode. /// API_PROPERTY() void SetIsOverride(bool value) { _override = value; } /// /// Gets the parameter resource graphics pipeline binding register index. /// FORCE_INLINE byte GetRegister() const { return _registerIndex; } /// /// Gets the parameter binding offset since the start of the constant buffer. /// FORCE_INLINE uint16 GetBindOffset() const { return _offset; } public: /// /// Gets the value of the parameter. /// /// The value. API_PROPERTY() Variant GetValue() const; /// /// Sets the value of the parameter. /// /// The value. API_PROPERTY() void SetValue(const Variant& value); public: /// /// The material parameter binding metadata. /// struct BindMeta { /// /// The GPU commands context. /// GPUContext* Context; /// /// The pointer to the constants buffer in the memory. /// Span Constants; /// /// The input scene color. It's optional and used in forward/postFx rendering. /// GPUTextureView* Input; /// /// The scene buffers. It's optional and used in forward/postFx rendering. /// const RenderBuffers* Buffers; /// /// True if parameters can sample depth buffer. /// bool CanSampleDepth; /// /// True if parameters can sample GBuffer. /// bool CanSampleGBuffer; }; /// /// Binds the parameter to the pipeline. /// /// The bind meta. void Bind(BindMeta& meta) const; bool HasContentLoaded() const; private: void clone(const MaterialParameter* param); public: bool operator==(const MaterialParameter& other) const; // [Object] String ToString() const override; }; /// /// The collection of material parameters. /// class FLAXENGINE_API MaterialParams : public Array { friend MaterialInstance; private: int32 _versionHash = 0; public: MaterialParameter* Get(const Guid& id); MaterialParameter* Get(const StringView& name); int32 Find(const Guid& id); int32 Find(const StringView& name); public: /// /// Gets the parameters version hash. Every time the parameters are modified (loaded, edited, etc.) the hash changes. Can be used to sync instanced parameters collection. /// int32 GetVersionHash() const; public: /// /// Binds the parameters to the pipeline. /// /// The parameters binding link. Used to support per-parameter override. /// The bind meta. static void Bind(MaterialParamsLink* link, MaterialParameter::BindMeta& meta); /// /// Clones the parameters list. /// /// The result container. void Clone(MaterialParams& result); /// /// Releases the whole data. /// void Dispose(); /// /// Loads material parameters from the stream. /// /// The stream with data. /// True if cannot load parameters for the file. bool Load(ReadStream* stream); /// /// Saves material parameters to the stream. /// /// The stream with data. void Save(WriteStream* stream); /// /// Saves the material parameters to the stream. /// /// The stream with data. /// The array of parameters. static void Save(WriteStream* stream, const Array* params); /// /// Saves the material parameters to the bytes container. /// /// The output data. /// The array of parameters. static void Save(BytesContainer& data, const Array* params); public: #if USE_EDITOR /// /// Gets the asset references (see Asset.GetReferences for more info). /// /// The output. void GetReferences(Array& output) const; #endif bool HasContentLoaded() const; private: void UpdateHash(); };