Merge "Add TOUCH_FOCUSABLE property" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / graphics / shaders / gradient-visual-shader.frag
1 #ifndef IS_REQUIRED_ROUNDED_CORNER
2 #define IS_REQUIRED_ROUNDED_CORNER 0
3 #endif
4 #ifndef IS_REQUIRED_BORDERLINE
5 #define IS_REQUIRED_BORDERLINE 0
6 #endif
7 #ifndef RADIAL
8 #define RADIAL 0
9 #endif
10
11 INPUT mediump vec2 vTexCoord;
12 #if IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
13 INPUT mediump vec2 vPosition;
14 INPUT mediump vec2 vRectSize;
15 INPUT mediump vec2 vOptRectSize;
16 #if IS_REQUIRED_ROUNDED_CORNER
17 INPUT mediump vec4 vCornerRadius;
18 #endif
19 #endif
20
21 uniform sampler2D sTexture; // sampler1D?
22 uniform lowp vec4 uColor;
23 uniform lowp vec3 mixColor;
24 #if IS_REQUIRED_BORDERLINE
25 uniform mediump float borderlineWidth;
26 uniform mediump float borderlineOffset;
27 uniform lowp vec4 borderlineColor;
28 #endif
29
30 #if IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
31 // Global values both rounded corner and borderline use
32
33 // radius of rounded corner on this quadrant
34 mediump float gRadius = 0.0;
35
36 // fragment coordinate. NOTE : vec2(0.0, 0.0) is vRectSize, the corner of visual
37 mediump vec2 gFragmentPosition = vec2(0.0, 0.0);
38 // center coordinate of rounded corner circle. vec2(gCenterPosition, gCenterPosition).
39 mediump float gCenterPosition = 0.0;
40 // relative coordinate of gFragmentPosition from gCenterPosition.
41 mediump vec2 gDiff = vec2(0.0, 0.0);
42 // potential value what our algorithm use.
43 mediump float gPotential = 0.0;
44
45 // threshold of potential
46 mediump float gPotentialRange = 0.0;
47 mediump float gMaxOutlinePotential = 0.0;
48 mediump float gMinOutlinePotential = 0.0;
49 mediump float gMaxInlinePotential = 0.0;
50 mediump float gMinInlinePotential = 0.0;
51
52 void calculateCornerRadius()
53 {
54 #if IS_REQUIRED_ROUNDED_CORNER
55   gRadius =
56   mix(
57     mix(vCornerRadius.x, vCornerRadius.y, sign(vPosition.x) * 0.5 + 0.5),
58     mix(vCornerRadius.w, vCornerRadius.z, sign(vPosition.x) * 0.5 + 0.5),
59     sign(vPosition.y) * 0.5 + 0.5
60   );
61 #endif
62 }
63
64 void calculatePosition()
65 {
66   gFragmentPosition = abs(vPosition) - vRectSize;
67   gCenterPosition = -gRadius;
68 #if IS_REQUIRED_BORDERLINE
69   gCenterPosition += borderlineWidth * (clamp(borderlineOffset, -1.0, 1.0) + 1.0) * 0.5;
70 #endif
71   gDiff = gFragmentPosition - gCenterPosition;
72 }
73
74 void calculatePotential()
75 {
76   gPotential = length(max(gDiff, 0.0)) + min(0.0, max(gDiff.x, gDiff.y));
77 }
78
79 void setupMinMaxPotential()
80 {
81   gPotentialRange = 1.0;
82
83   gMaxOutlinePotential = gRadius + gPotentialRange;
84   gMinOutlinePotential = gRadius - gPotentialRange;
85
86 #if IS_REQUIRED_BORDERLINE
87   gMaxInlinePotential = gMaxOutlinePotential - borderlineWidth;
88   gMinInlinePotential = gMinOutlinePotential - borderlineWidth;
89 #else
90   gMaxInlinePotential = gMaxOutlinePotential;
91   gMinInlinePotential = gMinOutlinePotential;
92 #endif
93
94   // reduce defect near edge of rounded corner.
95   gMaxOutlinePotential += clamp(-min(gDiff.x, gDiff.y)/ max(1.0, gRadius) , 0.0, 1.0);
96   gMinOutlinePotential += clamp(-min(gDiff.x, gDiff.y)/ max(1.0, gRadius) , 0.0, 1.0);
97 }
98
99 void PreprocessPotential()
100 {
101   calculateCornerRadius();
102   calculatePosition();
103   calculatePotential();
104
105   setupMinMaxPotential();
106 }
107 #endif
108
109
110 #if IS_REQUIRED_BORDERLINE
111 lowp vec4 convertBorderlineColor(lowp vec4 textureColor)
112 {
113   mediump float potential = gPotential;
114
115   // default opacity of borderline is 0.0
116   mediump float borderlineOpacity = 0.0;
117
118   // calculate borderline opacity by potential
119   if(potential > gMinInlinePotential)
120   {
121     // potential is inside borderline range.
122     borderlineOpacity = smoothstep(gMinInlinePotential, gMaxInlinePotential, potential);
123   }
124
125   //calculate inside of borderline when outilneColor.a < 1.0
126   if(borderlineColor.a < 1.0)
127   {
128     mediump float tCornerRadius = -gCenterPosition;
129     mediump float MaxTexturelinePotential = tCornerRadius + gPotentialRange;
130     mediump float MinTexturelinePotential = tCornerRadius - gPotentialRange;
131     if(potential > MaxTexturelinePotential)
132     {
133       // potential is out of texture range. use borderline color instead of texture
134       textureColor = vec4(borderlineColor.xyz, 0.0);
135     }
136     else if(potential > MinTexturelinePotential)
137     {
138       // potential is in texture range
139       textureColor = mix(textureColor, vec4(borderlineColor.xyz, 0.0), smoothstep(MinTexturelinePotential, MaxTexturelinePotential, potential));
140     }
141     borderlineOpacity *= borderlineColor.a;
142   }
143   return mix(textureColor, vec4(borderlineColor.xyz, 1.0), borderlineOpacity);
144 }
145 #endif
146
147 #if IS_REQUIRED_ROUNDED_CORNER
148 mediump float calculateCornerOpacity()
149 {
150   mediump float potential = gPotential;
151
152   // default opacity is 1.0
153   mediump float opacity = 1.0;
154
155   // calculate borderline opacity by potential
156   if(potential > gMaxOutlinePotential)
157   {
158     // potential is out of borderline range
159     opacity = 0.0;
160   }
161   else if(potential > gMinOutlinePotential)
162   {
163     opacity = 1.0 - smoothstep(gMinOutlinePotential, gMaxOutlinePotential, potential);
164   }
165   return opacity;
166 }
167 #endif
168
169 void main()
170 {
171 #if RADIAL
172   lowp vec4 textureColor = TEXTURE(sTexture, vec2(length(vTexCoord), 0.5)) * vec4(mixColor, 1.0) * uColor;
173 #else
174   lowp vec4 textureColor = TEXTURE(sTexture, vec2(vTexCoord.y, 0.5)) * vec4(mixColor, 1.0) * uColor;
175 #endif
176
177 #if IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
178   // skip most potential calculate for performance
179   if(abs(vPosition.x) < vOptRectSize.x && abs(vPosition.y) < vOptRectSize.y)
180   {
181     OUT_COLOR = textureColor;
182     return;
183   }
184   PreprocessPotential();
185 #endif
186
187 #if IS_REQUIRED_BORDERLINE
188   textureColor = convertBorderlineColor(textureColor);
189 #endif
190   OUT_COLOR = textureColor;
191
192 #if IS_REQUIRED_ROUNDED_CORNER
193   mediump float opacity = calculateCornerOpacity();
194   OUT_COLOR *= opacity;
195 #endif
196 }