1 #ifndef __DALI_TOOLKIT_SHADER_EFFECT_DISTANCEFIELD_H__
2 #define __DALI_TOOLKIT_SHADER_EFFECT_DISTANCEFIELD_H__
5 * Copyright (c) 2017 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/object/property-map.h>
26 #include <dali-toolkit/public-api/visuals/visual-properties.h>
35 * Creates a new DistanceFieldEffect
37 * DistanceFieldEffect is a custom shader effect to achieve distance field on Image actors
39 * Animatable/Constrainable uniforms - These will need to be registered to the actor as a custom property to take into effect:
41 * "uDoGlow" - The glow state. If true, glow is enabled
42 * "uGlowBoundary" - The glow boundary factor
43 * "uGlowColor" - The glow color multiplier
45 * "uDoShadow" - The shadow state. If true, shadows is enabled. Cannot be used with glow/and or outline
46 * "uShadowColor" - The shadow color multiplier
47 * "uShadowOffset" - The shadow offset
49 * "uDoOutline" - The outline state. If true, outline is enabled
50 * "uOutlineColor" - The outline color multiplier
51 * "uOutlineParams"- Thickness of outline. The outline thickness is determined by two values.
52 * First value [0-1] Specifies the distance field value for the center of the outline.
53 * Second value [0-1] Specifies the softness/width/anti-aliasing of the outlines inner edge.
55 * @return The newly created Property::Map with the distance field effect
57 inline Dali::Property::Map CreateDistanceFieldEffect()
59 const char* fragmentShaderPrefix( "#extension GL_OES_standard_derivatives : enable\n" );
61 const char* fragmentShader( DALI_COMPOSE_SHADER(
62 varying mediump vec2 vTexCoord;\n
64 uniform mediump float uGlowBoundary;\n
65 uniform mediump vec2 uOutlineParams;\n
66 uniform lowp vec4 uOutlineColor;\n
67 uniform lowp vec4 uShadowColor;\n
68 uniform mediump vec2 uShadowOffset;\n
69 uniform lowp vec4 uGlowColor;\n
70 uniform lowp float uDoOutline;\n
71 uniform lowp float uDoShadow;\n
72 uniform lowp float uDoGlow;\n
74 uniform sampler2D sTexture;\n
75 uniform lowp vec4 uColor;\n
79 // sample distance field\n
80 mediump float smoothing = 0.5;\n
82 mediump float distance = texture2D(sTexture, vTexCoord).a;\n
83 mediump float smoothWidth = fwidth(distance);\n
84 mediump float alphaFactor = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, distance);\n
86 if (uDoShadow == 0.0)\n
88 mediump float alpha = uColor.a * alphaFactor;\n
89 lowp vec4 rgb = uColor;\n
91 if (uDoOutline > 0.0)\n
93 mediump float outlineWidth = uOutlineParams[1] + smoothWidth;\n
94 mediump float outlineBlend = smoothstep(uOutlineParams[0] - outlineWidth, uOutlineParams[0] + outlineWidth, distance);\n
95 alpha = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, distance);\n
96 rgb = mix(uOutlineColor, uColor, outlineBlend);\n
101 rgb = mix(uGlowColor, rgb, alphaFactor);\n
102 alpha = smoothstep(uGlowBoundary, smoothing, distance);\n
105 // set fragment color\n
106 color = vec4(rgb.rgb, alpha);\n
109 else // (uDoShadow > 0.0)\n
111 mediump float shadowDistance = texture2D(sTexture, vTexCoord - uShadowOffset).a;\n
112 mediump float inText = alphaFactor;\n
113 mediump float inShadow = smoothstep(smoothing - smoothWidth, smoothing + smoothWidth, shadowDistance);\n
115 // inside object, outside shadow\n
120 // inside object, outside shadow\n
121 else if ((inText != 0.0) && (inShadow == 0.0))\n
126 // outside object, completely inside shadow\n
127 else if ((inText == 0.0) && (inShadow == 1.0))\n
129 color = uShadowColor;\n
131 // inside object, completely inside shadow\n
132 else if ((inText != 0.0) && (inShadow == 1.0))\n
134 color = mix(uShadowColor, uColor, inText);\n
135 color.a = uShadowColor.a;\n
137 // inside object, inside shadow's border\n
138 else if ((inText != 0.0) && (inShadow != 0.0))\n
140 color = mix(uShadowColor, uColor, inText);\n
141 color.a *= max(inText, inShadow);\n
143 // inside shadow's border\n
144 else if (inShadow != 0.0)\n
146 color = uShadowColor;\n
147 color.a *= inShadow;\n
149 // outside shadow and object\n
157 gl_FragColor = color;\n
164 Property::Map customShader;
166 std::string fragmentShaderString;
167 fragmentShaderString.reserve( strlen( fragmentShaderPrefix ) + strlen( fragmentShader ) );
168 fragmentShaderString.append( fragmentShaderPrefix );
169 fragmentShaderString.append( fragmentShader );
171 customShader[ Visual::Shader::Property::FRAGMENT_SHADER ] = fragmentShaderString;
172 customShader[ Visual::Shader::Property::HINTS ] = Shader::Hint::OUTPUT_IS_TRANSPARENT;
174 map[ Toolkit::Visual::Property::SHADER ] = customShader;
179 } // namespace Toolkit
183 #endif // __DALI_TOOLKIT_SHADER_EFFECT_SPOT_H__