-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRandom.hpp
103 lines (89 loc) · 1.86 KB
/
Random.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#ifndef GPU_RAY_TRACING_RANDOM_HPP_
#define GPU_RAY_TRACING_RANDOM_HPP_
#include "Preprocessor.hpp"
#include "constants.hpp"
#include "types.hpp"
#include <glm/geometric.hpp>
using RandomState = void*;
#include <random>
using RandomStateCPU = std::mt19937;
#ifdef USE_GPU
#include <curand.h>
#include <curand_kernel.h>
using RandomStateGPU = curandState;
#endif
__host__ __device__
static
inline
num
get_next_rand(RandomState* s) {
#if defined(__CUDA_ARCH__) && defined(__CUDACC__)
return curand_uniform (reinterpret_cast<RandomStateGPU*>(s));
#else
thread_local std::uniform_real_distribution<num> dist{CONST(0.0), CONST(1.0)};
return dist (*reinterpret_cast<RandomStateCPU*>(s));
#endif
}
__host__ __device__
inline
num
random_positive_unit (RandomState* s)
{
return get_next_rand(s);
}
__host__ __device__
inline
num
random_unit (RandomState* s)
{
return get_next_rand(s) * CONST(2.0) - CONST(1.0);
}
__host__ __device__
inline
num
random_angle (RandomState* s)
{
return get_next_rand(s) * (CONST(2.0) * pi);
}
__host__ __device__
inline
int
random_int (RandomState* s, int low, int high)
{
return static_cast<int> (random_positive_unit (s) * (high - low) + low);
}
__host__ __device__
inline
vec3
random_unit_vector (RandomState* s)
{
num a = random_angle (s);
num z = random_unit (s);
num r = sqrtf (CONST (1.0) - z * z);
return vec3 (r * cosf (a), r * sinf (a), z);
}
__host__ __device__
inline
vec3
random_in_unit_sphere (RandomState* s)
{
while (true)
{
vec3 p {random_unit (s), random_unit (s), random_unit (s)};
if (glm::dot (p, p) >= 1)
continue;
return p;
}
}
__host__ __device__
inline
vec3
random_in_hemisphere (RandomState* s, const vec3 &normal)
{
vec3 in_unit_sphere = random_unit_vector (s);
if (glm::dot (in_unit_sphere, normal) > 0.0)
return in_unit_sphere;
else
return -in_unit_sphere;
}
#endif