Merge "DALi Version 2.0.43" 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     lowp vec3 BorderlineColorRGB = borderlineColor.xyz * borderlineColor.a;
132     if(potential > MaxTexturelinePotential)
133     {
134       // potential is out of texture range. use borderline color instead of texture
135       textureColor = vec4(BorderlineColorRGB, 0.0);
136     }
137     else if(potential > MinTexturelinePotential)
138     {
139       // potential is in texture range
140       textureColor = mix(textureColor, vec4(BorderlineColorRGB, 0.0), smoothstep(MinTexturelinePotential, MaxTexturelinePotential, potential));
141     }
142     borderlineOpacity *= borderlineColor.a;
143     return mix(textureColor, vec4(BorderlineColorRGB, 1.0), borderlineOpacity);
144   }
145   return mix(textureColor, borderlineColor, borderlineOpacity);
146 }
147 #endif
148
149 #if IS_REQUIRED_ROUNDED_CORNER
150 mediump float calculateCornerOpacity()
151 {
152   mediump float potential = gPotential;
153
154   // default opacity is 1.0
155   mediump float opacity = 1.0;
156
157   // calculate borderline opacity by potential
158   if(potential > gMaxOutlinePotential)
159   {
160     // potential is out of borderline range. just discard here
161     discard;
162   }
163   else if(potential > gMinOutlinePotential)
164   {
165     opacity = 1.0 - smoothstep(gMinOutlinePotential, gMaxOutlinePotential, potential);
166   }
167   return opacity;
168 }
169 #endif
170
171 void main()
172 {
173 #if RADIAL
174   lowp vec4 textureColor = TEXTURE(sTexture, vec2(length(vTexCoord), 0.5)) * vec4(mixColor, 1.0);
175 #else
176   lowp vec4 textureColor = TEXTURE(sTexture, vec2(vTexCoord.y, 0.5)) * vec4(mixColor, 1.0);
177 #endif
178
179 #if IS_REQUIRED_ROUNDED_CORNER || IS_REQUIRED_BORDERLINE
180   // skip most potential calculate for performance
181   if(abs(vPosition.x) < vOptRectSize.x && abs(vPosition.y) < vOptRectSize.y)
182   {
183     OUT_COLOR = textureColor * uColor;
184     return;
185   }
186   PreprocessPotential();
187 #endif
188
189 #if IS_REQUIRED_BORDERLINE
190   textureColor = convertBorderlineColor(textureColor);
191 #endif
192   OUT_COLOR = textureColor * uColor;
193
194 #if IS_REQUIRED_ROUNDED_CORNER
195   mediump float opacity = calculateCornerOpacity();
196   OUT_COLOR *= opacity;
197 #endif
198 }