1 #ifndef DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H
2 #define DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H
4 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <dali/public-api/common/vector-wrapper.h>
22 #include <dali/public-api/images/image-operations.h>
23 #include <dali/public-api/math/vector4.h>
27 #include <dali-scene3d/public-api/api.h>
28 #include <dali-scene3d/public-api/loader/environment-definition.h>
29 #include <dali-scene3d/public-api/loader/index.h>
30 #include <dali-scene3d/public-api/loader/utils.h>
31 #include <dali-scene3d/public-api/model-components/material.h>
33 namespace Dali::Scene3D::Loader
36 * @brief Helper enum for encoding and decoding sampler states.
39 struct DALI_SCENE3D_API SamplerFlags
47 FILTER_LINEAR = NthBit(0),
48 FILTER_MIPMAP_NEAREST = NthBit(1),
49 FILTER_MIPMAP_LINEAR = NthBit(2),
53 WRAP_CLAMP = NthBit(0),
54 WRAP_MIRROR = NthBit(1),
56 // Layout - apply shift, then mask
58 FILTER_MIN_MASK = NthBit(FILTER_MIN_BITS) - 1,
61 FILTER_MAG_SHIFT = FILTER_MIN_BITS,
62 FILTER_MAG_MASK = NthBit(FILTER_MAG_BITS) - 1,
65 WRAP_S_SHIFT = FILTER_MAG_SHIFT + FILTER_MAG_BITS,
66 WRAP_S_MASK = NthBit(WRAP_S_BITS) - 1,
69 WRAP_T_SHIFT = WRAP_S_SHIFT + WRAP_S_BITS,
70 WRAP_T_MASK = NthBit(WRAP_T_BITS) - 1,
73 MIPMAP_MASK = FILTER_MIPMAP_LINEAR | FILTER_MIPMAP_NEAREST,
76 DEFAULT = FILTER_LINEAR | (FILTER_LINEAR << FILTER_MAG_SHIFT) | (WRAP_REPEAT << WRAP_S_SHIFT) | (WRAP_REPEAT << WRAP_T_SHIFT), // LINEAR filters, REPEAT wraps
80 * @brief Retrieves the bit pattern calculated from the given Dali Sampler settings.
82 * @return SamplerFlags bit pattern.
84 static Type Encode(FilterMode::Type minFilter, FilterMode::Type magFilter, WrapMode::Type wrapS, WrapMode::Type wrapT);
87 * @brief Decodes the minification filter patter of @a flags into the corresponding FilterMode.
90 static FilterMode::Type GetMinFilter(Type flags);
93 * @brief Decodes the magnification filter patter of @a flags into the corresponding FilterMode.
96 static FilterMode::Type GetMagFilter(Type flags);
99 * @brief Decodes the horizontal wrap pattern of @a flags into the corresponding WrapMode.
102 static WrapMode::Type GetWrapS(Type flags);
105 * @brief Decodes the vertical wrap pattern of @a flags into the corresponding WrapMode.
108 static WrapMode::Type GetWrapT(Type flags);
111 * @brief Creates a Sampler with the settings encoded in @a flags.
114 static Sampler MakeSampler(Type flags);
118 * @brief Defines a texture from a combination of an image URI and its sampler definition.
121 struct DALI_SCENE3D_API TextureDefinition
123 std::string mImageUri; // When the texture is loaded from embedded resources, this URI is used as a data stream.
124 std::string mDirectoryPath;
125 SamplerFlags::Type mSamplerFlags;
126 ImageDimensions mMinImageDimensions;
127 SamplingMode::Type mSamplingMode;
128 std::vector<uint8_t> mTextureBuffer;
130 TextureDefinition(const std::string& imageUri = "", SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR);
131 TextureDefinition(std::string&& imageUri, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR);
132 TextureDefinition(std::vector<uint8_t>&& textureBuffer, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR);
136 * @brief Defines a material with a number of texture stages, whether mipmappping
137 * is enabled, and an index of an environment (usually of all environments in a
138 * scene). Textures from the environment are added last when the DALi TextureSet
142 struct DALI_SCENE3D_API MaterialDefinition
144 enum Flags : uint32_t
148 METALLIC = NthBit(1),
149 ROUGHNESS = NthBit(2),
151 EMISSIVE = NthBit(4),
152 OCCLUSION = NthBit(5),
153 SPECULAR = NthBit(6),
154 SPECULAR_COLOR = NthBit(7),
155 SUBSURFACE = NthBit(8), // Note: dli-only
157 // Other binary options
158 TRANSPARENCY = NthBit(20),
159 GLTF_CHANNELS = NthBit(21), // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture
161 // Alpha cutoff - reserved from the 24th bit
162 ALPHA_CUTOFF_BITS = 8,
163 ALPHA_CUTOFF_SHIFT = sizeof(uint32_t) * 8 - ALPHA_CUTOFF_BITS,
164 ALPHA_CUTOFF_MASK = (1 << ALPHA_CUTOFF_BITS) - 1,
168 * @brief A(n image based) texture that's used in a material.
174 TextureDefinition mTexture;
177 using Vector = std::vector<std::pair<MaterialDefinition, TextureSet>>;
184 SamplerFlags::Type mSamplerFlags;
187 std::vector<TextureData> mTextures;
190 MaterialDefinition() = default;
192 MaterialDefinition(const MaterialDefinition&) = delete;
193 MaterialDefinition& operator=(const MaterialDefinition&) = delete;
195 MaterialDefinition(MaterialDefinition&&) = default;
196 MaterialDefinition& operator=(MaterialDefinition&&) = default;
199 * @brief Loads (or, in the case of solid color materials, creates) raw pixel data,
200 * which is then returned.
202 * @note This may be called from any thread.
204 RawData LoadRaw(const std::string& imagesPath);
207 * @brief Creates Textures from the pixel data in @a raw, gets the
208 * the cube maps from the iEnvironment'th element of @a environments,
209 * then creates a DALi TextureSet and returns it.
211 * @note This must be called from the event thread.
212 * @note The textures are added in the following order: 2D, cube maps.
214 TextureSet Load(const EnvironmentDefinition::Vector& environments, RawData&& raw) const;
217 * @brief Checks if the given mask matches any of the textures defined.
220 bool CheckTextures(uint32_t flags) const;
223 * @return The alpha test reference value.
225 * @note A value of 0.f means no alpha testing.
227 float GetAlphaCutoff() const
229 return ((mFlags >> ALPHA_CUTOFF_SHIFT) & ALPHA_CUTOFF_MASK) / 255.f;
233 * @brief Encodes the alpha test reference @a value in flags.
235 * @note A value of 0.f means no alpha testing.
237 void SetAlphaCutoff(float value)
239 DALI_ASSERT_DEBUG(value >= 0.f && value <= 1.f);
240 mFlags |= static_cast<uint8_t>(std::round(value * 255.f)) << ALPHA_CUTOFF_SHIFT;
244 std::shared_ptr<RawData> mRawData;
245 uint32_t mFlags = 0x0;
247 Index mEnvironmentIdx = 0;
248 Vector4 mColor = Color::WHITE;
249 float mMetallic = 1.f;
250 float mRoughness = 1.f;
251 Vector4 mBaseColorFactor = Vector4::ONE;
252 float mNormalScale = 1.f;
253 float mOcclusionStrength = 1.f;
254 Vector3 mEmissiveFactor = Vector3::ZERO;
256 float mDielectricSpecular = 0.04f;
257 float mSpecularFactor = 1.0f;
258 Vector3 mSpecularColorFactor = Vector3::ONE;
260 // For the glTF, each of albedo, metallicRoughness, normal textures are not essential.
261 bool mNeedAlbedoTexture = true;
262 bool mNeedMetallicRoughnessTexture = true;
263 bool mNeedNormalTexture = true;
264 bool mDoubleSided = false;
266 Scene3D::Material::AlphaModeType mAlphaModeType = Scene3D::Material::AlphaModeType::OPAQUE;
267 bool mIsOpaque = true;
268 bool mIsMask = false;
270 bool mShadowAvailable = false;
272 std::vector<TextureStage> mTextureStages;
276 } // namespace Dali::Scene3D::Loader
278 #endif //DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H