Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Courses
Scotty3D
Commits
c2535f0f
Commit
c2535f0f
authored
Sep 26, 2020
by
TheNumbat
Browse files
upstream changes
parent
8b8ee1f1
Changes
93
Show whitespace changes
Inline
Side-by-side
src/student/samplers.cpp
View file @
c2535f0f
#include "debug.h"
#include "../util/rand.h"
#include "../rays/samplers.h"
#include "../util/rand.h"
#include "debug.h"
namespace
Samplers
{
Vec2
Rect
::
Uniform
::
sample
(
float
&
pdf
)
const
{
Vec2
Rect
::
Uniform
::
sample
(
float
&
pdf
)
const
{
// TODO (PathTracer): Task 1
// Generate a uniformly random point on a rectangle of size size.x * size.y
...
...
@@ -15,14 +15,14 @@ Vec2 Rect::Uniform::sample(float& pdf) const {
return
Vec2
();
}
Vec3
Hemisphere
::
Cosine
::
sample
(
float
&
pdf
)
const
{
Vec3
Hemisphere
::
Cosine
::
sample
(
float
&
pdf
)
const
{
// TODO (PathTracer): Task 6
// You may implement this, but don't have to.
return
Vec3
();
}
Vec3
Sphere
::
Uniform
::
sample
(
float
&
pdf
)
const
{
Vec3
Sphere
::
Uniform
::
sample
(
float
&
pdf
)
const
{
// TODO (PathTracer): Task 7
// Generate a uniformly random point on the unit sphere (or equivalently, direction)
...
...
@@ -32,7 +32,7 @@ Vec3 Sphere::Uniform::sample(float& pdf) const {
return
Vec3
();
}
Sphere
::
Image
::
Image
(
const
HDR_Image
&
image
)
{
Sphere
::
Image
::
Image
(
const
HDR_Image
&
image
)
{
// TODO (PathTracer): Task 7
// Set up importance sampling for a spherical environment map image.
...
...
@@ -40,11 +40,12 @@ Sphere::Image::Image(const HDR_Image& image) {
// You may make use of the pdf, cdf, and total members, or create your own
// representation.
const
auto
[
_w
,
_h
]
=
image
.
dimension
();
w
=
_w
;
h
=
_h
;
const
auto
[
_w
,
_h
]
=
image
.
dimension
();
w
=
_w
;
h
=
_h
;
}
Vec3
Sphere
::
Image
::
sample
(
float
&
out_pdf
)
const
{
Vec3
Sphere
::
Image
::
sample
(
float
&
out_pdf
)
const
{
// TODO (PathTracer): Task 7
// Use your importance sampling data structure to generate a sample direction.
...
...
@@ -54,14 +55,14 @@ Vec3 Sphere::Image::sample(float& out_pdf) const {
return
Vec3
();
}
Vec3
Point
::
sample
(
float
&
pmf
)
const
{
Vec3
Point
::
sample
(
float
&
pmf
)
const
{
pmf
=
1.0
f
;
return
point
;
}
Vec3
Two_Points
::
sample
(
float
&
pmf
)
const
{
if
(
RNG
::
unit
()
<
prob
)
{
Vec3
Two_Points
::
sample
(
float
&
pmf
)
const
{
if
(
RNG
::
unit
()
<
prob
)
{
pmf
=
prob
;
return
p1
;
}
...
...
@@ -69,7 +70,7 @@ Vec3 Two_Points::sample(float& pmf) const {
return
p2
;
}
Vec3
Hemisphere
::
Uniform
::
sample
(
float
&
pdf
)
const
{
Vec3
Hemisphere
::
Uniform
::
sample
(
float
&
pdf
)
const
{
float
Xi1
=
RNG
::
unit
();
float
Xi2
=
RNG
::
unit
();
...
...
@@ -85,4 +86,4 @@ Vec3 Hemisphere::Uniform::sample(float& pdf) const {
return
Vec3
(
xs
,
ys
,
zs
);
}
}
}
// namespace Samplers
src/student/shapes.cpp
View file @
c2535f0f
#include "debug.h"
#include "../rays/shapes.h"
#include "debug.h"
namespace
PT
{
const
char
*
Shape_Type_Names
[(
int
)
Shape_Type
::
count
]
=
{
"None"
,
"Sphere"
};
const
char
*
Shape_Type_Names
[(
int
)
Shape_Type
::
count
]
=
{
"None"
,
"Sphere"
};
BBox
Sphere
::
bbox
()
const
{
...
...
@@ -17,7 +14,7 @@ BBox Sphere::bbox() const {
return
box
;
}
Trace
Sphere
::
hit
(
const
Ray
&
ray
)
const
{
Trace
Sphere
::
hit
(
const
Ray
&
ray
)
const
{
// TODO (PathTracer): Task 2
// Intersect this ray with a sphere of radius Sphere::radius centered at the origin.
...
...
@@ -36,4 +33,4 @@ Trace Sphere::hit(const Ray& ray) const {
return
ret
;
}
}
}
// namespace PT
src/student/skeleton.cpp
View file @
c2535f0f
...
...
@@ -35,7 +35,7 @@ Mat4 Joint::joint_to_posed() const {
return
Mat4
::
I
;
}
Vec3
Skeleton
::
end_of
(
Joint
*
j
)
{
Vec3
Skeleton
::
end_of
(
Joint
*
j
)
{
// TODO(Animation): Task 2
...
...
@@ -44,7 +44,7 @@ Vec3 Skeleton::end_of(Joint* j) {
return
Vec3
{};
}
Vec3
Skeleton
::
posed_end_of
(
Joint
*
j
)
{
Vec3
Skeleton
::
posed_end_of
(
Joint
*
j
)
{
// TODO(Animation): Task 2
...
...
@@ -53,7 +53,7 @@ Vec3 Skeleton::posed_end_of(Joint* j) {
return
Vec3
{};
}
Mat4
Skeleton
::
joint_to_bind
(
const
Joint
*
j
)
const
{
Mat4
Skeleton
::
joint_to_bind
(
const
Joint
*
j
)
const
{
// TODO(Animation): Task 2
...
...
@@ -62,7 +62,7 @@ Mat4 Skeleton::joint_to_bind(const Joint* j) const {
return
Mat4
::
I
;
}
Mat4
Skeleton
::
joint_to_posed
(
const
Joint
*
j
)
const
{
Mat4
Skeleton
::
joint_to_posed
(
const
Joint
*
j
)
const
{
// TODO(Animation): Task 2
...
...
@@ -71,7 +71,8 @@ Mat4 Skeleton::joint_to_posed(const Joint* j) const {
return
Mat4
::
I
;
}
void
Skeleton
::
find_joints
(
const
GL
::
Mesh
&
mesh
,
std
::
unordered_map
<
unsigned
int
,
std
::
vector
<
Joint
*>>&
map
)
{
void
Skeleton
::
find_joints
(
const
GL
::
Mesh
&
mesh
,
std
::
unordered_map
<
unsigned
int
,
std
::
vector
<
Joint
*>>
&
map
)
{
// TODO(Animation): Task 3
...
...
@@ -79,10 +80,9 @@ void Skeleton::find_joints(const GL::Mesh& mesh, std::unordered_map<unsigned int
// that should effect the vertex. A joint should effect a vertex if it is within Joint::radius
// distance of the bone segment in bind position.
const
std
::
vector
<
GL
::
Mesh
::
Vert
>&
verts
=
mesh
.
verts
();
for_joints
([
&
](
Joint
*
j
)
{
const
std
::
vector
<
GL
::
Mesh
::
Vert
>
&
verts
=
mesh
.
verts
();
for_joints
([
&
](
Joint
*
j
)
{
// What vertices does joint j effect?
});
...
...
@@ -90,8 +90,8 @@ void Skeleton::find_joints(const GL::Mesh& mesh, std::unordered_map<unsigned int
(
void
)
verts
;
}
void
Skeleton
::
skin
(
const
GL
::
Mesh
&
input
,
GL
::
Mesh
&
output
,
const
std
::
unordered_map
<
unsigned
int
,
std
::
vector
<
Joint
*>>
&
map
)
{
void
Skeleton
::
skin
(
const
GL
::
Mesh
&
input
,
GL
::
Mesh
&
output
,
const
std
::
unordered_map
<
unsigned
int
,
std
::
vector
<
Joint
*>>
&
map
)
{
// TODO(Animation): Task 3
...
...
@@ -103,7 +103,7 @@ void Skeleton::skin(const GL::Mesh& input, GL::Mesh& output,
// Currently, this just copies the input to the output without modification.
std
::
vector
<
GL
::
Mesh
::
Vert
>
verts
=
input
.
verts
();
for
(
size_t
i
=
0
;
i
<
verts
.
size
();
i
++
)
{
for
(
size_t
i
=
0
;
i
<
verts
.
size
();
i
++
)
{
// Skin vertex i.
}
...
...
src/student/spline.cpp
View file @
c2535f0f
#include "debug.h"
#include "../geometry/spline.h"
#include "debug.h"
template
<
typename
T
>
T
Spline
<
T
>::
cubic_unit_spline
(
float
time
,
const
T
&
position0
,
const
T
&
position1
,
const
T
&
tangent0
,
const
T
&
tangent1
)
{
template
<
typename
T
>
T
Spline
<
T
>::
cubic_unit_spline
(
float
time
,
const
T
&
position0
,
const
T
&
position1
,
const
T
&
tangent0
,
const
T
&
tangent1
)
{
// TODO (Animation): Task 1a
// Given time in [0,1] compute the cubic spline coefficients and use them to compute
...
...
@@ -15,8 +16,7 @@ T Spline<T>::cubic_unit_spline(float time, const T& position0, const T& position
return
T
();
}
template
<
typename
T
>
T
Spline
<
T
>::
at
(
float
time
)
const
{
template
<
typename
T
>
T
Spline
<
T
>::
at
(
float
time
)
const
{
// TODO (Animation): Task 1b
...
...
src/student/tri_mesh.cpp
View file @
c2535f0f
#include "debug.h"
#include "../rays/tri_mesh.h"
#include "debug.h"
namespace
PT
{
...
...
@@ -13,13 +13,15 @@ BBox Triangle::bbox() const {
return
box
;
}
Trace
Triangle
::
hit
(
const
Ray
&
ray
)
const
{
Trace
Triangle
::
hit
(
const
Ray
&
ray
)
const
{
// Vertices of triangle - has postion and surface normal
Tri_Mesh_Vert
v_0
=
vertex_list
[
v0
];
Tri_Mesh_Vert
v_1
=
vertex_list
[
v1
];
Tri_Mesh_Vert
v_2
=
vertex_list
[
v2
];
(
void
)
v_0
;
(
void
)
v_1
;
(
void
)
v_2
;
(
void
)
v_0
;
(
void
)
v_1
;
(
void
)
v_2
;
// TODO (PathTracer): Task 2
// Intersect this ray with a triangle defined by the three above points.
...
...
@@ -33,42 +35,37 @@ Trace Triangle::hit(const Ray& ray) const {
return
ret
;
}
Triangle
::
Triangle
(
Tri_Mesh_Vert
*
verts
,
unsigned
int
v0
,
unsigned
int
v1
,
unsigned
int
v2
)
Triangle
::
Triangle
(
Tri_Mesh_Vert
*
verts
,
unsigned
int
v0
,
unsigned
int
v1
,
unsigned
int
v2
)
:
vertex_list
(
verts
),
v0
(
v0
),
v1
(
v1
),
v2
(
v2
)
{}
void
Tri_Mesh
::
build
(
const
GL
::
Mesh
&
mesh
)
{
void
Tri_Mesh
::
build
(
const
GL
::
Mesh
&
mesh
)
{
verts
.
clear
();
triangles
.
clear
();
for
(
const
auto
&
v
:
mesh
.
verts
())
{
for
(
const
auto
&
v
:
mesh
.
verts
())
{
verts
.
push_back
({
v
.
pos
,
v
.
norm
});
}
const
auto
&
idxs
=
mesh
.
indices
();
const
auto
&
idxs
=
mesh
.
indices
();
std
::
vector
<
Triangle
>
tris
;
for
(
size_t
i
=
0
;
i
<
idxs
.
size
();
i
+=
3
)
{
tris
.
push_back
(
Triangle
(
verts
.
data
(),
idxs
[
i
],
idxs
[
i
+
1
],
idxs
[
i
+
2
]));
for
(
size_t
i
=
0
;
i
<
idxs
.
size
();
i
+=
3
)
{
tris
.
push_back
(
Triangle
(
verts
.
data
(),
idxs
[
i
],
idxs
[
i
+
1
],
idxs
[
i
+
2
]));
}
triangles
.
build
(
std
::
move
(
tris
),
4
);
}
Tri_Mesh
::
Tri_Mesh
(
const
GL
::
Mesh
&
mesh
)
{
build
(
mesh
);
}
Tri_Mesh
::
Tri_Mesh
(
const
GL
::
Mesh
&
mesh
)
{
build
(
mesh
);
}
BBox
Tri_Mesh
::
bbox
()
const
{
return
triangles
.
bbox
();
}
BBox
Tri_Mesh
::
bbox
()
const
{
return
triangles
.
bbox
();
}
Trace
Tri_Mesh
::
hit
(
const
Ray
&
ray
)
const
{
return
triangles
.
hit
(
ray
);
}
Trace
Tri_Mesh
::
hit
(
const
Ray
&
ray
)
const
{
return
triangles
.
hit
(
ray
);
}
size_t
Tri_Mesh
::
visualize
(
GL
::
Lines
&
lines
,
GL
::
Lines
&
active
,
size_t
level
,
const
Mat4
&
trans
)
const
{
size_t
Tri_Mesh
::
visualize
(
GL
::
Lines
&
lines
,
GL
::
Lines
&
active
,
size_t
level
,
const
Mat4
&
trans
)
const
{
return
triangles
.
visualize
(
lines
,
active
,
level
,
trans
);
}
}
}
// namespace PT
src/util/camera.cpp
View file @
c2535f0f
#include "camera.h"
const
Vec3
UP
=
Vec3
{
0.0
f
,
1.0
f
,
0.0
f
};
Camera
::
Camera
(
Vec2
dim
)
{
reset
();
set_ar
(
dim
);
}
Mat4
Camera
::
get_view
()
const
{
return
view
;
}
Mat4
Camera
::
get_view
()
const
{
return
view
;
}
Mat4
Camera
::
get_proj
()
const
{
return
Mat4
::
project
(
vert_fov
,
aspect_ratio
,
near_plane
);
}
Mat4
Camera
::
get_proj
()
const
{
return
Mat4
::
project
(
vert_fov
,
aspect_ratio
,
near_plane
);
}
Vec3
Camera
::
pos
()
const
{
return
position
;
}
Vec3
Camera
::
pos
()
const
{
return
position
;
}
Vec3
Camera
::
front
()
const
{
return
(
looking_at
-
position
).
unit
();
}
Vec3
Camera
::
front
()
const
{
return
(
looking_at
-
position
).
unit
();
}
float
Camera
::
dist
()
const
{
return
(
position
-
looking_at
).
norm
();
}
float
Camera
::
dist
()
const
{
return
(
position
-
looking_at
).
norm
();
}
void
Camera
::
look_at
(
Vec3
cent
,
Vec3
pos
)
{
position
=
pos
;
looking_at
=
cent
;
radius
=
(
pos
-
cent
).
norm
();
update_dirs
();
rot
=
Quat
::
euler
(
Mat4
::
rotate_z_to
(
front
()).
to_euler
());
update_pos
();
}
void
Camera
::
reset
()
{
vert_fov
=
90.0
f
;
aspect_ratio
=
1.7778
f
;
pitch
=
-
45.0
f
;
yaw
=
45.0
f
;
rot
=
Quat
::
euler
(
Vec3
(
-
45.0
f
,
45.0
f
,
0.0
f
));
near_plane
=
0.01
f
;
radius
=
5.0
f
;
radius_sens
=
0.25
f
;
move_sens
=
0.015
f
;
orbit_sens
=
0.2
f
;
looking_at
=
Vec3
();
global_up
=
Vec3
(
0
,
1
,
0
);
update_pos
();
}
void
Camera
::
mouse_orbit
(
Vec2
off
)
{
yaw
+=
off
.
x
*
orbit_sens
;
pitch
+=
off
.
y
*
orbit_sens
;
if
(
yaw
>
360.0
f
)
yaw
=
0.0
f
;
else
if
(
yaw
<
0.0
f
)
yaw
=
360.0
f
;
pitch
=
clamp
(
pitch
,
-
89.5
f
,
89.5
f
);
float
up_rot
=
-
off
.
x
*
orbit_sens
;
float
right_rot
=
off
.
y
*
orbit_sens
;
Vec3
up
=
rot
.
rotate
(
UP
);
Vec3
f
=
front
();
Vec3
right
=
cross
(
f
,
up
).
unit
();
rot
=
Quat
::
axis_angle
(
UP
,
up_rot
)
*
Quat
::
axis_angle
(
right
,
right_rot
)
*
rot
;
update_pos
();
}
void
Camera
::
mouse_move
(
Vec2
off
)
{
Vec3
front
=
(
position
-
looking_at
).
unit
();
Vec3
right
=
cross
(
front
,
global_up
).
unit
();
Vec3
up
=
cross
(
front
,
right
).
unit
();
looking_at
+=
right
*
off
.
x
*
move_sens
-
up
*
off
.
y
*
move_sens
;
Vec3
up
=
rot
.
rotate
(
UP
);
Vec3
f
=
front
();
Vec3
right
=
cross
(
f
,
up
).
unit
();
looking_at
+=
-
right
*
off
.
x
*
move_sens
+
up
*
off
.
y
*
move_sens
;
update_pos
();
}
...
...
@@ -71,9 +66,7 @@ void Camera::mouse_radius(float off) {
update_pos
();
}
void
Camera
::
set_fov
(
float
f
)
{
vert_fov
=
f
;
}
void
Camera
::
set_fov
(
float
f
)
{
vert_fov
=
f
;
}
float
Camera
::
get_h_fov
()
const
{
float
vfov
=
Radians
(
vert_fov
);
...
...
@@ -81,46 +74,21 @@ float Camera::get_h_fov() const {
return
Degrees
(
hfov
);
}
float
Camera
::
get_fov
()
const
{
return
vert_fov
;
}
float
Camera
::
get_fov
()
const
{
return
vert_fov
;
}
float
Camera
::
get_ar
()
const
{
return
aspect_ratio
;
}
float
Camera
::
get_ar
()
const
{
return
aspect_ratio
;
}
float
Camera
::
get_near
()
const
{
return
near_plane
;
}
Vec3
Camera
::
center
()
const
{
return
looking_at
;
}
float
Camera
::
get_near
()
const
{
return
near_plane
;
}
void
Camera
::
set_ar
(
float
a
)
{
aspect_ratio
=
a
;
}
Vec3
Camera
::
center
()
const
{
return
looking_at
;
}
void
Camera
::
set_ar
(
Vec2
dim
)
{
aspect_ratio
=
dim
.
x
/
dim
.
y
;
}
void
Camera
::
set_ar
(
float
a
)
{
aspect_ratio
=
a
;
}
void
Camera
::
update_dirs
()
{
Vec3
dir
=
front
();
yaw
=
Degrees
(
std
::
atan2
(
dir
.
z
,
dir
.
x
));
pitch
=
Degrees
(
std
::
atan2
(
dir
.
y
,
Vec2
(
dir
.
x
,
dir
.
z
).
norm
()));
while
(
yaw
>
360.0
f
)
yaw
-=
360.0
f
;
while
(
yaw
<
0.0
f
)
yaw
+=
360.0
f
;
pitch
=
clamp
(
pitch
,
-
89.5
f
,
89.5
f
);
update_pos
();
}
void
Camera
::
set_ar
(
Vec2
dim
)
{
aspect_ratio
=
dim
.
x
/
dim
.
y
;
}
void
Camera
::
update_pos
()
{
position
.
x
=
std
::
cos
(
Radians
(
pitch
))
*
std
::
cos
(
Radians
(
yaw
));
position
.
y
=
std
::
sin
(
Radians
(
pitch
));
position
.
z
=
std
::
sin
(
Radians
(
yaw
))
*
std
::
cos
(
Radians
(
pitch
));
position
=
looking_at
-
radius
*
position
.
unit
();
view
=
Mat4
::
look_at
(
position
,
looking_at
,
global_up
);
iview
=
view
.
inverse
();
position
=
rot
.
rotate
(
Vec3
{
0.0
f
,
0.0
f
,
1.0
f
});
position
=
looking_at
+
radius
*
position
.
unit
();
iview
=
Mat4
::
translate
(
position
)
*
rot
.
to_mat
();
view
=
iview
.
inverse
();
}
src/util/camera.h
View file @
c2535f0f
...
...
@@ -54,15 +54,15 @@ public:
float
get_near
()
const
;
private:
void
update_dirs
();
void
update_pos
();
/// Camera parameters
Vec3
position
,
looking_at
,
global_up
;
Vec3
position
,
looking_at
;
float
vert_fov
,
aspect_ratio
;
Quat
rot
;
/// For updating position & looking_at
float
pitch
,
yaw
,
radius
,
near_plane
;
float
radius
,
near_plane
;
/// For mouse control
float
orbit_sens
,
move_sens
,
radius_sens
;
...
...
src/util/hdr_image.cpp
View file @
c2535f0f
...
...
@@ -22,9 +22,7 @@ HDR_Image HDR_Image::copy() const {
return
ret
;
}
std
::
pair
<
size_t
,
size_t
>
HDR_Image
::
dimension
()
const
{
return
{
w
,
h
};
}
std
::
pair
<
size_t
,
size_t
>
HDR_Image
::
dimension
()
const
{
return
{
w
,
h
};
}
void
HDR_Image
::
resize
(
size_t
_w
,
size_t
_h
)
{
w
=
_w
;
...
...
@@ -35,11 +33,12 @@ void HDR_Image::resize(size_t _w, size_t _h) {
}
void
HDR_Image
::
clear
(
Spectrum
color
)
{
for
(
auto
&
s
:
pixels
)
s
=
color
;
for
(
auto
&
s
:
pixels
)
s
=
color
;
dirty
=
true
;
}
Spectrum
&
HDR_Image
::
at
(
size_t
i
)
{
Spectrum
&
HDR_Image
::
at
(
size_t
i
)
{
assert
(
i
<
w
*
h
);
dirty
=
true
;
return
pixels
[
i
];
...
...
@@ -50,7 +49,7 @@ Spectrum HDR_Image::at(size_t i) const {
return
pixels
[
i
];
}
Spectrum
&
HDR_Image
::
at
(
size_t
x
,
size_t
y
)
{
Spectrum
&
HDR_Image
::
at
(
size_t
x
,
size_t
y
)
{
assert
(
x
<
w
&&
y
<
h
);
size_t
idx
=
y
*
w
+
x
;
dirty
=
true
;
...
...
@@ -65,11 +64,11 @@ Spectrum HDR_Image::at(size_t x, size_t y) const {
std
::
string
HDR_Image
::
load_from
(
std
::
string
file
)
{
if
(
IsEXR
(
file
.
c_str
())
==
TINYEXR_SUCCESS
)
{
if
(
IsEXR
(
file
.
c_str
())
==
TINYEXR_SUCCESS
)
{
int
n_w
,
n_h
;
float
*
data
;
const
char
*
err
=
nullptr
;
float
*
data
;
const
char
*
err
=
nullptr
;
int
ret
=
LoadEXR
(
&
data
,
&
n_w
,
&
n_h
,
file
.
c_str
(),
&
err
);
...
...
@@ -79,17 +78,18 @@ std::string HDR_Image::load_from(std::string file) {
std
::
string
err_s
(
err
);
FreeEXRErrorMessage
(
err
);
return
err_s
;
}
else
return
"Unknown failure."
;
}
else
return
"Unknown failure."
;
}
else
{
resize
(
n_w
,
n_h
);
for
(
size_t
j
=
0
;
j
<
h
;
j
++
)
{
for
(
size_t
i
=
0
;
i
<
w
;
i
++
)
{
for
(
size_t
j
=
0
;
j
<
h
;
j
++
)
{
for
(
size_t
i
=
0
;
i
<
w
;
i
++
)
{
size_t
didx
=
4
*
(
j
*
w
+
i
);
size_t
pidx
=
(
h
-
j
-
1
)
*
w
+
i
;
pixels
[
pidx
]
=
Spectrum
(
data
[
didx
],
data
[
didx
+
1
],
data
[
didx
+
2
]);
pixels
[
pidx
]
=
Spectrum
(
data
[
didx
],
data
[
didx
+
1
],
data
[
didx
+
2
]);
}
}
...
...
@@ -103,24 +103,27 @@ std::string HDR_Image::load_from(std::string file) {
int
n_w
,
n_h
,
channels
;
unsigned
char
*
data
=
stbi_load
(
file
.
c_str
(),
&
n_w
,
&
n_h
,
&
channels
,
0
);
if
(
!
data
)
return
std
::
string
(
stbi_failure_reason
());
if
(
channels
<
3
)
return
"Image has less than 3 color channels."
;
if
(
!
data
)
return
std
::
string
(
stbi_failure_reason
());
if
(
channels
<
3
)
return
"Image has less than 3 color channels."
;
resize
(
n_w
,
n_h
);
for
(
size_t
i
=
0
;
i
<
w
*
h
*
channels
;
i
+=
channels
)
{
for
(
size_t
i
=
0
;
i
<
w
*
h
*
channels
;
i
+=
channels
)
{
float
r
=
data
[
i
]
/
255.0
f
;
float
g
=
data
[
i
+
1
]
/
255.0
f
;
float
b
=
data
[
i
+
2
]
/
255.0
f
;
pixels
[
i
/
channels
]
=
Spectrum
(
r
,
g
,
b
);
float
g
=
data
[
i
+
1
]
/
255.0
f
;
float
b
=
data
[
i
+
2
]
/
255.0
f
;
pixels
[
i
/
channels
]
=
Spectrum
(
r
,
g
,
b
);
}
stbi_image_free
(
data
);
}
for
(
size_t
i
=
0
;
i
<
pixels
.
size
();
i
++
)
{
for
(
size_t
i
=
0
;
i
<
pixels
.
size
();
i
++
)
{
pixels
[
i
].
make_linear
();
if
(
!
pixels
[
i
].
valid
())
pixels
[
i
]
=
{};
if
(
!
pixels
[
i
].
valid
())
pixels
[
i
]
=
{};
}
last_path
=
file
;
...
...
@@ -128,20 +131,19 @@ std::string HDR_Image::load_from(std::string file) {
return
{};
}
std
::
string
HDR_Image
::
loaded_from
()
const
{
return
last_path
;
}
std
::
string
HDR_Image
::
loaded_from
()
const
{
return
last_path
;
}
void
HDR_Image
::
tonemap
(
float
e
)
const
{
if
(
e
<=
0.0
f
)
{
if
(
e
<=
0.0
f
)
{
e
=
exposure
;
}
else
if
(
e
!=
exposure
)
{
}
else
if
(
e
!=
exposure
)
{
exposure
=
e
;
dirty
=
true
;
}
if
(
!
dirty
)
return
;
if
(
!
dirty
)
return
;
std
::
vector
<
unsigned
char
>
data
;
tonemap_to
(
data
,
e
);
...
...
@@ -150,38 +152,38 @@ void HDR_Image::tonemap(float e) const {
dirty
=
false
;
}
const
GL
::
Tex2D
&
HDR_Image
::
get_texture
(
float
e
)
const
{
const
GL
::
Tex2D
&
HDR_Image
::
get_texture
(
float
e
)
const
{
tonemap
(
e
);
return
render_tex
;
}
void
HDR_Image
::
tonemap_to
(
std
::
vector
<
unsigned
char
>
&
data
,
float
e
)
const
{
void
HDR_Image
::
tonemap_to
(
std
::
vector
<
unsigned
char
>
&
data
,
float
e
)
const
{
if
(
e
<=
0.0
f
)
{
if
(
e
<=
0.0
f
)
{
e
=
exposure
;
}
if
(
data
.
size
()
!=
w
*
h
*
4
)
if
(
data
.
size
()
!=
w
*
h
*
4
)
data
.
resize
(
w
*
h
*
4
);
for
(
size_t
j
=
0
;
j
<
h
;
j
++
)
{
for
(
size_t
i
=
0
;
i
<
w
;
i
++
)
{
for
(
size_t
j
=
0
;
j
<
h
;
j
++
)
{
for
(
size_t
i
=
0
;
i
<
w
;
i
++
)
{
size_t
pidx
=
(
h
-
j
-
1
)
*
w
+
i
;
const
Spectrum
&
sample
=
pixels
[
pidx
];
const
Spectrum
&
sample
=
pixels
[
pidx
];
float
r
=
1.0
f
-
std
::
exp
(
-
sample
.
r
*
exposure
);
float
g
=
1.0
f
-
std
::
exp
(
-
sample
.
g
*
exposure
);
float
b
=
1.0
f
-
std
::
exp
(
-
sample
.
b
*
exposure
);
Spectrum
out
(
r
,
g
,
b
);
Spectrum
out
(
r
,
g
,
b
);
out
.
make_srgb
();
size_t
didx
=
4
*
(
j
*
w
+
i
);
data
[
didx
]
=
(
unsigned
char
)
std
::
round
(
out
.
r
*
255.0
f
);
data
[
didx
+
1
]
=
(
unsigned
char
)
std
::
round
(
out
.
g
*
255.0
f
);
data
[
didx
+
2
]
=
(
unsigned
char
)
std
::
round
(
out
.
b
*
255.0
f
);
data
[
didx
+
3
]
=
255
;
data
[
didx
+
1
]
=
(
unsigned
char
)
std
::
round
(
out
.
g
*
255.0
f
);
data
[
didx
+
2
]
=
(
unsigned
char
)
std
::
round
(
out
.
b
*
255.0
f
);
data
[
didx
+
3
]
=
255
;
}
}
}
src/util/hdr_image.h
View file @
c2535f0f
...
...
@@ -3,36 +3,36 @@
#include <vector>
#include "../platform/gl.h"
#include "../lib/spectrum.h"
#include "../platform/gl.h"
class
HDR_Image
{
public:
HDR_Image
();
HDR_Image
(
size_t
w
,
size_t
h
);
HDR_Image
(
const
HDR_Image
&
src
)
=
delete
;
HDR_Image
(
HDR_Image
&&
src
)
=
default
;
HDR_Image
(
const
HDR_Image
&
src
)
=
delete
;
HDR_Image
(
HDR_Image
&&
src
)
=
default
;
~
HDR_Image
()
=
default
;
HDR_Image
copy
()
const
;
HDR_Image
&
operator
=
(
const
HDR_Image
&
src
)
=
delete
;
HDR_Image
&
operator
=
(
HDR_Image
&&
src
)
=
default
;
HDR_Image
&
operator
=
(
const
HDR_Image
&
src
)
=
delete
;
HDR_Image
&
operator
=
(
HDR_Image
&&
src
)
=
default
;
Spectrum
&
at
(
size_t
x
,
size_t
y
);
Spectrum
&
at
(
size_t
x
,
size_t
y
);
Spectrum
at
(
size_t
x
,
size_t
y
)
const
;
Spectrum
&
at
(
size_t
i
);
Spectrum
&
at
(
size_t
i
);
Spectrum
at
(
size_t
i
)
const
;
void
clear
(
Spectrum
color
);
void
resize
(
size_t
w
,
size_t
h
);
std
::
pair
<
size_t
,
size_t
>
dimension
()
const
;
std
::
pair
<
size_t
,
size_t
>
dimension
()
const
;
std
::
string
load_from
(
std
::
string
file
);
std
::
string
loaded_from
()
const
;
void
tonemap_to
(
std
::
vector
<
unsigned
char
>
&
data
,
float
exposure
=
0.0
f
)
const
;
const
GL
::
Tex2D
&
get_texture
(
float
exposure
=
0.0
f
)
const
;
void
tonemap_to
(
std
::
vector
<
unsigned
char
>
&
data
,
float
exposure
=
0.0
f
)
const
;
const
GL
::
Tex2D
&
get_texture
(
float
exposure
=
0.0
f
)
const
;
private:
void
tonemap
(
float
exposure
=
0.0
f
)
const
;
...
...
src/util/rand.cpp
View file @
c2535f0f
...
...
@@ -15,20 +15,17 @@ float unit() {
return
d
(
rng
);
}
int
integer
(
int
min
,
int
max
)
{
return
(
int
)
lerp
((
float
)
min
,
(
float
)
max
,
unit
());
}
int
integer
(
int
min
,
int
max
)
{
return
(
int
)
lerp
((
float
)
min
,
(
float
)
max
,
unit
());
}
bool
coin_flip
(
float
p
)
{
return
unit
()
<
p
;
}
bool
coin_flip
(
float
p
)
{
return
unit
()
<
p
;
}
void
seed
()
{
std
::
random_device
r
;
std
::
random_device
::
result_type
seed
=
r
()
^
std
::
random_device
::
result_type
seed
=
r
()
^
(
std
::
random_device
::
result_type
)
std
::
hash
<
std
::
thread
::
id
>
()(
std
::
this_thread
::
get_id
())
^
(
std
::
random_device
::
result_type
)
std
::
hash
<
time_t
>
()(
std
::
time
(
nullptr
));
rng
.
seed
(
seed
);
}
}
}
// namespace RNG
src/util/rand.h
View file @
c2535f0f
...
...
@@ -3,16 +3,15 @@
namespace
RNG
{
// Generate random float in the range [0,1]
float
unit
();
// Generate random float in the range [0,1]
float
unit
();
// Generate random integer in the range [min,max)
int
integer
(
int
min
,
int
max
);
// Generate random integer in the range [min,max)
int
integer
(
int
min
,
int
max
);
// Return true with probability p and false with probability 1-p
bool
coin_flip
(
float
p
=
0.5
f
);
// Seed the current thread's PRNG
void
seed
();
}
// Return true with probability p and false with probability 1-p
bool
coin_flip
(
float
p
=
0.5
f
);
// Seed the current thread's PRNG
void
seed
();
}
// namespace RNG
src/util/thread_pool.cpp
View file @
c2535f0f
...
...
@@ -2,28 +2,25 @@
#include "thread_pool.h"
#include "../util/rand.h"
Thread_Pool
::
Thread_Pool
(
size_t
threads
)
{
start
(
threads
);
}
Thread_Pool
::
Thread_Pool
(
size_t
threads
)
{
start
(
threads
);
}
Thread_Pool
::~
Thread_Pool
()
{
stop
();
}
Thread_Pool
::~
Thread_Pool
()
{
stop
();
}
void
Thread_Pool
::
start
(
size_t
threads
)
{
n_threads
=
threads
;
stop_now
=
false
;
stop_when_done
=
false
;
for
(
size_t
i
=
0
;
i
<
threads
;
i
++
)
workers
.
emplace_back
([
this
]{
for
(
size_t
i
=
0
;
i
<
threads
;
i
++
)
workers
.
emplace_back
([
this
]
{
RNG
::
seed
();
for
(;;)
{
for
(;;)
{
std
::
function
<
void
()
>
task
;
{
std
::
unique_lock
<
std
::
mutex
>
lock
(
this
->
queue_mutex
);
this
->
condition
.
wait
(
lock
,
[
this
]{
return
this
->
stop_now
||
this
->
stop_when_done
||
!
this
->
tasks
.
empty
();
});
if
(
this
->
stop_now
||
(
this
->
stop_when_done
&&
this
->
tasks
.
empty
()))
this
->
condition
.
wait
(
lock
,
[
this
]
{
return
this
->
stop_now
||
this
->
stop_when_done
||
!
this
->
tasks
.
empty
();
});
if
(
this
->
stop_now
||
(
this
->
stop_when_done
&&
this
->
tasks
.
empty
()))
return
;
task
=
std
::
move
(
this
->
tasks
.
front
());
this
->
tasks
.
pop
();
...
...
@@ -46,7 +43,7 @@ void Thread_Pool::wait() {
}
condition
.
notify_all
();
for
(
std
::
thread
&
worker
:
workers
)
{
for
(
std
::
thread
&
worker
:
workers
)
{
worker
.
join
();
}
workers
.
clear
();
...
...
@@ -62,7 +59,7 @@ void Thread_Pool::stop() {
}
condition
.
notify_all
();
for
(
std
::
thread
&
worker
:
workers
)
{
for
(
std
::
thread
&
worker
:
workers
)
{
worker
.
join
();
}
workers
.
clear
();
...
...
src/util/thread_pool.h
View file @
c2535f0f
#pragma once
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>
#include <future>
#include <mutex>
#include <queue>
#include <thread>
#include "../lib/log.h"
...
...
@@ -19,8 +19,9 @@ public:
void
wait
();
void
clear
();
template
<
class
F
,
class
...
Args
>
auto
enqueue
(
F
&&
f
,
Args
&&
...
args
)
->
std
::
future
<
typename
std
::
invoke_result
<
F
,
Args
...
>::
type
>
{
template
<
class
F
,
class
...
Args
>
auto
enqueue
(
F
&&
f
,
Args
&&
...
args
)
->
std
::
future
<
typename
std
::
invoke_result
<
F
,
Args
...
>::
type
>
{
using
return_type
=
typename
std
::
invoke_result
<
F
,
Args
...
>::
type
;
assert
(
!
stop_now
&&
!
stop_when_done
);
...
...
@@ -31,7 +32,7 @@ public:
std
::
future
<
return_type
>
res
=
task
->
get_future
();
{
std
::
unique_lock
<
std
::
mutex
>
lock
(
queue_mutex
);
tasks
.
emplace
([
task
](){
(
*
task
)();
});
tasks
.
emplace
([
task
]()
{
(
*
task
)();
});
}
condition
.
notify_one
();
return
res
;
...
...
Prev
1
2
3
4
5
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment