From: Eunki Hong Date: Fri, 5 Jan 2024 16:01:50 +0000 (+0900) Subject: [Tizen] Fix bug that IBLFactor / Roughness not works well when we change material X-Git-Tag: accepted/tizen/7.0/unified/20240111.013537^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=736d5c18c213acf89263fe1b031fed76a1960a39;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git [Tizen] Fix bug that IBLFactor / Roughness not works well when we change material There was some bug when we change Material info, uMaxLOD and uIblIntensity does not applied what primitive has. This is because Material's SetUniform API overwrite the value of those uniform. This patch make we ensure the order of uniform register, so let we use correct LOD and IBL intensity. Change-Id: Ic14b7f9b6c0e443ac17188a8968ac71a7c6328d6 Signed-off-by: Eunki Hong --- diff --git a/automated-tests/src/dali-scene3d/utc-Dali-Model.cpp b/automated-tests/src/dali-scene3d/utc-Dali-Model.cpp index 1b898a0..959f746 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-Model.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-Model.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,8 @@ #include #include +#include + #include using namespace Dali; @@ -118,6 +121,39 @@ void OnResourceReady(Control control) gResourceReadyCalled = true; } +void ApplyAllMaterialPropertyRecursively(Scene3D::ModelNode modelNode, const std::vector& materialPropertyValues) +{ + if(!modelNode) + { + return; + } + + for(uint32_t primitiveIndex = 0u; primitiveIndex < modelNode.GetModelPrimitiveCount(); ++primitiveIndex) + { + Scene3D::ModelPrimitive primitive = modelNode.GetModelPrimitive(primitiveIndex); + if(primitive) + { + Scene3D::Material material = primitive.GetMaterial(); + if(material) + { + for(const auto& keyValuePair : materialPropertyValues) + { + if(keyValuePair.first.type == Property::Key::Type::INDEX) + { + material.SetProperty(keyValuePair.first.indexKey, keyValuePair.second); + } + } + } + } + } + + for(uint32_t childIndex = 0u; childIndex < modelNode.GetChildCount(); ++childIndex) + { + Scene3D::ModelNode childNode = Scene3D::ModelNode::DownCast(modelNode.GetChildAt(childIndex)); + ApplyAllMaterialPropertyRecursively(childNode, materialPropertyValues); + } +} + } // namespace // Negative test case for a method @@ -1687,3 +1723,73 @@ int UtcDaliModelBlendShapeMotionDataByName(void) END_TEST; } + +int UtcDaliModelMaterialUniformChange(void) +{ + ToolkitTestApplication application; + + static std::vector customUniforms = + { + UniformData("uColorFactor", Property::Type::VECTOR4), + UniformData("uBaseColorTextureTransformAvailable", Property::Type::FLOAT), + UniformData(Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName().data(), Property::Type::FLOAT), + UniformData(Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), Property::Type::FLOAT), + }; + + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); + + auto& gl = application.GetGlAbstraction(); + + Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_FILE_NAME); + + gResourceReadyCalled = false; + model.ResourceReadySignal().Connect(&OnResourceReady); + + float expectIblFactor = 0.5f; + model.SetImageBasedLightSource(TEST_DIFFUSE_TEXTURE, TEST_SPECULAR_TEXTURE, expectIblFactor); + DALI_TEST_EQUALS(model.GetImageBasedLightScaleFactor(), expectIblFactor, TEST_LOCATION); + + DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION); + application.GetScene().Add(model); + + application.SendNotification(); + application.Render(); + + // Wait 3 task. (Load 1 model + Load 2 IBL) + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION); + DALI_TEST_EQUALS(model.GetImageBasedLightScaleFactor(), expectIblFactor, TEST_LOCATION); + + // Check uniform values before change material value + Vector4 expectBaseColorFactor = Vector4(1.000f, 0.766f, 0.336f, 1.0f); // Defined at AnimatedCube.gltf + float expectTransformValid = 1.0f; ///< Note : This value will be true when gltf have BaseColorTexture. + float expectMaxLOD = 5.0f; ///< Note : The number of LOD what TEST_SPECULAR_TEXTURE file has is 5. + + tet_printf("Check uniform value result\n"); + DALI_TEST_EQUALS(gl.CheckUniformValue("uColorFactor", expectBaseColorFactor), true, TEST_LOCATION); + DALI_TEST_EQUALS(gl.CheckUniformValue("uBaseColorTextureTransformAvailable", expectTransformValid), true, TEST_LOCATION); + DALI_TEST_EQUALS(gl.CheckUniformValue(Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName().data(), expectMaxLOD), true, TEST_LOCATION); + DALI_TEST_EQUALS(gl.CheckUniformValue(Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), expectIblFactor), true, TEST_LOCATION); + + // Change all materials in Model. + expectBaseColorFactor = Color::BLUE; + + Scene3D::ModelNode rootModelNode = model.GetModelRoot(); + DALI_TEST_CHECK(rootModelNode); + ApplyAllMaterialPropertyRecursively(rootModelNode, {{Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR, expectBaseColorFactor}}); + + application.SendNotification(); + application.Render(); + + tet_printf("Check whether uniform values are not changed instead what we change now\n"); + DALI_TEST_EQUALS(gl.CheckUniformValue("uColorFactor", expectBaseColorFactor), true, TEST_LOCATION); + DALI_TEST_EQUALS(gl.CheckUniformValue("uBaseColorTextureTransformAvailable", expectTransformValid), true, TEST_LOCATION); + DALI_TEST_EQUALS(gl.CheckUniformValue(Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName().data(), expectMaxLOD), true, TEST_LOCATION); + DALI_TEST_EQUALS(gl.CheckUniformValue(Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), expectIblFactor), true, TEST_LOCATION); + + END_TEST; +} \ No newline at end of file diff --git a/dali-scene3d/internal/model-components/material-impl.cpp b/dali-scene3d/internal/model-components/material-impl.cpp index 7496e4e..084e080 100644 --- a/dali-scene3d/internal/model-components/material-impl.cpp +++ b/dali-scene3d/internal/model-components/material-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,6 +61,8 @@ static constexpr uint32_t ALPHA_CUTOFF_FLAG = Scene3D::Lo static constexpr std::string_view THREE_TEX_KEYWORD = "THREE_TEX"; static constexpr std::string_view GLTF_CHANNELS_KEYWORD = "GLTF_CHANNELS"; +static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f); + enum TextureIndex { BASE_COLOR, @@ -73,6 +75,23 @@ enum TextureIndex TEXTURE_TYPE_NUMBER, }; +/** + * @brief Helper API to register uniform property only if don't register before. + * + * @tparam T Type of uniform value. + * @param[in] renderer The renderer what we want to check / register property. + * @param[in] uniformName The name of uniform. + * @param[in] defaultUniformValue The default value if renderer don't register given uniform before. + */ +template +void RegisterUniformIfNotDefinedBefore(Renderer renderer, const std::string_view& uniformName, const T& defaultUniformValue) +{ + if(renderer.GetPropertyIndex(uniformName.data()) == Property::INVALID_INDEX) + { + renderer.RegisterProperty(uniformName, defaultUniformValue); + } +} + } // unnamed namespace MaterialPtr Material::New() @@ -700,11 +719,12 @@ void Material::SetRendererUniform(Dali::Renderer renderer) renderer.RegisterProperty("uMask", mask); renderer.RegisterProperty("uAlphaThreshold", mAlphaCutoff); - renderer.RegisterProperty("uCubeMatrix", Matrix::IDENTITY); + // Setup default uniform values what we might need. + RegisterUniformIfNotDefinedBefore(renderer, "uCubeMatrix", Matrix::IDENTITY); - renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName().data(), 6.f); - renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), 1.0f); - renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblYDirectionUniformName().data(), Vector3(1.0f, -1.0, 1.0)); + RegisterUniformIfNotDefinedBefore(renderer, Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName(), 1.0f); + RegisterUniformIfNotDefinedBefore(renderer, Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName(), 1.0f); + RegisterUniformIfNotDefinedBefore(renderer, Scene3D::Loader::NodeDefinition::GetIblYDirectionUniformName(), Y_DIRECTION); Scene3D::Loader::RendererState::Apply(mRendererState, renderer); } diff --git a/dali-scene3d/internal/model-components/model-primitive-impl.cpp b/dali-scene3d/internal/model-components/model-primitive-impl.cpp index f86b951..ba78874 100644 --- a/dali-scene3d/internal/model-components/model-primitive-impl.cpp +++ b/dali-scene3d/internal/model-components/model-primitive-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -464,9 +464,9 @@ void ModelPrimitive::UpdateRendererUniform() { if(mMaterial) { + GetImplementation(mMaterial).SetRendererUniform(mRenderer); mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName().data(), mIblScaleFactor); mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightMaxLodUniformName().data(), static_cast(mSpecularMipmapLevels)); - GetImplementation(mMaterial).SetRendererUniform(mRenderer); } }