Revision 9420f2fe
Added by Leszek Koltunski over 8 years ago
src/main/res/raw/main_vertex_shader.glsl | ||
---|---|---|
50 | 50 |
////////////////////////////////////////////////////////////////////////////////////////////// |
51 | 51 |
// HELPER FUNCTIONS |
52 | 52 |
////////////////////////////////////////////////////////////////////////////////////////////// |
53 |
// Let (v.x,v.y) be point P (the current vertex). |
|
54 |
// Let vPoint[effect].xy be point S (the center of effect) |
|
55 |
// Let vPoint[effect].xy + vRegion[effect].xy be point O (the center of the Region circle) |
|
56 |
// Let X be the point where the halfline SP meets a) if region is non-null, the region circle b) otherwise, the edge of the bitmap. |
|
57 |
// |
|
58 |
// If P is inside the Region, this function returns |PX|/||SX|, aka the 'degree' of point P. Otherwise, it returns 0. |
|
59 |
// |
|
60 |
// We compute the point where half-line from S to P intersects the edge of the bitmap. If that's inside the circle, end. If not, we solve the |
|
61 |
// the triangle with vertices at O, P and the point of intersection with the circle we are looking for X. |
|
62 |
// We know the lengths |PO|, |OX| and the angle OPX , because cos(OPX) = cos(180-OPS) = -cos(OPS) = -PS*PO/(|PS|*|PO|) |
|
63 |
// then from the law of cosines PX^2 + PO^2 - 2*PX*PO*cos(OPX) = OX^2 so |
|
64 |
// PX = -a + sqrt(a^2 + OX^2 - PO^2) where a = PS*PO/|PS| but we are really looking for d = |PX|/(|PX|+|PS|) = 1/(1+ (|PS|/|PX|) ) and |
|
65 |
// |PX|/|PS| = -b + sqrt(b^2 + (OX^2-PO^2)/PS^2) where b=PS*PO/|PS|^2 which can be computed with only one sqrt. |
|
66 |
// |
|
67 |
// the trick below is the if-less version of the |
|
53 |
// The trick below is the if-less version of the |
|
68 | 54 |
// |
69 | 55 |
// t = dx<0.0 ? (u_objD.x-v.x) / (u_objD.x-ux) : (u_objD.x+v.x) / (u_objD.x+ux); |
70 | 56 |
// h = dy<0.0 ? (u_objD.y-v.y) / (u_objD.y-uy) : (u_objD.y+v.y) / (u_objD.y+uy); |
... | ... | |
90 | 76 |
} |
91 | 77 |
|
92 | 78 |
////////////////////////////////////////////////////////////////////////////////////////////// |
93 |
// return degree of the point as defined by the Region |
|
94 |
// Currently only supports circles; .xy = vector from center of effect to the center of the circle, .z = radius |
|
79 |
// Return degree of the point as defined by the Region. Currently only supports circular regions. |
|
80 |
// |
|
81 |
// Let 'PS' be the vector from point P (the current vertex) to point S (the center of the effect). |
|
82 |
// Should work regardless if S is inside or outside of the circle. |
|
83 |
// Let region.xy be the vector from point S to point O (the center point of the region circle) |
|
84 |
// Let region.z be the radius of the region circle. |
|
85 |
// |
|
86 |
// If P is outside the circle, return 0. |
|
87 |
// Otherwise, let X be the point where the halfline SP meets the region circle - return |PX|/||SX|, |
|
88 |
// aka the 'degree' of point P. |
|
89 |
// |
|
90 |
// We solve the the triangle OPX. |
|
91 |
// We know the lengths |PO|, |OX| and the angle OPX, because cos(OPX) = cos(180-OPS) = -cos(OPS) = -PS*PO/(|PS|*|PO|) |
|
92 |
// then from the law of cosines PX^2 + PO^2 - 2*PX*PO*cos(OPX) = OX^2 so PX = -a + sqrt(a^2 + OX^2 - PO^2) |
|
93 |
// where a = PS*PO/|PS| but we are really looking for d = |PX|/(|PX|+|PS|) = 1/(1+ (|PS|/|PX|) ) and |
|
94 |
// |PX|/|PS| = -b + sqrt(b^2 + (OX^2-PO^2)/PS^2) where b=PS*PO/|PS|^2 which can be computed with only one sqrt. |
|
95 | 95 |
|
96 | 96 |
float degree_region(in vec3 region, in vec2 PS) |
97 | 97 |
{ |
98 | 98 |
vec2 PO = PS + region.xy; |
99 | 99 |
float D = region.z*region.z-dot(PO,PO); // D = |OX|^2 - |PO|^2 |
100 |
|
|
101 |
if( D<=0.0 ) return 0.0; |
|
102 |
|
|
100 | 103 |
float ps_sq = dot(PS,PS); |
101 | 104 |
float one_over_ps_sq = 1.0/(ps_sq+1.0-sign(ps_sq)); // return 1.0 if ps_sq = 0.0 |
102 | 105 |
float DOT = dot(PS,PO)*one_over_ps_sq; |
103 | 106 |
|
104 |
return max(sign(D),0.0) / (1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT)); // if D<=0 (i.e p is outside the Region) return 0.
|
|
107 |
return 1.0 / (1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT));
|
|
105 | 108 |
} |
106 | 109 |
|
107 | 110 |
////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
111 | 114 |
{ |
112 | 115 |
vec2 PO = PS + region.xy; |
113 | 116 |
float D = region.z*region.z-dot(PO,PO); // D = |OX|^2 - |PO|^2 |
117 |
|
|
118 |
if( D<=0.0 ) return 0.0; |
|
119 |
|
|
114 | 120 |
vec2 A = sign(PS)*u_objD.xy + S; |
115 | 121 |
vec2 signA = sign(A); |
116 | 122 |
vec2 signA_SQ = signA*signA; |
... | ... | |
121 | 127 |
float one_over_ps_sq = 1.0/(ps_sq+1.0-sign(ps_sq)); // return 1.0 if ps_sq = 0.0 |
122 | 128 |
float DOT = dot(PS,PO)*one_over_ps_sq; |
123 | 129 |
|
124 |
return max(sign(D),0.0) * min(1.0/(1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT)),E); // if D<=0 (i.e p is outside the Region) return 0.
|
|
130 |
return min(1.0/(1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT)),E);
|
|
125 | 131 |
} |
126 | 132 |
|
127 | 133 |
////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Fix for Bug 19: SWIRL effect: mess if Center out of Region.