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>
/*
- * 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.
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)
{
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)
{
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;
-#version 300 es
// Original Code
// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/glTF-WebGL-PBR/shaders/pbr-frag.glsl
// 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;
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;
// 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);
#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
#ifdef METALLIC_ROUGHNESS_TEX
- lowp vec4 metrou = texture(sMetalRoughness, vUV);
+ lowp vec4 metrou = TEXTURE(sMetalRoughness, vUV);
metallic = metrou.METALLIC * metallic;
perceptualRoughness = metrou.ROUGHNESS * perceptualRoughness;
#endif // METALLIC_ROUGHNESS_TEX
#ifdef NORMAL_TEX
- n = texture(sNormal, vUV).rgb;
+ n = TEXTURE(sNormal, vUV).rgb;
n = normalize(vTBN * ((2.0 * n - 1.0) * vec3(uNormalScale, uNormalScale, 1.0)));
#endif // NORMAL_TEX
#else // THREE_TEX
- vec4 albedoMetal = texture(sAlbedoMetal, vUV);
+ vec4 albedoMetal = TEXTURE(sAlbedoMetal, vUV);
lowp vec4 baseColor = vec4(linear(albedoMetal.rgb), 1.0) * vColor * uColorFactor;
metallic = albedoMetal.METALLIC * metallic;
- vec4 normalRoughness = texture(sNormalRoughness, vUV);
+ vec4 normalRoughness = TEXTURE(sNormalRoughness, vUV);
perceptualRoughness = normalRoughness.ROUGHNESS * perceptualRoughness;
n = normalRoughness.rgb;
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));
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);
// 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);
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);
}
#ifdef OCCLUSION
- lowp float ao = texture(sOcclusion, vUV).r;
+ lowp float ao = TEXTURE(sOcclusion, vUV).r;
color = mix(color, color * ao, uOcclusionStrength);
#endif // OCCLUSION
#ifdef EMISSIVE_TEXTURE
- lowp vec3 emissive = linear(texture(sEmissive, vUV).rgb) * uEmissiveFactor;
+ lowp vec3 emissive = linear(TEXTURE(sEmissive, vUV).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;
}
-#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 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;
uniform mat4 uProjection;
#ifdef SKINNING
- in vec4 aJoints;
- in vec4 aWeights;
- #define MAX_BONES 64
- uniform mat4 uBone[MAX_BONES];
- uniform mediump vec3 uYDirection;
+INPUT vec4 aJoints;
+INPUT vec4 aWeights;
+#define MAX_BONES 80
+uniform mat4 uBone[MAX_BONES];
+uniform mediump vec3 uYDirection;
#endif
#ifdef MORPH
// Shadow
uniform lowp int uIsShadowEnabled;
uniform highp mat4 uShadowLightViewProjectionMatrix;
-out highp vec3 positionFromLightView;
+OUTPUT highp vec3 positionFromLightView;
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);
#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)
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;
#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;
#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;
#endif
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);
-#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
-#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()
{
-#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
#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
-#version 300 es
precision highp float;
-in vec3 aPosition;
-in vec2 aTexCoord;
-in vec4 aVertexColor;
+INPUT vec3 aPosition;
+INPUT vec2 aTexCoord;
+INPUT vec4 aVertexColor;
-out mediump vec2 vUV;
-out lowp vec4 vColor;
+#ifdef GLSL_VERSION_1_0
+INPUT float aVertexID;
+#endif
+
+OUTPUT mediump vec2 vUV;
+OUTPUT lowp vec4 vColor;
+
+#ifdef MORPH
+uniform highp sampler2D sBlendShapeGeometry;
+#ifdef GLSL_VERSION_1_0
+uniform int uBlendShapeGeometryWidth;
+uniform int uBlendShapeGeometryHeight;
+#endif
+#endif
uniform highp mat4 uViewMatrix;
uniform highp mat4 uModelMatrix;
uniform highp mat4 uProjection;
#ifdef SKINNING
- in vec4 aJoints;
- in vec4 aWeights;
- #define MAX_BONES 64
- uniform mat4 uBone[MAX_BONES];
- uniform mediump vec3 uYDirection;
+INPUT vec4 aJoints;
+INPUT vec4 aWeights;
+#define MAX_BONES 80
+uniform mat4 uBone[MAX_BONES];
+uniform mediump vec3 uYDirection;
#endif
#ifdef MORPH
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] )
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;
return texture;
}
+constexpr uint32_t MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE = 300;
+
} // unnamed namespace
ModelPrimitivePtr ModelPrimitive::New()
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)
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);
+ }
mShader.Reset();
mShader = mShaderManager->ProduceShader(shaderOption);
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)
{
if(index == textureCount - GetImplementation(mMaterial).GetShadowMapTextureOffset())
{
texture = (!!mShadowMapTexture) ? mShadowMapTexture : MakeEmptyTexture();
+ 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);
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()));
+ }
+ }
}
}
#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.
*
* 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
*
#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.
*
* 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
*
/*
- * 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.
{
namespace
{
+enum class LoadDataType
+{
+ UNSIGNED_BYTE = 0,
+ UNSIGNED_SHORT,
+ FLOAT
+};
+
+struct LoadAccessorInputs
+{
+ MeshDefinition::RawData& rawData;
+ MeshDefinition::Accessor& accessor;
+ uint32_t flags;
+ std::fstream& fileStream;
+ std::string& meshPath;
+ BufferDefinition::Vector& buffers;
+};
+
+struct LoadAccessorListInputs
+{
+ MeshDefinition::RawData& rawData;
+ std::vector<MeshDefinition::Accessor>& accessors;
+ uint32_t flags;
+ std::fstream& fileStream;
+ std::string& meshPath;
+ BufferDefinition::Vector& buffers;
+};
+
template<bool use32BitIndices>
class IndexProvider
{
return stream;
}
+constexpr uint32_t MINIMUM_SHADER_VERSION_SUPPORT_VERTEX_ID = 300;
+
} // namespace
MeshDefinition::SparseBlob::SparseBlob(const Blob& indices, const Blob& values, uint32_t count)
}
raw.mBlendShapeData = Devel::PixelBuffer::Convert(geometryPixelBuffer);
}
-
return raw;
}
}
}
+ 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);
/*
- * 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.
}
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)
ApplyDefine(raw.mVertexShaderSource, definevar);
ApplyDefine(raw.mFragmentShaderSource, definevar);
ApplyDefine(raw.mShadowVertexShaderSource, definevar);
+ ApplyDefine(raw.mShadowFragmentShaderSource, definevar);
}
}
/*
- * 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.
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;
}
}
}
+ if(DALI_UNLIKELY(Dali::Shader::GetShaderLanguageVersion() < MINIMUM_SHADER_VERSION_SUPPORT_TEXTURE_TEXEL_AND_SIZE))
+ {
+ option.AddOption(ShaderOption::Type::GLSL_VERSION_1_0);
+ }
return option;
}
/*
- * 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.
"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]);
} // namespace
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());
}
#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.
public:
enum class Type
{
- GLTF_CHANNELS = 0,
- THREE_TEXTURE,
- BASE_COLOR_TEXTURE,
- METALLIC_ROUGHNESS_TEXTURE,
- NORMAL_TEXTURE,
- OCCLUSION,
- EMISSIVE,
- ALPHA_TEST,
- SUBSURFACE,
- SPECULAR,
- SPECULAR_COLOR,
- SKINNING,
- FLIP_UVS_VERTICAL,
- COLOR_ATTRIBUTE,
- VEC4_TANGENT,
- MORPH_POSITION,
- MORPH_NORMAL,
- MORPH_TANGENT,
- MORPH_VERSION_2_0
+ GLTF_CHANNELS = 0, // 00001
+ THREE_TEXTURE, // 00002
+ BASE_COLOR_TEXTURE, // 00004
+ METALLIC_ROUGHNESS_TEXTURE, // 00008
+ NORMAL_TEXTURE, // 00010
+ OCCLUSION, // 00020
+ EMISSIVE, // 00040
+ ALPHA_TEST, // 00080
+ SUBSURFACE, // 00100
+ SPECULAR, // 00200
+ SPECULAR_COLOR, // 00400
+ SKINNING, // 00800
+ FLIP_UVS_VERTICAL, // 01000
+ COLOR_ATTRIBUTE, // 02000
+ VEC4_TANGENT, // 04000
+ MORPH_POSITION, // 08000
+ MORPH_NORMAL, // 10000
+ MORPH_TANGENT, // 20000
+ MORPH_VERSION_2_0, // 40000
+ GLSL_VERSION_1_0, // 80000
};
public: