Remove/Move experimental features
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / shader-effects / soft-button-effect.h
1 #ifndef __DALI_TOOLKIT_SHADER_EFFECT_SOFT_BUTTON_H__
2 #define __DALI_TOOLKIT_SHADER_EFFECT_SOFT_BUTTON_H__
3
4 /*
5  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/shader-effects/shader-effect.h>
23
24 namespace Dali
25 {
26
27 namespace Toolkit
28 {
29
30 /**
31  * @brief Creates a new soft button shader effect
32  *
33  * Soft button shader effect works on a per object basis. Using animatable parameters user can create
34  * effect of button pushing in / out. Can be applied to ImageActor only.
35  *
36  * Usage example:-
37  *
38  * // Create shader used for doing soft button\n
39  * ShaderEffect softButtonEffect = CreateSoftButtonEffect();
40  *
41  * // set image actor shader to the soft button one\n
42  * ImageActor imageActor = ImageActor::New( ... );\n
43  * imageActor.SetShaderEffect( softButtonEffect );
44  *
45  * // animate a button push, using e.g. AlphaFunction::BOUNCE. With these values the button pushes in and pops out slightly at the end\n
46  * Animation animation = Animation::New( ... );\n
47  * animation.AnimateTo( Property(softButtonEffect, "uLightingIndentationAmount), 0.25f, AlphaFunction::BOUNCE, ... );\n
48  * animation.AnimateTo( Property(softButtonEffect, "uLightingIndentationAmount"), -0.05f, AlphaFunction::BOUNCE, ... );\n
49  * animation.AnimateTo( Property(softButtonEffect, "uTextureDistortAmount"), 0.25f, AlphaFunction::BOUNCE, ... );\n
50  * animation.AnimateTo( Property(softButtonEffect, "uTextureDistortAmount"), -0.05f, AlphaFunction::BOUNCE, ... );\n
51  * animation.Play();\n
52  *
53  * Animatable/Constrainable uniforms:
54  *
55  *  "uLightingIndentationAmount"  - This property changes the lighting, to make it look like the button is pushed in. User should animate
56  *                                  this in conjunction with texture distortion. Allowable values range from [-1..1], higher values give
57  *                                  more change in lighting. Default 0.0 (no lighting change).
58  *  "uTextureDistortAmount"       - This property changes the distortion, to make it look like the button is pushed in. User should animate
59  *                                  this in conjunction with lighting indentation. Allowable values range from [-1..1) - note 1.0 is NOT
60  *                                  allowed - higher values give more distortion. Default 0.0 (no distortion).
61  *  "uAmbientLight"               - The ambient light is used in the lighting calculation. Care must be taken to not saturate the image by
62  *                                  setting this value too high, or the indentation will not look correct. Default 0.15
63  *  "uDiffuseLight"               - The diffuse light is used in the lighting calculation. Default is (0.0, 0.7070168, 0.7070168),
64  *                                  i.e. a light angled at the surface from in front and above. Note that you need to Normalize()
65  *                                  the Vector3 that you set with this property
66  *  "uLightMultiplier"            - The ambient and diffuse lighting is multiplied by this factor. Since a diffuse light at an angle will
67  *                                  cause the whole image to darken, even outside the soft button indentation, this property can be used
68  *                                  to scale the image back up closer to the pixel values of the original diffuse texture. Care must be
69  *                                  taken to not saturate the image,or the indentation will not look correct. Default 1.2.
70  *  "uInsideCircleSizeScale"      - The SoftButtonEffect consists of two shapes, one inside the other. The outside shape fits exactly to
71  *                                  the actor, touching its edges but completely contained. The inside shape size is given by a multiplier
72  *                                  of the outside shape size. For example a value of 0.5 means that the inside shape is half the size of
73  *                                  the outside one. Allowable values are in the range (0.0 - 1.0), note that 0.0 and 1.0 themselves are
74  *                                  not allowed. Default 0.75.
75  *  "uOutsideCircleDepth"         - The SoftButtonEffect consists of two shapes, one inside the other. The depth of the indentation at the
76  *                                  transition between the inside and outside shapes is controlled by this property. The values lies in the
77  *                                  range [0.0 - 1.0]. A value of 0.0 means the outside shape has no depth (and is thus invisible), value of
78  *                                  1.0 means the outside shape has maximum depth (and the inside shape is thus invisible). Default 0.05
79  *  "uEffectRegion"               - The soft button effect is applied within the supplied rect region of the texture. Default values for this
80  *                                  is (0.0, 0.0, 1.0, 1.0) which is the entire image with 0,0 being the top left and 1.0, 1.0 being the bottom
81  *                                  right. If the image texture is split between multiple ImageActors then the developer should specify the pixel
82  *                                  area of the texture the effect should be applied with. Example, If the Image is split among two ImageActors
83  *                                  side by side, with the left one using left half of the texture and right one using the right half of the
84  *                                  texture then the pixel area value for the left ImageActor will be (0.0, 0.0, 0.5, 1.0) and the pixel area for
85  *                                  the right will be (0.5,0.0,1.0,1.0).
86  * "uRectangleSizeScale"          - This property can be used to set the mix between proportion of rectangle and proportion of ellipse - the
87  *                                  result is a rectangle with rounded corners. If the value is 0.0, the shape is an ellipse. If the value is
88  *                                  close to 1.0, the shape is close to a rectangle. The value lies in the range [0.0 - 1.0). Note that a value
89  *                                  of 1.0 is NOT allowed.Default 0.5.
90  *
91  * @param type The type of the soft button, can be either ELLIPTICAL, RECTANGULAR, or FIXED.
92  * @return A handle to a newly allocated ShaderEffect
93  */
94 typedef enum
95 {
96   SOFT_BUTTON_ELLIPTICAL = 0,   /// Button is elliptical
97   SOFT_BUTTON_RECTANGULAR,      /// Button is rectangular
98   SOFT_BUTTON_FIXED             /// Button does not indent (move). Useful for matching lighting between areas that do not indent (which can thus use a cheaper shader) and those that do indent.
99 }SoftButtonEffectType;
100
101 static void InverseConstraint( float& current, const PropertyInputContainer& inputs )
102 {
103   current = 1.0f / inputs[0]->GetFloat();
104 }
105
106 inline ShaderEffect CreateSoftButtonEffect(SoftButtonEffectType type)
107 {
108   std::string vertexSource;
109   vertexSource =  "precision mediump float;\n"
110       "uniform vec3 uDiffuseLight;\n"
111       "uniform float uAmbientLight;\n"
112       "uniform float uLightMultiplier;\n"
113       "uniform vec4 uEffectRegion;\n"
114       "varying vec2 vCentredCoord;\n"
115
116       "const vec3 norm = vec3(0.0, 0.0, 1.0);\n"
117
118       "void main()\n"
119       "{\n"
120       "  vTexCoord = mix( sTextureRect.xy, sTextureRect.zw, aTexCoord );\n"
121       // Get the rect coords of the effect region in -1..1 range, i.e. circle centred around the center of the rect
122       // Done in the vertex shader itself to make use of gl interpolation for varying.
123       "  vCentredCoord = vec2( ( (vTexCoord.x - uEffectRegion.x)/(uEffectRegion.z - uEffectRegion.x) * 2.0 - 1.0 ), ( (vTexCoord.y - uEffectRegion.y)/(uEffectRegion.w - uEffectRegion.y) * 2.0 - 1.0  ) );\n"
124       "  gl_Position = uMvpMatrix * vec4(aPosition, 1.0);\n"
125       "}\n";
126
127   std::string fragmentSourceFixed;
128   fragmentSourceFixed =  "precision mediump float;\n"
129
130       "uniform vec3 uDiffuseLight;\n"
131       "uniform float uAmbientLight;\n"
132       "uniform float uLightMultiplier;\n"
133       "varying vec2 vCentredCoord;\n"
134
135       "const vec3 norm = vec3(0.0, 0.0, 1.0);\n"
136
137       "void main()\n"
138       "{\n"
139       "   vec4 col = texture2D(sTexture, vTexCoord);\n"
140       // calc lighting
141       "   float lighting = (dot(uDiffuseLight, norm) + uAmbientLight) * uLightMultiplier;\n"
142       // output col = image * light
143       // use the lighting value for colors only
144       "   gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
145       "}\n";
146
147   std::string fragmentSourceElliptical;
148   fragmentSourceElliptical =  "precision mediump float;\n"
149
150       "uniform float uLightingIndentationAmount;\n"
151       "uniform float uTextureDistortAmount;\n"
152       "uniform vec3 uDiffuseLight;\n"
153       "uniform float uAmbientLight;\n"
154       "uniform float uLightMultiplier;\n"
155       "uniform float uInsideCircleSizeScale;\n"
156       "uniform float uRecipInsideCircleSizeScale;\n"
157       "uniform float uOutsideCircleDepth;\n"
158       "uniform vec4 uEffectRegion;\n"
159       "varying vec2 vCentredCoord;\n"
160
161       "const float PI = 3.1415927;\n"
162
163       "void main()\n"
164       "{\n"
165       // Apply distortion only if the pixel is within the rect specified
166       "if( (vTexCoord.x > uEffectRegion.x) && (vTexCoord.x < uEffectRegion.z) && (vTexCoord.y > uEffectRegion.y) && (vTexCoord.y < uEffectRegion.w) )\n"
167       "{\n"
168       "   vec2 coord = vCentredCoord;\n"
169
170       // find a coordinate representing distance from circle centre, such that we split into inside / outside circles that can have different gradients / normals
171       "   float realDistFromCentre = length(coord);\n"
172       "   realDistFromCentre = min(1.0, realDistFromCentre);\n" // clamp corners of square to vertical normal
173       "   float distFromCentre;\n"
174       "   if(realDistFromCentre <= uInsideCircleSizeScale)\n"
175       "   {\n"
176       "     distFromCentre = realDistFromCentre * uRecipInsideCircleSizeScale * (1.0 - uOutsideCircleDepth);\n" // inside circle indent, up to outline depth
177       "   }\n"
178       "   else                                                                                                                      \n"
179       "   {\n"
180       "     distFromCentre = mix(1.0 - uOutsideCircleDepth, 1.0, (realDistFromCentre - ( uInsideCircleSizeScale)) / (1.0 - uInsideCircleSizeScale));\n" // outside circle
181       "   }\n"
182
183       // get coords in -PI..PI range, i.e. scale the circle for use by trig functions
184       "  coord *= PI;\n"
185
186       // get a z value for the distorted surface in 0..1 range, using cos for a smooth curve (note, we ignore inside / outside circles since the difference isn't noticeable visually)
187       "   vec2 cosThetaCoord = (cos(coord) * 0.5) + 0.5;\n"
188       "   float z = cosThetaCoord.x * cosThetaCoord.y;\n"
189
190       // get the normal for the distorted surface, using the fact that the derivative of cos is -sin, finding tangent vector from slope and then normal by cross product...
191       "   float sinThetaCoord = sin(distFromCentre*PI) * uLightingIndentationAmount;\n" // slope, so tangent vec is (1.0, -sin)
192       // ...2D normal vector along distFromCentre vec is (sin, 1.0), convert to components in 3D.
193       "   vec3 norm = normalize(vec3(coord.x * sinThetaCoord, coord.y * sinThetaCoord, 1.0));\n"
194
195       // form surface z and project texture onto it.
196       "   float indentAmount = 1.0 / (1.0 - (z * uTextureDistortAmount));\n"
197       "   vec2 distortedCoord = vCentredCoord * indentAmount;\n"
198
199       // Convert the rect coordinates in -1 to 1 range back to the original coordinates
200       "   vec2 texCoord = vec2( ( (distortedCoord.x + 1.0)*(0.5) * (uEffectRegion.z - uEffectRegion.x) + uEffectRegion.x ), ( (distortedCoord.y + 1.0)*(0.5) * (uEffectRegion.w - uEffectRegion.y) + uEffectRegion.y  ) );  \n"
201       "   vec4 col = texture2D(sTexture, texCoord);\n"
202
203       // calc lighting
204       "   float lighting = (dot(uDiffuseLight, norm) + uAmbientLight) * uLightMultiplier;\n"
205       "  gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
206       "}\n"
207       "else\n"
208       "{\n"
209       "  vec4 col = texture2D(sTexture, vTexCoord);\n"
210       "  float lighting = (dot(uDiffuseLight, vec3(0.0, 0.0, 1.0)) + uAmbientLight) * uLightMultiplier;\n"
211       "  gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
212       "}\n"
213       "}\n";
214
215   std::string fragmentSourceRectangular;
216   fragmentSourceRectangular =  "precision mediump float;\n"
217
218       "uniform float uLightingIndentationAmount;\n"
219       "uniform float uTextureDistortAmount;\n"
220       "uniform vec3 uDiffuseLight;\n"
221       "uniform float uAmbientLight;\n"
222       "uniform float uLightMultiplier;\n"
223       "uniform float uInsideCircleSizeScale;\n"
224       "uniform float uRecipInsideCircleSizeScale;\n"
225       "uniform float uOutsideCircleDepth;\n"
226       "uniform float uRectangleSizeScale;\n"
227       "uniform vec4 uEffectRegion;\n"
228       "varying vec2 vCentredCoord;\n"
229
230       "const float PI = 3.1415927;\n"
231
232       "void main()\n"
233       "{\n"
234       // Apply distortion only if the pixel is within the rect specified
235       "if( (vTexCoord.x > uEffectRegion.x) && (vTexCoord.x < uEffectRegion.z) && (vTexCoord.y > uEffectRegion.y) && (vTexCoord.y < uEffectRegion.w) )\n"
236       "{ \n"
237       // get the rect coords to -1..1 range, i.e. circle centred around the center of the rect
238       "   vec2 centredCoord = vCentredCoord;\n"
239       // clamp coords such that the circle is split into 4 pieces that lie in the corners of the actor. uRectangleScale is the distance along each axis from the centre
240       // of the actor, e.g. 0.5 is half way along an axis from centre to actor edge.
241       "   vec2 clampedCoord;\n"
242       "   if(centredCoord.x > 0.0)\n"
243       "   {\n"
244       "     if(centredCoord.x < uRectangleSizeScale)\n"
245       "     {\n"
246       // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
247       "       clampedCoord.x = 0.0;\n"
248       "     }\n"
249       "     else\n"
250       "     {\n"
251       // we are outside rectangular region along this axis, so we want curvature.
252       "       clampedCoord.x = smoothstep(0.0, 1.0, (centredCoord.x - uRectangleSizeScale) / (1.0 - uRectangleSizeScale));\n"
253       "     }\n"
254       "   }\n"
255       "   else\n"
256       "   {\n"
257       "     if(centredCoord.x > -uRectangleSizeScale)\n"
258       "     {\n"
259       // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
260       "       clampedCoord.x = 0.0;\n"
261       "     }\n"
262       "     else\n"
263       "     {\n"
264       // we are outside rectangular region along this axis, so we want curvature.
265       "       clampedCoord.x = -smoothstep(0.0, 1.0, (centredCoord.x + uRectangleSizeScale) / (uRectangleSizeScale - 1.0));\n"
266       "     }\n"
267       "   }\n"
268       "   if(centredCoord.y > 0.0)\n"
269       "   {\n"
270       "     if(centredCoord.y < uRectangleSizeScale)\n"
271       "     {\n"
272       // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
273       "       clampedCoord.y = 0.0;\n"
274       "     }\n"
275       "     else\n"
276       "     {\n"
277       // we are outside rectangular region along this axis, so we want curvature.
278       "       clampedCoord.y = smoothstep(0.0, 1.0, (centredCoord.y - uRectangleSizeScale) / (1.0 - uRectangleSizeScale));\n"
279       "     }\n"
280       "   }\n"
281       "   else\n"
282       "   {\n"
283       "     if(centredCoord.y > -uRectangleSizeScale)\n"
284       "     {\n"
285       // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
286       "       clampedCoord.y = 0.0;\n"
287       "     }\n"
288       "     else\n"
289       "     {\n"
290       // we are outside rectangular region along this axis, so we want curvature.
291       "       clampedCoord.y = -smoothstep(0.0, 1.0, (centredCoord.y + uRectangleSizeScale) / (uRectangleSizeScale - 1.0));\n"
292       "     }\n"
293       "   }\n"
294       // get coords in -PI..PI range, i.e. scale above circle for use by trig functions
295       "   vec2 thetaCoord = clampedCoord * PI;\n"
296       // get a z value for the distorted surface in 0..1 range, using cos for a smooth curve (note, we ignore inside / outside circles since the difference isn't noticeable visually)
297       "   vec2 cosThetaCoord = (cos(thetaCoord) * 0.5) + 0.5;\n"
298       "   float z = cosThetaCoord.x * cosThetaCoord.y;\n"
299       // find a coordinate representing distance from circle centre, such that we split into inside / outside circles that can have different gradients / normals
300       "   float realDistFromCentre = length(thetaCoord);\n"
301       "   realDistFromCentre = min(PI, realDistFromCentre);\n" // clamp corners of square to vertical normal
302       "   float distFromCentre;\n"
303       "   if(realDistFromCentre <= PI * uInsideCircleSizeScale)\n"
304       "   {\n"
305       "     distFromCentre = realDistFromCentre * uRecipInsideCircleSizeScale * (PI - (uOutsideCircleDepth * PI)) / PI;\n" // inside circle indent, up to outline depth
306       "   }\n"
307       "   else\n"
308       "   {\n"
309       "     distFromCentre = mix(PI - (uOutsideCircleDepth * PI), PI, (realDistFromCentre - ( PI * uInsideCircleSizeScale)) / (PI - (PI * uInsideCircleSizeScale)));\n" // outside circle
310       "   }\n"
311       // get the normal for the distorted surface, using the fact that the derivative of cos is -sin, finding tangent vector from slope and then normal by cross product...
312       "   float sinThetaCoord = sin(distFromCentre) * uLightingIndentationAmount;\n" // slope, so tangent vec is (1.0, -sin)
313       // ...2D normal vector along distFromCentre vec is (sin, 1.0), convert to components in 3D.
314       "   vec3 norm = normalize(vec3(thetaCoord.x * sinThetaCoord, thetaCoord.y * sinThetaCoord, 1.0));\n"
315       // form surface z and project texture onto it.
316       "   float indentAmount = 1.0 / (1.0 - (z * uTextureDistortAmount));\n"
317       "   vec2 distortedCoord = centredCoord * indentAmount;\n"
318       // Convert the rect coordinates in -1 to 1 range back to the original coordinates
319       "   vec2 texCoord = vec2( ( (distortedCoord.x + 1.0)/(2.0) * (uEffectRegion.z - uEffectRegion.x) + uEffectRegion.x ), ( (distortedCoord.y + 1.0)/(2.0) * (uEffectRegion.w - uEffectRegion.y) + uEffectRegion.y  ) );\n"
320       "   vec4 col = texture2D(sTexture, texCoord);\n"
321       // calc lighting
322       "   float lighting = (dot(uDiffuseLight, norm) + uAmbientLight) * uLightMultiplier;\n"
323       // output col = image * light
324       // use the lighting value for colors only
325       "   gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
326
327       "}\n"
328       "else\n"
329       "{\n"
330       "   vec4 col = texture2D(sTexture, vTexCoord);\n"
331       "   float lighting = (dot(uDiffuseLight, vec3(0.0, 0.0, 1.0)) + uAmbientLight) * uLightMultiplier;\n"
332       "   gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
333       "} \n"
334       "}\n";
335
336
337   //////////////////////////////////////
338   // Create shader effectCreateSoftButtonEffect
339   //
340   //
341
342   ShaderEffect shader;
343   switch(type)
344   {
345     case SOFT_BUTTON_RECTANGULAR:
346       shader = ShaderEffect::New( vertexSource, fragmentSourceRectangular, ShaderEffect::GeometryHints( ShaderEffect::HINT_NONE ));
347       break;
348
349     case SOFT_BUTTON_ELLIPTICAL:
350       shader = ShaderEffect::New( vertexSource, fragmentSourceElliptical, ShaderEffect::GeometryHints( ShaderEffect::HINT_NONE ));
351       break;
352
353     case SOFT_BUTTON_FIXED:
354     default:
355       shader = ShaderEffect::New( vertexSource, fragmentSourceFixed, ShaderEffect::GeometryHints( ShaderEffect::HINT_NONE ));
356       break;
357   }
358
359   //////////////////////////////////////
360   // Register uniform properties
361   //
362   //
363   static const float SOFT_BUTTON_LIGHTING_INDENTATION_AMOUNT_DEFAULT = 0.0f;
364   static const float SOFT_BUTTON_TEXTURE_DISTORTION_AMOUNT_DEFAULT = 0.0f;
365   static const float SOFT_BUTTON_AMBIENT_LIGHT_AMOUNT_DEFAULT = 0.15f;
366   static const Vector3 SOFT_BUTTON_DIFFUSE_LIGHT_DEFAULT = Vector3(0.0f, 0.7070168f, 0.7071068f);
367   static const float SOFT_BUTTON_LIGHTING_MULTIPLIER_DEFAULT = 1.2f;
368   static const float SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_DEFAULT = 0.75f;
369   static const float SOFT_BUTTON_OUTSIDE_SHAPE_DEPTH_DEFAULT = Math::PI * 0.05f;
370   static const Vector4 SOFT_BUTTON_EFFECT_PIXEL_AREA_DEFAULT = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
371   static const float SOFT_BUTTON_RECTANGLE_SIZE_SCALE_DEFAULT = 0.5f;
372
373   // factors that scale the look, defaults
374   shader.SetUniform("uAmbientLight", SOFT_BUTTON_AMBIENT_LIGHT_AMOUNT_DEFAULT);
375   shader.SetUniform("uDiffuseLight", SOFT_BUTTON_DIFFUSE_LIGHT_DEFAULT);
376   shader.SetUniform("uLightMultiplier", SOFT_BUTTON_LIGHTING_MULTIPLIER_DEFAULT);
377   if(SOFT_BUTTON_FIXED != type)
378   {
379     shader.SetUniform("uLightingIndentationAmount", SOFT_BUTTON_LIGHTING_INDENTATION_AMOUNT_DEFAULT);
380     shader.SetUniform("uTextureDistortAmount", SOFT_BUTTON_TEXTURE_DISTORTION_AMOUNT_DEFAULT);
381     shader.SetUniform("uInsideCircleSizeScale", SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_DEFAULT);
382     shader.SetUniform("uRecipInsideCircleSizeScale", 1.0f / SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_DEFAULT);
383     shader.SetUniform("uOutsideCircleDepth", SOFT_BUTTON_OUTSIDE_SHAPE_DEPTH_DEFAULT);
384     shader.SetUniform("uEffectRegion", SOFT_BUTTON_EFFECT_PIXEL_AREA_DEFAULT);
385     if(SOFT_BUTTON_RECTANGULAR == type)
386     {
387       shader.SetUniform("uRectangleSizeScale", SOFT_BUTTON_RECTANGLE_SIZE_SCALE_DEFAULT);
388     }
389
390     // precalc 1.0 / uInsideCircleSizeScale on CPU to save shader insns, using constraint to tie to the normal property
391     Dali::Property::Index insideCircleSizeScalePropertyIndex = shader.GetPropertyIndex("uInsideCircleSizeScale");
392     Dali::Property::Index recipInsideCircleSizeScalePropertyIndex = shader.GetPropertyIndex("uRecipInsideCircleSizeScale");
393     Constraint constraint = Constraint::New<float>( shader, recipInsideCircleSizeScalePropertyIndex, InverseConstraint );
394     constraint.AddSource( LocalSource(insideCircleSizeScalePropertyIndex) );
395     constraint.Apply();
396   }
397
398   return shader;
399 }
400
401 }
402
403 }
404
405 #endif //#ifndef __DALI_TOOLKIT_SHADER_EFFECT_SOFT_BUTTON_H__