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 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 struct TextureTransform { 157 BASE_NS::Math::Vec2 translation { 0.f, 0.f }; 158 float rotation { 0.f }; 159 BASE_NS::Math::Vec2 scale { 1.f, 1.f }; 160 }; 161 162 struct TextureInfo { 163 CORE_NS::EntityReference image; 164 CORE_NS::EntityReference sampler; 165 BASE_NS::Math::Vec4 factor; 166 TextureTransform transform; 167 }; 168 169 /** Default material component shader */ 170 struct Shader { 171 /** Shader to be used. (If invalid, a default is chosen by the default material renderer) 172 * NOTE: the material medata and custom properties are updated when the shader is updated. 173 */ 174 CORE_NS::EntityReference shader; 175 /** Shader graphics state to be used. (If invalid, a default is chosen by the default material renderer) */ 176 CORE_NS::EntityReference graphicsState; 177 }; 178 #endif 179 /** Material type which can be one of the following Type::METALLIC_ROUGHNESS, Type::SPECULAR_GLOSSINESS */ 180 DEFINE_PROPERTY(Type, type, "Material Type", 0, VALUE(Type::METALLIC_ROUGHNESS)) 181 182 /** Alpha cut off value, set the cutting value for alpha (0.0 - 1.0). Below 1.0 starts to affect. 183 */ 184 DEFINE_PROPERTY(float, alphaCutoff, "Alpha Cutoff", 0, VALUE(1.0f)) 185 186 /** Material lighting flags that define the lighting related settings for this material */ 187 DEFINE_BITFIELD_PROPERTY(LightingFlags, materialLightingFlags, "Material Lighting Flags", 188 PropertyFlags::IS_BITFIELD, 189 VALUE(MaterialComponent::LightingFlagBits::SHADOW_RECEIVER_BIT | 190 MaterialComponent::LightingFlagBits::SHADOW_CASTER_BIT | 191 MaterialComponent::LightingFlagBits::PUNCTUAL_LIGHT_RECEIVER_BIT | 192 MaterialComponent::LightingFlagBits::INDIRECT_LIGHT_RECEIVER_BIT), 193 MaterialComponent::LightingFlagBits) 194 195 /** Material shader. Prefer using automatic selection (or editor selection) if no custom shaders. 196 * Needs to match default material layouts and specializations (api/3d/shaders/common). 197 * If no default slot given to shader default material shader slots are used automatically. 198 * Therefore, do not set slots and their graphics states if no special handling is needed. 199 * Use OPAQUE_FW core3d_dm_fw.shader as an example reference. 200 * (I.e. if one wants to things just work, do not specify slots or additional custom graphics states per slots) 201 * NOTE: when material shader is updated the possible material metadata and custom properties are updated 202 * NOTE: one needs to reload the shader file(s) with shader manager to get dynamic updated custom property data 203 */ 204 DEFINE_PROPERTY(Shader, materialShader, "Material Shader", 0, ) 205 206 /** Depth shader. Prefer using automatic selection (or editor selection) if no custom shaders. 207 * Needs to match default material layouts and specializations (api/3d/shaders/common). 208 * If no default slot given to shader default material shader slots are used automatically. 209 * (I.e. if one wants to things just work, do not specify slots or additional custom graphics states per slots) 210 */ 211 DEFINE_PROPERTY(Shader, depthShader, "Depth Shader", 0, ) 212 213 /** Extra material rendering flags define special rendering hints */ 214 DEFINE_BITFIELD_PROPERTY(ExtraRenderingFlags, extraRenderingFlags, "ExtraRenderingFlags", 215 PropertyFlags::IS_BITFIELD, VALUE(0u), MaterialComponent::ExtraRenderingFlagBits) 216 217 /** Array of texture information. With default shaders TextureIndex is used for identifying texures for different 218 * material properties. Use of TextureInfo::factor depends on the index. 219 * 220 * BASE_COLOR: RGBA, base color, if an image is specified, this value is multiplied with the texel values. 221 * NOTE: the pre-multiplication is done always, i.e. use only for base color with custom materials 222 * NOTE: the built-in default material shaders write out alpha values from 0.0 - 1.0 223 * opaque flag is enabled to shader is graphics state's blending mode is not active -> alpha 1.0 224 * 225 * NORMAL: R, normal scale, scalar multiplier applied to each normal vector of the texture. (Ignored if image is not 226 * specified, this value is linear). 227 * 228 * MATERIAL: For Type::METALLIC_ROUGHNESS: G roughness (smooth 0.0 - 1.0 rough), B metallic (dielectric 0.0 - 1.0 229 * metallic)., and A reflectance at normal incidence 230 * For Type::SPECULAR_GLOSSINESS: RGB specular color (linear), A glossiness (rough 0.0 - 1.0 glossy). Texel values 231 * are multiplied with the corresponding factors. 232 * 233 * EMISSIVE: RGB, emissive color, A intensity, if an image is specified, this value is multiplied with the texel 234 * values. 235 * 236 * AO: R, ambient occlusion factor, this value is multiplied with the texel values (no ao 0.0 - 1.0 full ao) 237 * 238 * CLEARCOAT: R, clearcoat layer intensity, if an image is specified, this value is multiplied with the texel 239 * values. 240 * 241 * CLEARCOAT_ROUGHNESS: G, clearcoat layer roughness, if an image is specified, this value is multiplied with the 242 * texel values. 243 * 244 * CLEARCOAT_NORMAL: RGB, clearcoat normal scale, scalar multiplier applied to each normal vector of the clearcoat 245 * normal texture. 246 * 247 * SHEEN: RGB, sheen color, if an image is specified, this value is multiplied with the texel values. 248 * SHEEN: A, sheen roughness, if an image is specified, this value is multiplied with the texel values. 249 * 250 * TRANSMISSION: R, Percentage of light that is transmitted through the surface, if an image is specified, this 251 * value is multiplied with the texel values. 252 * 253 * SPECULAR: RGB color of the specular reflection, A strength of the specular reflection, if an image is specified, 254 * this value is multiplied with the texel values. 255 */ 256 DEFINE_ARRAY_PROPERTY(TextureInfo, TextureIndex::TEXTURE_COUNT, textures, "", PropertyFlags::IS_HIDDEN, 257 ARRAY_VALUE( // 258 TextureInfo { {}, {}, { 1.f, 1.f, 1.f, 1.f }, {} }, // base color opaque white 259 TextureInfo { {}, {}, { 1.f, 0.f, 0.f, 0.f }, {} }, // normal scale 1 260 TextureInfo { {}, {}, { 0.f, 1.f, 1.f, 0.04f }, {} }, // material (empty, roughness, metallic, reflectance) 261 TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 1.f }, {} }, // emissive 0 262 TextureInfo { {}, {}, { 1.f, 0.f, 0.f, 0.f }, {} }, // ambient occlusion 1 263 TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 0.f }, {} }, // clearcoat intensity 0 264 TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 0.f }, {} }, // clearcoat roughness 0 265 TextureInfo { {}, {}, { 1.f, 0.f, 0.f, 0.f }, {} }, // clearcoat normal scale 1 266 TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 0.f }, {} }, // sheen color black, roughness 0 267 TextureInfo { {}, {}, { 0.f, 0.f, 0.f, 0.f }, {} }, // transmission 0 268 TextureInfo { {}, {}, { 1.f, 1.f, 1.f, 1.f }, {} } // specular white 269 )) 270 271 /** Texture coordinates from set 0 or 1. */ 272 DEFINE_PROPERTY(uint32_t, useTexcoordSetBit, "Active Texture Coordinate", 0, 273 VALUE(0u)) // if uses set 1 (1 << enum TextureIndex) 274 275 /** Custom forced render slot id. One can force rendering with e.g. opaque or translucent render slots */ 276 DEFINE_PROPERTY(uint32_t, customRenderSlotId, "Custom Render Slot ID", ~0, VALUE(~0u)) 277 278 /** Custom material extension resources. Deprecates and prevents MaterialExtensionComponent usage. 279 * Are automatically bound to custom shader, custom pipeline layout custom descriptor set if they are in order. 280 */ 281 DEFINE_PROPERTY( 282 BASE_NS::vector<CORE_NS::EntityReference>, customResources, "Custom Material Extension Resources", 0, ) 283 284 /** Per material additional user property data which is passed to shader UBO. 285 * Max size is 256 bytes. 286 */ 287 DEFINE_PROPERTY(CORE_NS::IPropertyHandle*, customProperties, "Custom Properties", 0, VALUE(nullptr)) 288 289 END_COMPONENT(IMaterialComponentManager, MaterialComponent, "56430c14-cb12-4320-80d3-2bef4f86a041") 290 #if !defined(IMPLEMENT_MANAGER) 291 CORE3D_END_NAMESPACE() 292 #endif 293 #endif 294