Support Scene3D on gles 2.0 21/305621/10
authorEunki, Hong <eunkiki.hong@samsung.com>
Mon, 5 Feb 2024 10:49:19 +0000 (19:49 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Wed, 21 Feb 2024 05:51:06 +0000 (05:51 +0000)
Let we support Scene3D::Model under gles 2.0 devices.

Note : Since glsl doesnt support textureLod, we cannot support roughness.

Change-Id: If518bf48361331eb47b0f8a5a2ef265ba3fee488
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
16 files changed:
automated-tests/src/dali-scene3d/utc-Dali-Light.cpp
automated-tests/src/dali-scene3d/utc-Dali-Model.cpp
dali-scene3d/internal/graphics/shaders/default-physically-based-shader.frag
dali-scene3d/internal/graphics/shaders/default-physically-based-shader.vert
dali-scene3d/internal/graphics/shaders/scene3d-joint-debug.frag
dali-scene3d/internal/graphics/shaders/scene3d-joint-debug.vert
dali-scene3d/internal/graphics/shaders/shadow-map-shader.frag
dali-scene3d/internal/graphics/shaders/shadow-map-shader.vert
dali-scene3d/internal/model-components/model-primitive-impl.cpp
dali-scene3d/public-api/controls/model/model.h
dali-scene3d/public-api/controls/scene-view/scene-view.h
dali-scene3d/public-api/loader/mesh-definition.cpp
dali-scene3d/public-api/loader/shader-definition.cpp
dali-scene3d/public-api/loader/shader-manager.cpp
dali-scene3d/public-api/loader/shader-option.cpp
dali-scene3d/public-api/loader/shader-option.h

index c9d9f79..e96737d 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.
@@ -748,6 +748,153 @@ int UtcDaliLightEnableShadowOnScene03(void)
   END_TEST;
 }
 
+int UtcDaliLightEnableShadowOnScene04(void)
+{
+  tet_infoline("Test when shader language version is low\n");
+  ToolkitTestApplication application;
+
+  auto originalShaderVersion = application.GetGlAbstraction().GetShaderLanguageVersion();
+
+  // Change the shader language version forcely!
+  application.GetGlAbstraction().mShaderLanguageVersion = 200;
+
+  try
+  {
+    Scene3D::SceneView sceneView = Scene3D::SceneView::New();
+    sceneView.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+    sceneView.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+    sceneView.SetProperty(Dali::Actor::Property::WIDTH_RESIZE_POLICY, ResizePolicy::FILL_TO_PARENT);
+    sceneView.SetProperty(Dali::Actor::Property::HEIGHT_RESIZE_POLICY, ResizePolicy::FILL_TO_PARENT);
+    application.GetScene().Add(sceneView);
+
+    Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+    sceneView.Add(model);
+
+    application.SendNotification();
+    application.Render();
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+    application.SendNotification();
+    application.Render();
+
+    // Light is added on layer when on scene
+    DALI_TEST_EQUALS(true, model.GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE), TEST_LOCATION);
+
+    Renderer renderer = model.FindChildByName("node2").GetRendererAt(0u);
+    DALI_TEST_CHECK(renderer);
+    Shader shader = renderer.GetShader();
+    DALI_TEST_CHECK(shader);
+
+    auto shadowEnabledIndex = shader.GetPropertyIndex("uIsShadowEnabled");
+    DALI_TEST_CHECK(shadowEnabledIndex != DALI_KEY_INVALID);
+    DALI_TEST_EQUALS(0, shader.GetProperty<int32_t>(shadowEnabledIndex), TEST_LOCATION);
+
+    Scene3D::Light light = Scene3D::Light::New();
+    light.SetProperty(Dali::Actor::Property::COLOR, Color::BLUE);
+    Dali::DevelActor::LookAt(light, Vector3(1.0f, 0.0f, 0.0f));
+    sceneView.Add(light);
+
+    DALI_TEST_CHECK(shadowEnabledIndex != DALI_KEY_INVALID);
+    DALI_TEST_EQUALS(0, shader.GetProperty<int32_t>(shadowEnabledIndex), TEST_LOCATION);
+
+    light.EnableShadow(true);
+
+    DALI_TEST_CHECK(shadowEnabledIndex != DALI_KEY_INVALID);
+    DALI_TEST_EQUALS(1, shader.GetProperty<int32_t>(shadowEnabledIndex), TEST_LOCATION);
+
+    light.EnableShadow(true);
+
+    DALI_TEST_CHECK(shadowEnabledIndex != DALI_KEY_INVALID);
+    DALI_TEST_EQUALS(1, shader.GetProperty<int32_t>(shadowEnabledIndex), TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false);
+  }
+
+  // Revert shader version. We should revert it even if UTC failed.
+  application.GetGlAbstraction().mShaderLanguageVersion = originalShaderVersion;
+
+  END_TEST;
+}
+
+int UtcDaliLightEnableShadowOnScene05(void)
+{
+  tet_infoline("Test when shader language version is low\n");
+  ToolkitTestApplication application;
+
+  auto originalShaderVersion = application.GetGlAbstraction().GetShaderLanguageVersion();
+
+  // Change the shader language version forcely!
+  application.GetGlAbstraction().mShaderLanguageVersion = 200;
+
+  try
+  {
+    Scene3D::SceneView sceneView = Scene3D::SceneView::New();
+    sceneView.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+    sceneView.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+    sceneView.SetProperty(Dali::Actor::Property::WIDTH_RESIZE_POLICY, ResizePolicy::FILL_TO_PARENT);
+    sceneView.SetProperty(Dali::Actor::Property::HEIGHT_RESIZE_POLICY, ResizePolicy::FILL_TO_PARENT);
+    application.GetScene().Add(sceneView);
+
+    Scene3D::Light light = Scene3D::Light::New();
+    light.SetProperty(Dali::Actor::Property::COLOR, Color::BLUE);
+    Dali::DevelActor::LookAt(light, Vector3(1.0f, 0.0f, 0.0f));
+    light.EnableShadow(true);
+    sceneView.Add(light);
+
+    application.SendNotification();
+    application.Render();
+
+    Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+    sceneView.Add(model);
+
+    application.SendNotification();
+    application.Render();
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+    application.SendNotification();
+    application.Render();
+
+    // Light is added on layer when on scene
+    DALI_TEST_EQUALS(true, model.GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE), TEST_LOCATION);
+
+    Renderer renderer = model.FindChildByName("node2").GetRendererAt(0u);
+    DALI_TEST_CHECK(renderer);
+    Shader shader = renderer.GetShader();
+    DALI_TEST_CHECK(shader);
+
+    auto shadowEnabledIndex = shader.GetPropertyIndex("uIsShadowEnabled");
+    DALI_TEST_CHECK(shadowEnabledIndex != DALI_KEY_INVALID);
+    DALI_TEST_EQUALS(1, shader.GetProperty<int32_t>(shadowEnabledIndex), TEST_LOCATION);
+
+    // Change material information, for line coverage.
+    auto modelNode = model.FindChildModelNodeByName("node2");
+    DALI_TEST_CHECK(modelNode);
+    DALI_TEST_GREATER(modelNode.GetModelPrimitiveCount(), 0u, TEST_LOCATION);
+    auto modelPrimitive = modelNode.GetModelPrimitive(0u);
+    DALI_TEST_CHECK(modelPrimitive);
+    auto material = modelPrimitive.GetMaterial();
+    DALI_TEST_CHECK(material);
+
+    auto originBaseColorFactor = material.GetProperty<Dali::Vector4>(Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR);
+    auto expectBaseColorFactor = Vector4(originBaseColorFactor.r + 0.05f, originBaseColorFactor.g - 0.05f, originBaseColorFactor.b, originBaseColorFactor.a);
+    material.SetProperty(Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR, expectBaseColorFactor);
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS(material.GetProperty<Dali::Vector4>(Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR), expectBaseColorFactor, TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false);
+  }
+
+  // Revert shader version. We should revert it even if UTC failed.
+  application.GetGlAbstraction().mShaderLanguageVersion = originalShaderVersion;
+
+  END_TEST;
+}
+
 // Disable Shadow
 int UtcDaliLightDisableShadow01(void)
 {
@@ -905,7 +1052,7 @@ int UtcDaliLightEnableShadowOfNotEnabledLight(void)
   Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
   sceneView.Add(model);
 
-  uint32_t maxLightCount = Scene3D::Light::GetMaximumEnabledLightCount();
+  uint32_t                    maxLightCount = Scene3D::Light::GetMaximumEnabledLightCount();
   std::vector<Scene3D::Light> lights;
   for(uint32_t i = 0; i < maxLightCount; ++i)
   {
index e8a372c..3ba8059 100644 (file)
@@ -1430,6 +1430,72 @@ int UtcDaliModelResourceReady(void)
   END_TEST;
 }
 
+int UtcDaliModelResourceReady02(void)
+{
+  tet_infoline("Test model load successfully even if shader language version is low\n");
+  ToolkitTestApplication application;
+
+  auto originalShaderVersion = application.GetGlAbstraction().GetShaderLanguageVersion();
+
+  // Change the shader language version forcely!
+  application.GetGlAbstraction().mShaderLanguageVersion = 200;
+
+  try
+  {
+    gOnRelayoutCallBackCalled = false;
+    gResourceReadyCalled      = false;
+    Scene3D::Model model      = Scene3D::Model::New(TEST_GLTF_MORPH_FILE_NAME);
+    model.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+    model.OnRelayoutSignal().Connect(OnRelayoutCallback);
+    model.ResourceReadySignal().Connect(OnResourceReady);
+    DALI_TEST_EQUALS(model.IsResourceReady(), false, TEST_LOCATION);
+
+    // Sanity check
+    DALI_TEST_CHECK(!gOnRelayoutCallBackCalled);
+    DALI_TEST_CHECK(!gResourceReadyCalled);
+
+    application.GetScene().Add(model);
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS(gOnRelayoutCallBackCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(model.IsResourceReady(), true, TEST_LOCATION);
+    DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
+
+    // Change material information, for line coverage.
+    auto modelNode = model.FindChildModelNodeByName("AnimatedMorphCube");
+    DALI_TEST_CHECK(modelNode);
+    DALI_TEST_GREATER(modelNode.GetModelPrimitiveCount(), 0u, TEST_LOCATION);
+    auto modelPrimitive = modelNode.GetModelPrimitive(0u);
+    DALI_TEST_CHECK(modelPrimitive);
+    auto material = modelPrimitive.GetMaterial();
+    DALI_TEST_CHECK(material);
+
+    auto originBaseColorFactor = material.GetProperty<Dali::Vector4>(Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR);
+    auto expectBaseColorFactor = Vector4(originBaseColorFactor.r + 0.05f, originBaseColorFactor.g - 0.05f, originBaseColorFactor.b, originBaseColorFactor.a);
+    material.SetProperty(Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR, expectBaseColorFactor);
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS(material.GetProperty<Dali::Vector4>(Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR), expectBaseColorFactor, TEST_LOCATION);
+  }
+  catch(...)
+  {
+    DALI_TEST_CHECK(false);
+  }
+
+  // Revert shader version. We should revert it even if UTC failed.
+  application.GetGlAbstraction().mShaderLanguageVersion = originalShaderVersion;
+
+  END_TEST;
+}
+
 int UtcDaliModelResourceCacheCheck(void)
 {
   ToolkitTestApplication application;
index 2dcebb1..78af54c 100644 (file)
@@ -1,4 +1,3 @@
-#version 300 es
 
 // Original Code
 // https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/glTF-WebGL-PBR/shaders/pbr-frag.glsl
@@ -97,7 +96,11 @@ uniform mediump vec3 uLightColor[MAX_LIGHTS];
 // For Shadow Map
 uniform lowp int uIsShadowEnabled;
 uniform sampler2D sShadowMap;
-in highp vec3 positionFromLightView;
+#ifdef GLSL_VERSION_1_0
+uniform int uShadowMapWidth;
+uniform int uShadowMapHeight;
+#endif
+INPUT highp vec3 positionFromLightView;
 
 //// For IBL
 uniform sampler2D sbrdfLUT;
@@ -113,12 +116,10 @@ uniform lowp float uMask;
 uniform lowp float uAlphaThreshold;
 
 // TODO: Multiple texture coordinate will be supported.
-in mediump vec2 vUV;
-in lowp mat3 vTBN;
-in lowp vec4 vColor;
-in highp vec3 vPositionToCamera;
-
-out vec4 FragColor;
+INPUT mediump vec2 vUV;
+INPUT lowp mat3 vTBN;
+INPUT lowp vec4 vColor;
+INPUT highp vec3 vPositionToCamera;
 
 const float c_MinRoughness = 0.04;
 const float M_PI = 3.141592653589793;
@@ -128,9 +129,9 @@ const float M_PI = 3.141592653589793;
 // Percentage Closer Filtering to mitigate the banding artifacts.
 const int kPcfSampleCount = 9;
 
-const float kPi = 3.141592653589f;
+const float kPi = 3.141592653589;
 const float kInvSampleCount = 1.0 / float(kPcfSampleCount);
-const float kPcfTheta = 2.f * kPi * kInvSampleCount;
+const float kPcfTheta = 2.0 * kPi * kInvSampleCount;
 const float kSinPcfTheta = sin(kPcfTheta);
 const float kCosPcfTheta = cos(kPcfTheta);
 
@@ -164,7 +165,7 @@ void main()
   // The albedo may be defined from a base texture or a flat color
 #ifdef BASECOLOR_TEX
   mediump vec2 baseColorTexCoords = mix(vUV, computeTextureTransform(vUV, uBaseColorTextureTransform), uBaseColorTextureTransformAvailable);
-  lowp vec4 baseColor = texture(sAlbedoAlpha, baseColorTexCoords);
+  lowp vec4 baseColor = TEXTURE(sAlbedoAlpha, baseColorTexCoords);
   baseColor = vColor * vec4(linear(baseColor.rgb), baseColor.w) * uColorFactor;
 #else // BASECOLOR_TEX
   lowp vec4 baseColor = vColor * uColorFactor;
@@ -172,25 +173,25 @@ void main()
 
 #ifdef METALLIC_ROUGHNESS_TEX
   mediump vec2 metalRoughnessTexCoords = mix(vUV, computeTextureTransform(vUV, uMetalRoughnessTextureTransform), uMetalRoughnessTextureTransformAvailable);
-  lowp vec4 metrou = texture(sMetalRoughness, metalRoughnessTexCoords);
+  lowp vec4 metrou = TEXTURE(sMetalRoughness, metalRoughnessTexCoords);
   metallic = metrou.METALLIC * metallic;
   perceptualRoughness = metrou.ROUGHNESS * perceptualRoughness;
 #endif // METALLIC_ROUGHNESS_TEX
 
 #ifdef NORMAL_TEX
   mediump vec2 normalTexCoords = mix(vUV, computeTextureTransform(vUV, uNormalTextureTransform), uNormalTextureTransformAvailable);
-  n = texture(sNormal, normalTexCoords).rgb;
+  n = TEXTURE(sNormal, normalTexCoords).rgb;
   n = normalize(vTBN * ((2.0 * n - 1.0) * vec3(uNormalScale, uNormalScale, 1.0)));
 #endif // NORMAL_TEX
 #else // THREE_TEX
   mediump vec2 baseColorTexCoords = mix(vUV, computeTextureTransform(vUV, uBaseColorTextureTransform), uBaseColorTextureTransformAvailable);
-  vec4 albedoMetal = texture(sAlbedoMetal, baseColorTexCoords);
+  vec4 albedoMetal = TEXTURE(sAlbedoMetal, baseColorTexCoords);
   lowp vec4 baseColor = vec4(linear(albedoMetal.rgb), 1.0) * vColor * uColorFactor;
 
   metallic = albedoMetal.METALLIC * metallic;
 
   mediump vec2 normalRoughnessTexCoords = mix(vUV, computeTextureTransform(vUV, uNormalRoughnessTextureTransform), uNormalRoughnessTextureTransformAvailable);
-  vec4 normalRoughness = texture(sNormalRoughness, normalRoughnessTexCoords);
+  vec4 normalRoughness = TEXTURE(sNormalRoughness, normalRoughnessTexCoords);
   perceptualRoughness = normalRoughness.ROUGHNESS * perceptualRoughness;
 
   n = normalRoughness.rgb;
@@ -220,10 +221,10 @@ void main()
   float specularWeight = 1.0;
   vec4 materialSpecularTexture = vec4(1.0);
 #ifdef MATERIAL_SPECULAR_TEXTURE
-  materialSpecularTexture.a = texture(sSpecular, vUV).a;
+  materialSpecularTexture.a = TEXTURE(sSpecular, vUV).a;
 #endif
 #ifdef MATERIAL_SPECULAR_COLOR_TEXTURE
-  materialSpecularTexture.rgb = texture(sSpecularColor, vUV).rgb;
+  materialSpecularTexture.rgb = TEXTURE(sSpecularColor, vUV).rgb;
 #endif
   specularWeight = uSpecularFactor * materialSpecularTexture.a;
   f0 = min(f0 * uSpecularColorFactor * materialSpecularTexture.rgb, vec3(1.0));
@@ -232,7 +233,7 @@ void main()
   mediump vec3 v = normalize(vPositionToCamera); // Vector from surface point to camera
   mediump float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
   mediump vec3 reflection = -normalize(reflect(v, n));
-  lowp vec3 brdf = texture(sbrdfLUT, vec2(NdotV, 1.0 - perceptualRoughness)).rgb;
+  lowp vec3 brdf = TEXTURE(sbrdfLUT, vec2(NdotV, 1.0 - perceptualRoughness)).rgb;
   vec3 Fr = max(vec3(1.0 - perceptualRoughness), f0) - f0;
   vec3 k_S = f0 + Fr * pow(1.0 - NdotV, 5.0);
   vec3 FssEss = specularWeight * (k_S * brdf.x + brdf.y);
@@ -240,12 +241,21 @@ void main()
   // Specular Light
   // uMaxLOD that means mipmap level of specular texture is used for bluring of reflection of specular following roughness.
   float lod = perceptualRoughness * (uMaxLOD - 1.0);
+#ifdef GLSL_VERSION_1_0
+  // glsl 1.0 doesn't support textureLod. Let we just use textureCube instead.
+  lowp vec3 specularLight = linear(textureCube(sSpecularEnvSampler, reflection * uYDirection).rgb);
+#else
   lowp vec3 specularLight = linear(textureLod(sSpecularEnvSampler, reflection * uYDirection, lod).rgb);
+#endif
   lowp vec3 specular = specularLight * FssEss;
 
   // Diffuse Light
   lowp vec3 diffuseColor = mix(baseColor.rgb, vec3(0), metallic);
-  lowp vec3 irradiance = linear(texture(sDiffuseEnvSampler, n * uYDirection).rgb);
+#ifdef GLSL_VERSION_1_0
+  lowp vec3 irradiance = linear(textureCube(sDiffuseEnvSampler, n * uYDirection).rgb);
+#else
+  lowp vec3 irradiance = linear(TEXTURE(sDiffuseEnvSampler, n * uYDirection).rgb);
+#endif
   float Ems = (1.0 - (brdf.x + brdf.y));
   vec3 F_avg = specularWeight * (f0 + (1.0 - f0) / 21.0);
   vec3 FmsEms = Ems * FssEss * F_avg / (1.0 - F_avg * Ems);
@@ -295,21 +305,25 @@ void main()
     mediump float exposureFactor = 0.0;
     if(uEnableShadowSoftFiltering > 0)
     {
+#ifdef GLSL_VERSION_1_0
+      ivec2 texSize = ivec2(uShadowMapWidth, uShadowMapHeight);
+#else
       ivec2 texSize = textureSize(sShadowMap, 0);
+#endif
       mediump vec2 texelSize = vec2(1.0) / vec2(texSize.x, texSize.y);
-      mediump vec2 pcfSample = vec2(1.f, 0.f);
+      mediump vec2 pcfSample = vec2(1.0, 0.0);
       for (int i = 0; i < kPcfSampleCount; ++i)
       {
         pcfSample = vec2(kCosPcfTheta * pcfSample.x - kSinPcfTheta * pcfSample.y,
                          kSinPcfTheta * pcfSample.x + kCosPcfTheta * pcfSample.y);
-        lowp float depthValue = texture(sShadowMap, positionFromLightView.xy + pcfSample * texelSize).r;
+        lowp float depthValue = TEXTURE(sShadowMap, positionFromLightView.xy + pcfSample * texelSize).r;
         exposureFactor += (depthValue < positionFromLightView.z - uShadowBias) ? 0.0 : 1.0;
       }
       exposureFactor *= kInvSampleCount;
     }
     else
     {
-      mediump float depthValue = texture(sShadowMap, positionFromLightView.xy).r;
+      mediump float depthValue = TEXTURE(sShadowMap, positionFromLightView.xy).r;
       exposureFactor           = (depthValue < positionFromLightView.z - uShadowBias) ? 0.0 : 1.0;
     }
     color *= (1.0 - (1.0 - exposureFactor) * uShadowIntensity);
@@ -317,17 +331,17 @@ void main()
 
 #ifdef OCCLUSION
   mediump vec2 occlusionTexCoords = mix(vUV, computeTextureTransform(vUV, uOcclusionTextureTransform), uOcclusionTextureTransformAvailable);
-  lowp float ao = texture(sOcclusion, occlusionTexCoords).r;
+  lowp float ao = TEXTURE(sOcclusion, occlusionTexCoords).r;
   color = mix(color, color * ao, uOcclusionStrength);
 #endif // OCCLUSION
 
 #ifdef EMISSIVE_TEXTURE
   mediump vec2 emissiveTexCoords = mix(vUV, computeTextureTransform(vUV, uEmissiveTextureTransform), uEmissiveTextureTransformAvailable);
-  lowp vec3 emissive = linear(texture(sEmissive, emissiveTexCoords).rgb) * uEmissiveFactor;
+  lowp vec3 emissive = linear(TEXTURE(sEmissive, emissiveTexCoords).rgb) * uEmissiveFactor;
 #else
   lowp vec3 emissive = uEmissiveFactor;
 #endif // EMISSIVE_TEXTURE
   color += emissive;
 
-  FragColor = vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a) * uColor;
+  OUT_COLOR = vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a) * uColor;
 }
index f88caf5..25e615d 100644 (file)
@@ -1,4 +1,3 @@
-#version 300 es
 
 // Original Code
 // https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/glTF-WebGL-PBR/shaders/pbr-vert.glsl
   precision mediump float;
 #endif
 
-in vec3 aPosition;
-in vec2 aTexCoord;
-in vec3 aNormal;
+INPUT vec3 aPosition;
+INPUT vec2 aTexCoord;
+INPUT vec3 aNormal;
 
 #ifdef VEC4_TANGENT
-in vec4 aTangent;
+INPUT vec4 aTangent;
 #else
-in vec3 aTangent;
+INPUT vec3 aTangent;
 #endif
 
-in vec4 aVertexColor;
+INPUT vec4 aVertexColor;
+
+#ifdef GLSL_VERSION_1_0
+INPUT float aVertexID;
+#endif
 
 #ifdef SKINNING
-in vec4 aJoints0;
-in vec4 aWeights0;
+INPUT vec4 aJoints0;
+INPUT vec4 aWeights0;
 ADD_EXTRA_SKINNING_ATTRIBUTES
 #endif
 
 #ifdef MORPH
-  uniform highp sampler2D sBlendShapeGeometry;
+uniform highp sampler2D sBlendShapeGeometry;
+#ifdef GLSL_VERSION_1_0
+uniform int uBlendShapeGeometryWidth;
+uniform int uBlendShapeGeometryHeight;
+#endif
 #endif
 
-out mediump vec2 vUV;
-out lowp mat3 vTBN;
-out lowp vec4 vColor;
-out highp vec3 vPositionToCamera;
+OUTPUT mediump vec2 vUV;
+OUTPUT lowp mat3 vTBN;
+OUTPUT lowp vec4 vColor;
+OUTPUT highp vec3 vPositionToCamera;
 
 uniform highp mat4 uViewMatrix;
 uniform mat3 uNormalMatrix;
@@ -53,11 +60,16 @@ uniform mat4 uProjection;
 
 #ifdef SKINNING
 
+#ifdef GLSL_VERSION_1_0
+#define MAX_BONES 80
+uniform mat4 uBone[MAX_BONES];
+#else
 #define MAX_BONES 256
 layout(std140) uniform Bones
 {
   mat4 uBone[MAX_BONES];
 };
+#endif
 
 uniform mediump vec3 uYDirection;
 #endif
@@ -77,7 +89,7 @@ uniform highp int uBlendShapeComponentSize;                               ///< T
 // Shadow
 uniform lowp int uIsShadowEnabled;
 uniform highp mat4 uShadowLightViewProjectionMatrix;
-out highp vec3 positionFromLightView;
+OUTPUT highp vec3 positionFromLightView;
 
 void main()
 {
@@ -86,10 +98,21 @@ void main()
   highp vec3 tangent = aTangent.xyz;
 
 #ifdef MORPH
+#ifdef GLSL_VERSION_1_0
+  int width = uBlendShapeGeometryWidth;
+#else
   int width = textureSize( sBlendShapeGeometry, 0 ).x;
+#endif
 
   highp int blendShapeBufferOffset = 0;
 
+#ifdef GLSL_VERSION_1_0
+  highp float blendShapeWidth = float(uBlendShapeGeometryWidth);
+  highp float blendShapeHeight = float(uBlendShapeGeometryHeight);
+  highp float invertBlendShapeWidth = 1.0 / blendShapeWidth;
+  highp float invertBlendShapeHeight = 1.0 / blendShapeHeight;
+#endif
+
   for( int index = 0; index < uNumberOfBlendShapes; ++index )
   {
     highp vec3 diff = vec3(0.0);
@@ -100,9 +123,15 @@ void main()
 
 #ifdef MORPH_POSITION
     // Calculate the index to retrieve the geometry from the texture.
+#ifdef GLSL_VERSION_1_0
+    vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
+    y = vertexId / width;
+    x = vertexId - y * width;
+#else
     vertexId = gl_VertexID + blendShapeBufferOffset;
     x = vertexId % width;
     y = vertexId / width;
+#endif
 
     // Retrieves the blend shape geometry from the texture, unnormalizes it and multiply by the weight.
     if(0.0 != weight)
@@ -113,7 +142,13 @@ void main()
        highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
 #endif
 
+#ifdef GLSL_VERSION_1_0
+      highp float floatX = float(x) + 0.5;
+      highp float floatY = float(y) + 0.5;
+      diff = weight * unnormalizeFactor * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
+#else
       diff = weight * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#endif
     }
 
     position.xyz += diff;
@@ -123,14 +158,26 @@ void main()
 
 #ifdef MORPH_NORMAL
     // Calculate the index to retrieve the normal from the texture.
+#ifdef GLSL_VERSION_1_0
+    vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
+    y = vertexId / width;
+    x = vertexId - y * width;
+#else
     vertexId = gl_VertexID + blendShapeBufferOffset;
     x = vertexId % width;
     y = vertexId / width;
+#endif
 
     // Retrieves the blend shape normal from the texture, unnormalizes it and multiply by the weight.
     if(0.0 != weight)
     {
+#ifdef GLSL_VERSION_1_0
+      highp float floatX = float(x) + 0.5;
+      highp float floatY = float(y) + 0.5;
+      diff = weight * 2.0 * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
+#else
       diff = weight * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#endif
     }
 
     normal += diff.xyz;
@@ -140,14 +187,26 @@ void main()
 
 #ifdef MORPH_TANGENT
     // Calculate the index to retrieve the tangent from the texture.
+#ifdef GLSL_VERSION_1_0
+    vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
+    y = vertexId / width;
+    x = vertexId - y * width;
+#else
     vertexId = gl_VertexID + blendShapeBufferOffset;
     x = vertexId % width;
     y = vertexId / width;
+#endif
 
     // Retrieves the blend shape tangent from the texture, unnormalizes it and multiply by the weight.
     if(0.0 != weight)
     {
+#ifdef GLSL_VERSION_1_0
+      highp float floatX = float(x) + 0.5;
+      highp float floatY = float(y) + 0.5;
+      diff = weight * 2.0 * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
+#else
       diff = weight * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#endif
     }
 
     tangent += diff.xyz;
@@ -181,7 +240,15 @@ void main()
 
   highp vec4 positionV = uViewMatrix * positionW;
 
+#ifdef GLSL_VERSION_1_0
+  highp vec3 i0 = uViewMatrix[0].xyz;
+  highp vec3 i1 = uViewMatrix[1].xyz;
+  highp vec3 i2 = uViewMatrix[2].xyz;
+
+  vPositionToCamera = mat3(vec3(i0.x, i1.x, i2.x), vec3(i0.y, i1.y, i2.y), vec3(i0.z, i1.z, i2.z)) * -vec3(positionV.xyz / positionV.w);
+#else
   vPositionToCamera = transpose(mat3(uViewMatrix)) * -vec3(positionV.xyz / positionV.w);
+#endif
 
   normal = normalize(normal);
   tangent = normalize(tangent);
index 633e91c..5e6f766 100644 (file)
@@ -1,12 +1,10 @@
-#version 300 es
 
 precision mediump float;
 uniform lowp vec4 uColor;
-flat in float vColor;
-out vec4 FragColor;
+flat INPUT float vColor;
 
 void main()
 {
   vec3 rgb = vec3(fract(vColor), fract(vColor * 0.00390625), fract(vColor * 0.00390625 * 0.00390625));
-  FragColor = vec4(rgb, 1.) * uColor;
+  OUT_COLOR = vec4(rgb, 1.) * uColor;
 }
\ No newline at end of file
index 98b6086..5e9d965 100644 (file)
@@ -1,10 +1,9 @@
-#version 300 es
 
 precision mediump float;
 uniform mat4 uMvpMatrix;
-in vec3 aPosition;
-in float aColor;
-flat out float vColor;
+INPUT vec3 aPosition;
+INPUT float aColor;
+flat OUTPUT float vColor;
 
 void main()
 {
index 91dace8..685c602 100644 (file)
@@ -1,14 +1,13 @@
-#version 300 es
 
 uniform lowp vec4 uColorFactor; // Color from material
 uniform lowp float uMask;
 uniform lowp float uAlphaThreshold;
 
-in mediump vec2 vUV;
-in lowp vec4 vColor;
+INPUT mediump vec2 vUV;
+INPUT lowp vec4 vColor;
 
-//in highp float depth;
-//out highp vec4 FragColor;
+//INPUT highp float depth;
+//OUTPUT highp vec4 FragColor;
 
 #ifdef THREE_TEX
 #ifdef BASECOLOR_TEX
@@ -28,13 +27,13 @@ void main()
 #ifdef THREE_TEX
   // The albedo may be defined from a base texture or a flat color
 #ifdef BASECOLOR_TEX
-  lowp vec4 baseColor = texture(sAlbedoAlpha, vUV);
+  lowp vec4 baseColor = TEXTURE(sAlbedoAlpha, vUV);
   baseColor = vColor * vec4(linear(baseColor.rgb), baseColor.w) * uColorFactor;
 #else // BASECOLOR_TEX
   lowp vec4 baseColor = vColor * uColorFactor;
 #endif // BASECOLOR_TEX
 #else // THREE_TEX
-  lowp vec4 albedoMetal = texture(sAlbedoMetal, vUV);
+  lowp vec4 albedoMetal = TEXTURE(sAlbedoMetal, vUV);
   lowp vec4 baseColor = vec4(linear(albedoMetal.rgb), 1.0) * vColor * uColorFactor;
 #endif // THREE_TEX
 
index 945198b..f724b92 100644 (file)
@@ -1,38 +1,56 @@
-#version 300 es
 
 #define ADD_EXTRA_SKINNING_ATTRIBUTES
 #define ADD_EXTRA_WEIGHTS
 
 precision highp float;
 
-in vec3 aPosition;
-in vec2 aTexCoord;
-in vec4 aVertexColor;
+INPUT vec3 aPosition;
+INPUT vec2 aTexCoord;
+INPUT vec4 aVertexColor;
+
+#ifdef GLSL_VERSION_1_0
+INPUT float aVertexID;
+#endif
 
 #ifdef SKINNING
-in vec4 aJoints0;
-in vec4 aWeights0;
+INPUT vec4 aJoints0;
+INPUT vec4 aWeights0;
 ADD_EXTRA_SKINNING_ATTRIBUTES;
 #endif
 
-out mediump vec2 vUV;
-out lowp vec4 vColor;
+#ifdef MORPH
+uniform highp sampler2D sBlendShapeGeometry;
+#ifdef GLSL_VERSION_1_0
+uniform int uBlendShapeGeometryWidth;
+uniform int uBlendShapeGeometryHeight;
+#endif
+#endif
+
+OUTPUT mediump vec2 vUV;
+OUTPUT lowp vec4 vColor;
 
 uniform highp mat4 uViewMatrix;
 uniform highp mat4 uModelMatrix;
 uniform highp mat4 uProjection;
 
 #ifdef SKINNING
+
+#ifdef GLSL_VERSION_1_0
+#define MAX_BONES 80
+uniform mat4 uBone[MAX_BONES];
+#else
 #define MAX_BONES 256
 layout(std140) uniform Bones
 {
   mat4 uBone[MAX_BONES];
 };
+#endif
+
 uniform mediump vec3 uYDirection;
 #endif
 
 #ifdef MORPH
-#define MAX_BLEND_SHAPE_NUMBER 128
+#define MAX_BLEND_SHAPE_NUMBER 256
 uniform int 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
@@ -50,22 +68,41 @@ void main()
   highp vec4 position = vec4(aPosition, 1.0);
 
 #ifdef MORPH
+
+#ifdef GLSL_VERSION_1_0
+  int width = uBlendShapeGeometryWidth;
+#else
   int width = textureSize( sBlendShapeGeometry, 0 ).x;
+#endif
 
   highp int blendShapeBufferOffset = 0;
 
+#ifdef GLSL_VERSION_1_0
+  highp float blendShapeWidth = float(uBlendShapeGeometryWidth);
+  highp float blendShapeHeight = float(uBlendShapeGeometryHeight);
+  highp float invertBlendShapeWidth = 1.0 / blendShapeWidth;
+  highp float invertBlendShapeHeight = 1.0 / blendShapeHeight;
+#endif
+
   for( int index = 0; index < uNumberOfBlendShapes; ++index )
   {
     highp vec3 diff = vec3(0.0);
     highp int vertexId = 0;
     highp int x = 0;
     highp int y = 0;
+    highp float weight = clamp(uBlendShapeWeight[index], 0.0, 1.0);
 
 #ifdef MORPH_POSITION
     // Calculate the index to retrieve the geometry from the texture.
+#ifdef GLSL_VERSION_1_0
+    vertexId = int(floor(aVertexID + 0.5)) + blendShapeBufferOffset;
+    y = vertexId / width;
+    x = vertexId - y * width;
+#else
     vertexId = gl_VertexID + blendShapeBufferOffset;
     x = vertexId % width;
     y = vertexId / width;
+#endif
 
     // Retrieves the blend shape geometry from the texture, unnormalizes it and multiply by the weight.
     if( 0.0 != uBlendShapeWeight[index] )
@@ -76,7 +113,13 @@ void main()
        highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
 #endif
 
-      diff = uBlendShapeWeight[index] * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#ifdef GLSL_VERSION_1_0
+      highp float floatX = float(x) + 0.5;
+      highp float floatY = float(y) + 0.5;
+      diff = weight * unnormalizeFactor * ( texture2D( sBlendShapeGeometry, vec2(floatX * invertBlendShapeWidth, floatY * invertBlendShapeHeight) ).xyz - 0.5 );
+#else
+      diff = weight * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
+#endif
     }
 
     position.xyz += diff;
index fb5a904..ce348d5 100644 (file)
@@ -112,6 +112,8 @@ DALI_TYPE_REGISTRATION_END()
 
 static constexpr uint32_t INDEX_FOR_LIGHT_CONSTRAINT_TAG = 10;
 
+constexpr uint32_t MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE = 300;
+
 } // unnamed namespace
 
 ModelPrimitivePtr ModelPrimitive::New()
@@ -264,6 +266,14 @@ void ModelPrimitive::SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeD
 void ModelPrimitive::SetBlendShapeGeometry(Dali::Texture blendShapeGeometry)
 {
   mBlendShapeGeometry = blendShapeGeometry;
+  if(DALI_UNLIKELY(Dali::Shader::GetShaderLanguageVersion() < MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE))
+  {
+    if(mRenderer && mBlendShapeGeometry)
+    {
+      mRenderer.RegisterProperty("uBlendShapeGeometryWidth", static_cast<int>(mBlendShapeGeometry.GetWidth()));
+      mRenderer.RegisterProperty("uBlendShapeGeometryHeight", static_cast<int>(mBlendShapeGeometry.GetHeight()));
+    }
+  }
 }
 
 void ModelPrimitive::SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents, Scene3D::Loader::BlendShapes::Version version)
@@ -337,6 +347,10 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag
         shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_VERSION_2_0);
       }
     }
+    if(DALI_UNLIKELY(Dali::Shader::GetShaderLanguageVersion() < MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE))
+    {
+      shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::GLSL_VERSION_1_0);
+    }
 
     Shader newShader = mShaderManager->ProduceShader(shaderOption);
     if(mShader != newShader)
@@ -380,6 +394,10 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag
       TextureSet newTextureSet = TextureSet::New();
       newTextureSet.SetTexture(0u, mBlendShapeGeometry);
 
+      Sampler blendShapeSampler = Sampler::New();
+      blendShapeSampler.SetFilterMode(Dali::FilterMode::NEAREST, Dali::FilterMode::NEAREST);
+      newTextureSet.SetSampler(0u, blendShapeSampler);
+
       const unsigned int numberOfTextures = mTextureSet.GetTextureCount();
       for(unsigned int index = 0u; index < numberOfTextures; ++index)
       {
@@ -487,6 +505,11 @@ void ModelPrimitive::UpdateShadowMapTexture()
         if(index == textureCount - GetImplementation(mMaterial).GetShadowMapTextureOffset())
         {
           texture = (!!mShadowMapTexture) ? mShadowMapTexture : Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyTextureWhiteRGB();
+          if(DALI_UNLIKELY(Dali::Shader::GetShaderLanguageVersion() < MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE))
+          {
+            mRenderer.RegisterProperty("uShadowMapWidth", static_cast<int>(texture.GetWidth()));
+            mRenderer.RegisterProperty("uShadowMapHeight", static_cast<int>(texture.GetHeight()));
+          }
         }
 
         newTextures.SetTexture(index, texture);
@@ -545,6 +568,20 @@ void ModelPrimitive::UpdateRendererUniform()
     GetImplementation(mMaterial).SetRendererUniform(mRenderer);
     mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName().data(), mIblScaleFactor);
     mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightMaxLodUniformName().data(), static_cast<float>(mSpecularMipmapLevels));
+
+    if(DALI_UNLIKELY(Dali::Shader::GetShaderLanguageVersion() < MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE))
+    {
+      if(mShadowMapTexture)
+      {
+        mRenderer.RegisterProperty("uShadowMapWidth", static_cast<int>(mShadowMapTexture.GetWidth()));
+        mRenderer.RegisterProperty("uShadowMapHeight", static_cast<int>(mShadowMapTexture.GetHeight()));
+      }
+      if(mBlendShapeGeometry)
+      {
+        mRenderer.RegisterProperty("uBlendShapeGeometryWidth", static_cast<int>(mBlendShapeGeometry.GetWidth()));
+        mRenderer.RegisterProperty("uBlendShapeGeometryHeight", static_cast<int>(mBlendShapeGeometry.GetHeight()));
+      }
+    }
   }
 }
 
index f218876..6ae5d61 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_SCENE3D_MODEL_H
 
 /*
- * 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.
@@ -56,6 +56,8 @@ class Model;
  *
  * By default, The loaded model has its own position and size which are defined in vertex buffer regardless of the Control size.
  *
+ * @note We support to render model well only if glsl version is higher than 300.
+ *
  * @SINCE_2_1.41
  * @code
  *
index 3c6f064..ff3d1c2 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_SCENE3D_SCENE_VIEW_H
 
 /*
- * 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.
@@ -86,6 +86,8 @@ class SceneView;
  *
  * And since SceneView is a Control, it can be placed together with other 2D UI components in the DALi window.
  *
+ * @note We support to render model well only if glsl version is higher than 300.
+ *
  * @SINCE_2_1.38
  * @code
  *
index 10555aa..4fc60e4 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.
@@ -32,7 +32,6 @@ namespace Dali::Scene3D::Loader
 {
 namespace
 {
-
 enum class LoadDataType
 {
   UNSIGNED_BYTE = 0,
@@ -969,7 +968,7 @@ uint32_t LoadPositions(LoadAccessorInputs positionsInput, bool hasBlendShape)
 
 bool LoadNormals(LoadAccessorInputs normalsInput, bool isTriangles, uint32_t positionBufferSize)
 {
-  auto       hasNormals  = normalsInput.accessor.IsDefined();
+  auto hasNormals = normalsInput.accessor.IsDefined();
   if(hasNormals)
   {
     const auto bufferSize = normalsInput.accessor.mBlob.GetBufferSize();
@@ -1044,7 +1043,7 @@ void LoadTextureCoordinates(LoadAccessorListInputs textureCoordinatesInput)
   {
     auto&      texCoords  = textureCoordinatesInput.accessors[0];
     const auto bufferSize = texCoords.mBlob.GetBufferSize();
-    uint32_t uvCount;
+    uint32_t   uvCount;
 
     if(MaskMatch(textureCoordinatesInput.flags, MeshDefinition::Flags::S8_TEXCOORD) || MaskMatch(textureCoordinatesInput.flags, MeshDefinition::Flags::U8_TEXCOORD))
     {
@@ -1311,6 +1310,8 @@ void LoadBlendShapes(MeshDefinition::RawData& rawData, std::vector<MeshDefinitio
   }
 }
 
+constexpr uint32_t MINIMUM_SHADER_VERSION_SUPPORT_VERTEX_ID = 300;
+
 } // namespace
 
 MeshDefinition::SparseBlob::SparseBlob(const Blob& indices, const Blob& values, uint32_t count)
@@ -1521,7 +1522,6 @@ MeshDefinition::LoadRaw(const std::string& modelsPath, BufferDefinition::Vector&
   }
 
   LoadBlendShapes(raw, mBlendShapes, mBlendShapeHeader, mBlendShapeVersion, numberOfVertices, fileStream, buffers);
-
   return raw;
 }
 
@@ -1551,6 +1551,29 @@ MeshGeometry MeshDefinition::Load(RawData&& raw) const
       }
     }
 
+    if(DALI_UNLIKELY(Dali::Shader::GetShaderLanguageVersion() < MINIMUM_SHADER_VERSION_SUPPORT_VERTEX_ID && !raw.mAttribs.empty()))
+    {
+      auto numElements = raw.mAttribs[0].mNumElements;
+
+      // gl_VertexID not support. We should add buffer hard.
+      Property::Map attribMap;
+      attribMap["aVertexID"] = Property::FLOAT;
+
+      VertexBuffer attribBuffer = VertexBuffer::New(attribMap);
+
+      std::vector<uint8_t> buffer(numElements * sizeof(float));
+      auto                 ids = reinterpret_cast<float*>(buffer.data());
+
+      for(uint32_t i = 0; i < numElements; i++)
+      {
+        ids[i] = static_cast<float>(i);
+      }
+
+      attribBuffer.SetData(buffer.data(), numElements);
+
+      meshGeometry.geometry.AddVertexBuffer(attribBuffer);
+    }
+
     for(auto& a : raw.mAttribs)
     {
       a.AttachBuffer(meshGeometry.geometry);
index da696a4..8cd505e 100644 (file)
@@ -146,10 +146,10 @@ ShaderDefinition::LoadRaw(const std::string& shadersPath) const
   }
   else
   {
-    raw.mVertexShaderSource         = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_VERT.data();
-    raw.mFragmentShaderSource       = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data();
-    raw.mShadowVertexShaderSource   = SHADER_SHADOW_MAP_SHADER_VERT.data();
-    raw.mShadowFragmentShaderSource = SHADER_SHADOW_MAP_SHADER_FRAG.data();
+    raw.mVertexShaderSource         = Dali::Shader::GetVertexShaderPrefix() + SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_VERT.data();
+    raw.mFragmentShaderSource       = Dali::Shader::GetFragmentShaderPrefix() + SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data();
+    raw.mShadowVertexShaderSource   = Dali::Shader::GetVertexShaderPrefix() + SHADER_SHADOW_MAP_SHADER_VERT.data();
+    raw.mShadowFragmentShaderSource = Dali::Shader::GetFragmentShaderPrefix() + SHADER_SHADOW_MAP_SHADER_FRAG.data();
   }
 
   if(!fail)
@@ -159,12 +159,14 @@ ShaderDefinition::LoadRaw(const std::string& shadersPath) const
       ApplyDefine(raw.mVertexShaderSource, definevar);
       ApplyDefine(raw.mFragmentShaderSource, definevar);
       ApplyDefine(raw.mShadowVertexShaderSource, definevar);
+      ApplyDefine(raw.mShadowFragmentShaderSource, definevar);
     }
     for(const auto& macroDef : mMacros)
     {
       RedefineMacro(raw.mVertexShaderSource, macroDef.macro, macroDef.definition);
       RedefineMacro(raw.mFragmentShaderSource, macroDef.macro, macroDef.definition);
       RedefineMacro(raw.mShadowVertexShaderSource, macroDef.macro, macroDef.definition);
+      RedefineMacro(raw.mShadowFragmentShaderSource, macroDef.macro, macroDef.definition);
     }
   }
 
index 35ebd63..2969443 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.
@@ -45,6 +45,8 @@ namespace
 static constexpr uint32_t INDEX_FOR_LIGHT_CONSTRAINT_TAG  = 10;
 static constexpr uint32_t INDEX_FOR_SHADOW_CONSTRAINT_TAG = 100;
 
+constexpr uint32_t MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE = 300;
+
 ShaderOption MakeOption(const MaterialDefinition& materialDef, const MeshDefinition& meshDef)
 {
   ShaderOption option;
@@ -167,6 +169,10 @@ ShaderOption MakeOption(const MaterialDefinition& materialDef, const MeshDefinit
       }
     }
   }
+  if(DALI_UNLIKELY(Dali::Shader::GetShaderLanguageVersion() < MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE))
+  {
+    option.AddOption(ShaderOption::Type::GLSL_VERSION_1_0);
+  }
 
   return option;
 }
index f504a99..859b65c 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.
@@ -49,6 +49,7 @@ static constexpr std::string_view OPTION_KEYWORD[] =
     "MORPH_NORMAL",
     "MORPH_TANGENT",
     "MORPH_VERSION_2_0",
+    "GLSL_VERSION_1_0",
 };
 static constexpr uint32_t NUMBER_OF_OPTIONS = sizeof(OPTION_KEYWORD) / sizeof(OPTION_KEYWORD[0]);
 static const char*        ADD_EXTRA_SKINNING_ATTRIBUTES{"ADD_EXTRA_SKINNING_ATTRIBUTES"};
@@ -105,8 +106,8 @@ void ShaderOption::AddJointMacros(size_t numberOfJointSets)
     std::ostringstream weights;
     for(size_t i = 1; i < numberOfJointSets; ++i)
     {
-      attributes << "in vec4 aJoints" << i << ";\n";
-      attributes << "in vec4 aWeights" << i << ";\n";
+      attributes << "INPUT vec4 aJoints" << i << ";\n";
+      attributes << "INPUT vec4 aWeights" << i << ";\n";
 
       weights << "bone +=\n"
               << "uBone[int(aJoints" << i << ".x)] * aWeights" << i << ".x +\n"
@@ -153,7 +154,7 @@ uint64_t ShaderOption::GetOptionHash() const
       HashString(hash, macroDef.macro.c_str());
       HashString(hash, macroDef.definition.c_str());
     }
-    optionHash |= (hash << 32 & 0xFFFFFFFF00000000);
+    optionHash |= ((hash << 32) & 0xFFFFFFFF00000000);
   }
   return optionHash;
 }
@@ -163,7 +164,7 @@ void ShaderOption::GetDefines(std::vector<std::string>& defines) const
   defines.clear();
   for(uint32_t i = 0; i < NUMBER_OF_OPTIONS; ++i)
   {
-    if(mOptionHash & 1 << i)
+    if(mOptionHash & (1 << i))
     {
       defines.push_back(OPTION_KEYWORD[i].data());
     }
index 063d4c0..65431db 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_SHADER_OPTION_H_
 #define DALI_SCENE3D_LOADER_SHADER_OPTION_H_
 /*
- * 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.
@@ -51,7 +51,8 @@ public:
     MORPH_POSITION,             // 08000
     MORPH_NORMAL,               // 10000
     MORPH_TANGENT,              // 20000
-    MORPH_VERSION_2_0           // 40000
+    MORPH_VERSION_2_0,          // 40000
+    GLSL_VERSION_1_0,           // 80000
   };
 
   struct MacroDefinition