2 * Copyright (c) 2022 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[]{
71 [](ShaderParameters& p) {},
73 RendererState::DEPTH_TEST | RendererState::CULL_BACK,
76 [](ShaderParameters& p)
78 p.materialDefinition.mFlags |= MaterialDefinition::TRANSPARENCY;
80 {ShaderOption::Type::THREE_TEXTURE},
81 RendererState::ALPHA_BLEND,
83 {[](ShaderParameters& p)
85 p.materialDefinition.mFlags |= MaterialDefinition::ALBEDO;
86 p.materialDefinition.mTextureStages.push_back({MaterialDefinition::ALBEDO, {}});
88 {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::BASE_COLOR_TEXTURE}},
89 {[](ShaderParameters& p)
91 p.materialDefinition.mTextureStages.push_back({MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {}});
93 {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE}},
94 {[](ShaderParameters& p)
96 p.materialDefinition.mFlags |= MaterialDefinition::NORMAL;
97 p.materialDefinition.mTextureStages.push_back({MaterialDefinition::NORMAL, {}});
99 {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::NORMAL_TEXTURE}},
100 {[](ShaderParameters& p)
102 p.materialDefinition.mFlags |= MaterialDefinition::SUBSURFACE;
104 {ShaderOption::Type::SUBSURFACE}},
105 {[](ShaderParameters& p)
107 p.materialDefinition.SetAlphaCutoff(.5f);
109 {ShaderOption::Type::ALPHA_TEST}},
110 {[](ShaderParameters& p)
112 p.materialDefinition.SetAlphaCutoff(1.f);
114 {ShaderOption::Type::ALPHA_TEST}},
115 {[](ShaderParameters& p)
117 p.materialDefinition.mFlags |= MaterialDefinition::GLTF_CHANNELS;
119 {ShaderOption::Type::GLTF_CHANNELS}},
120 {[](ShaderParameters& p)
122 p.meshDefinition.mJoints0.mBlob.mOffset = 0;
123 p.meshDefinition.mWeights0.mBlob.mOffset = 0;
125 {ShaderOption::Type::SKINNING}},
126 {[](ShaderParameters& p)
128 p.meshDefinition.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL;
130 {ShaderOption::Type::FLIP_UVS_VERTICAL}},
132 [](ShaderParameters& p)
134 p.meshDefinition.mBlendShapes.push_back({});
137 {[](ShaderParameters& p)
139 p.meshDefinition.mBlendShapes.back().deltas.mBlob.mOffset = 0;
141 {ShaderOption::Type::MORPH_POSITION}},
142 {[](ShaderParameters& p)
144 p.meshDefinition.mBlendShapes.back().normals.mBlob.mOffset = 0;
146 {ShaderOption::Type::MORPH_NORMAL}},
147 {[](ShaderParameters& p)
149 p.meshDefinition.mBlendShapes.back().tangents.mBlob.mOffset = 0;
151 {ShaderOption::Type::MORPH_TANGENT}},
152 {[](ShaderParameters& p)
154 auto& blendShapes = p.meshDefinition.mBlendShapes;
155 DALI_ASSERT_ALWAYS(!blendShapes.empty() &&
156 (blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID ||
157 blendShapes.back().normals.mBlob.mOffset != MeshDefinition::INVALID ||
158 blendShapes.back().tangents.mBlob.mOffset != MeshDefinition::INVALID));
159 p.meshDefinition.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
161 {ShaderOption::Type::MORPH_VERSION_2_0}},
163 {[](ShaderParameters& p)
165 p.materialDefinition.mFlags |= MaterialDefinition::OCCLUSION;
167 {ShaderOption::Type::OCCLUSION}},
169 {[](ShaderParameters& p)
171 p.meshDefinition.mColors.mBlob.mOffset = 0;
173 {ShaderOption::Type::COLOR_ATTRIBUTE}},
174 {[](ShaderParameters& p)
176 p.meshDefinition.mTangentType = Property::VECTOR4;
178 {ShaderOption::Type::VEC4_TANGENT}},
181 PermutationSet permutationSets[]{
183 {{&permutations[0]}},
186 {{&permutations[0], &permutations[1]}},
188 // three-texture setups
189 {{&permutations[0], &permutations[2]}},
190 {{&permutations[0], &permutations[3]}},
191 {{&permutations[0], &permutations[4]}},
192 {{&permutations[0], &permutations[2], &permutations[3]}},
193 {{&permutations[0], &permutations[3], &permutations[4]}},
194 {{&permutations[0], &permutations[4], &permutations[2]}},
195 {{&permutations[0], &permutations[2], &permutations[3], &permutations[4]}},
197 // subsurface scattering
198 {{&permutations[0], &permutations[5]}},
201 {{&permutations[0], &permutations[6]}},
202 {{&permutations[0], &permutations[7]}},
205 {{&permutations[0], &permutations[8]}},
208 {{&permutations[0], &permutations[9]}},
211 {{&permutations[0], &permutations[10]}},
214 {{&permutations[0], &permutations[11], &permutations[12]}},
215 {{&permutations[0], &permutations[11], &permutations[13]}},
216 {{&permutations[0], &permutations[11], &permutations[14]}},
217 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13]}},
218 {{&permutations[0], &permutations[11], &permutations[13], &permutations[14]}},
219 {{&permutations[0], &permutations[11], &permutations[14], &permutations[12]}},
220 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14]}},
222 {{&permutations[0], &permutations[11], &permutations[12], &permutations[15]}},
223 {{&permutations[0], &permutations[11], &permutations[13], &permutations[15]}},
224 {{&permutations[0], &permutations[11], &permutations[14], &permutations[15]}},
225 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[15]}},
226 {{&permutations[0], &permutations[11], &permutations[13], &permutations[14], &permutations[15]}},
227 {{&permutations[0], &permutations[11], &permutations[14], &permutations[12], &permutations[15]}},
228 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14], &permutations[15]}},
231 {{&permutations[0], &permutations[1], &permutations[2]}},
232 {{&permutations[0], &permutations[1], &permutations[3]}},
233 {{&permutations[0], &permutations[1], &permutations[2], &permutations[3]}},
236 {{&permutations[0], &permutations[16]}},
240 ShaderManager shaderManager;
241 for(auto& permutationSet : permutationSets)
244 tet_printf("Test %d's tc\n", ++tc);
245 auto modelRenderable = new ModelRenderable();
246 modelRenderable->mMeshIdx = 0;
247 modelRenderable->mMaterialIdx = 0;
249 NodeDefinition nodeDefinition;
250 std::unique_ptr<NodeDefinition::Renderable> renderable;
251 renderable.reset(modelRenderable);
252 nodeDefinition.mRenderables.push_back(std::move(renderable));
254 MeshDefinition meshDefinition;
255 MaterialDefinition materialDefinition;
256 ShaderParameters shaderParameter{meshDefinition, materialDefinition, nodeDefinition};
258 std::set<std::string> defines;
260 RendererState::Type rendererState = 0;
261 for(auto permutation : permutationSet.permutations)
263 permutation->configureFn(shaderParameter);
264 if(materialDefinition.mFlags & MaterialDefinition::TRANSPARENCY)
266 option.SetTransparency();
268 for(auto&& optionType : permutation->options)
270 option.AddOption(optionType);
272 rendererState = (rendererState | permutation->rendererStateSet) & ~permutation->rendererStateClear;
274 option.AddOption(ShaderOption::Type::THREE_TEXTURE);
276 Shader shaderFromMeshAndMaterial = shaderManager.ProduceShader(materialDefinition, meshDefinition);
277 Shader shaderFromOption = shaderManager.ProduceShader(option);
278 DALI_TEST_EQUAL(shaderFromMeshAndMaterial, shaderFromOption);
280 RendererState::Type rendererStateFromMaterialDefinition = shaderManager.GetRendererState(materialDefinition);
281 DALI_TEST_EQUAL(rendererStateFromMaterialDefinition, rendererState);
287 int UtcDaliShaderManagerAddAndRemoveLights(void)
290 ShaderManager shaderManager;
292 ShaderOption option1;
293 option1.AddOption(ShaderOption::Type::THREE_TEXTURE);
294 Dali::Shader shader1 = shaderManager.ProduceShader(option1);
296 ShaderOption option2;
297 option2.AddOption(ShaderOption::Type::BASE_COLOR_TEXTURE);
298 Dali::Shader shader2 = shaderManager.ProduceShader(option2);
300 DALI_TEST_NOT_EQUALS(shader1, shader2, 0.1f, TEST_LOCATION);
301 DALI_TEST_EQUALS(shader1.GetProperty<int>(shader1.GetPropertyIndex("uLightCount")), 0, TEST_LOCATION);
302 DALI_TEST_EQUALS(shader2.GetProperty<int>(shader2.GetPropertyIndex("uLightCount")), 0, TEST_LOCATION);
304 Scene3D::Light light = Scene3D::Light::New();
305 shaderManager.AddLight(light);
307 DALI_TEST_EQUALS(shader1.GetProperty<int>(shader1.GetPropertyIndex("uLightCount")), 1, TEST_LOCATION);
308 DALI_TEST_EQUALS(shader2.GetProperty<int>(shader2.GetPropertyIndex("uLightCount")), 1, TEST_LOCATION);
310 ShaderOption option3;
311 option3.AddOption(ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE);
312 Dali::Shader shader3 = shaderManager.ProduceShader(option3);
314 DALI_TEST_NOT_EQUALS(shader1, shader3, 0.1f, TEST_LOCATION);
315 DALI_TEST_NOT_EQUALS(shader2, shader3, 0.1f, TEST_LOCATION);
317 DALI_TEST_EQUALS(shader3.GetProperty<int>(shader3.GetPropertyIndex("uLightCount")), 1, TEST_LOCATION);