• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
16 #if !defined(API_3D_ECS_COMPONENTS_MATERIAL_COMPONENT_H) || defined(IMPLEMENT_MANAGER)
17 #define API_3D_ECS_COMPONENTS_MATERIAL_COMPONENT_H
18 
19 #if !defined(IMPLEMENT_MANAGER)
20 #include <3d/namespace.h>
21 #include <base/containers/vector.h>
22 #include <base/math/vector.h>
23 #include <core/ecs/component_struct_macros.h>
24 #include <core/ecs/entity_reference.h>
25 #include <core/ecs/intf_component_manager.h>
26 
27 CORE3D_BEGIN_NAMESPACE()
28 /** \addtogroup group_material_materialdesc
29  *  @{
30  */
31 #endif
32 
33 /** Material properties.
34  * With full customization one can use custom resources property
35  */
36 BEGIN_COMPONENT(IMaterialComponentManager, MaterialComponent)
37 #if !defined(IMPLEMENT_MANAGER)
38     /** Material type enumeration */
39     enum class Type : uint8_t {
40         /** Enumeration for Metallic roughness workflow */
41         METALLIC_ROUGHNESS = 0,
42         /** Enumumeration for Specular glossiness workflow */
43         SPECULAR_GLOSSINESS = 1,
44         /** Enumumeration for KHR materials unlit workflow */
45         UNLIT = 2,
46         /** Enumumeration for special unlit shadow receiver */
47         UNLIT_SHADOW_ALPHA = 3,
48         /** Custom material. Could be used with custom material model e.g. with shader graph.
49          * Disables automatic factor based modifications for flags.
50          * Note: that base color is always automatically pre-multiplied in all cases
51          */
52         CUSTOM = 4,
53         /** Custom complex material. Could be used with custom material model e.g. with shader graph.
54          * Disables automatic factor based modifications for flags.
55          * Does not use deferred rendering path in any case due to complex material model.
56          * Note: that base color is always automatically pre-multiplied in all cases
57          */
58         CUSTOM_COMPLEX = 5,
59     };
60 
61     /** Material specialization flags */
62     enum LightingFlagBits : uint32_t {
63         /** Defines whether this material receives shadow */
64         SHADOW_RECEIVER_BIT = (1 << 0),
65         /** Defines whether this material is a shadow caster */
66         SHADOW_CASTER_BIT = (1 << 1),
67         /** Defines whether this material will receive light from punctual lights (points, spots, directional) */
68         PUNCTUAL_LIGHT_RECEIVER_BIT = (1 << 2),
69         /** Defines whether this material will receive indirect light from SH and cubemaps */
70         INDIRECT_LIGHT_RECEIVER_BIT = (1 << 3),
71     };
72     /** Container for material flag bits */
73     using LightingFlags = uint32_t;
74 
75     /** Rendering flags (specialized rendering flags) */
76     enum ExtraRenderingFlagBits : uint32_t {
77         /** Is an additional flag which can be used to discard some materials from rendering from render node graph */
78         DISCARD_BIT = (1 << 0),
79         /** Is an additional flag which disables default render system push to render data stores and rendering */
80         DISABLE_BIT = (1 << 1),
81         /** Allow rendering mutiple instances of the same mesh using GPU instancing. materialShader must support
82            instancing. */
83         ALLOW_GPU_INSTANCING_BIT = (1 << 2),
84     };
85     /** Container for extra material rendering flag bits */
86     using ExtraRenderingFlags = uint32_t;
87 
88     /** Needs to match the texture ordering with default material shader pipeline layout. The names are for default
89      * materials.
90      *
91      * For other predefined material shaders included in 3D:
92      *
93      * "core3d_dm_fw_reflection_plane.shader":
94      * CLEARCOAT_ROUGHNESS index has been reserved for reflection image.
95      */
96     enum TextureIndex : uint8_t {
97         /** basecolor texture (expected to be premultiplied alpha) (aka. diffuse for specular-glossiness)*/
98         BASE_COLOR,
99         /** normal map texture */
100         NORMAL,
101         /** metallic-roughness or specular-glossiness texture */
102         MATERIAL,
103         /** emissive texture */
104         EMISSIVE,
105         /** ambient-occlusion texture */
106         AO,
107 
108         /** clearcoat intensity texture */
109         CLEARCOAT,
110         /** clearcoat roughness texture */
111         CLEARCOAT_ROUGHNESS,
112         /** clearcoat normal map texture */
113         CLEARCOAT_NORMAL,
114 
115         /** sheen color texture in rgb, sheen roughness in alpha */
116         SHEEN,
117 
118         /** transmission percentage texture */
119         TRANSMISSION,
120 
121         /** specular color and reflection strength texture */
122         SPECULAR,
123 
124         /** number of textures */
125         TEXTURE_COUNT
126     };
127 
128     /** Channel mapping for materials using Type::METALLIC_ROUGHNESS
129      *  that can be used to access a specific channel in a TextureIndex::MATERIAL texture.
130      */
131     enum MetallicRoughnessChannel : uint8_t {
132         /** Index of the roughness channel in the material texture. */
133         ROUGHNESS = 1,
134 
135         /** Index of the metallic channel in the material texture. */
136         METALLIC,
137     };
138 
139     /** Channel mapping for materials using Type::SPECULAR_GLOSSINESS
140      *  that can be used to access a specific channel in a TextureIndex::MATERIAL texture.
141      */
142     enum SpecularGlossinessChannel : uint8_t {
143         /** Index of the specular red channel in the material texture. */
144         SPECULAR_R = 0,
145 
146         /** Index of the specular green channel in the material texture. */
147         SPECULAR_G,
148 
149         /** Index of the specular blue channel in the material texture. */
150         SPECULAR_B,
151 
152         /** Index of the glossiness channel in the material texture. */
153         GLOSSINESS,
154     };
155 
156     /** Texture transform. */
157     struct TextureTransform {
158         /** Translation */
159         BASE_NS::Math::Vec2 translation { 0.f, 0.f };
160         /** Rotation */
161         float rotation { 0.f };
162         /** Scale */
163         BASE_NS::Math::Vec2 scale { 1.f, 1.f };
164     };
165     /** Texture info. */
166     struct TextureInfo {
167         /** Image */
168         CORE_NS::EntityReference image;
169         /** Sampler */
170         CORE_NS::EntityReference sampler;
171         /** Factor */
172         BASE_NS::Math::Vec4 factor { 1.f, 1.f, 1.f, 1.f };
173         /** Transforms */
174         TextureTransform transform;
175     };
176 
177     /** Default render sort layer id */
178     static constexpr uint32_t DEFAULT_RENDER_SORT_LAYER_ID = 32u;
179     /** Render time sorting
180      * Material based sorting
181      * Submesh based sorting will overpass this
182      */
183     struct RenderSort {
184         /** Render sort layer. Within a render slot a layer can define a sort layer order.
185          * There are 0-63 values available. Default id value is 32.
186          * 0 first, 63 last
187          * 1. Typical use case is to set render sort layer to objects which render with depth test without depth write.
188          * 2. Typical use case is to always render character and/or camera object first to cull large parts of the view.
189          * 3. Sort e.g. plane layers.
190          */
191         /** Sort layer used sorting submeshes in rendering in render slots. Valid ID values 0 - 63. */
192         uint8_t renderSortLayer { DEFAULT_RENDER_SORT_LAYER_ID };
193         /** Sort layer order to describe fine order within sort layer. Valid order 0 - 255 */
194         uint8_t renderSortLayerOrder { 0u };
195     };
196 
197     /** Default material component shader
198      * Render slot processing order:
199      * 1. If graphics state has render slot this defines the render slot
200      * 2. if graphics state did not have render slot then the shader render slot defines the actual render slot
201      */
202     struct Shader {
203         /** Shader to be used. (If invalid, a default is chosen by the default material renderer)
204          * NOTE: the material medata and custom properties are updated when the shader is updated.
205          */
206         CORE_NS::EntityReference shader;
207         /** Shader graphics state to be used. (If invalid, a default is chosen by the default material renderer)
208          * If graphics state is given it's render slot is used to define where the material is send for rendering.
209          */
210         CORE_NS::EntityReference graphicsState;
211     };
212 #endif
213     /** Material type which can be one of the following Type::METALLIC_ROUGHNESS, Type::SPECULAR_GLOSSINESS */
214     DEFINE_PROPERTY(Type, type, "Material Type", 0, VALUE(Type::METALLIC_ROUGHNESS))
215 
216     /** Alpha cut off value, set the cutting value for alpha (0.0 - 1.0). Below 1.0 starts to affect.
217      */
218     DEFINE_PROPERTY(float, alphaCutoff, "Alpha Cutoff", 0, VALUE(1.0f))
219 
220     /** Material lighting flags that define the lighting related settings for this material */
221     DEFINE_BITFIELD_PROPERTY(LightingFlags, materialLightingFlags, "Material Lighting Flags",
222         PropertyFlags::IS_BITFIELD,
223         VALUE(MaterialComponent::LightingFlagBits::SHADOW_RECEIVER_BIT |
224               MaterialComponent::LightingFlagBits::SHADOW_CASTER_BIT |
225               MaterialComponent::LightingFlagBits::PUNCTUAL_LIGHT_RECEIVER_BIT |
226               MaterialComponent::LightingFlagBits::INDIRECT_LIGHT_RECEIVER_BIT),
227         MaterialComponent::LightingFlagBits)
228 
229     /** Material shader. Prefer using automatic selection (or editor selection) if no custom shaders.
230      * Needs to match default material layouts and specializations (api/3d/shaders/common).
231      * If no default slot given to shader default material shader slots are used automatically.
232      * Therefore, do not set slots and their graphics states if no special handling is needed.
233      * Use OPAQUE_FW core3d_dm_fw.shader as an example reference.
234      * (I.e. if one wants to things just work, do not specify slots or additional custom graphics states per slots)
235      * NOTE: when material shader is updated the possible material metadata and custom properties are updated
236      * NOTE: one needs to reload the shader file(s) with shader manager to get dynamic updated custom property data
237      */
238     DEFINE_PROPERTY(Shader, materialShader, "Material Shader", 0, )
239 
240     /** Depth shader. Prefer using automatic selection (or editor selection) if no custom shaders.
241      * Needs to match default material layouts and specializations (api/3d/shaders/common).
242      * If no default slot given to shader default material shader slots are used automatically.
243      * (I.e. if one wants to things just work, do not specify slots or additional custom graphics states per slots)
244      */
245     DEFINE_PROPERTY(Shader, depthShader, "Depth Shader", 0, )
246 
247     /** Extra material rendering flags define special rendering hints */
248     DEFINE_BITFIELD_PROPERTY(ExtraRenderingFlags, extraRenderingFlags, "ExtraRenderingFlags",
249         PropertyFlags::IS_BITFIELD, VALUE(0u), MaterialComponent::ExtraRenderingFlagBits)
250 
251     /** Array of texture information. With default shaders TextureIndex is used for identifying texures for different
252      * material properties. Use of TextureInfo::factor depends on the index.
253      *
254      * BASE_COLOR: RGBA, base color, if an image is specified, this value is multiplied with the texel values.
255      * NOTE: the pre-multiplication is done always, i.e. use only for base color with custom materials
256      * NOTE: the built-in default material shaders write out alpha values from 0.0 - 1.0
257      *       opaque flag is enabled to shader is graphics state's blending mode is not active -> alpha 1.0
258      *
259      * NORMAL: R, normal scale, scalar multiplier applied to each normal vector of the texture. (Ignored if image is not
260      * specified, this value is linear).
261      *
262      * MATERIAL: For Type::METALLIC_ROUGHNESS: G roughness (smooth 0.0 - 1.0 rough), B metallic (dielectric 0.0 - 1.0
263      * metallic)., and A reflectance at normal incidence
264      * For Type::SPECULAR_GLOSSINESS: RGB specular color (linear), A glossiness (rough 0.0 - 1.0 glossy). Texel values
265      * are multiplied with the corresponding factors.
266      *
267      * EMISSIVE: RGB, emissive color, A intensity, if an image is specified, this value is multiplied with the texel
268      * values.
269      *
270      * AO: R, ambient occlusion factor, this value is multiplied with the texel values (no ao 0.0 - 1.0 full ao)
271      *
272      * CLEARCOAT: R, clearcoat layer intensity, if an image is specified, this value is multiplied with the texel
273      * values.
274      *
275      * CLEARCOAT_ROUGHNESS: G, clearcoat layer roughness, if an image is specified, this value is multiplied with the
276      * texel values.
277      *
278      * CLEARCOAT_NORMAL: RGB, clearcoat normal scale, scalar multiplier applied to each normal vector of the clearcoat
279      * normal texture.
280      *
281      * SHEEN: RGB, sheen color, if an image is specified, this value is multiplied with the texel values.
282      * SHEEN: A, sheen roughness, if an image is specified, this value is multiplied with the texel values.
283      *
284      * TRANSMISSION: R, Percentage of light that is transmitted through the surface, if an image is specified, this
285      * value is multiplied with the texel values.
286      *
287      * SPECULAR: RGB color of the specular reflection, A strength of the specular reflection, if an image is specified,
288      * this value is multiplied with the texel values.
289      */
290     DEFINE_ARRAY_PROPERTY(TextureInfo, TextureIndex::TEXTURE_COUNT, textures, "", PropertyFlags::IS_HIDDEN,
291         ARRAY_VALUE(                                              //
292             TextureInfo { {}, {}, { 1.f, 1.f, 1.f, 1.f }, {} },   // base color opaque white
293             TextureInfo { {}, {}, { 1.f, 0.f, 0.f, 0.f }, {} },   // normal scale 1
294             TextureInfo { {}, {}, { 0.f, 1.f, 1.f, 0.04f }, {} }, // material (empty, roughness, metallic, reflectance)
295             TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 1.f }, {} },   // emissive 0
296             TextureInfo { {}, {}, { 1.f, 0.f, 0.f, 0.f }, {} },   // ambient occlusion 1
297             TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 0.f }, {} },   // clearcoat intensity 0
298             TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 0.f }, {} },   // clearcoat roughness 0
299             TextureInfo { {}, {}, { 1.f, 0.f, 0.f, 0.f }, {} },   // clearcoat normal scale 1
300             TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 0.f }, {} },   // sheen color black, roughness 0
301             TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 0.f }, {} },   // transmission 0
302             TextureInfo { {}, {}, { 1.f, 1.f, 1.f, 1.f }, {} }    // specular white
303             ))
304 
305     /** Texture coordinates from set 0 or 1. */
306     DEFINE_PROPERTY(uint32_t, useTexcoordSetBit, "Active Texture Coordinate", 0,
307         VALUE(0u)) // if uses set 1 (1 << enum TextureIndex)
308 
309     /** Custom forced render slot id. One can force rendering with e.g. opaque or translucent render slots */
310     DEFINE_PROPERTY(uint32_t, customRenderSlotId, "Custom Render Slot ID", ~0, VALUE(~0u))
311 
312     /** Custom material extension resources. Deprecates and prevents MaterialExtensionComponent usage.
313      * Are automatically bound to custom shader, custom pipeline layout custom descriptor set if they are in order.
314      */
315     DEFINE_PROPERTY(
316         BASE_NS::vector<CORE_NS::EntityReference>, customResources, "Custom Material Extension Resources", 0, )
317 
318     /** Per material additional user property data which is passed to shader UBO.
319      * Max size is 256 bytes.
320      */
321     DEFINE_PROPERTY(CORE_NS::IPropertyHandle*, customProperties, "Custom Properties", 0, VALUE(nullptr))
322 
323     /** Per material additional user bindings properties.
324      */
325     DEFINE_PROPERTY(CORE_NS::IPropertyHandle*, customBindingProperties, "Custom Binding Properties", 0, VALUE(nullptr))
326 
327     /** Render sorting for layers (sorting priority)
328      */
329     DEFINE_PROPERTY(RenderSort, renderSort, "Render Sort Layers", 0, )
330 
331     /** Camera based effect, which will go through all the viewport culling
332      * Designed to be used e.g. when one wants to have a camera (fullscreen) effect with typical material
333      * Can be used only with a single camera, if needed with more cameras the material needs to be duplicated
334      * for all the cameras.
335      * The render sort is still respected.
336      */
337     DEFINE_PROPERTY(CORE_NS::Entity, cameraEntity, "Camera entity for camera effect", 0, )
338 
339 END_COMPONENT(IMaterialComponentManager, MaterialComponent, "56430c14-cb12-4320-80d3-2bef4f86a041")
340 #if !defined(IMPLEMENT_MANAGER)
341 CORE3D_END_NAMESPACE()
342 #endif
343 #endif
344