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.
38 struct DALI_SCENE3D_API SamplerFlags
46 FILTER_LINEAR = NthBit(0),
47 FILTER_MIPMAP_NEAREST = NthBit(1),
48 FILTER_MIPMAP_LINEAR = NthBit(2),
52 WRAP_CLAMP = NthBit(0),
53 WRAP_MIRROR = NthBit(1),
55 // Layout - apply shift, then mask
57 FILTER_MIN_MASK = NthBit(FILTER_MIN_BITS) - 1,
60 FILTER_MAG_SHIFT = FILTER_MIN_BITS,
61 FILTER_MAG_MASK = NthBit(FILTER_MAG_BITS) - 1,
64 WRAP_S_SHIFT = FILTER_MAG_SHIFT + FILTER_MAG_BITS,
65 WRAP_S_MASK = NthBit(WRAP_S_BITS) - 1,
68 WRAP_T_SHIFT = WRAP_S_SHIFT + WRAP_S_BITS,
69 WRAP_T_MASK = NthBit(WRAP_T_BITS) - 1,
72 MIPMAP_MASK = FILTER_MIPMAP_LINEAR | FILTER_MIPMAP_NEAREST,
75 DEFAULT = FILTER_LINEAR | (FILTER_LINEAR << FILTER_MAG_SHIFT) | (WRAP_REPEAT << WRAP_S_SHIFT) | (WRAP_REPEAT << WRAP_T_SHIFT), // LINEAR filters, REPEAT wraps
79 * @return SamplerFlags bit pattern calculated from the given Dali Sampler settings.
81 static Type Encode(FilterMode::Type minFilter, FilterMode::Type magFilter, WrapMode::Type wrapS, WrapMode::Type wrapT);
84 * @brief Decodes the minification filter patter of @a flags into the corresponding FilterMode.
86 static FilterMode::Type GetMinFilter(Type flags);
89 * @brief Decodes the magnification filter patter of @a flags into the corresponding FilterMode.
91 static FilterMode::Type GetMagFilter(Type flags);
94 * @brief Decodes the horizontal wrap pattern of @a flags into the corresponding WrapMode.
96 static WrapMode::Type GetWrapS(Type flags);
99 * @brief Decodes the vertical wrap pattern of @a flags into the corresponding WrapMode.
101 static WrapMode::Type GetWrapT(Type flags);
104 * @brief Creates a Sampler with the settings encoded in @a flags.
106 static Sampler MakeSampler(Type flags);
110 * @brief Defines a texture from a combination of an image URI and its sampler definition.
112 struct DALI_SCENE3D_API TextureDefinition
114 static const Matrix3 DEFAULT_TRANSFORM;
116 std::string mImageUri; // When the texture is loaded from embedded resources, this URI is used as a data stream.
117 std::string mDirectoryPath;
118 SamplerFlags::Type mSamplerFlags;
119 ImageDimensions mMinImageDimensions;
120 SamplingMode::Type mSamplingMode;
121 Matrix3 mTransform{DEFAULT_TRANSFORM}; // Texture transform
122 std::vector<uint8_t> mTextureBuffer;
124 TextureDefinition(const std::string& imageUri = "", SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM);
125 TextureDefinition(std::string&& imageUri, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM);
126 TextureDefinition(std::vector<uint8_t>&& textureBuffer, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM);
130 * @brief Defines a material with a number of texture stages, whether mipmappping
131 * is enabled, and an index of an environment (usually of all environments in a
132 * scene). Textures from the environment are added last when the DALi TextureSet
135 struct DALI_SCENE3D_API MaterialDefinition
137 enum Flags : uint32_t
141 METALLIC = NthBit(1),
142 ROUGHNESS = NthBit(2),
144 EMISSIVE = NthBit(4),
145 OCCLUSION = NthBit(5),
146 SPECULAR = NthBit(6),
147 SPECULAR_COLOR = NthBit(7),
148 SUBSURFACE = NthBit(8), // Note: dli-only
150 // Other binary options
151 TRANSPARENCY = NthBit(20),
152 GLTF_CHANNELS = NthBit(21), // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture
154 // Alpha cutoff - reserved from the 24th bit
155 ALPHA_CUTOFF_BITS = 8,
156 ALPHA_CUTOFF_SHIFT = sizeof(uint32_t) * 8 - ALPHA_CUTOFF_BITS,
157 ALPHA_CUTOFF_MASK = (1 << ALPHA_CUTOFF_BITS) - 1,
161 * @brief A(n image based) texture that's used in a material.
166 TextureDefinition mTexture;
169 using Vector = std::vector<std::pair<MaterialDefinition, TextureSet>>;
176 SamplerFlags::Type mSamplerFlags;
179 std::vector<TextureData> mTextures;
182 MaterialDefinition() = default;
184 MaterialDefinition(const MaterialDefinition&) = delete;
185 MaterialDefinition& operator=(const MaterialDefinition&) = delete;
187 MaterialDefinition(MaterialDefinition&&) = default;
188 MaterialDefinition& operator=(MaterialDefinition&&) = default;
191 * @brief Loads (or, in the case of solid color materials, creates) raw pixel data,
192 * which is then returned.
193 * @note This may be called from any thread.
195 RawData LoadRaw(const std::string& imagesPath);
198 * @brief Creates Textures from the pixel data in @a raw, gets the
199 * the cube maps from the iEnvironment'th element of @a environments,
200 * then creates a DALi TextureSet and returns it.
201 * @note This must be called from the event thread.
202 * @note The textures are added in the following order: 2D, cube maps.
204 TextureSet Load(const EnvironmentDefinition::Vector& environments, RawData&& raw) const;
207 * @brief Checks if the given mask matches any of the textures defined.
209 bool CheckTextures(uint32_t flags) const;
212 * @return The alpha test reference value.
213 * @note A value of 0.f means no alpha testing.
215 float GetAlphaCutoff() const
217 return ((mFlags >> ALPHA_CUTOFF_SHIFT) & ALPHA_CUTOFF_MASK) / 255.f;
221 * @brief Encodes the alpha test reference @a value in flags.
222 * @note A value of 0.f means no alpha testing.
224 void SetAlphaCutoff(float value)
226 DALI_ASSERT_DEBUG(value >= 0.f && value <= 1.f);
227 mFlags |= static_cast<uint8_t>(std::round(value * 255.f)) << ALPHA_CUTOFF_SHIFT;
231 std::shared_ptr<RawData> mRawData;
232 uint32_t mFlags = 0x0;
234 Index mEnvironmentIdx = 0;
235 Vector4 mColor = Color::WHITE;
236 float mMetallic = 1.f;
237 float mRoughness = 1.f;
238 Vector4 mBaseColorFactor = Vector4::ONE;
239 float mNormalScale = 1.f;
240 float mOcclusionStrength = 1.f;
241 Vector3 mEmissiveFactor = Vector3::ZERO;
243 float mDielectricSpecular = 0.04f;
244 float mSpecularFactor = 1.0f;
245 Vector3 mSpecularColorFactor = Vector3::ONE;
247 // For the glTF, each of albedo, metallicRoughness, normal textures are not essential.
248 bool mNeedAlbedoTexture = true;
249 bool mNeedMetallicRoughnessTexture = true;
250 bool mNeedNormalTexture = true;
251 bool mDoubleSided = false;
253 Scene3D::Material::AlphaModeType mAlphaModeType = Scene3D::Material::AlphaModeType::OPAQUE;
254 bool mIsOpaque = true;
255 bool mIsMask = false;
257 bool mShadowAvailable = false;
259 std::vector<TextureStage> mTextureStages;
263 } // namespace Dali::Scene3D::Loader
265 #endif //DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H