-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathray.cu
124 lines (100 loc) · 4.95 KB
/
ray.cu
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "cuda_path_tracer/camera.cuh"
#include "cuda_path_tracer/ray.cuh"
#include "cuda_path_tracer/vec3.cuh"
__host__ __device__ Ray::Ray() : origin(0), direction(0) {};
__host__ __device__ Ray::Ray(const Vec3 &origin, const Vec3 &direction)
: origin(origin), direction(direction) {};
__host__ __device__ auto Ray::getOrigin() const -> Vec3 { return origin; }
__host__ __device__ auto Ray::getDirection() const -> Vec3 { return direction; }
__host__ __device__ auto Ray::at(const float t) const -> Vec3 {
return origin + direction * t;
}
__device__ auto getRay(const Vec3 &origin, const Vec3 &pixel00,
const Vec3 &deltaU, const Vec3 &deltaV,
const Vec3 &defocusDiskU, const Vec3 &defocusDiskV,
const float defocusAngle, const uint16_t x,
const uint16_t y, curandState_t &state) -> Ray {
const auto a = curand_uniform(&state);
const auto b = curand_uniform(&state);
// We sample an area of "half pixel" around the pixel centers to achieve
// anti-aliasing. This helps in reducing the jagged edges by averaging the
// colors of multiple samples within each pixel, resulting in smoother
// transitions and more realistic images.
const auto offset = Vec3{a - 0.5F, b - 0.5F, 0};
const auto sample = pixel00 + ((static_cast<float>(x) + offset.x) * deltaU) +
((static_cast<float>(y) + offset.y) * deltaV);
auto newOrigin = origin;
if (defocusAngle > 0) {
newOrigin = defocusDiskSample(state, origin, defocusDiskU, defocusDiskV);
}
const auto direction = sample - newOrigin;
return {newOrigin, direction};
}
__device__ auto get2Rays(const Vec3 &origin, const Vec3 &pixel00,
const Vec3 &deltaU, const Vec3 &deltaV,
const Vec3 &defocusDiskU, const Vec3 &defocusDiskV,
const float defocusAngle, const uint16_t x,
const uint16_t y, curandStatePhilox4_32_10_t &state)
-> cuda::std::tuple<Ray, Ray> {
const auto values = curand_uniform4(&state);
const auto offsetA = Vec3{values.z - 0.5F, values.w - 0.5F, 0};
const auto offsetB = Vec3{values.x - 0.5F, values.y - 0.5F, 0};
const auto sampleA = pixel00 +
((static_cast<float>(x) + offsetA.x) * deltaU) +
((static_cast<float>(y) + offsetA.y) * deltaV);
const auto sampleB = pixel00 +
((static_cast<float>(x) + offsetB.x) * deltaU) +
((static_cast<float>(y) + offsetB.y) * deltaV);
auto newOriginA = origin;
auto newOriginB = origin;
if (defocusAngle > 0) {
newOriginA = defocusDiskSample(state, origin, defocusDiskU, defocusDiskV);
newOriginB = defocusDiskSample(state, origin, defocusDiskU, defocusDiskV);
}
const auto directionA = sampleA - newOriginA;
const auto directionB = sampleB - newOriginB;
return {{newOriginA, directionA}, {newOriginB, directionB}};
}
__device__ auto get4Rays(const Vec3 &origin, const Vec3 &pixel00,
const Vec3 &deltaU, const Vec3 &deltaV,
const Vec3 &defocusDiskU, const Vec3 &defocusDiskV,
const float defocusAngle, const uint16_t x,
const uint16_t y, curandStatePhilox4_32_10_t &state)
-> cuda::std::tuple<Ray, Ray, Ray, Ray> {
const auto values1 = curand_uniform4(&state);
const auto values2 = curand_uniform4(&state);
const auto offsetA = Vec3{values1.z - 0.5F, values1.w - 0.5F, 0};
const auto offsetB = Vec3{values1.x - 0.5F, values1.y - 0.5F, 0};
const auto offsetC = Vec3{values2.z - 0.5F, values2.w - 0.5F, 0};
const auto offsetD = Vec3{values2.x - 0.5F, values2.y - 0.5F, 0};
const auto sampleA = pixel00 +
((static_cast<float>(x) + offsetA.x) * deltaU) +
((static_cast<float>(y) + offsetA.y) * deltaV);
const auto sampleB = pixel00 +
((static_cast<float>(x) + offsetB.x) * deltaU) +
((static_cast<float>(y) + offsetB.y) * deltaV);
const auto sampleC = pixel00 +
((static_cast<float>(x) + offsetC.x) * deltaU) +
((static_cast<float>(y) + offsetC.y) * deltaV);
const auto sampleD = pixel00 +
((static_cast<float>(x) + offsetD.x) * deltaU) +
((static_cast<float>(y) + offsetD.y) * deltaV);
auto newOriginA = origin;
auto newOriginB = origin;
auto newOriginC = origin;
auto newOriginD = origin;
if (defocusAngle > 0) {
const auto [s1, s2, s3, s4] =
defocusDisk4Samples(state, origin, defocusDiskU, defocusDiskV);
newOriginA = s1;
newOriginB = s2;
newOriginC = s3;
newOriginD = s4;
}
const auto directionA = sampleA - newOriginA;
const auto directionB = sampleB - newOriginB;
return {{newOriginA, directionA},
{newOriginB, directionB},
{newOriginC, sampleC - newOriginC},
{newOriginD, sampleD - newOriginD}};
}