Fix the 3D model rendering issue after the KHR_texture_transform extension support
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / model-components / material-impl.cpp
index a117d48..3b35ffd 100644 (file)
@@ -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.
@@ -30,6 +30,7 @@
 #include <dali-scene3d/internal/model-components/material-modify-observer.h>
 #include <dali-scene3d/public-api/loader/node-definition.h>
 #include <dali-scene3d/public-api/loader/renderer-state.h>
+#include <dali-scene3d/public-api/loader/shader-option.h>
 #include <dali-scene3d/public-api/loader/utils.h>
 
 namespace Dali
@@ -52,6 +53,7 @@ BaseHandle Create()
 DALI_TYPE_REGISTRATION_BEGIN(Scene3D::Material, Dali::BaseHandle, Create);
 DALI_TYPE_REGISTRATION_END()
 
+static constexpr uint32_t         OFFSET_FOR_SHADOW_MAP_TEXTURE    = 4u;
 static constexpr uint32_t         OFFSET_FOR_DIFFUSE_CUBE_TEXTURE  = 2u;
 static constexpr uint32_t         OFFSET_FOR_SPECULAR_CUBE_TEXTURE = 1u;
 static constexpr uint32_t         INVALID_INDEX                    = 0u;
@@ -100,13 +102,13 @@ Material::Material()
   mTextureInformations[SPECULAR].mSemantic       = Scene3D::Loader::MaterialDefinition::SPECULAR;
   mTextureInformations[SPECULAR_COLOR].mSemantic = Scene3D::Loader::MaterialDefinition::SPECULAR_COLOR;
 
-  mTextureInformations[BASE_COLOR].mDefineKeyword         = "BASECOLOR_TEX";
-  mTextureInformations[METALLIC_ROUGHNESS].mDefineKeyword = "METALLIC_ROUGHNESS_TEX";
-  mTextureInformations[NORMAL].mDefineKeyword             = "NORMAL_TEX";
-  mTextureInformations[OCCLUSION].mDefineKeyword          = "OCCLUSION";
-  mTextureInformations[EMISSIVE].mDefineKeyword           = "EMISSIVE";
-  mTextureInformations[SPECULAR].mDefineKeyword           = "MATERIAL_SPECULAR_TEXTURE";
-  mTextureInformations[SPECULAR_COLOR].mDefineKeyword     = "MATERIAL_SPECULAR_COLOR_TEXTURE";
+  mTextureInformations[BASE_COLOR].mShaderOptionType         = Loader::ShaderOption::Type::BASE_COLOR_TEXTURE;
+  mTextureInformations[METALLIC_ROUGHNESS].mShaderOptionType = Loader::ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE;
+  mTextureInformations[NORMAL].mShaderOptionType             = Loader::ShaderOption::Type::NORMAL_TEXTURE;
+  mTextureInformations[OCCLUSION].mShaderOptionType          = Loader::ShaderOption::Type::OCCLUSION;
+  mTextureInformations[EMISSIVE].mShaderOptionType           = Loader::ShaderOption::Type::EMISSIVE;
+  mTextureInformations[SPECULAR].mShaderOptionType           = Loader::ShaderOption::Type::SPECULAR;
+  mTextureInformations[SPECULAR_COLOR].mShaderOptionType     = Loader::ShaderOption::Type::SPECULAR_COLOR;
 
   mTextureInformations[TextureIndex::EMISSIVE].mFactor = Vector4::ZERO;
 }
@@ -322,6 +324,16 @@ void Material::SetProperty(Dali::Property::Index index, Dali::Property::Value pr
       }
       break;
     }
+    case Dali::Scene3D::Material::Property::DEPTH_INDEX:
+    {
+      int32_t depthIndex = 0;
+      if(propertyValue.Get(depthIndex) && mDepthIndex != depthIndex)
+      {
+        mDepthIndex = depthIndex;
+        mModifyFlag |= MaterialModifyObserver::ModifyFlag::PROPERTY;
+      }
+      break;
+    }
   }
 
   if(needToApply)
@@ -435,6 +447,11 @@ Dali::Property::Value Material::GetProperty(Dali::Property::Index index) const
       value = Vector3(mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor);
       break;
     }
+    case Dali::Scene3D::Material::Property::DEPTH_INDEX:
+    {
+      value = mDepthIndex;
+      break;
+    }
   }
   return value;
 }
@@ -516,14 +533,9 @@ Dali::Sampler Material::GetSampler(Scene3D::Material::TextureType index)
   return Dali::Sampler();
 }
 
-std::string Material::GetVertexShader()
-{
-  return mShaderData.mVertexShaderSource;
-}
-
-std::string Material::GetFragmentShader()
+Scene3D::Loader::ShaderOption Material::GetShaderOption() const
 {
-  return mShaderData.mFragmentShaderSource;
+  return mShaderOption;
 }
 
 void Material::Apply()
@@ -613,34 +625,31 @@ void Material::UpdateMaterialData()
     materialFlag |= textureInformation.mSemantic;
   }
 
-  if(mMaterialFlag != materialFlag || mShaderData.mVertexShaderSource.empty() || mShaderData.mFragmentShaderSource.empty())
+  if(mMaterialFlag != materialFlag)
   {
     mModifyFlag |= MaterialModifyObserver::ModifyFlag::SHADER;
 
-    mMaterialFlag                     = materialFlag;
-    mShaderData.mVertexShaderSource   = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_VERT.data();
-    mShaderData.mFragmentShaderSource = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data();
+    mMaterialFlag = materialFlag;
 
-    std::vector<std::string> defines;
-    defines.push_back(THREE_TEX_KEYWORD.data());
+    mShaderOption = Loader::ShaderOption();
     for(auto&& textureInformation : mTextureInformations)
     {
       if(!textureInformation.mTexture)
       {
         continue;
       }
-      defines.push_back(textureInformation.mDefineKeyword);
+      mShaderOption.AddOption(textureInformation.mShaderOptionType);
     }
-    defines.push_back(GLTF_CHANNELS_KEYWORD.data());
-
-    for(const auto& define : defines)
+    mShaderOption.AddOption(Loader::ShaderOption::Type::THREE_TEXTURE);
+    mShaderOption.AddOption(Loader::ShaderOption::Type::GLTF_CHANNELS);
+    if(materialFlag & Scene3D::Loader::MaterialDefinition::TRANSPARENCY)
     {
-      Scene3D::Loader::ShaderDefinition::ApplyDefine(mShaderData.mFragmentShaderSource, define);
+      mShaderOption.SetTransparency();
     }
   }
 
   // Finish to make all the material flag according to the gltf2-util.
-  // Then make defines as fallowing shader-definition-factory.
+  // Then make defines as fallowing shader-manager.
 
   // The renderer State below can be used in primitive to set renderer properties.
 
@@ -685,6 +694,21 @@ 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);
+
+  renderer.RegisterProperty("uBaseColorTextureTransform", Matrix3::IDENTITY);
+  renderer.RegisterProperty("uNormalRoughnessTextureTransform", Matrix3::IDENTITY);
+  renderer.RegisterProperty("uNormalTextureTransform", Matrix3::IDENTITY);
+  renderer.RegisterProperty("uMetalRoughnessTextureTransform", Matrix3::IDENTITY);
+  renderer.RegisterProperty("uOcclusionTextureTransform", Matrix3::IDENTITY);
+  renderer.RegisterProperty("uEmissiveTextureTransform", Matrix3::IDENTITY);
+
   float opaque = mIsOpaque ? 1.0f : 0.0f;
   float mask   = mIsMask ? 1.0f : 0.0f;
   renderer.RegisterProperty("uOpaque", opaque);
@@ -697,22 +721,17 @@ void Material::SetRendererUniform(Dali::Renderer renderer)
   renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), 1.0f);
   renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblYDirectionUniformName().data(), Vector3(1.0f, -1.0, 1.0));
 
-  std::string lightCountPropertyName(Scene3D::Internal::Light::GetLightCountUniformName());
-  renderer.RegisterProperty(lightCountPropertyName, 0);
-
-  uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount();
-  for(uint32_t i = 0; i < maxLightCount; ++i)
-  {
-    std::string lightDirectionPropertyName(Scene3D::Internal::Light::GetLightDirectionUniformName());
-    lightDirectionPropertyName += "[" + std::to_string(i) + "]";
-    renderer.RegisterProperty(lightDirectionPropertyName, Vector3::ZAXIS);
+  Scene3D::Loader::RendererState::Apply(mRendererState, renderer);
+}
 
-    std::string lightColorPropertyName(Scene3D::Internal::Light::GetLightColorUniformName());
-    lightColorPropertyName += "[" + std::to_string(i) + "]";
-    renderer.RegisterProperty(lightColorPropertyName, Vector3(Color::WHITE));
-  }
+void Material::SetRendererProperty(Dali::Renderer renderer)
+{
+  renderer.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, mDepthIndex);
+}
 
-  Scene3D::Loader::RendererState::Apply(mRendererState, renderer);
+uint32_t Material::GetShadowMapTextureOffset()
+{
+  return OFFSET_FOR_SHADOW_MAP_TEXTURE;
 }
 
 uint32_t Material::GetSpecularImageBasedLightTextureOffset()
@@ -768,7 +787,8 @@ void Material::NotifyObserver()
     mObserverNotifying = false;
 
     // Resolve observer queue during notify
-    mObservers.erase(std::remove_if(mObservers.begin(), mObservers.end(), [](auto& e) { return !e.second; }), mObservers.end());
+    mObservers.erase(std::remove_if(mObservers.begin(), mObservers.end(), [](auto& e) { return !e.second; }),
+                     mObservers.end());
   }
 }