kernel_random.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * Copyright 2011-2013 Blender Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "kernel/kernel_jitter.h"
  17. #include "util/util_hash.h"
  18. CCL_NAMESPACE_BEGIN
  19. /* Pseudo random numbers, uncomment this for debugging correlations. Only run
  20. * this single threaded on a CPU for repeatable results. */
  21. //#define __DEBUG_CORRELATION__
  22. /* High Dimensional Sobol.
  23. *
  24. * Multidimensional sobol with generator matrices. Dimension 0 and 1 are equal
  25. * to classic Van der Corput and Sobol sequences. */
  26. #ifdef __SOBOL__
  27. /* Skip initial numbers that for some dimensions have clear patterns that
  28. * don't cover the entire sample space. Ideally we would have a better
  29. * progressive pattern that doesn't suffer from this problem, because even
  30. * with this offset some dimensions are quite poor.
  31. */
  32. # define SOBOL_SKIP 64
  33. ccl_device uint sobol_dimension(KernelGlobals *kg, int index, int dimension)
  34. {
  35. uint result = 0;
  36. uint i = index + SOBOL_SKIP;
  37. for (uint j = 0; i; i >>= 1, j++) {
  38. if (i & 1) {
  39. result ^= kernel_tex_fetch(__sobol_directions, 32 * dimension + j);
  40. }
  41. }
  42. return result;
  43. }
  44. #endif /* __SOBOL__ */
  45. ccl_device_forceinline float path_rng_1D(
  46. KernelGlobals *kg, uint rng_hash, int sample, int num_samples, int dimension)
  47. {
  48. #ifdef __DEBUG_CORRELATION__
  49. return (float)drand48();
  50. #endif
  51. #ifdef __CMJ__
  52. # ifdef __SOBOL__
  53. if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ)
  54. # endif
  55. {
  56. /* Correlated multi-jitter. */
  57. int p = rng_hash + dimension;
  58. return cmj_sample_1D(sample, num_samples, p);
  59. }
  60. #endif
  61. #ifdef __SOBOL__
  62. /* Sobol sequence value using direction vectors. */
  63. uint result = sobol_dimension(kg, sample, dimension);
  64. float r = (float)result * (1.0f / (float)0xFFFFFFFF);
  65. /* Cranly-Patterson rotation using rng seed */
  66. float shift;
  67. /* Hash rng with dimension to solve correlation issues.
  68. * See T38710, T50116.
  69. */
  70. uint tmp_rng = cmj_hash_simple(dimension, rng_hash);
  71. shift = tmp_rng * (1.0f / (float)0xFFFFFFFF);
  72. return r + shift - floorf(r + shift);
  73. #endif
  74. }
  75. ccl_device_forceinline void path_rng_2D(KernelGlobals *kg,
  76. uint rng_hash,
  77. int sample,
  78. int num_samples,
  79. int dimension,
  80. float *fx,
  81. float *fy)
  82. {
  83. #ifdef __DEBUG_CORRELATION__
  84. *fx = (float)drand48();
  85. *fy = (float)drand48();
  86. return;
  87. #endif
  88. #ifdef __CMJ__
  89. # ifdef __SOBOL__
  90. if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ)
  91. # endif
  92. {
  93. /* Correlated multi-jitter. */
  94. int p = rng_hash + dimension;
  95. cmj_sample_2D(sample, num_samples, p, fx, fy);
  96. return;
  97. }
  98. #endif
  99. #ifdef __SOBOL__
  100. /* Sobol. */
  101. *fx = path_rng_1D(kg, rng_hash, sample, num_samples, dimension);
  102. *fy = path_rng_1D(kg, rng_hash, sample, num_samples, dimension + 1);
  103. #endif
  104. }
  105. ccl_device_inline void path_rng_init(KernelGlobals *kg,
  106. int sample,
  107. int num_samples,
  108. uint *rng_hash,
  109. int x,
  110. int y,
  111. float *fx,
  112. float *fy)
  113. {
  114. /* load state */
  115. *rng_hash = hash_int_2d(x, y);
  116. *rng_hash ^= kernel_data.integrator.seed;
  117. #ifdef __DEBUG_CORRELATION__
  118. srand48(*rng_hash + sample);
  119. #endif
  120. if (sample == 0) {
  121. *fx = 0.5f;
  122. *fy = 0.5f;
  123. }
  124. else {
  125. path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_FILTER_U, fx, fy);
  126. }
  127. }
  128. /* Linear Congruential Generator */
  129. ccl_device uint lcg_step_uint(uint *rng)
  130. {
  131. /* implicit mod 2^32 */
  132. *rng = (1103515245 * (*rng) + 12345);
  133. return *rng;
  134. }
  135. ccl_device float lcg_step_float(uint *rng)
  136. {
  137. /* implicit mod 2^32 */
  138. *rng = (1103515245 * (*rng) + 12345);
  139. return (float)*rng * (1.0f / (float)0xFFFFFFFF);
  140. }
  141. ccl_device uint lcg_init(uint seed)
  142. {
  143. uint rng = seed;
  144. lcg_step_uint(&rng);
  145. return rng;
  146. }
  147. /* Path Tracing Utility Functions
  148. *
  149. * For each random number in each step of the path we must have a unique
  150. * dimension to avoid using the same sequence twice.
  151. *
  152. * For branches in the path we must be careful not to reuse the same number
  153. * in a sequence and offset accordingly.
  154. */
  155. ccl_device_inline float path_state_rng_1D(KernelGlobals *kg,
  156. const ccl_addr_space PathState *state,
  157. int dimension)
  158. {
  159. return path_rng_1D(
  160. kg, state->rng_hash, state->sample, state->num_samples, state->rng_offset + dimension);
  161. }
  162. ccl_device_inline void path_state_rng_2D(
  163. KernelGlobals *kg, const ccl_addr_space PathState *state, int dimension, float *fx, float *fy)
  164. {
  165. path_rng_2D(kg,
  166. state->rng_hash,
  167. state->sample,
  168. state->num_samples,
  169. state->rng_offset + dimension,
  170. fx,
  171. fy);
  172. }
  173. ccl_device_inline float path_state_rng_1D_hash(KernelGlobals *kg,
  174. const ccl_addr_space PathState *state,
  175. uint hash)
  176. {
  177. /* Use a hash instead of dimension, this is not great but avoids adding
  178. * more dimensions to each bounce which reduces quality of dimensions we
  179. * are already using. */
  180. return path_rng_1D(kg,
  181. cmj_hash_simple(state->rng_hash, hash),
  182. state->sample,
  183. state->num_samples,
  184. state->rng_offset);
  185. }
  186. ccl_device_inline float path_branched_rng_1D(KernelGlobals *kg,
  187. uint rng_hash,
  188. const ccl_addr_space PathState *state,
  189. int branch,
  190. int num_branches,
  191. int dimension)
  192. {
  193. return path_rng_1D(kg,
  194. rng_hash,
  195. state->sample * num_branches + branch,
  196. state->num_samples * num_branches,
  197. state->rng_offset + dimension);
  198. }
  199. ccl_device_inline void path_branched_rng_2D(KernelGlobals *kg,
  200. uint rng_hash,
  201. const ccl_addr_space PathState *state,
  202. int branch,
  203. int num_branches,
  204. int dimension,
  205. float *fx,
  206. float *fy)
  207. {
  208. path_rng_2D(kg,
  209. rng_hash,
  210. state->sample * num_branches + branch,
  211. state->num_samples * num_branches,
  212. state->rng_offset + dimension,
  213. fx,
  214. fy);
  215. }
  216. /* Utility functions to get light termination value,
  217. * since it might not be needed in many cases.
  218. */
  219. ccl_device_inline float path_state_rng_light_termination(KernelGlobals *kg,
  220. const ccl_addr_space PathState *state)
  221. {
  222. if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
  223. return path_state_rng_1D(kg, state, PRNG_LIGHT_TERMINATE);
  224. }
  225. return 0.0f;
  226. }
  227. ccl_device_inline float path_branched_rng_light_termination(KernelGlobals *kg,
  228. uint rng_hash,
  229. const ccl_addr_space PathState *state,
  230. int branch,
  231. int num_branches)
  232. {
  233. if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
  234. return path_branched_rng_1D(kg, rng_hash, state, branch, num_branches, PRNG_LIGHT_TERMINATE);
  235. }
  236. return 0.0f;
  237. }
  238. ccl_device_inline uint lcg_state_init(PathState *state, uint scramble)
  239. {
  240. return lcg_init(state->rng_hash + state->rng_offset + state->sample * scramble);
  241. }
  242. ccl_device_inline uint lcg_state_init_addrspace(ccl_addr_space PathState *state, uint scramble)
  243. {
  244. return lcg_init(state->rng_hash + state->rng_offset + state->sample * scramble);
  245. }
  246. ccl_device float lcg_step_float_addrspace(ccl_addr_space uint *rng)
  247. {
  248. /* Implicit mod 2^32 */
  249. *rng = (1103515245 * (*rng) + 12345);
  250. return (float)*rng * (1.0f / (float)0xFFFFFFFF);
  251. }
  252. CCL_NAMESPACE_END