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/8.0/unified/20240109.155453~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F48%2F303848%2F1;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 0962643..224a9f2 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 @@ -33,6 +34,8 @@ #include #include +#include + #include using namespace Dali; @@ -121,6 +124,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 @@ -1817,3 +1853,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 0eb6213..40ece79 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() @@ -694,25 +713,25 @@ void Material::SetRendererUniform(Dali::Renderer renderer) renderer.RegisterProperty("uSpecularFactor", mTextureInformations[TextureIndex::SPECULAR].mFactor.x); renderer.RegisterProperty("uSpecularColorFactor", Vector3(mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor)); - // No requirement to use texture transform for runtime generated models. - renderer.RegisterProperty("uBaseColorTextureTransformAvailable", 0.0f); - renderer.RegisterProperty("uNormalTextureTransformAvailable", 0.0f); - renderer.RegisterProperty("uNormalRoughnessTextureTransformAvailable", 0.0f); - renderer.RegisterProperty("uMetalRoughnessTextureTransformAvailable", 0.0f); - renderer.RegisterProperty("uOcclusionTextureTransformAvailable", 0.0f); - renderer.RegisterProperty("uEmissiveTextureTransformAvailable", 0.0f); - float opaque = mIsOpaque ? 1.0f : 0.0f; float mask = mIsMask ? 1.0f : 0.0f; renderer.RegisterProperty("uOpaque", opaque); renderer.RegisterProperty("uMask", mask); renderer.RegisterProperty("uAlphaThreshold", mAlphaCutoff); - renderer.RegisterProperty("uCubeMatrix", Matrix::IDENTITY); + // Setup default uniform values what we might need. + RegisterUniformIfNotDefinedBefore(renderer, "uBaseColorTextureTransformAvailable", 0.0f); + RegisterUniformIfNotDefinedBefore(renderer, "uNormalTextureTransformAvailable", 0.0f); + RegisterUniformIfNotDefinedBefore(renderer, "uNormalRoughnessTextureTransformAvailable", 0.0f); + RegisterUniformIfNotDefinedBefore(renderer, "uMetalRoughnessTextureTransformAvailable", 0.0f); + RegisterUniformIfNotDefinedBefore(renderer, "uOcclusionTextureTransformAvailable", 0.0f); + RegisterUniformIfNotDefinedBefore(renderer, "uEmissiveTextureTransformAvailable", 0.0f); + + 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 27c8170..8c2c1c5 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. @@ -549,9 +549,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); } }