[Tizen] Reduce prediction error for blendshape 32/292232/1
authorEunki, Hong <eunkiki.hong@samsung.com>
Fri, 21 Apr 2023 11:13:40 +0000 (20:13 +0900)
committerseungho baek <sbsh.baek@samsung.com>
Tue, 2 May 2023 05:27:11 +0000 (14:27 +0900)
1. Let we use highp integer for vertex shader. (since some device's
   mediump int only use 16bit signed integer, so it might not allow
   to use more than 32768 vertex id)

2. Do not use divide and sqrtf operator if we can

Change-Id: Ib76d1ff6095f07aad9f797b96be93d0dc8dd8188
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali-scene3d/internal/graphics/shaders/default-physically-based-shader.vert
dali-scene3d/public-api/loader/mesh-definition.cpp

index 35323d3..5b48af0 100644 (file)
@@ -45,14 +45,14 @@ uniform mat4 uProjection;
 
 #ifdef MORPH
 #define MAX_BLEND_SHAPE_NUMBER 128
-uniform float uNumberOfBlendShapes;                                 ///< Total number of blend shapes loaded.
+uniform float uNumberOfBlendShapes;                                       ///< Total number of blend shapes loaded.
 uniform highp float uBlendShapeWeight[MAX_BLEND_SHAPE_NUMBER];            ///< The weight of each blend shape.
 #ifdef MORPH_VERSION_2_0
-uniform float uBlendShapeUnnormalizeFactor;                         ///< Factor used to unnormalize the geometry of the blend shape.
+uniform highp float uBlendShapeUnnormalizeFactor;                         ///< Factor used to unnormalize the geometry of the blend shape.
 #else
-uniform float uBlendShapeUnnormalizeFactor[MAX_BLEND_SHAPE_NUMBER]; ///< Factor used to unnormalize the geometry of the blend shape.
+uniform highp float uBlendShapeUnnormalizeFactor[MAX_BLEND_SHAPE_NUMBER]; ///< Factor used to unnormalize the geometry of the blend shape.
 #endif
-uniform float uBlendShapeComponentSize;                             ///< The size in the texture of either the vertices, normals or tangents. Used to calculate the offset to address them.
+uniform highp float uBlendShapeComponentSize;                             ///< The size in the texture of either the vertices, normals or tangents. Used to calculate the offset to address them.
 #endif
 
 void main()
@@ -64,27 +64,30 @@ void main()
 #ifdef MORPH
   int width = textureSize( sBlendShapeGeometry, 0 ).x;
 
-  int blendShapeBufferOffset = 0;
-  int blendShapeComponentSize = int(uBlendShapeComponentSize);
+  highp int blendShapeBufferOffset = 0;
+  highp int blendShapeComponentSize = int(uBlendShapeComponentSize);
   int numberOfBlendShapes = int(uNumberOfBlendShapes);
 
   for( int index = 0; index < numberOfBlendShapes; ++index )
   {
     highp vec3 diff = vec3(0.0);
+    highp int vertexId = 0;
+    highp int x = 0;
+    highp int y = 0;
 
 #ifdef MORPH_POSITION
     // Calculate the index to retrieve the geometry from the texture.
-    int vertexId = gl_VertexID + blendShapeBufferOffset;
-    int x = vertexId % width;
-    int y = vertexId / width;
+    vertexId = gl_VertexID + blendShapeBufferOffset;
+    x = vertexId % width;
+    y = vertexId / width;
 
     // Retrieves the blend shape geometry from the texture, unnormalizes it and multiply by the weight.
     if( 0.0 != uBlendShapeWeight[index] )
     {
 #ifdef MORPH_VERSION_2_0
-       float unnormalizeFactor = uBlendShapeUnnormalizeFactor;
+       highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor;
 #else
-       float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
+       highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
 #endif
 
       diff = uBlendShapeWeight[index] * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
index a485e97..948cb89 100644 (file)
@@ -382,7 +382,7 @@ void CalculateTextureSize(uint32_t totalTextureSize, uint32_t& textureWidth, uin
 void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDefinition::BlendShape>& blendShapes, uint32_t numberOfVertices, float& blendShapeUnnormalizeFactor, BufferDefinition::Vector& buffers)
 {
   uint32_t geometryBufferIndex = 0u;
-  float    maxDistance         = 0.f;
+  float    maxDistanceSquared  = 0.f;
   Vector3* geometryBufferV3    = reinterpret_cast<Vector3*>(geometryBuffer);
   for(const auto& blendShape : blendShapes)
   {
@@ -406,7 +406,7 @@ void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDe
           Vector3& delta = geometryBufferV3[geometryBufferIndex++];
           delta          = deltasBuffer[index];
 
-          maxDistance = std::max(maxDistance, delta.LengthSquared());
+          maxDistanceSquared = std::max(maxDistanceSquared, delta.LengthSquared());
         }
       }
     }
@@ -475,6 +475,14 @@ void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDe
   }
 
   geometryBufferIndex = 0u;
+
+  const float maxDistance = sqrtf(maxDistanceSquared);
+
+  const float normalizeFactor = (maxDistanceSquared < Math::MACHINE_EPSILON_1000) ? 1.f : (0.5f / maxDistance);
+
+  // Calculate and store the unnormalize factor.
+  blendShapeUnnormalizeFactor = maxDistance * 2.0f;
+
   for(const auto& blendShape : blendShapes)
   {
     // Normalize all the deltas and translate to a possitive value.
@@ -482,8 +490,6 @@ void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDe
     // whose values that are less than zero are clamped.
     if(blendShape.deltas.IsDefined())
     {
-      const float normalizeFactor = (fabsf(maxDistance) < Math::MACHINE_EPSILON_1000) ? 1.f : (0.5f / sqrtf(maxDistance));
-
       for(uint32_t index = 0u; index < numberOfVertices; ++index)
       {
         Vector3& delta = geometryBufferV3[geometryBufferIndex++];
@@ -491,9 +497,6 @@ void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDe
         delta.y        = Clamp(((delta.y * normalizeFactor) + 0.5f), 0.f, 1.f);
         delta.z        = Clamp(((delta.z * normalizeFactor) + 0.5f), 0.f, 1.f);
       }
-
-      // Calculate and store the unnormalize factor.
-      blendShapeUnnormalizeFactor = 1.f / normalizeFactor;
     }
 
     if(blendShape.normals.IsDefined())