Merge changes I7b63ee17,I61bd1ed2 into devel/master
authorSeungho BAEK <sbsh.baek@samsung.com>
Fri, 29 Apr 2022 06:48:30 +0000 (06:48 +0000)
committerGerrit Code Review <gerrit@review>
Fri, 29 Apr 2022 06:48:30 +0000 (06:48 +0000)
* changes:
  Use default PBR shader to the scene-loader
  Fix Scene3d-View light issue

18 files changed:
automated-tests/src/dali-scene-loader/utc-Dali-Gltf2Loader.cpp
automated-tests/src/dali-scene-loader/utc-Dali-ShaderDefinitionFactory.cpp
dali-scene-loader/internal/gltf2-asset.h
dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.frag [new file with mode: 0644]
dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.vert [new file with mode: 0644]
dali-scene-loader/public-api/gltf2-loader.cpp
dali-scene-loader/public-api/material-definition.cpp
dali-scene-loader/public-api/material-definition.h
dali-scene-loader/public-api/node-definition.cpp
dali-scene-loader/public-api/shader-definition-factory.cpp
dali-scene-loader/public-api/shader-definition.cpp
dali-scene-loader/public-api/shader-definition.h
dali-toolkit/devel-api/controls/scene3d-view/scene3d-view.h
dali-toolkit/internal/controls/scene3d-view/gltf-loader.cpp
dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.cpp
dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.h
dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.frag
dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.vert

index 47515b3..b4dceb9 100644 (file)
@@ -167,12 +167,15 @@ int UtcDaliGltfLoaderSuccess1(void)
   DALI_TEST_EQUAL(2u, materials.size());
   const MaterialDefinition materialGroundTruth[]{
     {MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+       MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION |
        MaterialDefinition::NORMAL | MaterialDefinition::TRANSPARENCY | MaterialDefinition::GLTF_CHANNELS |
        (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
      0,
      Vector4(1.f, .766f, .336f, 1.f),
+     Vector3(0.2, 0.1, 0.0),
      1.f,
      0.f,
+     1.f,
      {
        {MaterialDefinition::ALBEDO,
         {"AnimatedCube_BaseColor.png",
@@ -183,13 +186,22 @@ int UtcDaliGltfLoaderSuccess1(void)
        {MaterialDefinition::NORMAL,
         {"AnimatedCube_BaseColor.png",
          SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
+       {MaterialDefinition::OCCLUSION,
+        {"AnimatedCube_BaseColor.png",
+         SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
+       {MaterialDefinition::EMISSIVE,
+        {"AnimatedCube_BaseColor.png",
+         SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
      }},
     {MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+       MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION |
        MaterialDefinition::NORMAL | MaterialDefinition::GLTF_CHANNELS,
      0,
      Vector4(1.f, .766f, .336f, 1.f),
+     Vector3(0.2, 0.1, 0.0),
      1.f,
      0.f,
+     1.f,
      {
        {MaterialDefinition::ALBEDO,
         {"AnimatedCube_BaseColor.png",
@@ -200,6 +212,12 @@ int UtcDaliGltfLoaderSuccess1(void)
        {MaterialDefinition::NORMAL,
         {"AnimatedCube_BaseColor.png",
          SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
+       {MaterialDefinition::OCCLUSION,
+        {"AnimatedCube_BaseColor.png",
+         SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
+       {MaterialDefinition::EMISSIVE,
+        {"AnimatedCube_BaseColor.png",
+         SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
      }},
   };
 
index 80ed66d..3fd8fbb 100644 (file)
@@ -31,11 +31,6 @@ using namespace Dali::SceneLoader;
 
 namespace
 {
-bool EndsWith(const std::string& str, const std::string& suffix) // ends_width() is C++20
-{
-  return str.size() >= suffix.size() && str.substr(str.size() - suffix.size()).compare(suffix) == 0;
-}
-
 MaterialDefinition& NewMaterialDefinition(ResourceBundle& resources)
 {
   resources.mMaterials.push_back({});
@@ -281,8 +276,6 @@ int UtcDaliShaderDefinitionFactoryProduceShader(void)
     DALI_TEST_EQUAL(ps.shaderIdx, shaderIdx);
 
     auto& shaderDef = ctx.resources.mShaders[shaderIdx].first;
-    DALI_TEST_CHECK(EndsWith(shaderDef.mVertexShaderPath, ".vsh"));
-    DALI_TEST_CHECK(EndsWith(shaderDef.mFragmentShaderPath, ".fsh"));
     DALI_TEST_EQUAL(shaderDef.mRendererState, rendererState);
 
     uint32_t definesUnmatched = shaderDef.mDefines.size();
index f5bd6b9..e074c28 100644 (file)
@@ -317,6 +317,7 @@ struct TextureInfo
   Ref<gltf2::Texture> mTexture;
   uint32_t            mTexCoord = 0;
   float               mScale    = 1.f;
+  float               mStrength = 1.f;
 
   operator bool() const
   {
diff --git a/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.frag b/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.frag
new file mode 100644 (file)
index 0000000..2581ad6
--- /dev/null
@@ -0,0 +1,183 @@
+#version 300 es
+
+#ifdef HIGHP
+  precision highp float;
+#else
+  precision mediump float;
+#endif
+
+#ifdef THREE_TEX
+#ifdef GLTF_CHANNELS
+// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture
+#define METALLIC b
+#define ROUGHNESS g
+#else //GLTF_CHANNELS
+#define METALLIC r
+#define ROUGHNESS a
+#endif //GLTF_CHANNELS
+#endif //THREE_TEX
+
+#ifdef THREE_TEX
+  uniform sampler2D sAlbedoAlpha;
+  uniform sampler2D sMetalRoughness;
+  uniform sampler2D sNormal;
+
+#ifdef ALPHA_TEST
+  uniform float uAlphaThreshold;
+#endif //ALPHA_TEST
+
+#else
+  uniform sampler2D sAlbedoMetal;
+  uniform sampler2D sNormalRoughness;
+#endif
+
+#ifdef OCCLUSION
+  uniform sampler2D sOcclusion;
+  uniform float uOcclusionStrength;
+#endif
+
+#ifdef EMISSIVE
+  uniform sampler2D sEmissive;
+  uniform vec3 uEmissiveFactor;
+#endif
+
+uniform samplerCube sDiffuse;
+uniform samplerCube sSpecular;
+
+// Number of mip map levels in the texture
+uniform float uMaxLOD;
+
+// Transformation matrix of the cubemap texture
+uniform mat4 uCubeMatrix;
+
+uniform vec4 uColor;
+uniform float uMetallicFactor;
+uniform float uRoughnessFactor;
+
+//IBL Light intensity
+uniform float uIblIntensity;
+
+// TODO: Multiple texture coordinate will be supported.
+in vec2 vUV;
+in vec3 vNormal;
+in vec3 vTangent;
+in vec3 vViewVec;
+
+out vec4 FragColor;
+
+// Functions for BRDF calculation come from
+// https://www.unrealengine.com/blog/physically-based-shading-on-mobile
+// Based on the paper by Dimitar Lazarov
+// http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf
+vec3 EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV )
+{
+  const vec4 c0 = vec4( -1.0, -0.0275, -0.572, 0.022 );
+  const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04 );
+  vec4 r = Roughness * c0 + c1;
+  float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
+  vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
+
+  return SpecularColor * AB.x + AB.y;
+}
+
+void main()
+{
+  // We get information from the maps (albedo, normal map, roughness, metalness
+  // I access the maps in the order they will be used
+#ifdef THREE_TEX
+  vec4 albedoAlpha = texture(sAlbedoAlpha, vUV.st);
+  float alpha = albedoAlpha.a;
+#ifdef ALPHA_TEST
+  if (alpha <= uAlphaThreshold)
+  {
+    discard;
+  }
+#endif //ALPHA_TEST
+  vec3 albedoColor = albedoAlpha.rgb * uColor.rgb;
+
+  vec4 metalRoughness = texture(sMetalRoughness, vUV.st);
+  float metallic = metalRoughness.METALLIC * uMetallicFactor;
+  float roughness = metalRoughness.ROUGHNESS * uRoughnessFactor;
+
+  vec3 normalMap = texture(sNormal, vUV.st).rgb;
+#else  //THREE_TEX
+  vec4 albedoMetal = texture(sAlbedoMetal, vUV.st);
+  vec3 albedoColor = albedoMetal.rgb * uColor.rgb;
+  float metallic = albedoMetal.a * uMetallicFactor;
+
+  vec4 normalRoughness = texture(sNormalRoughness, vUV.st);
+  vec3 normalMap = normalRoughness.rgb;
+  float roughness = normalRoughness.a * uRoughnessFactor;
+#endif
+  //Normalize vectors
+  vec3 normal = normalize(vNormal);
+  vec3 tangent = normalize(vTangent);
+
+  // NOTE: normal and tangent have to be orthogonal for the result of the cross()
+  // product to be a unit vector. We might find that we need to normalize().
+  vec3 bitangent = cross(normal, tangent);
+
+  vec3 viewVec = normalize(vViewVec);
+
+  // Create Inverse Local to world matrix
+  mat3 vInvTBN = mat3(tangent, bitangent, normal);
+
+  // Get normal map info in world space
+  normalMap = normalize(normalMap - 0.5);
+  vec3 newNormal = vInvTBN * normalMap.rgb;
+
+  // Calculate normal dot view vector
+  float NoV = max(dot(newNormal, -viewVec), 0.0);
+
+  // Reflect vector
+  vec3 reflectionVec = reflect(viewVec, newNormal);
+
+  //transform it now to environment coordinates (used when the environment rotates)
+  vec3 reflecCube = (uCubeMatrix * vec4( reflectionVec, 0.0 ) ).xyz;
+  reflecCube = normalize( reflecCube );
+
+  //transform it now to environment coordinates
+  vec3 normalCube = ( uCubeMatrix * vec4( newNormal, 0.0 ) ).xyz;
+  normalCube = normalize( normalCube );
+
+  // Get irradiance from diffuse cubemap
+  vec3 irradiance = texture( sDiffuse, normalCube ).rgb;
+
+  // Access reflection color using roughness value
+  float finalLod = mix( 0.0, uMaxLOD - 2.0, roughness);
+  vec3 reflectionColor = textureLod(sSpecular, reflecCube, finalLod).rgb;
+
+  // We are supposed to be using DielectricColor (0.04) of a plastic (almost everything)
+  // http://blog.selfshadow.com/publications/s2014-shading-course/hoffman/s2014_pbs_physics_math_slides.pdf
+  // however that seems to prevent achieving very dark tones (i.e. get dark gray blacks).
+  vec3 DiffuseColor = albedoColor - albedoColor * metallic;  // 1 mad
+  vec3 SpecularColor = mix( vec3(0.04), albedoColor, metallic); // 2 mad
+
+  // Calculate specular color using Magic Function (takes original roughness and normal dot view).
+  vec3 specColor =  reflectionColor.rgb * EnvBRDFApprox(SpecularColor, roughness, NoV );
+
+  // Multiply the result by albedo texture and do energy conservation
+  vec3 diffuseColor = irradiance * DiffuseColor;
+
+  // Final color is the sum of the diffuse and specular term
+  vec3 finalColor = diffuseColor + specColor;
+
+  finalColor = sqrt( finalColor ) * uIblIntensity;
+
+
+#ifdef OCCLUSION
+  float ao = texture(sOcclusion, vUV.st).r;
+  finalColor = mix( finalColor, finalColor * ao, uOcclusionStrength );
+#endif
+
+#ifdef EMISSIVE
+  vec3 emissive = texture( sEmissive, vUV.st ).rgb * uEmissiveFactor;
+  finalColor += emissive;
+#endif
+
+#ifdef THREE_TEX
+  FragColor = vec4( finalColor, alpha );
+#else //THREE_TEX
+  FragColor = vec4( finalColor, 1.0 );
+#endif //THREE_TEX
+}
diff --git a/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.vert b/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.vert
new file mode 100644 (file)
index 0000000..e9381c5
--- /dev/null
@@ -0,0 +1,149 @@
+#version 300 es
+
+#ifdef HIGHP
+  precision highp float;
+#else
+  precision mediump float;
+#endif
+
+in vec3 aPosition;
+in vec2 aTexCoord;
+in vec3 aNormal;
+in vec3 aTangent;
+
+#ifdef MORPH
+  uniform sampler2D sBlendShapeGeometry;
+#endif
+
+out vec2 vUV;
+out vec3 vNormal;
+out vec3 vTangent;
+out vec3 vViewVec;
+
+uniform highp mat4 uMvpMatrix;
+uniform highp mat4 uViewMatrix;
+uniform mat3 uNormalMatrix;
+uniform mat4 uModelMatrix;
+uniform mat4 uModelView;
+uniform mat4 uProjection;
+
+#ifdef SKINNING
+  in vec4 aJoints;
+  in vec4 aWeights;
+  #define MAX_BONES 64
+  uniform mat4 uBone[MAX_BONES];
+#endif
+
+#ifdef MORPH
+#define MAX_BLEND_SHAPE_NUMBER 128
+uniform int uNumberOfBlendShapes;                                   ///< Total number of blend shapes loaded.
+uniform 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.
+#else
+uniform float uBlendShapeUnnormalizeFactor[MAX_BLEND_SHAPE_NUMBER]; ///< Factor used to unnormalize the geometry of the blend shape.
+#endif
+uniform int uBlendShapeComponentSize;                               ///< The size in the texture of either the vertices, normals or tangents. Used to calculate the offset to address them.
+#endif
+
+void main()
+{
+  vec4 position = vec4(aPosition, 1.0);
+  vec3 normal = aNormal;
+  vec3 tangent = aTangent;
+
+#ifdef MORPH
+  int width = textureSize( sBlendShapeGeometry, 0 ).x;
+
+  int blendShapeBufferOffset = 0;
+  for( int index = 0; index < uNumberOfBlendShapes; ++index )
+  {
+#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;
+
+    vec3 diff = vec3(0.0);
+    // 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;
+#else
+       float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
+#endif
+
+      diff = uBlendShapeWeight[index] * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+    }
+
+    position.xyz += diff;
+
+    blendShapeBufferOffset += uBlendShapeComponentSize;
+#endif
+
+#ifdef MORPH_NORMAL
+    // Calculate the index to retrieve the normal from the texture.
+    vertexId = gl_VertexID + blendShapeBufferOffset;
+    x = vertexId % width;
+    y = vertexId / width;
+
+    // Retrieves the blend shape normal from the texture, unnormalizes it and multiply by the weight.
+    if( 0.0 != uBlendShapeWeight[index] )
+    {
+      diff = uBlendShapeWeight[index] * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+    }
+
+    normal += diff.xyz;
+
+    blendShapeBufferOffset += uBlendShapeComponentSize;
+#endif
+
+#ifdef MORPH_TANGENT
+    // Calculate the index to retrieve the tangent from the texture.
+    vertexId = gl_VertexID + blendShapeBufferOffset;
+    x = vertexId % width;
+    y = vertexId / width;
+
+    // Retrieves the blend shape tangent from the texture, unnormalizes it and multiply by the weight.
+    if( 0.0 != uBlendShapeWeight[index] )
+    {
+      diff = uBlendShapeWeight[index] * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+    }
+
+    tangent += diff.xyz;
+
+    blendShapeBufferOffset += uBlendShapeComponentSize;
+#endif
+  }
+
+#endif
+
+#ifdef SKINNING
+  mat4 bone = uBone[int(aJoints.x)] * aWeights.x +
+    uBone[int(aJoints.y)] * aWeights.y +
+    uBone[int(aJoints.z)] * aWeights.z +
+    uBone[int(aJoints.w)] * aWeights.w;
+  position = bone * position;
+  normal = (bone * vec4(normal, 0.0)).xyz;
+  tangent = (bone * vec4(tangent, 0.0)).xyz;
+#endif
+
+  vec4 vPosition = uModelMatrix * position;
+
+  vNormal = normalize(uNormalMatrix * normal);
+
+  vTangent = normalize(uNormalMatrix * tangent);
+
+
+  vec4 viewPosition = uViewMatrix * vPosition;
+  gl_Position = uProjection * viewPosition;
+
+#ifdef FLIP_V
+  vUV = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
+#else
+  vUV = aTexCoord;
+#endif
+
+  vViewVec = viewPosition.xyz;
+}
index 923d0e4..be7e538 100644 (file)
@@ -157,7 +157,8 @@ const auto TEXURE_READER = std::move(js::Reader<gt::Texture>()
 const auto TEXURE_INFO_READER = std::move(js::Reader<gt::TextureInfo>()
                                             .Register(*js::MakeProperty("index", gt::RefReader<gt::Document>::Read<gt::Texture, &gt::Document::mTextures>, &gt::TextureInfo::mTexture))
                                             .Register(*js::MakeProperty("texCoord", js::Read::Number<uint32_t>, &gt::TextureInfo::mTexCoord))
-                                            .Register(*js::MakeProperty("scale", js::Read::Number<float>, &gt::TextureInfo::mScale)));
+                                            .Register(*js::MakeProperty("scale", js::Read::Number<float>, &gt::TextureInfo::mScale))
+                                            .Register(*js::MakeProperty("strength", js::Read::Number<float>, &gt::TextureInfo::mStrength)));
 
 const auto MATERIAL_PBR_READER = std::move(js::Reader<gt::Material::Pbr>()
                                              .Register(*js::MakeProperty("baseColorFactor", gt::ReadDaliVector<Vector4>, &gt::Material::Pbr::mBaseColorFactor))
@@ -440,7 +441,7 @@ void ConvertMaterial(const gt::Material& m, decltype(ResourceBundle::mMaterials)
 
   matDef.mColor = pbr.mBaseColorFactor;
 
-  matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!m.mNormalTexture);
+  matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!m.mNormalTexture + !!m.mOcclusionTexture + !!m.mEmissiveTexture);
   if(pbr.mBaseColorTexture)
   {
     const auto semantic = MaterialDefinition::ALBEDO;
@@ -470,6 +471,23 @@ void ConvertMaterial(const gt::Material& m, decltype(ResourceBundle::mMaterials)
   }
 
   // TODO: handle doubleSided
+  if(m.mOcclusionTexture)
+  {
+    const auto semantic = MaterialDefinition::OCCLUSION;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(m.mOcclusionTexture)});
+    // TODO: and there had better be one
+    matDef.mFlags |= semantic;
+    matDef.mOcclusionStrength = m.mOcclusionTexture.mStrength;
+  }
+
+  if(m.mEmissiveTexture)
+  {
+    const auto semantic = MaterialDefinition::EMISSIVE;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(m.mEmissiveTexture)});
+    // TODO: and there had better be one
+    matDef.mFlags |= semantic;
+    matDef.mEmissiveFactor = m.mEmissiveFactor;
+  }
 
   outMaterials.emplace_back(std::move(matDef), TextureSet());
 }
index 3c7a391..1342ced 100644 (file)
@@ -110,7 +110,9 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath) const
   RawData raw;
 
   const bool hasTransparency = MaskMatch(mFlags, TRANSPARENCY);
-  uint32_t   numBuffers      = mTextureStages.size() + (hasTransparency ? !CheckTextures(ALBEDO) + !CheckTextures(METALLIC | ROUGHNESS) + !CheckTextures(NORMAL) : !CheckTextures(ALBEDO | METALLIC) + !CheckTextures(NORMAL | ROUGHNESS));
+  // Why we add additional count here?
+  uint32_t numBuffers = mTextureStages.size() + (hasTransparency ? !CheckTextures(ALBEDO) + !CheckTextures(METALLIC | ROUGHNESS) + !CheckTextures(NORMAL)
+                                                                 : !CheckTextures(ALBEDO | METALLIC) + !CheckTextures(NORMAL | ROUGHNESS));
   if(numBuffers == 0)
   {
     return raw;
@@ -210,7 +212,7 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath) const
     }
   }
 
-  // Extra textures. TODO: emissive, occlusion etc.
+  // Extra textures.
   if(checkStage(SUBSURFACE))
   {
     raw.mTextures.push_back({SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags});
@@ -223,6 +225,12 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath) const
     ++iTexture;
   }
 
+  if(checkStage(EMISSIVE))
+  {
+    raw.mTextures.push_back({SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags});
+    ++iTexture;
+  }
+
   return raw;
 }
 
index 80e93e7..e36f74b 100644 (file)
@@ -219,10 +219,12 @@ struct DALI_SCENE_LOADER_API MaterialDefinition
 public: // DATA
   uint32_t mFlags = 0x0;
 
-  Index                     mEnvironmentIdx = 0;
-  Vector4                   mColor          = Color::WHITE;
-  float                     mMetallic       = 1.f;
-  float                     mRoughness      = 1.f;
+  Index                     mEnvironmentIdx    = 0;
+  Vector4                   mColor             = Color::WHITE;
+  Vector3                   mEmissiveFactor    = Vector3::ZERO;
+  float                     mMetallic          = 1.f;
+  float                     mRoughness         = 1.f;
+  float                     mOcclusionStrength = 1.f;
   std::vector<TextureStage> mTextureStages;
 };
 
index 45e0b23..e8f6b82 100644 (file)
@@ -153,6 +153,14 @@ void ModelNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParam
   auto& matDef = resources.mMaterials[mMaterialIdx].first;
   actor.RegisterProperty("uMetallicFactor", matDef.mMetallic);
   actor.RegisterProperty("uRoughnessFactor", matDef.mRoughness);
+  if(matDef.mFlags & MaterialDefinition::OCCLUSION)
+  {
+    actor.RegisterProperty("uOcclusionStrength", matDef.mOcclusionStrength);
+  }
+  if(matDef.mFlags & MaterialDefinition::EMISSIVE)
+  {
+    actor.RegisterProperty("uEmissiveFactor", matDef.mEmissiveFactor);
+  }
 
   Index envIdx = matDef.mEnvironmentIdx;
   actor.RegisterProperty("uIblIntensity", resources.mEnvironmentMaps[envIdx].first.mIblIntensity);
index bd6b168..6f9ab4e 100644 (file)
@@ -56,8 +56,6 @@ struct ResourceReceiver : IResourceReceiver
   }
 };
 
-const std::string PBR_SHADER_NAME = "dli_pbr";
-
 void RetrieveBlendShapeComponents(const std::vector<MeshDefinition::BlendShape>& blendShapes, bool& hasPositions, bool& hasNormals, bool& hasTangents)
 {
   for(const auto& blendShape : blendShapes)
@@ -72,9 +70,6 @@ uint64_t HashNode(const NodeDefinition& nodeDef, const MaterialDefinition& mater
 {
   Hash hash;
 
-  // note: could be per vertex / fragment component - in WatchViewer, these have the same name.
-  hash.Add(PBR_SHADER_NAME);
-
   const bool hasTransparency = MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY);
   hash.Add(hasTransparency);
 
@@ -101,6 +96,11 @@ uint64_t HashNode(const NodeDefinition& nodeDef, const MaterialDefinition& mater
     hash.Add("OCCL" /*USION*/);
   }
 
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE))
+  {
+    hash.Add("EMIS" /*SIVE*/);
+  }
+
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))
   {
     hash.Add("GLTF" /*_CHANNELS*/);
@@ -192,8 +192,7 @@ Index ShaderDefinitionFactory::ProduceShader(const NodeDefinition& nodeDef)
   }
 
   ShaderDefinition shaderDef;
-  shaderDef.mVertexShaderPath   = PBR_SHADER_NAME + ".vsh";
-  shaderDef.mFragmentShaderPath = PBR_SHADER_NAME + ".fsh";
+  shaderDef.mUseBuiltInShader = true;
   shaderDef.mRendererState      = RendererState::DEPTH_TEST | RendererState::DEPTH_WRITE | RendererState::CULL_BACK;
 
   auto&      materialDef     = *receiver.mMaterialDef;
@@ -222,12 +221,17 @@ Index ShaderDefinitionFactory::ProduceShader(const NodeDefinition& nodeDef)
     shaderDef.mDefines.push_back("SSS");
   }
 
-  if(MaskMatch(receiver.mMaterialDef->mFlags, MaterialDefinition::OCCLUSION))
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION))
   {
     shaderDef.mDefines.push_back("OCCLUSION");
   }
 
-  if(MaskMatch(receiver.mMaterialDef->mFlags, MaterialDefinition::GLTF_CHANNELS))
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE))
+  {
+    shaderDef.mDefines.push_back("EMISSIVE");
+  }
+
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))
   {
     shaderDef.mDefines.push_back("GLTF_CHANNELS");
   }
index 73c18ba..71024f3 100644 (file)
@@ -18,6 +18,7 @@
 // INTERNAL INCLUDES
 #include "dali-scene-loader/public-api/shader-definition.h"
 #include "dali-scene-loader/public-api/utils.h"
+#include <dali-scene-loader/internal/graphics/builtin-shader-extern-gen.h>
 
 namespace Dali
 {
@@ -36,7 +37,8 @@ ShaderDefinition::ShaderDefinition(const ShaderDefinition& other)
   mFragmentShaderPath(other.mFragmentShaderPath),
   mDefines(other.mDefines),
   mHints(other.mHints),
-  mUniforms(other.mUniforms)
+  mUniforms(other.mUniforms),
+  mUseBuiltInShader(false)
 {
 }
 
@@ -80,28 +82,38 @@ ShaderDefinition::LoadRaw(const std::string& shadersPath) const
 {
   RawData raw;
 
-  bool fail               = false;
-  raw.mVertexShaderSource = LoadTextFile((shadersPath + mVertexShaderPath).c_str(), &fail);
-  if(!fail)
+  bool fail = false;
+  if(!mUseBuiltInShader)
   {
-    raw.mFragmentShaderSource = LoadTextFile((shadersPath + mFragmentShaderPath).c_str(), &fail);
+    raw.mVertexShaderSource = LoadTextFile((shadersPath + mVertexShaderPath).c_str(), &fail);
     if(!fail)
     {
-      for(auto definevar : mDefines)
+      raw.mFragmentShaderSource = LoadTextFile((shadersPath + mFragmentShaderPath).c_str(), &fail);
+      if(fail)
       {
-        ApplyDefine(raw.mVertexShaderSource, definevar);
-        ApplyDefine(raw.mFragmentShaderSource, definevar);
+        ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mFragmentShaderPath << "'.";
       }
     }
     else
     {
-      ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mFragmentShaderPath << "'.";
+      ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mVertexShaderPath << "'.";
     }
   }
   else
   {
-    ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mVertexShaderPath << "'.";
+    raw.mVertexShaderSource   = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_VERT.data();
+    raw.mFragmentShaderSource = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data();
+  }
+
+  if(!fail)
+  {
+    for(auto definevar : mDefines)
+    {
+      ApplyDefine(raw.mVertexShaderSource, definevar);
+      ApplyDefine(raw.mFragmentShaderSource, definevar);
+    }
   }
+
   return raw;
 }
 
index d7f390b..5d0a49e 100644 (file)
@@ -79,8 +79,8 @@ public: // DATA
   std::string              mFragmentShaderPath;
   std::vector<std::string> mDefines;
   std::vector<std::string> mHints;
-
-  Property::Map mUniforms;
+  Property::Map            mUniforms;
+  bool                     mUseBuiltInShader;
 };
 
 } // namespace SceneLoader
index 1f0effb..756a7a5 100644 (file)
@@ -80,15 +80,9 @@ public:
     // Scene doesn't use both of point and directional light\r
     NONE = 0,\r
     // Scene use point light\r
-    POINT_LIGHT,\r
+    POINT_LIGHT = 1,\r
     // Scene use directional light\r
-    DIRECTIONAL_LIGHT,\r
-    // Scene use Image Based Lighting\r
-    IMAGE_BASED_LIGHT,\r
-    // Scene use Image Based Lighting and point light\r
-    IMAGE_BASED_LIGHT_AND_POINT_LIGHT,\r
-    // Scene use Image Based Lighting and directional light\r
-    IMAGE_BASED_LIGHT_AND_DIRECTIONAL_LIGHT\r
+    DIRECTIONAL_LIGHT = 2\r
   };\r
 \r
   /**\r
index 2c8de12..55dfd8d 100644 (file)
@@ -1509,7 +1509,7 @@ Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index)
     VERTEX_SHADER += SHADER_GLTF_PHYSICALLY_BASED_SHADER_VERT.data();
     FRAGMENT_SHADER = SHADER_GLTF_GLES_VERSION_300_DEF.data();
 
-    bool useIBL = (scene3dView.GetLightType() >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT);
+    bool useIBL = scene3dView.HasImageBasedLighting();
     if(isMaterial)
     {
       MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
@@ -1592,11 +1592,14 @@ Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index)
     actor.RotateBy(orientation);
     actor.SetProperty(Actor::Property::POSITION, translation);
 
-    shader.RegisterProperty("uLightType", (scene3dView.GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT));
+    float hasLightSource = static_cast<float>(!!(scene3dView.GetLightType() & (Toolkit::Scene3dView::LightType::POINT_LIGHT | Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT)));
+    float isPointLight = static_cast<float>(!!(scene3dView.GetLightType() & Toolkit::Scene3dView::LightType::POINT_LIGHT));
+    shader.RegisterProperty("uHasLightSource", hasLightSource);
+    shader.RegisterProperty("uIsPointLight", isPointLight);
     shader.RegisterProperty("uLightVector", scene3dView.GetLightVector());
     shader.RegisterProperty("uLightColor", scene3dView.GetLightColor());
 
-    actor.RegisterProperty("uIsColor", meshInfo.attribute.COLOR.size() > 0);
+    actor.RegisterProperty("uHasVertexColor", meshInfo.attribute.COLOR.size() > 0 ? 1.0f : 0.0f);
     if(isMaterial)
     {
       MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx];
@@ -1605,15 +1608,15 @@ Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index)
 
       if(materialInfo.alphaMode == "OPAQUE")
       {
-        actor.RegisterProperty("alphaMode", 0);
+        actor.RegisterProperty("uAlphaMode", 0.0f);
       }
       else if(materialInfo.alphaMode == "MASK")
       {
-        actor.RegisterProperty("alphaMode", 1);
+        actor.RegisterProperty("uAlphaMode", 1.0f);
       }
       else
       {
-        actor.RegisterProperty("alphaMode", 2);
+        actor.RegisterProperty("uAlphaMode", 2.0f);
       }
       actor.RegisterProperty("alphaCutoff", materialInfo.alphaCutoff);
 
index aa8438a..6231b64 100644 (file)
@@ -54,7 +54,8 @@ Scene3dView::Scene3dView()
   mAnimationArray(),
   mLightType(Toolkit::Scene3dView::LightType::NONE),
   mLightVector(Vector3::ONE),
-  mLightColor(Vector3::ONE)
+  mLightColor(Vector3::ONE),
+  mUseIBL(false)
 {
 }
 
@@ -130,20 +131,16 @@ bool Scene3dView::PlayAnimations()
 
 bool Scene3dView::SetLight(Toolkit::Scene3dView::LightType type, Vector3 lightVector, Vector3 lightColor)
 {
-  if(type > Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT)
-  {
-    return false;
-  }
-
-  mLightType = static_cast<Toolkit::Scene3dView::LightType>(
-    (mLightType >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT) ? Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT + type : type);
-
+  mLightType = type;
   mLightVector = lightVector;
   mLightColor  = lightColor;
 
   for(auto&& shader : mShaderArray)
   {
-    shader.RegisterProperty("uLightType", (GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT));
+    float hasLightSource = static_cast<float>(!!(GetLightType() & (Toolkit::Scene3dView::LightType::POINT_LIGHT | Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT)));
+    float isPointLight = static_cast<float>(!!(GetLightType() & Toolkit::Scene3dView::LightType::POINT_LIGHT));
+    shader.RegisterProperty("uHasLightSource", hasLightSource);
+    shader.RegisterProperty("uIsPointLight", isPointLight);
     shader.RegisterProperty("uLightVector", lightVector);
     shader.RegisterProperty("uLightColor", lightColor);
   }
@@ -203,8 +200,6 @@ void Scene3dView::UploadTextureFace(Texture& texture, Devel::PixelBuffer pixelBu
 
 void Scene3dView::SetCubeMap(const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 scaleFactor)
 {
-  mLightType = Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT;
-
   // BRDF texture
   const std::string imageDirPath = AssetManager::GetDaliImagePath();
   const std::string imageBrdfUrl = imageDirPath + IMAGE_BRDF_FILE_NAME;
@@ -235,6 +230,7 @@ void Scene3dView::SetCubeMap(const std::string& diffuseTexturePath, const std::s
   mSpecularTexture.GenerateMipmaps();
 
   mIBLScaleFactor = scaleFactor;
+  mUseIBL = true;
 }
 
 bool Scene3dView::SetDefaultCamera(const Dali::Camera::Type type, const float nearPlane, const Vector3 cameraPosition)
@@ -318,6 +314,11 @@ Texture Scene3dView::GetSpecularTexture()
   return mSpecularTexture;
 }
 
+bool Scene3dView::HasImageBasedLighting()
+{
+  return mUseIBL;
+}
+
 Texture Scene3dView::GetDiffuseTexture()
 {
   return mDiffuseTexture;
index 6dbe859..bc731d3 100644 (file)
@@ -185,6 +185,11 @@ public:
    */\r
   Texture GetSpecularTexture();\r
 \r
+  /**\r
+   * @brief Get whether the scene has image based rendering or not.\r
+   */\r
+  bool HasImageBasedLighting();\r
+\r
 private:\r
   /**\r
    * @brief Get Cropped image buffer.\r
@@ -232,6 +237,7 @@ private:
   Texture mBRDFTexture;     // BRDF texture for the PBR rendering\r
   Texture mSpecularTexture; // Specular cube map texture\r
   Texture mDiffuseTexture;  // Diffuse cube map texture\r
+  bool    mUseIBL;\r
 \r
 private:\r
   // Undefined copy constructor.\r
index cefd19e..9477e40 100644 (file)
@@ -1,13 +1,13 @@
 uniform lowp vec3 uLightColor;
 uniform lowp vec4 uBaseColorFactor;
 uniform lowp vec2 uMetallicRoughnessFactors;
-uniform lowp int alphaMode;
 uniform lowp float alphaCutoff;
+uniform lowp float uAlphaMode;
+uniform lowp float uHasLightSource;
 
 in lowp vec2 vUV[2];
 in lowp mat3 vTBN;
 in lowp vec4 vColor;
-flat in int visLight;
 in highp vec3 vLightDirection;
 in highp vec3 vPositionToCamera;
 
@@ -30,20 +30,20 @@ const float c_MinRoughness = 0.04;
 vec3 getNormal()
 {
 #ifdef TEXTURE_NORMAL
-  lowp vec3 n = texture( uNormalSampler, vUV[uNormalTexCoordIndex] ).rgb;
-  n = normalize( vTBN * ( ( 2.0 * n - 1.0 ) * vec3( uNormalScale, uNormalScale, 1.0 ) ) );
+  lowp vec3 n = texture(uNormalSampler, vUV[uNormalTexCoordIndex]).rgb;
+  n = normalize(vTBN * ((2.0 * n - 1.0) * vec3(uNormalScale, uNormalScale, 1.0)));
 #else
   lowp vec3 n = normalize( vTBN[2].xyz );
 #endif
   return n;
 }
 
-vec3 specularReflection( PBRInfo pbrInputs )
+vec3 specularReflection(PBRInfo pbrInputs)
 {
-  return pbrInputs.reflectance0 + ( pbrInputs.reflectance90 - pbrInputs.reflectance0 ) * pow( clamp( 1.0 - pbrInputs.VdotH, 0.0, 1.0 ), 5.0 );
+  return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
 }
 
-float geometricOcclusion( PBRInfo pbrInputs )
+float geometricOcclusion(PBRInfo pbrInputs)
 {
   mediump float NdotL = pbrInputs.NdotL;
   mediump float NdotV = pbrInputs.NdotV;
@@ -61,7 +61,7 @@ float microfacetDistribution(PBRInfo pbrInputs)
   return roughnessSq / (M_PI * f * f);
 }
 
-vec3 linear( vec3 color )
+vec3 linear(vec3 color)
 {
   return pow(color,vec3(2.2));
 }
@@ -96,13 +96,13 @@ void main()
   lowp vec4 baseColor = vColor * uBaseColorFactor;
 #endif
 
-  if( alphaMode == 0 )
+  if(uAlphaMode < 0.5f)
   {
     baseColor.w = 1.0;
   }
-  else if( alphaMode == 1 )
+  else if(uAlphaMode < 1.5f)
   {
-    if( baseColor.w >= alphaCutoff )
+    if(baseColor.w >= alphaCutoff)
     {
       baseColor.w = 1.0;
     }
@@ -150,7 +150,7 @@ void main()
 
   // Calculate the shading terms for the microfacet specular shading model
   lowp vec3 color = vec3(0.0);
-  if( visLight == 1 )
+  if( uHasLightSource > 0.5f )
   {
     lowp vec3 F = specularReflection( pbrInputs );
     lowp float G = geometricOcclusion( pbrInputs );
index 6628865..095e839 100644 (file)
@@ -9,51 +9,34 @@ uniform mediump vec3 uSize;
 uniform mediump mat4 uModelMatrix;
 uniform mediump mat4 uViewMatrix;
 uniform mediump mat4 uProjection;
-uniform lowp int uLightType;
 uniform mediump vec3 uLightVector;
-uniform lowp int uIsColor;
+uniform lowp float uIsPointLight;
+uniform lowp float uHasVertexColor;
 
 out lowp vec2 vUV[2];
 out lowp mat3 vTBN;
 out lowp vec4 vColor;
-flat out int visLight;
 out highp vec3 vLightDirection;
 out highp vec3 vPositionToCamera;
 
 void main()
 {
   highp vec4 invY = vec4(1.0, -1.0, 1.0, 1.0);
-  highp vec4 positionW = uModelMatrix * vec4( aPosition * uSize, 1.0 );
-  highp vec4 positionV = uViewMatrix * ( invY * positionW );
+  highp vec4 positionW = uModelMatrix * vec4(aPosition * uSize, 1.0);
+  highp vec4 positionV = uViewMatrix * (invY * positionW);
 
-  vPositionToCamera = transpose( mat3( uViewMatrix ) ) * ( -vec3( positionV.xyz / positionV.w ) );
+  vPositionToCamera = transpose(mat3(uViewMatrix)) * (-vec3(positionV.xyz / positionV.w));
   vPositionToCamera *= invY.xyz;
 
   lowp vec3 bitangent = cross(aNormal, aTangent.xyz) * aTangent.w;
-  vTBN = mat3( uModelMatrix ) * mat3(aTangent.xyz, bitangent, aNormal);
+  vTBN = mat3(uModelMatrix) * mat3(aTangent.xyz, bitangent, aNormal);
 
   vUV[0] = aTexCoord0;
   vUV[1] = aTexCoord1;
 
-  visLight = 1;
-  if( uLightType == 1 )
-  {
-    vLightDirection = ( invY.xyz * uLightVector ) - ( positionW.xyz / positionW.w );
-  }
-  else if( uLightType == 2 )
-  {
-    vLightDirection = -( invY.xyz * uLightVector );
-  }
-  else
-  {
-    visLight = 0;
-  }
-
-  vColor = vec4( 1.0 );
-  if( uIsColor == 1 )
-  {
-    vColor = aVertexColor;
-  }
+  vLightDirection = mix(-(invY.xyz * uLightVector), (invY.xyz * uLightVector) - (positionW.xyz / positionW.w), uIsPointLight);
+
+  vColor = mix(vec4(1.0f), aVertexColor, uHasVertexColor);
 
   gl_Position = uProjection * positionV; // needs w for proper perspective correction
   gl_Position = gl_Position/gl_Position.w;