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