A game about forced loneliness, made by TACStudios
1#ifndef UNITY_FIBONACCI_INCLUDED
2#define UNITY_FIBONACCI_INCLUDED
3
4#if SHADER_API_MOBILE || SHADER_API_GLES3 || SHADER_API_SWITCH || defined(UNITY_UNIFIED_SHADER_PRECISION_MODEL)
5#pragma warning (disable : 3205) // conversion of larger type to smaller
6#endif
7
8// Computes a point using the Fibonacci sequence of length N.
9// Input: Fib[N - 1], Fib[N - 2], and the index 'i' of the point.
10// Ref: Efficient Quadrature Rules for Illumination Integrals
11real2 Fibonacci2dSeq(real fibN1, real fibN2, uint i)
12{
13 // 3 cycles on GCN if 'fibN1' and 'fibN2' are known at compile time.
14 // N.b.: According to Swinbank and Pusser [SP06], the uniformity of the distribution
15 // can be slightly improved by introducing an offset of 1/N to the Z (or R) coordinates.
16 return real2(i / fibN1 + (0.5 / fibN1), frac(i * (fibN2 / fibN1)));
17}
18
19#define GOLDEN_RATIO 1.618033988749895
20#define GOLDEN_ANGLE 2.399963229728653
21
22// Replaces the Fibonacci sequence in Fibonacci2dSeq() with the Golden ratio.
23real2 Golden2dSeq(uint i, real n)
24{
25 // GoldenAngle = 2 * Pi * (1 - 1 / GoldenRatio).
26 // We can drop the "1 -" part since all it does is reverse the orientation.
27 return real2(i / n + (0.5 / n), frac(i * rcp(GOLDEN_RATIO)));
28}
29
30static const uint k_FibonacciSeq[] = {
31 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181
32};
33
34static const real2 k_Fibonacci2dSeq21[] = {
35 real2(0.02380952, 0.00000000),
36 real2(0.07142857, 0.61904764),
37 real2(0.11904762, 0.23809528),
38 real2(0.16666667, 0.85714293),
39 real2(0.21428572, 0.47619057),
40 real2(0.26190478, 0.09523821),
41 real2(0.30952382, 0.71428585),
42 real2(0.35714287, 0.33333349),
43 real2(0.40476191, 0.95238113),
44 real2(0.45238096, 0.57142878),
45 real2(0.50000000, 0.19047642),
46 real2(0.54761904, 0.80952406),
47 real2(0.59523809, 0.42857170),
48 real2(0.64285713, 0.04761887),
49 real2(0.69047618, 0.66666698),
50 real2(0.73809522, 0.28571510),
51 real2(0.78571427, 0.90476227),
52 real2(0.83333331, 0.52380943),
53 real2(0.88095236, 0.14285755),
54 real2(0.92857140, 0.76190567),
55 real2(0.97619045, 0.38095284)
56};
57
58static const real2 k_Fibonacci2dSeq34[] = {
59 real2(0.01470588, 0.00000000),
60 real2(0.04411765, 0.61764705),
61 real2(0.07352941, 0.23529410),
62 real2(0.10294118, 0.85294116),
63 real2(0.13235295, 0.47058821),
64 real2(0.16176471, 0.08823538),
65 real2(0.19117647, 0.70588231),
66 real2(0.22058824, 0.32352924),
67 real2(0.25000000, 0.94117641),
68 real2(0.27941176, 0.55882359),
69 real2(0.30882353, 0.17647076),
70 real2(0.33823529, 0.79411745),
71 real2(0.36764705, 0.41176462),
72 real2(0.39705881, 0.02941132),
73 real2(0.42647058, 0.64705849),
74 real2(0.45588234, 0.26470566),
75 real2(0.48529410, 0.88235283),
76 real2(0.51470590, 0.50000000),
77 real2(0.54411763, 0.11764717),
78 real2(0.57352942, 0.73529434),
79 real2(0.60294116, 0.35294151),
80 real2(0.63235295, 0.97058773),
81 real2(0.66176468, 0.58823490),
82 real2(0.69117647, 0.20588207),
83 real2(0.72058821, 0.82352924),
84 real2(0.75000000, 0.44117641),
85 real2(0.77941179, 0.05882263),
86 real2(0.80882353, 0.67646980),
87 real2(0.83823532, 0.29411697),
88 real2(0.86764705, 0.91176414),
89 real2(0.89705884, 0.52941132),
90 real2(0.92647058, 0.14705849),
91 real2(0.95588237, 0.76470566),
92 real2(0.98529410, 0.38235283)
93};
94
95static const real2 k_Fibonacci2dSeq55[] = {
96 real2(0.00909091, 0.00000000),
97 real2(0.02727273, 0.61818182),
98 real2(0.04545455, 0.23636365),
99 real2(0.06363636, 0.85454547),
100 real2(0.08181818, 0.47272730),
101 real2(0.10000000, 0.09090900),
102 real2(0.11818182, 0.70909095),
103 real2(0.13636364, 0.32727289),
104 real2(0.15454546, 0.94545460),
105 real2(0.17272727, 0.56363630),
106 real2(0.19090909, 0.18181801),
107 real2(0.20909090, 0.80000019),
108 real2(0.22727273, 0.41818190),
109 real2(0.24545455, 0.03636360),
110 real2(0.26363635, 0.65454578),
111 real2(0.28181818, 0.27272701),
112 real2(0.30000001, 0.89090919),
113 real2(0.31818181, 0.50909138),
114 real2(0.33636364, 0.12727261),
115 real2(0.35454544, 0.74545479),
116 real2(0.37272727, 0.36363602),
117 real2(0.39090911, 0.98181820),
118 real2(0.40909091, 0.60000038),
119 real2(0.42727274, 0.21818161),
120 real2(0.44545454, 0.83636379),
121 real2(0.46363637, 0.45454597),
122 real2(0.48181817, 0.07272720),
123 real2(0.50000000, 0.69090843),
124 real2(0.51818180, 0.30909157),
125 real2(0.53636366, 0.92727280),
126 real2(0.55454546, 0.54545403),
127 real2(0.57272726, 0.16363716),
128 real2(0.59090906, 0.78181839),
129 real2(0.60909092, 0.39999962),
130 real2(0.62727273, 0.01818275),
131 real2(0.64545453, 0.63636398),
132 real2(0.66363639, 0.25454521),
133 real2(0.68181819, 0.87272835),
134 real2(0.69999999, 0.49090958),
135 real2(0.71818179, 0.10909081),
136 real2(0.73636365, 0.72727203),
137 real2(0.75454545, 0.34545517),
138 real2(0.77272725, 0.96363640),
139 real2(0.79090911, 0.58181763),
140 real2(0.80909091, 0.20000076),
141 real2(0.82727271, 0.81818199),
142 real2(0.84545457, 0.43636322),
143 real2(0.86363637, 0.05454636),
144 real2(0.88181818, 0.67272758),
145 real2(0.89999998, 0.29090881),
146 real2(0.91818184, 0.90909195),
147 real2(0.93636364, 0.52727318),
148 real2(0.95454544, 0.14545441),
149 real2(0.97272730, 0.76363754),
150 real2(0.99090910, 0.38181686)
151};
152
153static const real2 k_Fibonacci2dSeq89[] = {
154 real2(0.00561798, 0.00000000),
155 real2(0.01685393, 0.61797750),
156 real2(0.02808989, 0.23595500),
157 real2(0.03932584, 0.85393250),
158 real2(0.05056180, 0.47191000),
159 real2(0.06179775, 0.08988762),
160 real2(0.07303371, 0.70786500),
161 real2(0.08426967, 0.32584238),
162 real2(0.09550562, 0.94382000),
163 real2(0.10674157, 0.56179762),
164 real2(0.11797753, 0.17977524),
165 real2(0.12921348, 0.79775238),
166 real2(0.14044943, 0.41573000),
167 real2(0.15168539, 0.03370762),
168 real2(0.16292135, 0.65168476),
169 real2(0.17415731, 0.26966286),
170 real2(0.18539326, 0.88764000),
171 real2(0.19662921, 0.50561714),
172 real2(0.20786516, 0.12359524),
173 real2(0.21910113, 0.74157238),
174 real2(0.23033708, 0.35955048),
175 real2(0.24157304, 0.97752762),
176 real2(0.25280899, 0.59550476),
177 real2(0.26404494, 0.21348286),
178 real2(0.27528089, 0.83146000),
179 real2(0.28651685, 0.44943714),
180 real2(0.29775280, 0.06741524),
181 real2(0.30898875, 0.68539238),
182 real2(0.32022473, 0.30336952),
183 real2(0.33146068, 0.92134666),
184 real2(0.34269664, 0.53932571),
185 real2(0.35393259, 0.15730286),
186 real2(0.36516854, 0.77528000),
187 real2(0.37640449, 0.39325714),
188 real2(0.38764045, 0.01123428),
189 real2(0.39887640, 0.62921333),
190 real2(0.41011235, 0.24719048),
191 real2(0.42134830, 0.86516762),
192 real2(0.43258426, 0.48314476),
193 real2(0.44382024, 0.10112190),
194 real2(0.45505619, 0.71910095),
195 real2(0.46629214, 0.33707809),
196 real2(0.47752810, 0.95505524),
197 real2(0.48876405, 0.57303238),
198 real2(0.50000000, 0.19100952),
199 real2(0.51123595, 0.80898666),
200 real2(0.52247190, 0.42696571),
201 real2(0.53370786, 0.04494286),
202 real2(0.54494381, 0.66292000),
203 real2(0.55617976, 0.28089714),
204 real2(0.56741571, 0.89887428),
205 real2(0.57865167, 0.51685333),
206 real2(0.58988762, 0.13483047),
207 real2(0.60112357, 0.75280762),
208 real2(0.61235952, 0.37078476),
209 real2(0.62359548, 0.98876190),
210 real2(0.63483149, 0.60673904),
211 real2(0.64606744, 0.22471619),
212 real2(0.65730339, 0.84269333),
213 real2(0.66853935, 0.46067429),
214 real2(0.67977530, 0.07865143),
215 real2(0.69101125, 0.69662857),
216 real2(0.70224720, 0.31460571),
217 real2(0.71348315, 0.93258286),
218 real2(0.72471911, 0.55056000),
219 real2(0.73595506, 0.16853714),
220 real2(0.74719101, 0.78651428),
221 real2(0.75842696, 0.40449142),
222 real2(0.76966292, 0.02246857),
223 real2(0.78089887, 0.64044571),
224 real2(0.79213482, 0.25842667),
225 real2(0.80337077, 0.87640381),
226 real2(0.81460673, 0.49438095),
227 real2(0.82584268, 0.11235809),
228 real2(0.83707863, 0.73033524),
229 real2(0.84831458, 0.34831238),
230 real2(0.85955054, 0.96628952),
231 real2(0.87078649, 0.58426666),
232 real2(0.88202250, 0.20224380),
233 real2(0.89325845, 0.82022095),
234 real2(0.90449440, 0.43820190),
235 real2(0.91573036, 0.05617905),
236 real2(0.92696631, 0.67415619),
237 real2(0.93820226, 0.29213333),
238 real2(0.94943821, 0.91011047),
239 real2(0.96067417, 0.52808762),
240 real2(0.97191012, 0.14606476),
241 real2(0.98314607, 0.76404190),
242 real2(0.99438202, 0.38201904)
243};
244
245// Loads elements from one of the precomputed tables for sample counts of 21, 34, 55, and 89.
246// Computes sample positions at runtime otherwise.
247// Sample count must be a Fibonacci number (see 'k_FibonacciSeq').
248real2 Fibonacci2d(uint i, uint sampleCount)
249{
250 switch (sampleCount)
251 {
252 case 21: return k_Fibonacci2dSeq21[i];
253 case 34: return k_Fibonacci2dSeq34[i];
254 case 55: return k_Fibonacci2dSeq55[i];
255 case 89: return k_Fibonacci2dSeq89[i];
256 default:
257 {
258 uint fibN1 = sampleCount;
259 uint fibN2 = sampleCount;
260
261 // These are all constants, so this loop will be optimized away.
262 for (uint j = 1; j < 20; j++)
263 {
264 if (k_FibonacciSeq[j] == fibN1)
265 {
266 fibN2 = k_FibonacciSeq[j - 1];
267 }
268 }
269
270 return Fibonacci2dSeq(fibN1, fibN2, i);
271 }
272 }
273}
274
275real2 SampleDiskGolden(uint i, uint sampleCount)
276{
277 real2 f = Golden2dSeq(i, sampleCount);
278 return real2(sqrt(f.x), TWO_PI * f.y);
279}
280
281// Returns the radius as the X coordinate, and the angle as the Y coordinate.
282real2 SampleDiskFibonacci(uint i, uint sampleCount)
283{
284 real2 f = Fibonacci2d(i, sampleCount);
285 return real2(sqrt(f.x), TWO_PI * f.y);
286}
287
288// Returns the zenith as the X coordinate, and the azimuthal angle as the Y coordinate.
289real2 SampleHemisphereFibonacci(uint i, uint sampleCount)
290{
291 real2 f = Fibonacci2d(i, sampleCount);
292 return real2(1 - f.x, TWO_PI * f.y);
293}
294
295// Returns the zenith as the X coordinate, and the azimuthal angle as the Y coordinate.
296real2 SampleSphereFibonacci(uint i, uint sampleCount)
297{
298 real2 f = Fibonacci2d(i, sampleCount);
299 return real2(1 - 2 * f.x, TWO_PI * f.y);
300}
301
302#if SHADER_API_MOBILE || SHADER_API_GLES3 || SHADER_API_SWITCH
303#pragma warning (enable : 3205) // conversion of larger type to smaller
304#endif
305
306#endif // UNITY_FIBONACCI_INCLUDED