Revision 20af7b69
Added by Leszek Koltunski over 7 years ago
src/main/res/raw/main_vertex_shader.glsl | ||
---|---|---|
70 | 70 |
|
71 | 71 |
vec2 signA = sign(A); // |
72 | 72 |
vec2 signA_SQ = signA*signA; // div = PS/A if A!=0, 0 otherwise. |
73 |
vec2 div = signA_SQ*PS/(A+signA_SQ-vec2(1,1)); //
|
|
73 |
vec2 div = signA_SQ*PS/(A-(vec2(1,1)-signA_SQ));//
|
|
74 | 74 |
|
75 | 75 |
return 1.0-max(div.x,div.y); |
76 | 76 |
} |
... | ... | |
101 | 101 |
if( D<=0.0 ) return 0.0; |
102 | 102 |
|
103 | 103 |
float ps_sq = dot(PS,PS); |
104 |
float one_over_ps_sq = 1.0/(ps_sq+1.0-sign(ps_sq)); // return 1.0 if ps_sq = 0.0 |
|
104 |
float one_over_ps_sq = 1.0/(ps_sq-(sign(ps_sq)-1.0)); // return 1.0 if ps_sq = 0.0 |
|
105 |
// Important: if we want to write |
|
106 |
// b = 1/a if a!=0, b=1 otherwise |
|
107 |
// we need to write that as |
|
108 |
// b = 1 / ( a-(sign(a)-1) ) |
|
109 |
// [ and NOT 1 / ( a + 1 - sign(a) ) ] |
|
110 |
// because the latter, if 0<a<2^-24, |
|
111 |
// will suffer from round-off error and in this case |
|
112 |
// a + 1.0 = 1.0 !! so 1 / (a+1-sign(a)) = 1/0 ! |
|
105 | 113 |
float DOT = dot(PS,PO)*one_over_ps_sq; |
106 | 114 |
|
107 | 115 |
return 1.0 / (1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT)); |
... | ... | |
120 | 128 |
vec2 A = sign(PS)*u_objD.xy + S; |
121 | 129 |
vec2 signA = sign(A); |
122 | 130 |
vec2 signA_SQ = signA*signA; |
123 |
vec2 div = signA_SQ*PS/(A+signA_SQ-vec2(1,1));
|
|
131 |
vec2 div = signA_SQ*PS/(A-(vec2(1,1)-signA_SQ));
|
|
124 | 132 |
float E = 1.0-max(div.x,div.y); |
125 | 133 |
|
126 | 134 |
float ps_sq = dot(PS,PS); |
127 |
float one_over_ps_sq = 1.0/(ps_sq+1.0-sign(ps_sq)); // return 1.0 if ps_sq = 0.0
|
|
135 |
float one_over_ps_sq = 1.0/(ps_sq-(sign(ps_sq)-1.0)); // return 1.0 if ps_sq = 0.0
|
|
128 | 136 |
float DOT = dot(PS,PO)*one_over_ps_sq; |
129 | 137 |
|
130 | 138 |
return min(1.0/(1.0 + 1.0/(sqrt(DOT*DOT+D*one_over_ps_sq)-DOT)),E); |
... | ... | |
281 | 289 |
vec2 w = vec2(vUniforms[effect].x, -vUniforms[effect].y); |
282 | 290 |
float uz = vUniforms[effect].z; // height of the bubble |
283 | 291 |
float denominator = dot(ps+(1.0-d)*w,ps); |
284 |
float one_over_denom = 1.0/(denominator+0.001*(1.0-sign(denominator))); // = denominator==0 ? 1000:1/denominator;
|
|
292 |
float one_over_denom = 1.0/(denominator-0.001*(sign(denominator)-1.0)); // = denominator==0 ? 1000:1/denominator;
|
|
285 | 293 |
|
286 | 294 |
//v.z += uz*d; // cone |
287 | 295 |
//b = -(uz*(1.0-d))*one_over_denom; // |
... | ... | |
326 | 334 |
vec3 SO = vUniforms[effect+1]; |
327 | 335 |
float d1_circle = degree_region(SO,PS); |
328 | 336 |
float d1_bitmap = degree_bitmap(S,PS); |
329 |
float sinA = vUniforms[effect].y; // sin(A) precomputed in EffectListVertex.postprocess
|
|
330 |
float cosA = vUniforms[effect].z; // cos(A) precomputed in EffectListVertex.postprocess
|
|
331 |
vec2 PS2 = vec2( PS.x*cosA+PS.y*sinA,-PS.x*sinA+PS.y*cosA ); // vector PS rotated by A radians clockwise around S.
|
|
337 |
float sinA = vUniforms[effect].y; // sin(A) precomputed in EffectListVertex.postprocess |
|
338 |
float cosA = vUniforms[effect].z; // cos(A) precomputed in EffectListVertex.postprocess |
|
339 |
vec2 PS2 = vec2( PS.x*cosA+PS.y*sinA,-PS.x*sinA+PS.y*cosA ); // vector PS rotated by A radians clockwise around S. |
|
332 | 340 |
vec3 SG = (1.0-d1_circle)*SO; // coordinates of the dilated circle P is going to get rotated around |
333 |
float d2 = max(0.0,degree(SG,S,PS2)); // make it a max(0,deg) because when S=left edge of the bitmap, otherwise
|
|
334 |
// some points end up with d2<0 and they disappear off view. |
|
341 |
float d2 = max(0.0,degree(SG,S,PS2)); // make it a max(0,deg) because otherwise when S=left edge of the
|
|
342 |
// bitmap some points end up with d2<0 and they disappear off view.
|
|
335 | 343 |
v.xy += min(d1_circle,d1_bitmap)*(PS - PS2/(1.0-d2)); // if d2=1 (i.e P=S) we should have P unchanged. How to do it? |
336 | 344 |
} |
337 | 345 |
|
Also available in: Unified diff
Correct an important bug in the vertex shader.
b = 1/a if a!=0, 1 otherwise was incorrectly computed as b = 1.0 / (a+1.0-sign(a)). This, when 0<a<2^-24, suffers from 'round-off error': then a+1.0 = 1.0 (sic!) thus b = 1/0 !.
Correct way: b = 1.0 / ( a - (sign(a)-1.0) )