Fix Scene3d::Loader bugs 30/284930/9
authorseungho baek <sbsh.baek@samsung.com>
Thu, 1 Dec 2022 05:51:41 +0000 (14:51 +0900)
committerSeungho BAEK <sbsh.baek@samsung.com>
Fri, 16 Dec 2022 06:18:10 +0000 (06:18 +0000)
 - Make Renderer translucent when AlphaMode is Blend
 - Use discard for AlphaMode.Mask in shader
 - Fixed ConvertSampler bug.
 - Fixed crash when there isn't "scene" property in glTF
 - Fixed wrong loading of buffer when the bufferView uses stride.
 - Returns MeshDefinition::Blob::GetBufferSize() only mLength
   This is because every use case of this method is to set real buffer size without considering stride.
 - Fix texture order of Specular and Specular color.

Change-Id: I244b366a9d4c36ad478ea8908725187ffd3277f6
Signed-off-by: seungho baek <sbsh.baek@samsung.com>
automated-tests/resources/AnimatedCubeStride.gltf [new file with mode: 0644]
automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp
dali-scene3d/internal/graphics/shaders/default-physically-based-shader.frag
dali-scene3d/public-api/loader/gltf2-loader.cpp
dali-scene3d/public-api/loader/material-definition.h
dali-scene3d/public-api/loader/mesh-definition.cpp
dali-scene3d/public-api/loader/node-definition.cpp
dali-scene3d/public-api/loader/shader-definition-factory.cpp

diff --git a/automated-tests/resources/AnimatedCubeStride.gltf b/automated-tests/resources/AnimatedCubeStride.gltf
new file mode 100644 (file)
index 0000000..d44ac0c
--- /dev/null
@@ -0,0 +1,84 @@
+{
+   "accessors" : [
+      {
+         "bufferView" : 0,
+         "byteOffset" : 0,
+         "componentType" : 5126,
+         "count" : 36,
+         "max" : [
+            1.000000,
+            1.000000,
+            1.000001
+         ],
+         "min" : [
+            -1.000000,
+            -1.000000,
+            -1.000000
+         ],
+         "type" : "VEC3"
+      }
+   ],
+   "asset" : {
+      "generator" : "VKTS glTF 2.0 exporter",
+      "version" : "2.0"
+   },
+   "bufferViews" : [
+      {
+         "buffer" : 0,
+         "byteLength" : 864,
+         "byteOffset" : 132,
+         "target" : 34962,
+         "byteStride": 24
+      }
+   ],
+   "buffers" : [
+      {
+         "byteLength" : 1860,
+         "uri" : "AnimatedCube.bin"
+      }
+   ],
+   "materials" : [
+      {
+         "name" : "AnimatedCube",
+         "pbrMetallicRoughness" : {
+         }
+      },
+      {
+         "name" : "AnimatedCube2",
+         "pbrMetallicRoughness" : {
+         }
+      }
+   ],
+   "meshes" : [
+      {
+         "name" : "AnimatedCube",
+         "primitives" : [
+            {
+               "attributes" : {
+                  "POSITION" : 0
+               }
+            }
+         ]
+      }
+   ],
+   "nodes" : [
+      {
+         "mesh" : 0,
+         "name" : "AnimatedCube",
+         "rotation" : [
+            0.000000,
+            -1.000000,
+            0.000000,
+            0.000000
+         ]
+      }
+   ],
+   "scene" : 0,
+   "scenes" : [
+      {
+         "nodes" : [
+            0
+         ]
+      }
+   ]
+}
\ No newline at end of file
index eb19c4d..369f19d 100644 (file)
@@ -213,6 +213,8 @@ int UtcDaliGltfLoaderSuccess1(void)
      false,
      true,
      false,
+     true,
+     true,
      {
        {MaterialDefinition::ALBEDO,
         {"AnimatedCube_BaseColor.png",
@@ -263,6 +265,8 @@ int UtcDaliGltfLoaderSuccess1(void)
      true,
      true,
      false,
+     true,
+     false,
      {
        {MaterialDefinition::ALBEDO,
         {"AnimatedCube_BaseColor.png",
@@ -313,6 +317,8 @@ int UtcDaliGltfLoaderSuccess1(void)
     DALI_TEST_EQUAL(md.mNeedAlbedoTexture, m.mNeedAlbedoTexture);
     DALI_TEST_EQUAL(md.mNeedMetallicRoughnessTexture, m.mNeedMetallicRoughnessTexture);
     DALI_TEST_EQUAL(md.mNeedNormalTexture, m.mNeedNormalTexture);
+    DALI_TEST_EQUAL(md.mIsOpaque, m.mIsOpaque);
+    DALI_TEST_EQUAL(md.mIsMask, m.mIsMask);
 
     DALI_TEST_EQUAL(md.mTextureStages.size(), m.mTextureStages.size());
     auto iTexture = md.mTextureStages.begin();
@@ -399,6 +405,33 @@ int UtcDaliGltfLoaderSuccess1(void)
   END_TEST;
 }
 
+int UtcDaliGltfLoaderSuccess2(void)
+{
+  Context ctx;
+  ShaderDefinitionFactory sdf;
+  sdf.SetResources(ctx.resources);
+
+  LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", sdf, ctx.loadResult);
+
+  DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
+  DALI_TEST_EQUAL(1u, ctx.scene.GetNodeCount());
+
+  TestApplication app;
+
+  Customization::Choices choices;
+  for(auto iRoot : ctx.scene.GetRoots())
+  {
+    auto resourceRefs = ctx.resources.CreateRefCounter();
+    ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs);
+    ctx.resources.LoadResources(resourceRefs, ctx.pathProvider);
+  }
+
+  DALI_TEST_EQUAL(true, ctx.resources.mMeshes[0u].first.mPositions.IsDefined());
+  DALI_TEST_EQUAL(432, ctx.resources.mMeshes[0u].first.mPositions.mBlob.mLength);
+
+  END_TEST;
+}
+
 int UtcDaliGltfLoaderSuccessShort(void)
 {
   TestApplication app;
index 8c9e7ea..bca3ba0 100644 (file)
@@ -55,15 +55,6 @@ uniform sampler2D sAlbedoMetal;
 uniform sampler2D sNormalRoughness;
 #endif
 
-uniform float uSpecularFactor;
-uniform vec3  uSpecularColorFactor;
-#ifdef MATERIAL_SPECULAR_TEXTURE
-uniform sampler2D sSpecular;
-#endif
-#ifdef MATERIAL_SPECULAR_COLOR_TEXTURE
-uniform sampler2D sSpecularColor;
-#endif
-
 #ifdef OCCLUSION
 uniform sampler2D sOcclusion;
 uniform float uOcclusionStrength;
@@ -74,6 +65,15 @@ uniform sampler2D sEmissive;
 uniform vec3 uEmissiveFactor;
 #endif
 
+uniform float uSpecularFactor;
+uniform vec3  uSpecularColorFactor;
+#ifdef MATERIAL_SPECULAR_TEXTURE
+uniform sampler2D sSpecular;
+#endif
+#ifdef MATERIAL_SPECULAR_COLOR_TEXTURE
+uniform sampler2D sSpecularColor;
+#endif
+
 //// For IBL
 uniform sampler2D sbrdfLUT;
 uniform samplerCube sDiffuseEnvSampler;
@@ -146,12 +146,15 @@ void main()
 #endif // THREE_TEX
 
   // The value of uOpaque and uMask can be 0.0 or 1.0.
+  // If uMask is 1.0, a Pixel that has bigger alpha than uAlphaThreashold becomes fully opaque,
+  // and, a pixel that has smaller alpha than uAlphaThreashold becomes fully transparent.
   // If uOpaque is 1.0, alpha value of final color is 1.0;
-  // If uOpaque is 0.0 and uMask is 1.0, alpha value of final color is 0.0 when input alpha is lower than uAlphaThreshold or
-  // 1.0 when input alpha is larger than uAlphaThreshold.
   // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#_material_alphamode
+  if(uMask > 0.5 && baseColor.a < uAlphaThreshold)
+  {
+    discard;
+  }
   baseColor.a = mix(baseColor.a, 1.0, uOpaque);
-  baseColor.a = min(mix(baseColor.a, floor(baseColor.a - uAlphaThreshold + 1.0), uMask), 1.0);
 
   metallic = clamp(metallic, 0.0, 1.0);
   // Roughness is authored as perceptual roughness; as is convention,
index 75d7ad0..15f207a 100644 (file)
@@ -425,7 +425,10 @@ SamplerFlags::Type ConvertSampler(const gt::Ref<gt::Sampler>& s)
 {
   if(s)
   {
-    return (s->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (s->mMinFilter - gt::Filter::NEAREST) : ((s->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2) | ((s->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) | (ConvertWrapMode(s->mWrapS) << SamplerFlags::WRAP_S_SHIFT) | (ConvertWrapMode(s->mWrapT) << SamplerFlags::WRAP_T_SHIFT);
+    return ((s->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (s->mMinFilter - gt::Filter::NEAREST) : ((s->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2)) | 
+           ((s->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) | 
+           (ConvertWrapMode(s->mWrapS) << SamplerFlags::WRAP_S_SHIFT) | 
+           (ConvertWrapMode(s->mWrapT) << SamplerFlags::WRAP_T_SHIFT);
   }
   else
   {
@@ -459,13 +462,14 @@ void ConvertMaterial(const gt::Material& material, const std::unordered_map<std:
   MaterialDefinition matDef;
 
   auto& pbr = material.mPbrMetallicRoughness;
-  if(pbr.mBaseColorFactor.a < 1.f)
+  if(material.mAlphaMode == gt::AlphaMode::BLEND)
   {
+    matDef.mIsOpaque = false;
     matDef.mFlags |= MaterialDefinition::TRANSPARENCY;
   }
-
-  if(material.mAlphaMode == gt::AlphaMode::MASK)
+  else if(material.mAlphaMode == gt::AlphaMode::MASK)
   {
+    matDef.mIsMask = true;
     matDef.SetAlphaCutoff(std::min(1.f, std::max(0.f, material.mAlphaCutoff)));
   }
 
@@ -888,16 +892,24 @@ void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& context, bool
 
 void ConvertNodes(const gt::Document& doc, ConversionContext& context, bool isMRendererModel)
 {
-  ConvertSceneNodes(*doc.mScene, context, isMRendererModel);
-
-  for(uint32_t i = 0, i1 = doc.mScene.GetIndex(); i < i1; ++i)
+  if(!doc.mScenes.empty())
   {
-    ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel);
-  }
+    uint32_t rootSceneIndex = 0u;
+    if(doc.mScene)
+    {
+      rootSceneIndex = doc.mScene.GetIndex();
+    }
+    ConvertSceneNodes(doc.mScenes[rootSceneIndex], context, isMRendererModel);
 
-  for(uint32_t i = doc.mScene.GetIndex() + 1; i < doc.mScenes.size(); ++i)
-  {
-    ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel);
+    for(uint32_t i = 0, i1 = rootSceneIndex; i < i1; ++i)
+    {
+      ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel);
+    }
+
+    for(uint32_t i = rootSceneIndex + 1; i < doc.mScenes.size(); ++i)
+    {
+      ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel);
+    }
   }
 }
 
index 08b59c6..e6df18e 100644 (file)
@@ -244,6 +244,9 @@ public: // DATA
   bool mNeedNormalTexture            = true;
   bool mDoubleSided                  = false;
 
+  bool mIsOpaque = true;
+  bool mIsMask   = false;
+
   std::vector<TextureStage> mTextureStages;
 };
 
index f147ca7..4b8f21d 100644 (file)
@@ -82,18 +82,22 @@ bool ReadBlob(const MeshDefinition::Blob& descriptor, std::istream& source, uint
   }
   else
   {
-    DALI_ASSERT_DEBUG(descriptor.mStride > descriptor.mElementSizeHint);
-    const uint32_t diff     = descriptor.mStride - descriptor.mElementSizeHint;
-    uint32_t       readSize = 0;
-    while(readSize < descriptor.mLength &&
-          source.read(reinterpret_cast<char*>(target), descriptor.mElementSizeHint) &&
-          source.seekg(diff, std::istream::cur))
-    {
-      readSize += descriptor.mStride;
-      target += descriptor.mElementSizeHint;
+    if(descriptor.mStride > descriptor.mElementSizeHint)
+    {
+      const uint32_t diff      = descriptor.mStride - descriptor.mElementSizeHint;
+      uint32_t       readSize  = 0;
+      uint32_t       totalSize = (descriptor.mLength / descriptor.mElementSizeHint) * descriptor.mStride;
+      while(readSize < totalSize &&
+            source.read(reinterpret_cast<char*>(target), descriptor.mElementSizeHint) &&
+            source.seekg(diff, std::istream::cur))
+      {
+        readSize += descriptor.mStride;
+        target += descriptor.mElementSizeHint;
+      }
+      return readSize == totalSize;
     }
-    return readSize == descriptor.mLength;
   }
+  return false;
 }
 
 template<typename T>
@@ -518,7 +522,7 @@ MeshDefinition::Blob::Blob(uint32_t offset, uint32_t length, uint16_t stride, ui
 
 uint32_t MeshDefinition::Blob::GetBufferSize() const
 {
-  return IsConsecutive() ? mLength : (mLength * mElementSizeHint / mStride);
+  return mLength;
 }
 
 void MeshDefinition::Blob::ComputeMinMax(uint32_t numComponents, uint32_t count, float* values)
index bbed301..10a4473 100644 (file)
@@ -244,20 +244,10 @@ void ModelRenderable::OnCreate(const NodeDefinition& node, NodeDefinition::Creat
   renderer.RegisterProperty(IBL_INTENSITY_STRING.data(), resources.mEnvironmentMaps[envIdx].first.mIblIntensity);
   renderer.RegisterProperty(IBL_Y_DIRECTION.data(), resources.mEnvironmentMaps[envIdx].first.mYDirection);
 
-  float opaque      = 0.0f;
-  float mask        = 0.0f;
+  float opaque      = matDef.mIsOpaque ? 1.0f : 0.0f;
+  float mask        = matDef.mIsMask ? 1.0f : 0.0f;
   float alphaCutoff = matDef.GetAlphaCutoff();
-  if(!MaskMatch(matDef.mFlags, MaterialDefinition::TRANSPARENCY))
-  {
-    opaque = 1.0f;
-  }
-  else
-  {
-    if(alphaCutoff > 0.f)
-    {
-      mask = 1.0f;
-    }
-  }
+
   renderer.RegisterProperty("uOpaque", opaque);
   renderer.RegisterProperty("uMask", mask);
   renderer.RegisterProperty("uAlphaThreshold", alphaCutoff);
index a341d20..8a5b639 100644 (file)
@@ -93,24 +93,24 @@ uint64_t HashNode(const MaterialDefinition& materialDef, const MeshDefinition& m
     hash.Add("SSS");
   }
 
-  if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR))
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION))
   {
-    hash.Add("SPECTEX");
+    hash.Add("OCCL" /*USION*/);
   }
 
-  if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR_COLOR))
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE))
   {
-    hash.Add("SPECCOLTEX");
+    hash.Add("EMIS" /*SIVE*/);
   }
 
-  if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION))
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR))
   {
-    hash.Add("OCCL" /*USION*/);
+    hash.Add("SPECTEX");
   }
 
-  if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE))
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR_COLOR))
   {
-    hash.Add("EMIS" /*SIVE*/);
+    hash.Add("SPECCOLTEX");
   }
 
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))
@@ -256,24 +256,24 @@ Index ShaderDefinitionFactory::ProduceShader(NodeDefinition::Renderable& rendera
       shaderDef.mDefines.push_back("SSS");
     }
 
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR))
+    if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION))
     {
-      shaderDef.mDefines.push_back("MATERIAL_SPECULAR_TEXTURE");
+      shaderDef.mDefines.push_back("OCCLUSION");
     }
 
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR_COLOR))
+    if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE))
     {
-      shaderDef.mDefines.push_back("MATERIAL_SPECULAR_COLOR_TEXTURE");
+      shaderDef.mDefines.push_back("EMISSIVE");
     }
 
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION))
+    if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR))
     {
-      shaderDef.mDefines.push_back("OCCLUSION");
+      shaderDef.mDefines.push_back("MATERIAL_SPECULAR_TEXTURE");
     }
 
-    if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE))
+    if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR_COLOR))
     {
-      shaderDef.mDefines.push_back("EMISSIVE");
+      shaderDef.mDefines.push_back("MATERIAL_SPECULAR_COLOR_TEXTURE");
     }
 
     if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))