From: Chu Hoang Date: Wed, 14 Oct 2015 10:53:40 +0000 (+0100) Subject: Changed Distance Field effect effect to use new custom shaders. X-Git-Tag: dali_1.1.7~14^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=f69688761a0814fcf2d0675a0f388a156ae046af;hp=-c Changed Distance Field effect effect to use new custom shaders. Change-Id: Ia8cc4142b68a51880d142ba4dbf7b01f61e271c4 --- f69688761a0814fcf2d0675a0f388a156ae046af diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp index 33dfee4..28de790 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp @@ -198,12 +198,38 @@ int UtcDaliCreateDissolveLocalEffect(void) END_TEST; } -int UtcDaliCreateDistanceFieldEffect(void) +int UtcDaliCreateDissolveEffect(void) { ToolkitTestApplication application; - ShaderEffect effect = Toolkit::CreateDistanceFieldEffect(); - DALI_TEST_CHECK( effect ); + Property::Map effect = Toolkit::CreateDistanceFieldEffect(); + DALI_TEST_CHECK( !effect.Empty() ); + + Property::Value* customShaderValue = effect.Find( "shader" ); + DALI_TEST_CHECK( customShaderValue ); + + Property::Map customShader; + DALI_TEST_CHECK( customShaderValue->Get( customShader ) ); + + Property::Value* vertexShaderValue = customShader.Find( "vertex-shader" ); + DALI_TEST_CHECK( !vertexShaderValue ); + + Property::Value* fragmentShaderValue = customShader.Find( "fragment-shader" ); + DALI_TEST_CHECK( fragmentShaderValue ); + + std::string fragmentShader; + DALI_TEST_CHECK( fragmentShaderValue->Get( fragmentShader ) ); + DALI_TEST_CHECK( !fragmentShader.empty() ); + + Property::Value* gridXValue = customShader.Find( "subdivide-grid-x" ); + DALI_TEST_CHECK( !gridXValue ); + + Property::Value* hintsValue = customShader.Find( "hints" ); + DALI_TEST_CHECK( hintsValue ); + + std::string hints; + DALI_TEST_CHECK( hintsValue->Get( hints ) ); + DALI_TEST_CHECK( hints == "output-is-transparent" ); END_TEST; } diff --git a/dali-toolkit/devel-api/shader-effects/dissolve-effect.h b/dali-toolkit/devel-api/shader-effects/dissolve-effect.h index 95cccc8..e160532 100644 --- a/dali-toolkit/devel-api/shader-effects/dissolve-effect.h +++ b/dali-toolkit/devel-api/shader-effects/dissolve-effect.h @@ -150,7 +150,7 @@ inline void DissolveEffectSetCentralLine( Actor& actor, const Vector2& position, * "uPercentage" - This value is proportional to the distortion applied; a value of zero means no distortion. * * @param[in] useHighPrecision True if using high precision in fragment shader for fully random noise, false otherwise - * @return A handle to a newly allocated ShaderEffect + * @return The newly created Property::Map with the dissolve effect */ inline Property::Map CreateDissolveEffect( bool useHighPrecision = true ) diff --git a/dali-toolkit/devel-api/shader-effects/distance-field-effect.h b/dali-toolkit/devel-api/shader-effects/distance-field-effect.h index c3b2669..aaeb537f 100644 --- a/dali-toolkit/devel-api/shader-effects/distance-field-effect.h +++ b/dali-toolkit/devel-api/shader-effects/distance-field-effect.h @@ -19,6 +19,7 @@ */ // EXTERNAL INCLUDES +#include #include namespace Dali @@ -32,10 +33,8 @@ namespace Toolkit * * DistanceFieldEffect is a custom shader effect to achieve distance field on Image actors * - * Animatable/Constrainable uniforms: + * Animatable/Constrainable uniforms - These will need to be registered to the actor as a custom property to take into effect: * - * "uSmoothing" - Soft edge smoothing. Specify the distance field value for the center of the edge. - * "uDoGlow" - The glow state. If true, glow is enabled * "uGlowBoundary" - The glow boundary factor * "uGlowColor" - The glow color multiplier @@ -50,132 +49,127 @@ namespace Toolkit * First value [0-1] Specifies the distance field value for the center of the outline. * Second value [0-1] Specifies the softness/width/anti-aliasing of the outlines inner edge. * - * @return A handle to a newly allocated ShaderEffect + * @return The newly created Property::Map with the distance field effect */ -inline ShaderEffect CreateDistanceFieldEffect() +inline Dali::Property::Map CreateDistanceFieldEffect() { - std::string fragmentShaderPrefix( - "#extension GL_OES_standard_derivatives : enable\n" - "\n" - ); - - std::string fragmentShader( - "uniform mediump float uSmoothing;\n" - "uniform mediump float uGlowBoundary;\n" - "uniform mediump vec2 uOutlineParams;\n" - "uniform lowp vec4 uOutlineColor;\n" - "uniform lowp vec4 uShadowColor;\n" - "uniform mediump vec2 uShadowOffset;\n" - "uniform lowp vec4 uGlowColor;\n" - "uniform lowp float uDoOutline;\n" - "uniform lowp float uDoShadow;\n" - "uniform lowp float uDoGlow;\n" - "\n" - "void main()\n" - "{\n" - " // sample distance field\n" - " mediump float distance = texture2D(sTexture, vTexCoord).a;\n" - " mediump float smoothWidth = fwidth(distance);\n" - " mediump float alphaFactor = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);\n" - " lowp vec4 color;\n" - " if (uDoShadow == 0.0)\n" - " {\n" - " mediump float alpha = uColor.a * alphaFactor;\n" - " lowp vec4 rgb = uColor;\n" - "\n" - " if (uDoOutline > 0.0)\n" - " {\n" - " mediump float outlineWidth = uOutlineParams[1] + smoothWidth;\n" - " mediump float outlineBlend = smoothstep(uOutlineParams[0] - outlineWidth, uOutlineParams[0] + outlineWidth, distance);\n" - " alpha = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);\n" - " rgb = mix(uOutlineColor, uColor, outlineBlend);\n" - " }\n" - "\n" - " if (uDoGlow > 0.0)\n" - " {\n" - " rgb = mix(uGlowColor, rgb, alphaFactor);\n" - " alpha = smoothstep(uGlowBoundary, uSmoothing, distance);\n" - " }\n" - "\n" - " // set fragment color\n" - " color = vec4(rgb.rgb, alpha);\n" - " }\n" - "\n" - " else // (uDoShadow > 0.0)\n" - " {\n" - " mediump float shadowDistance = texture2D(sTexture, vTexCoord - uShadowOffset).a;\n" - " mediump float inText = alphaFactor;\n" - " mediump float inShadow = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, shadowDistance);\n" - "\n" - " // inside object, outside shadow\n" - " if (inText == 1.0)\n" - " {\n" - " color = uColor;\n" - " }\n" - " // inside object, outside shadow\n" - " else if ((inText != 0.0) && (inShadow == 0.0))\n" - " {\n" - " color = uColor;\n" - " color.a *= inText;\n" - " }\n" - " // outside object, completely inside shadow\n" - " else if ((inText == 0.0) && (inShadow == 1.0))\n" - " {\n" - " color = uShadowColor;\n" - " }\n" - " // inside object, completely inside shadow\n" - " else if ((inText != 0.0) && (inShadow == 1.0))\n" - " {\n" - " color = mix(uShadowColor, uColor, inText);\n" - " color.a = uShadowColor.a;\n" - " }\n" - " // inside object, inside shadow's border\n" - " else if ((inText != 0.0) && (inShadow != 0.0))\n" - " {\n" - " color = mix(uShadowColor, uColor, inText);\n" - " color.a *= max(inText, inShadow);\n" - " }\n" - " // inside shadow's border\n" - " else if (inShadow != 0.0)\n" - " {\n" - " color = uShadowColor;\n" - " color.a *= inShadow;\n" - " }\n" - " // outside shadow and object\n" - " else \n" - " {\n" - " color.a = 0.0;\n" - " }\n" - "\n" - " }\n" - "\n" - " gl_FragColor = color;\n" - "\n" - "}\n" + const char* fragmentShaderPrefix( "#extension GL_OES_standard_derivatives : enable\n" ); + + const char* fragmentShader( DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + \n + uniform mediump float uGlowBoundary;\n + uniform mediump vec2 uOutlineParams;\n + uniform lowp vec4 uOutlineColor;\n + uniform lowp vec4 uShadowColor;\n + uniform mediump vec2 uShadowOffset;\n + uniform lowp vec4 uGlowColor;\n + uniform lowp float uDoOutline;\n + uniform lowp float uDoShadow;\n + uniform lowp float uDoGlow;\n + \n + uniform sampler2D sTexture;\n + uniform lowp vec4 uColor;\n + \n + void main()\n + {\n + // sample distance field\n + mediump float smoothing = 0.5;\n + + mediump float distance = texture2D(sTexture, vTexCoord).a;\n + mediump float smoothWidth = fwidth(distance);\n + mediump float alphaFactor = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, distance);\n + lowp vec4 color;\n + if (uDoShadow == 0.0)\n + {\n + mediump float alpha = uColor.a * alphaFactor;\n + lowp vec4 rgb = uColor;\n + \n + if (uDoOutline > 0.0)\n + {\n + mediump float outlineWidth = uOutlineParams[1] + smoothWidth;\n + mediump float outlineBlend = smoothstep(uOutlineParams[0] - outlineWidth, uOutlineParams[0] + outlineWidth, distance);\n + alpha = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, distance);\n + rgb = mix(uOutlineColor, uColor, outlineBlend);\n + }\n + \n + if (uDoGlow > 0.0)\n + {\n + rgb = mix(uGlowColor, rgb, alphaFactor);\n + alpha = smoothstep(uGlowBoundary, smoothing, distance);\n + }\n + \n + // set fragment color\n + color = vec4(rgb.rgb, alpha);\n + }\n + \n + else // (uDoShadow > 0.0)\n + {\n + mediump float shadowDistance = texture2D(sTexture, vTexCoord - uShadowOffset).a;\n + mediump float inText = alphaFactor;\n + mediump float inShadow = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, shadowDistance);\n + \n + // inside object, outside shadow\n + if (inText == 1.0)\n + {\n + color = uColor;\n + }\n + // inside object, outside shadow\n + else if ((inText != 0.0) && (inShadow == 0.0))\n + {\n + color = uColor;\n + color.a *= inText;\n + }\n + // outside object, completely inside shadow\n + else if ((inText == 0.0) && (inShadow == 1.0))\n + {\n + color = uShadowColor;\n + }\n + // inside object, completely inside shadow\n + else if ((inText != 0.0) && (inShadow == 1.0))\n + {\n + color = mix(uShadowColor, uColor, inText);\n + color.a = uShadowColor.a;\n + }\n + // inside object, inside shadow's border\n + else if ((inText != 0.0) && (inShadow != 0.0))\n + {\n + color = mix(uShadowColor, uColor, inText);\n + color.a *= max(inText, inShadow);\n + }\n + // inside shadow's border\n + else if (inShadow != 0.0)\n + {\n + color = uShadowColor;\n + color.a *= inShadow;\n + }\n + // outside shadow and object\n + else \n + {\n + color.a = 0.0;\n + }\n + \n + }\n + \n + gl_FragColor = color;\n + \n + } ) ); - // Create the implementation, temporarily owned on stack - Dali::ShaderEffect shaderEffect = Dali::ShaderEffect::NewWithPrefix( - "", "", - fragmentShaderPrefix, fragmentShader, - ShaderEffect::GeometryHints( ShaderEffect::HINT_BLENDING)); + Property::Map map; - shaderEffect.SetUniform("uSmoothing",0.5f); - shaderEffect.SetUniform("uOutlineColor",Color::BLACK); - shaderEffect.SetUniform("uOutlineParams",Vector2(0.51f, 0.0f)); - shaderEffect.SetUniform("uGlowBoundary",0.4f); - shaderEffect.SetUniform("uGlowColor",Color::GREEN); - shaderEffect.SetUniform("uShadowColor",Vector4(0.0f, 0.0f, 0.0f, 0.4f)); + Property::Map customShader; - // TODO: find a way to set the shadow offset in texel coordinates instead of UVs. - shaderEffect.SetUniform("uShadowOffset",Vector2(0.05f, 0.05f)); + std::string fragmentShaderString; + fragmentShaderString.reserve( strlen( fragmentShaderPrefix ) + strlen( fragmentShader ) ); + fragmentShaderString.append( fragmentShaderPrefix ); + fragmentShaderString.append( fragmentShader ); - // Default: - shaderEffect.SetUniform("uDoOutline",false); - shaderEffect.SetUniform("uDoGlow",false); - shaderEffect.SetUniform("uDoShadow",false); + customShader[ "fragment-shader" ] = fragmentShaderString; + customShader[ "hints" ] = "output-is-transparent"; - return shaderEffect; + map[ "shader" ] = customShader; + return map; }