1 #ifndef __DALI_TOOLKIT_SHADER_EFFECT_DISTANCEFIELD_H__
2 #define __DALI_TOOLKIT_SHADER_EFFECT_DISTANCEFIELD_H__
5 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
23 #include <dali/public-api/shader-effects/shader-effect.h>
32 * Creates a new DistanceFieldEffect
34 * DistanceFieldEffect is a custom shader effect to achieve distance field on Image actors
36 * Animatable/Constrainable uniforms - These will need to be registered to the actor as a custom property to take into effect:
38 * "uDoGlow" - The glow state. If true, glow is enabled
39 * "uGlowBoundary" - The glow boundary factor
40 * "uGlowColor" - The glow color multiplier
42 * "uDoShadow" - The shadow state. If true, shadows is enabled. Cannot be used with glow/and or outline
43 * "uShadowColor" - The shadow color multiplier
44 * "uShadowOffset" - The shadow offset
46 * "uDoOutline" - The outline state. If true, outline is enabled
47 * "uOutlineColor" - The outline color multiplier
48 * "uOutlineParams"- Thickness of outline. The outline thickness is determined by two values.
49 * First value [0-1] Specifies the distance field value for the center of the outline.
50 * Second value [0-1] Specifies the softness/width/anti-aliasing of the outlines inner edge.
52 * @return The newly created Property::Map with the distance field effect
54 inline Dali::Property::Map CreateDistanceFieldEffect()
56 const char* fragmentShaderPrefix( "#extension GL_OES_standard_derivatives : enable\n" );
58 const char* fragmentShader( DALI_COMPOSE_SHADER(
59 varying mediump vec2 vTexCoord;\n
61 uniform mediump float uGlowBoundary;\n
62 uniform mediump vec2 uOutlineParams;\n
63 uniform lowp vec4 uOutlineColor;\n
64 uniform lowp vec4 uShadowColor;\n
65 uniform mediump vec2 uShadowOffset;\n
66 uniform lowp vec4 uGlowColor;\n
67 uniform lowp float uDoOutline;\n
68 uniform lowp float uDoShadow;\n
69 uniform lowp float uDoGlow;\n
71 uniform sampler2D sTexture;\n
72 uniform lowp vec4 uColor;\n
76 // sample distance field\n
77 mediump float smoothing = 0.5;\n
79 mediump float distance = texture2D(sTexture, vTexCoord).a;\n
80 mediump float smoothWidth = fwidth(distance);\n
81 mediump float alphaFactor = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, distance);\n
83 if (uDoShadow == 0.0)\n
85 mediump float alpha = uColor.a * alphaFactor;\n
86 lowp vec4 rgb = uColor;\n
88 if (uDoOutline > 0.0)\n
90 mediump float outlineWidth = uOutlineParams[1] + smoothWidth;\n
91 mediump float outlineBlend = smoothstep(uOutlineParams[0] - outlineWidth, uOutlineParams[0] + outlineWidth, distance);\n
92 alpha = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, distance);\n
93 rgb = mix(uOutlineColor, uColor, outlineBlend);\n
98 rgb = mix(uGlowColor, rgb, alphaFactor);\n
99 alpha = smoothstep(uGlowBoundary, smoothing, distance);\n
102 // set fragment color\n
103 color = vec4(rgb.rgb, alpha);\n
106 else // (uDoShadow > 0.0)\n
108 mediump float shadowDistance = texture2D(sTexture, vTexCoord - uShadowOffset).a;\n
109 mediump float inText = alphaFactor;\n
110 mediump float inShadow = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, shadowDistance);\n
112 // inside object, outside shadow\n
117 // inside object, outside shadow\n
118 else if ((inText != 0.0) && (inShadow == 0.0))\n
123 // outside object, completely inside shadow\n
124 else if ((inText == 0.0) && (inShadow == 1.0))\n
126 color = uShadowColor;\n
128 // inside object, completely inside shadow\n
129 else if ((inText != 0.0) && (inShadow == 1.0))\n
131 color = mix(uShadowColor, uColor, inText);\n
132 color.a = uShadowColor.a;\n
134 // inside object, inside shadow's border\n
135 else if ((inText != 0.0) && (inShadow != 0.0))\n
137 color = mix(uShadowColor, uColor, inText);\n
138 color.a *= max(inText, inShadow);\n
140 // inside shadow's border\n
141 else if (inShadow != 0.0)\n
143 color = uShadowColor;\n
144 color.a *= inShadow;\n
146 // outside shadow and object\n
154 gl_FragColor = color;\n
161 Property::Map customShader;
163 std::string fragmentShaderString;
164 fragmentShaderString.reserve( strlen( fragmentShaderPrefix ) + strlen( fragmentShader ) );
165 fragmentShaderString.append( fragmentShaderPrefix );
166 fragmentShaderString.append( fragmentShader );
168 customShader[ "fragmentShader" ] = fragmentShaderString;
169 customShader[ "hints" ] = "outputIsTransparent";
171 map[ "shader" ] = customShader;
176 } // namespace Toolkit
180 #endif // __DALI_TOOLKIT_SHADER_EFFECT_SPOT_H__