1
2/*
3Copyright (c) 2019 The Khronos Group Inc.
4Use of this source code is governed by an MIT-style license that can be
5found in the LICENSE.txt file.
6*/
7
8
9#ifdef GL_ES
10precision mediump float;
11#endif
12varying vec4 color;
13
14void main (void)
15{
16	const float M_PI = 3.14159265358979323846;
17	vec2 x = 2.0 * (color.gg - 0.5);
18	vec2 y = 2.0 * (color.bb - 0.5);
19	vec2 c;
20	vec2 atan_c = vec2(0.0);
21	vec2 scale = vec2(1.0);
22	vec2 sign = vec2(1.0);
23	vec4 result = vec4(0.0, 0.0, 0.0, 1.0);
24	const float epsilon = 1.0e-4;
25
26	// Avoid evaluating atan(0, x) for x < epsilon because it's implementation-dependent
27	if(x[0] > epsilon || abs(y[0]) > epsilon)
28	{
29		if(x[0] < 0.0 ^^ y[0] < 0.0)
30		{
31			sign[0] = -1.0;
32		}
33
34		if(abs(y[0]) <= abs(x[0]))
35		{
36			c[0] = abs(y[0] / x[0]);
37			// Taylors series expansion for atan
38			atan_c[0] += scale[0] * pow(c[0], float(1)) / float(1);
39			scale[0] *= -1.0;
40			atan_c[0] += scale[0] * pow(c[0], float(3)) / float(3);
41			scale[0] *= -1.0;
42			atan_c[0] += scale[0] * pow(c[0], float(5)) / float(5);
43			scale[0] *= -1.0;
44			atan_c[0] += scale[0] * pow(c[0], float(7)) / float(7);
45			scale[0] *= -1.0;
46			atan_c[0] += scale[0] * pow(c[0], float(9)) / float(9);
47			scale[0] *= -1.0;
48			atan_c[0] += scale[0] * pow(c[0], float(11)) / float(11);
49			scale[0] *= -1.0;
50
51			result[0] = sign[0] * atan_c[0] / (2.0 * M_PI) + 0.5;
52		}
53		else
54		{
55			c[0] = abs(x[0] / y[0]);
56
57			// Taylors series expansion for atan
58			atan_c[0] += scale[0] * pow(c[0], float(1)) / float(1);
59			scale[0] *= -1.0;
60			atan_c[0] += scale[0] * pow(c[0], float(3)) / float(3);
61			scale[0] *= -1.0;
62			atan_c[0] += scale[0] * pow(c[0], float(5)) / float(5);
63			scale[0] *= -1.0;
64			atan_c[0] += scale[0] * pow(c[0], float(7)) / float(7);
65			scale[0] *= -1.0;
66			atan_c[0] += scale[0] * pow(c[0], float(9)) / float(9);
67			scale[0] *= -1.0;
68			atan_c[0] += scale[0] * pow(c[0], float(11)) / float(11);
69			scale[0] *= -1.0;
70
71			result[0] = sign[0] * (M_PI / 2.0 - atan_c[0]) / (2.0 * M_PI) + 0.5;
72		}
73
74		if(x[0] < 0.0)
75			if(y[0] < 0.0) result[0] -= 0.5;
76			else if(y[0] > 0.0) result[0] += 0.5;
77	}
78
79	if(x[1] > epsilon || abs(y[1]) > epsilon)
80	{
81
82		if(x[1] < 0.0 ^^ y[1] < 0.0)
83		{
84			sign[1] = -1.0;
85		}
86
87		if(abs(y[1]) <= abs(x[1]))
88		{
89			c[1] = abs(y[1] / x[1]);
90			// Taylors series expansion for atan
91			atan_c[1] += scale[1] * pow(c[1], float(1)) / float(1);
92			scale[1] *= -1.0;
93			atan_c[1] += scale[1] * pow(c[1], float(3)) / float(3);
94			scale[1] *= -1.0;
95			atan_c[1] += scale[1] * pow(c[1], float(5)) / float(5);
96			scale[1] *= -1.0;
97			atan_c[1] += scale[1] * pow(c[1], float(7)) / float(7);
98			scale[1] *= -1.0;
99			atan_c[1] += scale[1] * pow(c[1], float(9)) / float(9);
100			scale[1] *= -1.0;
101			atan_c[1] += scale[1] * pow(c[1], float(11)) / float(11);
102			scale[1] *= -1.0;
103
104			result[1] = sign[1] * atan_c[1] / (2.0 * M_PI) + 0.5;
105		}
106		else
107		{
108			c[1] = abs(x[1] / y[1]);
109
110			// Taylors series expansion for atan
111			atan_c[1] += scale[1] * pow(c[1], float(1)) / float(1);
112			scale[1] *= -1.0;
113			atan_c[1] += scale[1] * pow(c[1], float(3)) / float(3);
114			scale[1] *= -1.0;
115			atan_c[1] += scale[1] * pow(c[1], float(5)) / float(5);
116			scale[1] *= -1.0;
117			atan_c[1] += scale[1] * pow(c[1], float(7)) / float(7);
118			scale[1] *= -1.0;
119			atan_c[1] += scale[1] * pow(c[1], float(9)) / float(9);
120			scale[1] *= -1.0;
121			atan_c[1] += scale[1] * pow(c[1], float(11)) / float(11);
122			scale[1] *= -1.0;
123
124			result[1] = sign[1] * (M_PI / 2.0 - atan_c[1]) / (2.0 * M_PI) + 0.5;
125		}
126
127		if(x[1] < 0.0)
128			if(y[1] < 0.0) result[1] -= 0.5;
129			else if(y[1] > 0.0) result[1] += 0.5;
130	}
131
132	gl_FragColor = result;
133}
134