Fibonacci.hlsl 9.7 KB

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