1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef SCENEPLUGIN_INTF_MATERIAL_H
16 #define SCENEPLUGIN_INTF_MATERIAL_H
17 
18 #include <scene_plugin/interface/intf_node.h>
19 
20 #include <base/containers/vector.h>
21 #include <render/device/intf_shader_manager.h>
22 #include <render/resource_handle.h>
23 
24 #include <meta/api/animation/animation.h>
25 #include <meta/base/meta_types.h>
26 #include <meta/interface/intf_container.h>
27 
28 #include <scene_plugin/interface/compatibility.h>
29 #include <scene_plugin/interface/intf_bitmap.h>
30 
31 SCENE_BEGIN_NAMESPACE()
32 
33 REGISTER_INTERFACE(ITextureInfo, "ab86c6e2-fac5-4425-b13a-16459bf51473")
34 class ITextureInfo : public META_NS::INamed {
35     META_INTERFACE(META_NS::INamed, ITextureInfo, InterfaceId::ITextureInfo)
36 public:
37     /**
38      * @brief Get index of texture slot this info is mapped to
39      * @return Index of the texture slot
40      */
41     META_PROPERTY(uint32_t, TextureSlotIndex)
42 
43     /**
44      * @brief Entity identifier of the image. DEPRECATED
45      * @return pointer to property
46      */
47     META_PROPERTY(SCENE_NS::IBitmap::Ptr, Image)
48 
49     /**
50      * @brief Predefined sampler types
51      */
52     enum SamplerId : uint8_t {
53         CORE_DEFAULT_SAMPLER_UNKNOWN,
54         /** Default sampler, nearest repeat */
55         CORE_DEFAULT_SAMPLER_NEAREST_REPEAT,
56         /** Default sampler, nearest clamp */
57         CORE_DEFAULT_SAMPLER_NEAREST_CLAMP,
58         /** Default sampler, linear repeat */
59         CORE_DEFAULT_SAMPLER_LINEAR_REPEAT,
60         /** Default sampler, linear clamp */
61         CORE_DEFAULT_SAMPLER_LINEAR_CLAMP,
62         /** Default sampler, linear mipmap repeat */
63         CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_REPEAT,
64         /** Default sampler, linear mipmap clamp */
65         CORE_DEFAULT_SAMPLER_LINEAR_MIPMAP_CLAMP
66     };
67 
68     /**
69      * @brief Sampler type to be used with texture.
70      *        BOUND ONLY TOWARDS ECS CURRENTLY, does not report back
71      * @return pointer to property
72      */
73     META_PROPERTY(uint8_t, Sampler)
74 
75     /**
76      * @brief Color components.
77      * @return pointer to property
78      */
79     META_PROPERTY(BASE_NS::Math::Vec4, Factor)
80 
81     /**
82      * @brief Translation of the texture.
83      * @return pointer to property
84      */
85     META_PROPERTY(BASE_NS::Math::Vec2, Translation)
86 
87     /**
88      * @brief Rotation of the texture.
89      * @return pointer to property
90      */
91     META_PROPERTY(float, Rotation)
92 
93     /**
94      * @brief Scale of the texture.
95      * @return pointer to property
96      */
97     META_PROPERTY(BASE_NS::Math::Vec2, Scale)
98 
99     /**
100      * @brief Set index of the texture slot the info is mapped to.
101      * @param index New index of the texture slot.
102      */
103     virtual void SetTextureSlotIndex(uint32_t index) = 0;
104 
105     /**
106      * @brief Retrieve index of the texture slot this info is mapped into.
107      * @return Index of the texture slot.
108      */
109     virtual uint32_t GetTextureSlotIndex() const = 0;
110 };
111 
112 SCENE_END_NAMESPACE()
113 
114 META_TYPE(SCENE_NS::ITextureInfo::WeakPtr);
115 META_TYPE(SCENE_NS::ITextureInfo::Ptr);
116 
117 SCENE_BEGIN_NAMESPACE()
118 
119 REGISTER_INTERFACE(IShader, "b75ef889-ceee-47f8-8679-4ea43801c022")
120 class IShader : public CORE_NS::IInterface {
121     META_INTERFACE(CORE_NS::IInterface, IShader, InterfaceId::IShader)
122 public:
123     /**
124      * @brief Uri of the shader definition
125      * @return pointer to property
126      */
127     META_PROPERTY(BASE_NS::string, Uri)
128 
129     virtual RENDER_NS::RenderHandleReference GetRenderHandleReference(RENDER_NS::IShaderManager& shaderManager) = 0;
130 };
131 
132 SCENE_END_NAMESPACE()
133 
134 META_TYPE(SCENE_NS::IShader::WeakPtr);
135 META_TYPE(SCENE_NS::IShader::Ptr);
136 
137 SCENE_BEGIN_NAMESPACE()
138 
139 class IMaterial;
140 
141 using IShaderGraphicsState = IPendingRequest<RENDER_NS::GraphicsState>;
142 
143 REGISTER_INTERFACE(IGraphicsState, "44e046fa-1a5b-4601-9fc9-bbed2e1f30bc")
144 class IGraphicsState : public CORE_NS::IInterface {
145     META_INTERFACE(CORE_NS::IInterface, IGraphicsState, InterfaceId::IGraphicsState)
146 public:
147     /**
148      * @brief Uri of the graphics state definition
149      * @return pointer to property
150      */
151     META_PROPERTY(BASE_NS::string, Uri)
152 
153     /**
154      * @brief Variant of the graphics state definition
155      * @return pointer to property
156      */
157     META_PROPERTY(BASE_NS::string, Variant)
158 
159     virtual RENDER_NS::RenderHandleReference GetRenderHandleReference(RENDER_NS::IShaderManager& shaderManager) = 0;
160 
161     virtual void SetGraphicsState(
162         const RENDER_NS::GraphicsState& state, BASE_NS::shared_ptr<SCENE_NS::IMaterial> mat) = 0;
163     virtual IShaderGraphicsState::Ptr GetGraphicsState(BASE_NS::shared_ptr<SCENE_NS::IMaterial> mat) = 0;
164 };
165 
166 SCENE_END_NAMESPACE()
167 
168 META_TYPE(SCENE_NS::IGraphicsState::WeakPtr);
169 META_TYPE(SCENE_NS::IGraphicsState::Ptr);
170 
171 SCENE_BEGIN_NAMESPACE()
172 
173 // Implemented by SCENE_NS::ClassId::Material
174 REGISTER_INTERFACE(IMaterial, "3a58fd01-78b1-46c3-b2ec-98b54422558d")
175 class IMaterial : public CORE_NS::IInterface {
176     META_INTERFACE(CORE_NS::IInterface, IMaterial, InterfaceId::IMaterial)
177 public:
178     enum MaterialType : uint8_t {
179         /** Enumeration for Metallic roughness workflow */
180         METALLIC_ROUGHNESS = 0,
181         /** Enumeration for Specular glossiness workflow */
182         SPECULAR_GLOSSINESS = 1,
183         /** Enumeration for KHR materials unlit workflow */
184         UNLIT = 2,
185         /** Enumeration for special unlit shadow receiver */
186         UNLIT_SHADOW_ALPHA = 3,
187         /** Custom material. Could be used with custom material model e.g. with shader graph.
188          * Disables automatic factor based modifications for flags.
189          * Note: that base color is always automatically pre-multiplied in all cases
190          */
191         CUSTOM = 4,
192         /** Custom complex material. Could be used with custom material model e.g. with shader graph.
193          * Disables automatic factor based modifications for flags.
194          * Does not use deferred rendering path in any case due to complex material model.
195          * Note: that base color is always automatically pre-multiplied in all cases
196          */
197         CUSTOM_COMPLEX = 5
198     };
199 
200     /**
201      * @brief Type of the material.
202      * @return pointer to property
203      */
204     META_PROPERTY(uint8_t, Type)
205 
206     /**
207      * @brief Alpha cut off value, set the cutting value for alpha (0.0 - 1.0). Below 1.0 starts to affect.
208      * @return pointer to property
209      */
210     META_PROPERTY(float, AlphaCutoff)
211 
212     /**
213      * @brief Bitfield of the material lighting flags.
214      * @return pointer to property
215      */
216     META_PROPERTY(uint32_t, LightingFlags)
217 
218     META_PROPERTY(IShader::Ptr, MaterialShader)
219     META_PROPERTY(IGraphicsState::Ptr, MaterialShaderState)
220     META_PROPERTY(IShader::Ptr, DepthShader)
221     META_PROPERTY(IGraphicsState::Ptr, DepthShaderState)
222 
223     /**
224      * @brief Primary inputs of the material. Depending the material type, different properties are
225      *        available through provided object
226      * @return pointer to property
227      */
228     META_READONLY_PROPERTY(META_NS::IObject::Ptr, CustomProperties)
229 
230     /**
231      * @brief Get all material inputs
232      * @return Array of all texture information structs.
233      */
234     META_ARRAY_PROPERTY(ITextureInfo::Ptr, Inputs)
235 
236     META_ARRAY_PROPERTY(ITextureInfo::Ptr, Textures)
237     /**
238      * @brief Sets the given bitmap to mesh texture.
239      */
240     virtual void SetImage(SCENE_NS::IBitmap::Ptr bitmap, size_t index = 0) = 0;
241 
242     /**
243      * @brief Sets the given bitmap to the named texture slot.
244      */
245     virtual void SetImage(SCENE_NS::IBitmap::Ptr bitmap, BASE_NS::string_view textureSlot) = 0;
246 
247     static constexpr BASE_NS::string_view MAPPED_INPUTS_COLOR { "Color" };
248     static constexpr BASE_NS::string_view MAPPED_INPUTS_FACTOR { "Factor" };
249     static constexpr BASE_NS::string_view MAPPED_INPUTS_GLOSSINESS { "Glossiness" };
250     static constexpr BASE_NS::string_view MAPPED_INPUTS_INTENSITY { "Intensity" };
251     static constexpr BASE_NS::string_view MAPPED_INPUTS_METALLIC { "Metallic" };
252     static constexpr BASE_NS::string_view MAPPED_INPUTS_NORMAL_SCALE { "Normal Scale" };
253     static constexpr BASE_NS::string_view MAPPED_INPUTS_REFLECTANCE { "Reflectance" };
254     static constexpr BASE_NS::string_view MAPPED_INPUTS_ROUGHNESS { "Roughness" };
255     static constexpr BASE_NS::string_view MAPPED_INPUTS_STRENGTH { "Strength" };
256     static constexpr BASE_NS::string_view MAPPED_INPUTS_TRANSMISSION { "Transmission" };
257 
258     /** @brief enumerations from engine. Fixed indices for built in shaders */
259     enum TextureIndex : uint8_t {
260         /** basecolor texture (expected to be premultiplied alpha) (aka. diffuse for specular-glossiness)*/
261         BASE_COLOR,
262         /** normal map texture */
263         NORMAL,
264         /** metallic-roughness or specular-glossiness texture */
265         MATERIAL,
266         /** emissive texture */
267         EMISSIVE,
268         /** ambient-occlusion texture */
269         AO,
270 
271         /** clearcoat intensity texture */
272         CLEARCOAT,
273         /** clearcoat roughness texture */
274         CLEARCOAT_ROUGHNESS,
275         /** clearcoat normal map texture */
276         CLEARCOAT_NORMAL,
277 
278         /** sheen color texture in rgb, sheen roughness in alpha */
279         SHEEN,
280 
281         /** transmission percentage texture */
282         TRANSMISSION,
283 
284         /** specular color and reflection strength texture */
285         SPECULAR,
286 
287         /** number of textures */
288         TEXTURE_COUNT
289     };
290 
291     template<typename ValueType>
GetMappedProperty(size_t textureSlotIndex,const BASE_NS::string_view & name)292     META_NS::Property<ValueType> GetMappedProperty(
293         size_t textureSlotIndex, const BASE_NS::string_view& name)
294     {
295         if (Inputs()) {
296             for (auto& info : Inputs()->GetValue()) {
297                 if (info->GetTextureSlotIndex() == textureSlotIndex) {
298                     if (auto meta = interface_pointer_cast<META_NS::IMetadata>(info)) {
299                         return meta->GetPropertyByName<ValueType>(name);
300                     }
301                 }
302             }
303         }
304 
305         return META_NS::Property<ValueType> {};
306     }
307 
308     /** @brief Convenience proxy for material base color property. May return null.
309      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
310      */
BaseColor()311     auto BaseColor()
312     {
313         return GetMappedProperty<SCENE_NS::Color>(BASE_COLOR, MAPPED_INPUTS_COLOR);
314     }
315 
316     /** @brief Convenience proxy for material normal map scale property. May return null.
317      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
318      */
NormalMapScale()319     auto NormalMapScale()
320     {
321         return GetMappedProperty<float>(NORMAL, MAPPED_INPUTS_NORMAL_SCALE);
322     }
323 
324     /** @brief Convenience proxy for material metallic roughness property. May return null.
325      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
326      */
MetallicRoughness()327     auto MetallicRoughness()
328     {
329         return GetMappedProperty<float>(MATERIAL, MAPPED_INPUTS_ROUGHNESS);
330     }
331 
332     /** @brief Convenience proxy for material metallic property. May return null.
333      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
334      */
Metallic()335     auto Metallic()
336     {
337         return GetMappedProperty<float>(MATERIAL, MAPPED_INPUTS_METALLIC);
338     }
339 
340     /** @brief Convenience proxy for material metallic reflectance property. May return null.
341      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
342      */
MetallicReflectance()343     auto MetallicReflectance()
344     {
345         return GetMappedProperty<float>(MATERIAL, MAPPED_INPUTS_REFLECTANCE);
346     }
347 
348     /** @brief Convenience proxy for material specular glossiness color property. May return null.
349      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
350      */
SpecularGlossinessColor()351     auto SpecularGlossinessColor()
352     {
353         return GetMappedProperty<SCENE_NS::Color>(MATERIAL, MAPPED_INPUTS_COLOR);
354     }
355 
356     /** @brief Convenience proxy for material specular glossiness property. May return null.
357      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
358      */
SpecularGlossiness()359     auto SpecularGlossiness()
360     {
361         return GetMappedProperty<float>(MATERIAL, MAPPED_INPUTS_GLOSSINESS);
362     }
363 
364     /** @brief Convenience proxy for material emissive color property. May return null.
365      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
366      */
EmissiveColor()367     auto EmissiveColor()
368     {
369         return GetMappedProperty<SCENE_NS::Color>(EMISSIVE, MAPPED_INPUTS_COLOR);
370     }
371 
372     /** @brief Convenience proxy for material emissive color intensity property. May return null.
373      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
374      */
EmissiveColorIntensity()375     auto EmissiveColorIntensity()
376     {
377         return GetMappedProperty<float>(EMISSIVE, MAPPED_INPUTS_INTENSITY);
378     }
379 
380     /** @brief Convenience proxy for material ambient occlusion strength property. May return null.
381      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
382      */
AmbientOcclusionStrength()383     auto AmbientOcclusionStrength()
384     {
385         return GetMappedProperty<float>(AO, MAPPED_INPUTS_STRENGTH);
386     }
387 
388     /** @brief Convenience proxy for material emissive color intensity property. May return null.
389      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
390      */
ClearCoatIntensity()391     auto ClearCoatIntensity()
392     {
393         return GetMappedProperty<float>(CLEARCOAT, MAPPED_INPUTS_INTENSITY);
394     }
395 
396     /** @brief Convenience proxy for material emissive color roughness property. May return null.
397      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
398      */
ClearCoatRoughness()399     auto ClearCoatRoughness()
400     {
401         return GetMappedProperty<float>(CLEARCOAT, MAPPED_INPUTS_ROUGHNESS);
402     }
403 
404     /** @brief Convenience proxy for material normal map scale property. May return null.
405      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
406      */
ClearCoatNormalScale()407     auto ClearCoatNormalScale()
408     {
409         return GetMappedProperty<float>(CLEARCOAT, MAPPED_INPUTS_NORMAL_SCALE);
410     }
411 
412     /** @brief Convenience proxy for material sheen color property. May return null.
413      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
414      */
SheenColor()415     auto SheenColor()
416     {
417         return GetMappedProperty<SCENE_NS::Color>(SHEEN, MAPPED_INPUTS_COLOR);
418     }
419 
420     /** @brief Convenience proxy for material normal map scale property. May return null.
421      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
422      */
SheenRoughness()423     auto SheenRoughness()
424     {
425         return GetMappedProperty<float>(SHEEN, MAPPED_INPUTS_ROUGHNESS);
426     }
427 
428     /** @brief Convenience proxy for material transmission property. May return null.
429      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
430      */
Transmission()431     auto Transmission()
432     {
433         return GetMappedProperty<float>(TRANSMISSION, MAPPED_INPUTS_TRANSMISSION);
434     }
435 
436     /** @brief Convenience proxy for material specular color property. May return null.
437      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
438      */
SpecularColor()439     auto SpecularColor()
440     {
441         return GetMappedProperty<SCENE_NS::Color>(SPECULAR, MAPPED_INPUTS_COLOR);
442     }
443 
444     /** @brief Convenience proxy for material specular color strength property. May return null.
445      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
446      */
SpecularColorStrength()447     auto SpecularColorStrength()
448     {
449         return GetMappedProperty<float>(SPECULAR, MAPPED_INPUTS_STRENGTH);
450     }
451 
452     /** @brief Convenience proxy for material custom properties. May return null if property is not
453      * found or the given type is incorrect.
454      * use of META_NS::GetValue() and META_NS::SetValue() recommended.
455      */
456     template<typename ValueType>
GetCustomProperty(const BASE_NS::string_view & name)457     typename META_NS::Property<ValueType>::Ptr GetCustomProperty(const BASE_NS::string_view& name)
458     {
459         if (auto customProperties = CustomProperties()) {
460             if (auto meta = interface_pointer_cast<META_NS::IMetadata>(customProperties->GetValue())) {
461                 return meta->GetPropertyByName<ValueType>(name);
462             }
463         }
464         return {};
465     }
466 };
467 
468 SCENE_END_NAMESPACE()
469 
470 META_TYPE(SCENE_NS::IMaterial::WeakPtr);
471 META_TYPE(SCENE_NS::IMaterial::Ptr);
472 
473 #endif // SCENEPLUGIN_INTF_MATERIAL_H
474