2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 // Enable debug log for test coverage
19 #define DEBUG_ENABLED 1
21 #include <dali-scene3d/public-api/loader/node-definition.h>
22 #include <dali-scene3d/public-api/loader/resource-bundle.h>
23 #include <dali-scene3d/public-api/loader/shader-manager.h>
24 #include <dali-test-suite-utils.h>
26 #include <string_view>
29 using namespace Dali::Scene3D::Loader;
35 ResourceBundle resources;
38 struct ShaderParameters
40 MeshDefinition& meshDefinition;
41 MaterialDefinition& materialDefinition;
42 NodeDefinition& nodeDefinition;
47 using ConfigureFn = void (*)(ShaderParameters&);
49 ConfigureFn configureFn;
51 std::set<ShaderOption::Type> options;
52 RendererState::Type rendererStateSet = 0;
53 RendererState::Type rendererStateClear = 0;
58 std::vector<const Permutation*> permutations;
63 int UtcDaliShaderManagerProduceShader(void)
66 ctx.resources.mMaterials.push_back({});
67 ctx.resources.mMeshes.push_back({});
69 Permutation permutations[]{
72 [](ShaderParameters& p) {},
74 RendererState::DEPTH_TEST | RendererState::CULL_BACK,
78 [](ShaderParameters& p) {
79 p.materialDefinition.mFlags |= MaterialDefinition::TRANSPARENCY;
81 {ShaderOption::Type::THREE_TEXTURE},
82 RendererState::ALPHA_BLEND,
85 [](ShaderParameters& p) {
86 p.materialDefinition.mFlags |= MaterialDefinition::ALBEDO;
87 p.materialDefinition.mTextureStages.push_back({MaterialDefinition::ALBEDO, {}});
89 {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::BASE_COLOR_TEXTURE}},
91 [](ShaderParameters& p) {
92 p.materialDefinition.mTextureStages.push_back({MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {}});
94 {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE}},
96 [](ShaderParameters& p) {
97 p.materialDefinition.mFlags |= MaterialDefinition::NORMAL;
98 p.materialDefinition.mTextureStages.push_back({MaterialDefinition::NORMAL, {}});
100 {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::NORMAL_TEXTURE}},
102 [](ShaderParameters& p) {
103 p.materialDefinition.mFlags |= MaterialDefinition::SUBSURFACE;
105 {ShaderOption::Type::SUBSURFACE}},
107 [](ShaderParameters& p) {
108 p.materialDefinition.SetAlphaCutoff(.5f);
110 {ShaderOption::Type::ALPHA_TEST}},
112 [](ShaderParameters& p) {
113 p.materialDefinition.SetAlphaCutoff(1.f);
115 {ShaderOption::Type::ALPHA_TEST}},
117 [](ShaderParameters& p) {
118 p.materialDefinition.mFlags |= MaterialDefinition::GLTF_CHANNELS;
120 {ShaderOption::Type::GLTF_CHANNELS}},
122 [](ShaderParameters& p) {
123 p.meshDefinition.mJoints[0].mBlob.mOffset = 0;
124 p.meshDefinition.mWeights[0].mBlob.mOffset = 0;
126 {ShaderOption::Type::SKINNING}},
128 [](ShaderParameters& p) {
129 p.meshDefinition.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL;
131 {ShaderOption::Type::FLIP_UVS_VERTICAL}},
134 [](ShaderParameters& p) {
135 p.meshDefinition.mBlendShapes.push_back({});
139 [](ShaderParameters& p) {
140 p.meshDefinition.mBlendShapes.back().deltas.mBlob.mOffset = 0;
142 {ShaderOption::Type::MORPH_POSITION}},
144 [](ShaderParameters& p) {
145 p.meshDefinition.mBlendShapes.back().normals.mBlob.mOffset = 0;
147 {ShaderOption::Type::MORPH_NORMAL}},
149 [](ShaderParameters& p) {
150 p.meshDefinition.mBlendShapes.back().tangents.mBlob.mOffset = 0;
152 {ShaderOption::Type::MORPH_TANGENT}},
154 [](ShaderParameters& p) {
155 auto& blendShapes = p.meshDefinition.mBlendShapes;
156 DALI_ASSERT_ALWAYS(!blendShapes.empty() &&
157 (blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID ||
158 blendShapes.back().normals.mBlob.mOffset != MeshDefinition::INVALID ||
159 blendShapes.back().tangents.mBlob.mOffset != MeshDefinition::INVALID));
160 p.meshDefinition.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
162 {ShaderOption::Type::MORPH_VERSION_2_0}},
165 [](ShaderParameters& p) {
166 p.materialDefinition.mFlags |= MaterialDefinition::OCCLUSION;
168 {ShaderOption::Type::OCCLUSION}},
171 [](ShaderParameters& p) {
172 p.meshDefinition.mColors[0].mBlob.mOffset = 0;
174 {ShaderOption::Type::COLOR_ATTRIBUTE}},
176 [](ShaderParameters& p) {
177 p.meshDefinition.mTangentType = Property::VECTOR4;
179 {ShaderOption::Type::VEC4_TANGENT}},
182 PermutationSet permutationSets[]{
184 {{&permutations[0]}},
187 {{&permutations[0], &permutations[1]}},
189 // three-texture setups
190 {{&permutations[0], &permutations[2]}},
191 {{&permutations[0], &permutations[3]}},
192 {{&permutations[0], &permutations[4]}},
193 {{&permutations[0], &permutations[2], &permutations[3]}},
194 {{&permutations[0], &permutations[3], &permutations[4]}},
195 {{&permutations[0], &permutations[4], &permutations[2]}},
196 {{&permutations[0], &permutations[2], &permutations[3], &permutations[4]}},
198 // subsurface scattering
199 {{&permutations[0], &permutations[5]}},
202 {{&permutations[0], &permutations[6]}},
203 {{&permutations[0], &permutations[7]}},
206 {{&permutations[0], &permutations[8]}},
209 {{&permutations[0], &permutations[9]}},
212 {{&permutations[0], &permutations[10]}},
215 {{&permutations[0], &permutations[11], &permutations[12]}},
216 {{&permutations[0], &permutations[11], &permutations[13]}},
217 {{&permutations[0], &permutations[11], &permutations[14]}},
218 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13]}},
219 {{&permutations[0], &permutations[11], &permutations[13], &permutations[14]}},
220 {{&permutations[0], &permutations[11], &permutations[14], &permutations[12]}},
221 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14]}},
223 {{&permutations[0], &permutations[11], &permutations[12], &permutations[15]}},
224 {{&permutations[0], &permutations[11], &permutations[13], &permutations[15]}},
225 {{&permutations[0], &permutations[11], &permutations[14], &permutations[15]}},
226 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[15]}},
227 {{&permutations[0], &permutations[11], &permutations[13], &permutations[14], &permutations[15]}},
228 {{&permutations[0], &permutations[11], &permutations[14], &permutations[12], &permutations[15]}},
229 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14], &permutations[15]}},
232 {{&permutations[0], &permutations[1], &permutations[2]}},
233 {{&permutations[0], &permutations[1], &permutations[3]}},
234 {{&permutations[0], &permutations[1], &permutations[2], &permutations[3]}},
237 {{&permutations[0], &permutations[16]}},
241 ShaderManager shaderManager;
242 for(auto& permutationSet : permutationSets)
245 tet_printf("Test %d's tc\n", ++tc);
246 auto modelRenderable = new ModelRenderable();
247 modelRenderable->mMeshIdx = 0;
248 modelRenderable->mMaterialIdx = 0;
250 NodeDefinition nodeDefinition;
251 std::unique_ptr<NodeDefinition::Renderable> renderable;
252 renderable.reset(modelRenderable);
253 nodeDefinition.mRenderables.push_back(std::move(renderable));
255 MeshDefinition meshDefinition;
256 MaterialDefinition materialDefinition;
257 ShaderParameters shaderParameter{meshDefinition, materialDefinition, nodeDefinition};
259 // Only define skinning accessors for skinning test...
260 if(permutationSet.permutations.size() > 1)
262 auto& checkP = permutationSet.permutations[1];
263 if(auto search = checkP->options.find(ShaderOption::Type::SKINNING);
264 search != checkP->options.end())
266 meshDefinition.mJoints.push_back(MeshDefinition::Accessor{MeshDefinition::Blob{0, 0}, {}});
267 meshDefinition.mWeights.push_back(MeshDefinition::Accessor{MeshDefinition::Blob{0, 0}, {}});
270 std::set<std::string> defines;
271 ShaderOption option1;
272 RendererState::Type rendererState = 0;
273 for(auto permutation : permutationSet.permutations)
275 permutation->configureFn(shaderParameter);
276 if(materialDefinition.mFlags & MaterialDefinition::TRANSPARENCY)
278 option1.SetTransparency();
280 for(auto&& optionType : permutation->options)
282 option1.AddOption(optionType);
284 // No permutation uses extra joint weights.
285 option1.AddJointMacros(0);
286 rendererState = (rendererState | permutation->rendererStateSet) & ~permutation->rendererStateClear;
288 option1.AddOption(ShaderOption::Type::THREE_TEXTURE);
290 ShaderOption option2 = shaderManager.ProduceShaderOption(materialDefinition, meshDefinition);
292 Shader shaderFromOption1 = shaderManager.ProduceShader(option1);
293 Shader shaderFromOption2 = shaderManager.ProduceShader(option2);
294 DALI_TEST_EQUAL(option1.GetOptionHash(), option2.GetOptionHash());
295 DALI_TEST_EQUAL(shaderFromOption1, shaderFromOption2);
297 RendererState::Type rendererStateFromMaterialDefinition = shaderManager.GetRendererState(materialDefinition);
298 DALI_TEST_EQUAL(rendererStateFromMaterialDefinition, rendererState);
304 int UtcDaliShaderManagerAddAndRemoveLights(void)
307 ShaderManager shaderManager;
309 ShaderOption option1;
310 option1.AddOption(ShaderOption::Type::THREE_TEXTURE);
311 Dali::Shader shader1 = shaderManager.ProduceShader(option1);
313 ShaderOption option2;
314 option2.AddOption(ShaderOption::Type::BASE_COLOR_TEXTURE);
315 Dali::Shader shader2 = shaderManager.ProduceShader(option2);
317 DALI_TEST_NOT_EQUALS(shader1, shader2, 0.1f, TEST_LOCATION);
318 DALI_TEST_EQUALS(shader1.GetProperty<int>(shader1.GetPropertyIndex("uLightCount")), 0, TEST_LOCATION);
319 DALI_TEST_EQUALS(shader2.GetProperty<int>(shader2.GetPropertyIndex("uLightCount")), 0, TEST_LOCATION);
321 Scene3D::Light light = Scene3D::Light::New();
322 shaderManager.AddLight(light);
324 DALI_TEST_EQUALS(shader1.GetProperty<int>(shader1.GetPropertyIndex("uLightCount")), 1, TEST_LOCATION);
325 DALI_TEST_EQUALS(shader2.GetProperty<int>(shader2.GetPropertyIndex("uLightCount")), 1, TEST_LOCATION);
327 ShaderOption option3;
328 option3.AddOption(ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE);
329 Dali::Shader shader3 = shaderManager.ProduceShader(option3);
331 DALI_TEST_NOT_EQUALS(shader1, shader3, 0.1f, TEST_LOCATION);
332 DALI_TEST_NOT_EQUALS(shader2, shader3, 0.1f, TEST_LOCATION);
334 DALI_TEST_EQUALS(shader3.GetProperty<int>(shader3.GetPropertyIndex("uLightCount")), 1, TEST_LOCATION);