Skip to content

Commit 526e877

Browse files
authored
Merge pull request CIS565-Fall-2021#3 from shineyruan/dev
Finished Physically-based Depth of Field
2 parents b7b5e47 + b9835e9 commit 526e877

File tree

7 files changed

+280
-1
lines changed

7 files changed

+280
-1
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Finished path tracing core features:
2121
Finished Advanced Features:
2222
- Refraction with Fresnel effects using Schlick's approximation
2323
- Stochastic sampled anti-aliasing
24+
- Physically-based depth of field
2425

2526
### Ray Refraction for Glass-like Materials
2627
| Perfect Specular Reflection | Glass-like Refraction |
@@ -32,3 +33,8 @@ Finished Advanced Features:
3233
| :-------------------------------------------------------------: | :-------------------------------------------------------------: |
3334
| ![](img/cornell.2021-10-04_01-14-01z.5000samp-antialias-1x.png) | ![](img/cornell.2021-10-04_01-07-24z.5000samp-antialias-4x.png) |
3435

36+
### Physically-Based Depth of Field
37+
| Pinhole Camera Model (Feature OFF) | Thin-Lens Camera Model |
38+
| :------------------------------------------------: | :------------------------------------------------: |
39+
| ![](img/cornell.2021-10-05_02-45-59z.5000samp.png) | ![](img/cornell.2021-10-05_02-40-08z.5000samp.png) |
40+
1.56 MB
Loading
1.26 MB
Loading

scenes/cornell_DOF.txt

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
// Emissive material (light)
2+
MATERIAL 0
3+
RGB 1 1 1
4+
SPECEX 0
5+
SPECRGB 0 0 0
6+
REFL 0
7+
REFR 0
8+
REFRIOR 0
9+
EMITTANCE 8
10+
11+
// Diffuse white
12+
MATERIAL 1
13+
RGB .98 .98 .98
14+
SPECEX 0
15+
SPECRGB 0 0 0
16+
REFL 0
17+
REFR 0
18+
REFRIOR 0
19+
EMITTANCE 0
20+
21+
// Diffuse red
22+
MATERIAL 2
23+
RGB .85 .35 .35
24+
SPECEX 0
25+
SPECRGB 0 0 0
26+
REFL 0
27+
REFR 0
28+
REFRIOR 0
29+
EMITTANCE 0
30+
31+
// Diffuse green
32+
MATERIAL 3
33+
RGB .35 .85 .35
34+
SPECEX 0
35+
SPECRGB 0 0 0
36+
REFL 0
37+
REFR 0
38+
REFRIOR 0
39+
EMITTANCE 0
40+
41+
// Specular white
42+
MATERIAL 4
43+
RGB .98 .98 .98
44+
SPECEX 0
45+
SPECRGB .98 .98 .98
46+
REFL 1
47+
REFR 0
48+
REFRIOR 0
49+
EMITTANCE 0
50+
51+
// Half-Specular white
52+
MATERIAL 5
53+
RGB .98 .98 .98
54+
SPECEX 0
55+
SPECRGB .98 .98 .98
56+
REFL 0.5
57+
REFR 0
58+
REFRIOR 0
59+
EMITTANCE 0
60+
61+
// Specular blue
62+
MATERIAL 6
63+
RGB .35 .35 .85
64+
SPECEX 0
65+
SPECRGB .35 .35 .85
66+
REFL 1
67+
REFR 0
68+
REFRIOR 0
69+
EMITTANCE 0
70+
71+
// Half-Specular green
72+
MATERIAL 7
73+
RGB .35 .85 .35
74+
SPECEX 0
75+
SPECRGB .98 .98 .98
76+
REFL 0.5
77+
REFR 0
78+
REFRIOR 0
79+
EMITTANCE 0
80+
81+
// glass yellow
82+
MATERIAL 8
83+
RGB .90 .90 .10
84+
SPECEX 0
85+
SPECRGB .90 .90 .10
86+
REFL 0
87+
REFR 1
88+
REFRIOR 1.5
89+
EMITTANCE 0
90+
91+
// Camera
92+
CAMERA
93+
RES 800 800
94+
FOVY 45
95+
ITERATIONS 5000
96+
DEPTH 8
97+
FILE cornell
98+
FOCALDIST 3
99+
LENRADIUS 0.1
100+
EYE 0 5 3.5
101+
LOOKAT -1 4 0.5
102+
UP 0 1 0
103+
104+
105+
// Ceiling light
106+
OBJECT 0
107+
cube
108+
material 0
109+
TRANS 0 10 0
110+
ROTAT 0 0 0
111+
SCALE 3 .3 3
112+
113+
// Floor
114+
OBJECT 1
115+
cube
116+
material 1
117+
TRANS 0 0 0
118+
ROTAT 0 0 0
119+
SCALE 10 .01 10
120+
121+
// Ceiling
122+
OBJECT 2
123+
cube
124+
material 1
125+
TRANS 0 10 0
126+
ROTAT 0 0 90
127+
SCALE .01 10 10
128+
129+
// Back wall
130+
OBJECT 3
131+
cube
132+
material 1
133+
TRANS 0 5 -5
134+
ROTAT 0 90 0
135+
SCALE .01 10 10
136+
137+
// Left wall
138+
OBJECT 4
139+
cube
140+
material 2
141+
TRANS -5 5 0
142+
ROTAT 0 0 0
143+
SCALE .01 10 10
144+
145+
// Right wall
146+
OBJECT 5
147+
cube
148+
material 3
149+
TRANS 5 5 0
150+
ROTAT 0 0 0
151+
SCALE .01 10 10
152+
153+
// Sphere
154+
OBJECT 6
155+
sphere
156+
material 4
157+
TRANS -1 4 -1
158+
ROTAT 0 0 0
159+
SCALE 1 1 1
160+
161+
// Sphere
162+
OBJECT 7
163+
sphere
164+
material 5
165+
TRANS -1 4 0
166+
ROTAT 0 0 0
167+
SCALE 1 1 1
168+
169+
// Sphere
170+
OBJECT 8
171+
sphere
172+
material 6
173+
TRANS -1 4 1
174+
ROTAT 0 0 0
175+
SCALE 1 1 1
176+
177+
// Sphere
178+
OBJECT 9
179+
sphere
180+
material 7
181+
TRANS -1 4 2
182+
ROTAT 0 0 0
183+
SCALE 1 1 1
184+
185+
// Sphere
186+
OBJECT 10
187+
sphere
188+
material 8
189+
TRANS -1 4 3
190+
ROTAT 0 0 0
191+
SCALE 1 1 1

src/pathtrace.cu

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <cstdio>
1010

1111
#include "glm/glm.hpp"
12+
#include "glm/gtc/matrix_transform.hpp"
1213
#include "glm/gtx/norm.hpp"
1314
#include "interactions.h"
1415
#include "intersections.h"
@@ -149,6 +150,72 @@ void pathtraceFree() {
149150
checkCUDAError("pathtraceFree");
150151
}
151152

153+
#ifdef DEPTH_OF_FIELD
154+
/**
155+
* Given a sampled point at [-1,1]x[-1,1], uniformly map to some values on disk
156+
* in concentric style
157+
*
158+
* @return (x,y) point on a unit disk
159+
*/
160+
__device__ glm::vec2 concentricSampleDisk(const glm::vec2 &u) {
161+
// Map uniform random numbers to [-1, 1]x[-1, 1]
162+
glm::vec2 offset = 2.f * u - glm::vec2(1, 1);
163+
164+
// Handle degeneracy at the origin
165+
if (offset.x == 0 && offset.y == 0) return glm::vec2(0, 0);
166+
167+
// Apply concentric mapping to point
168+
float theta, r;
169+
if (std::abs(offset.x) > std::abs(offset.y)) {
170+
r = offset.x;
171+
theta = PI_4 * (offset.y / offset.x);
172+
} else {
173+
r = offset.y;
174+
theta = PI_2 - PI_4 * (offset.x / offset.y);
175+
}
176+
return r * glm::vec2(std::cos(theta), std::sin(theta));
177+
}
178+
179+
/**
180+
* Updates the origin & direction of each generated ray based on thin-lens
181+
* camera model Reference:
182+
* https://www.pbr-book.org/3ed-2018/Camera_Models/Projective_Camera_Models
183+
*
184+
* @return Ray& ray
185+
*/
186+
__device__ void updateRayOnLens(Camera cam, int iter, int ray_index, int depth,
187+
Ray &ray) {
188+
glm::mat4 view_mat = glm::lookAt(cam.position, cam.lookAt, cam.up);
189+
glm::mat4 view_mat_inverse = glm::inverse(view_mat);
190+
191+
// 1. sample point on len disk
192+
thrust::default_random_engine rng =
193+
makeSeededRandomEngine(iter, ray_index, depth);
194+
thrust::uniform_real_distribution<float> u01(0, 1);
195+
glm::vec3 pt_on_lens =
196+
cam.lensRadius *
197+
glm::vec3(concentricSampleDisk(glm::vec2(u01(rng), u01(rng))), 0.0f);
198+
199+
// 2. compute intersection of pinhole ray with plane of focus (in camera local
200+
// coordinates)
201+
glm::vec3 origin_local = glm::vec3(view_mat * glm::vec4(ray.origin, 1.0f));
202+
glm::vec3 dir_local = glm::vec3(view_mat * glm::vec4(ray.direction, 0.0f));
203+
float ft = glm::abs(cam.focalDistance / dir_local.z);
204+
glm::vec3 pt_on_focus_local = origin_local + ft * dir_local;
205+
glm::vec3 pt_on_focus =
206+
glm::vec3(view_mat_inverse * glm::vec4(pt_on_focus_local, 1.0f));
207+
208+
// 3. update ray's origin & direction on point
209+
glm::vec3 origin_new =
210+
glm::vec3(view_mat_inverse * glm::vec4(pt_on_lens, 1.0f));
211+
glm::vec3 dir_new = glm::normalize(pt_on_focus - origin_new);
212+
213+
// 4. return
214+
ray.origin = origin_new;
215+
ray.direction = dir_new;
216+
}
217+
#endif
218+
152219
/**
153220
* Generate PathSegments with rays from the camera through the screen into the
154221
* scene, which is the first bounce of rays.
@@ -177,6 +244,11 @@ __global__ void generateRayFromCamera(Camera cam, int iter, int traceDepth,
177244
((float)x - (float)cam.resolution.x * 0.5f) -
178245
cam.up * cam.pixelLength.y *
179246
((float)y - (float)cam.resolution.y * 0.5f));
247+
#ifdef DEPTH_OF_FIELD
248+
if (cam.lensRadius > 0) {
249+
updateRayOnLens(cam, iter, index, INT_MAX, segment.ray);
250+
}
251+
#endif
180252

181253
// implement antialiasing by jittering the ray
182254
// sub-sampled extra rays per pixel
@@ -196,6 +268,11 @@ __global__ void generateRayFromCamera(Camera cam, int iter, int traceDepth,
196268
((float)x + u01(rng) - (float)cam.resolution.x * 0.5f) -
197269
cam.up * cam.pixelLength.y *
198270
((float)y + u01(rng) - (float)cam.resolution.y * 0.5f));
271+
#ifdef DEPTH_OF_FIELD
272+
if (cam.lensRadius > 0) {
273+
updateRayOnLens(cam, iter, index, i, extra_segment.ray);
274+
}
275+
#endif
199276
}
200277
}
201278
}

src/static_config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <device_launch_parameters.h>
66

77
#define CACHE_INTERSECTIONS
8-
#define DEPTH_OF_FIELD
8+
// #define DEPTH_OF_FIELD
99
#define EPS 0.0001f
1010
#define ANTIALIAS_FACTOR 4
1111

src/utilities.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010

1111
#include "glm/glm.hpp"
1212

13+
// reference:
14+
// https://www.pbr-book.org/3ed-2018/Utilities/Main_Include_File.html#PiOver4
15+
#define PI_2 1.57079632679489661923f
16+
#define PI_4 0.78539816339744830961f
17+
1318
#define PI 3.1415926535897932384626422832795028841971f
1419
#define TWO_PI 6.2831853071795864769252867665590057683943f
1520
#define SQRT_OF_ONE_THIRD 0.5773502691896257645091487805019574556476f

0 commit comments

Comments
 (0)