Skip to content

Commit 8afb894

Browse files
committed
Extract camera, rand
- performance appears unchanged
1 parent f5c2ebe commit 8afb894

File tree

4 files changed

+92
-88
lines changed

4 files changed

+92
-88
lines changed

src/RayTracingWeekend.jl

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -59,44 +59,7 @@ function __init__()
5959
nothing
6060
end
6161

62-
# Reset the per-thread random seeds to make results reproducible
63-
reseed!() = for i in 1:Threads.nthreads() Random.seed!(TRNG[i], i) end
64-
65-
"Per-thread rand()"
66-
@inline function trand()
67-
@inbounds rng = TRNG[Threads.threadid()]
68-
rand(rng)
69-
end
70-
71-
@inline function trand(::Type{T}) where T
72-
@inbounds rng = TRNG[Threads.threadid()]
73-
rand(rng, T)
74-
end
75-
76-
@inline function random_vec3_in_sphere(::Type{T}) where T # equiv to random_in_unit_sphere()
77-
while true
78-
p = random_vec3(T(-1), T(1))
79-
if pp <= 1
80-
return p
81-
end
82-
end
83-
end
84-
85-
@inline random_between(min::T=0, max::T=1) where T = trand(T)*(max-min) + min # equiv to random_double()
86-
@inline random_vec3(min::T, max::T) where T = @inbounds @SVector[random_between(min, max) for i 1:3]
87-
@inline random_vec2(min::T, max::T) where T = @inbounds @SVector[random_between(min, max) for i 1:2]
88-
89-
"Random unit vector. Equivalent to C++'s `unit_vector(random_in_unit_sphere())`"
90-
@inline random_vec3_on_sphere(::Type{T}) where T = normalize(random_vec3_in_sphere(T))
91-
92-
@inline function random_vec2_in_disk(::Type{T}) where T # equiv to random_in_unit_disk()
93-
while true
94-
p = random_vec2(T(-1), T(1))
95-
if pp <= 1
96-
return p
97-
end
98-
end
99-
end
62+
include("rand.jl")
10063

10164
"An object that can be hit by Ray"
10265
abstract type Hittable end
@@ -223,55 +186,6 @@ end
223186
Scatter(Ray(rec.p, reflected), mat.albedo)
224187
end
225188

226-
struct Camera{T <: AbstractFloat}
227-
origin::Vec3{T}
228-
lower_left_corner::Vec3{T}
229-
horizontal::Vec3{T}
230-
vertical::Vec3{T}
231-
u::Vec3{T}
232-
v::Vec3{T}
233-
w::Vec3{T}
234-
lens_radius::T
235-
end
236-
237-
"""
238-
Args:
239-
vfov: vertical field-of-view in degrees
240-
aspect_ratio: horizontal/vertical ratio of pixels
241-
aperture: if 0 - no depth-of-field
242-
"""
243-
function default_camera(lookfrom::Vec3{T}=(SA{T}[0,0,0]),
244-
lookat::Vec3{T}=(SA{T}[0,0,-1]),
245-
vup::Vec3{T}=(SA{T}[0,1,0]),
246-
vfov::T=T(90), aspect_ratio::T=T(16/9),
247-
aperture::T=T(0), focus_dist::T=T(1)) where T
248-
viewport_height = T(2) * tand(vfov/T(2))
249-
viewport_width = aspect_ratio * viewport_height
250-
251-
w = normalize(lookfrom - lookat)
252-
u = normalize(vup × w)
253-
v = w × u
254-
255-
origin = lookfrom
256-
horizontal = focus_dist * viewport_width * u
257-
vertical = focus_dist * viewport_height * v
258-
lower_left_corner = origin - horizontal/T(2) - vertical/T(2) - focus_dist*w
259-
lens_radius = aperture/T(2)
260-
Camera{T}(origin, lower_left_corner, horizontal, vertical, u, v, w, lens_radius)
261-
end
262-
263-
default_camera(lookfrom, lookat, vup, vfov, aspect_ratio, aperture, focus_dist; elem_type::Type{T}) where T =
264-
default_camera(Vec3{T}(lookfrom), Vec3{T}(lookat), Vec3{T}(vup),
265-
T(vfov), T(aspect_ratio), T(aperture), T(focus_dist)
266-
)
267-
268-
@inline @fastmath function get_ray(c::Camera{T}, s::T, t::T) where T
269-
rd = SVector{2,T}(c.lens_radius * random_vec2_in_disk(T))
270-
offset = c.u * rd.x + c.v * rd.y #offset = c.u * rd.x + c.v * rd.y
271-
Ray(c.origin + offset, normalize(c.lower_left_corner + s*c.horizontal +
272-
t*c.vertical - c.origin - offset))
273-
end
274-
275189
"""Compute color for a ray, recursively
276190
277191
Args:
@@ -302,6 +216,8 @@ end
302216
end
303217
end
304218

219+
include("camera.jl")
220+
305221
"""Render an image of `scene` using the specified camera, number of samples.
306222
307223
Args:

src/camera.jl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
struct Camera{T <: AbstractFloat}
2+
origin::Vec3{T}
3+
lower_left_corner::Vec3{T}
4+
horizontal::Vec3{T}
5+
vertical::Vec3{T}
6+
u::Vec3{T}
7+
v::Vec3{T}
8+
w::Vec3{T}
9+
lens_radius::T
10+
end
11+
12+
"""
13+
Args:
14+
vfov: vertical field-of-view in degrees
15+
aspect_ratio: horizontal/vertical ratio of pixels
16+
aperture: if 0 - no depth-of-field
17+
"""
18+
function default_camera(lookfrom::Vec3{T}=(SA{T}[0,0,0]),
19+
lookat::Vec3{T}=(SA{T}[0,0,-1]),
20+
vup::Vec3{T}=(SA{T}[0,1,0]),
21+
vfov::T=T(90), aspect_ratio::T=T(16/9),
22+
aperture::T=T(0), focus_dist::T=T(1)) where T
23+
viewport_height = T(2) * tand(vfov/T(2))
24+
viewport_width = aspect_ratio * viewport_height
25+
26+
w = normalize(lookfrom - lookat)
27+
u = normalize(vup × w)
28+
v = w × u
29+
30+
origin = lookfrom
31+
horizontal = focus_dist * viewport_width * u
32+
vertical = focus_dist * viewport_height * v
33+
lower_left_corner = origin - horizontal/T(2) - vertical/T(2) - focus_dist*w
34+
lens_radius = aperture/T(2)
35+
Camera{T}(origin, lower_left_corner, horizontal, vertical, u, v, w, lens_radius)
36+
end
37+
38+
default_camera(lookfrom, lookat, vup, vfov, aspect_ratio, aperture, focus_dist; elem_type::Type{T}) where T =
39+
default_camera(Vec3{T}(lookfrom), Vec3{T}(lookat), Vec3{T}(vup),
40+
T(vfov), T(aspect_ratio), T(aperture), T(focus_dist)
41+
)
42+
43+
@inline @fastmath function get_ray(c::Camera{T}, s::T, t::T) where T
44+
rd = SVector{2,T}(c.lens_radius * random_vec2_in_disk(T))
45+
offset = c.u * rd.x + c.v * rd.y #offset = c.u * rd.x + c.v * rd.y
46+
Ray(c.origin + offset, normalize(c.lower_left_corner + s*c.horizontal +
47+
t*c.vertical - c.origin - offset))
48+
end

src/proto/proto.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ render(scene_2_spheres(; elem_type=ELEM_TYPE), t_default_cam, 96, 1) # 1 sample
192192
# 304.877 ms (1884433 allocations: 144.26 MiB)
193193
# Extract the scene creation from the render() call:
194194
# 300.344 ms (1883484 allocations: 144.21 MiB)
195+
# Separate the module's reusable functions/classes from this proto.jl
196+
# 296.824 ms (min) (1909996 allocs: 146.23 MiB)
195197
print("render(scene_random_spheres(; elem_type=ELEM_TYPE), t_cam1, 200, 32):")
196198
reseed!()
197199
_scene_random_spheres = scene_random_spheres(; elem_type=ELEM_TYPE)
@@ -271,5 +273,5 @@ _scene_random_spheres = scene_random_spheres(; elem_type=ELEM_TYPE)
271273
using Profile
272274
render(scene_random_spheres(; elem_type=ELEM_TYPE), t_cam1, 16, 1)
273275
Profile.clear_malloc_data()
274-
render(scene_random_spheres(; elem_type=ELEM_TYPE), t_cam1, 17, 13)
276+
render(scene_random_spheres(; elem_type=ELEM_TYPE), t_cam1, 320, 64)
275277

src/rand.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Reset the per-thread random seeds to make results reproducible
2+
reseed!() = for i in 1:Threads.nthreads() Random.seed!(TRNG[i], i) end
3+
4+
"Per-thread rand()"
5+
@inline function trand()
6+
@inbounds rng = TRNG[Threads.threadid()]
7+
rand(rng)
8+
end
9+
10+
@inline function trand(::Type{T}) where T
11+
@inbounds rng = TRNG[Threads.threadid()]
12+
rand(rng, T)
13+
end
14+
15+
@inline function random_vec3_in_sphere(::Type{T}) where T # equiv to random_in_unit_sphere()
16+
while true
17+
p = random_vec3(T(-1), T(1))
18+
if pp <= 1
19+
return p
20+
end
21+
end
22+
end
23+
24+
@inline random_between(min::T=0, max::T=1) where T = trand(T)*(max-min) + min # equiv to random_double()
25+
@inline random_vec3(min::T, max::T) where T = @inbounds @SVector[random_between(min, max) for i 1:3]
26+
@inline random_vec2(min::T, max::T) where T = @inbounds @SVector[random_between(min, max) for i 1:2]
27+
28+
"Random unit vector. Equivalent to C++'s `unit_vector(random_in_unit_sphere())`"
29+
@inline random_vec3_on_sphere(::Type{T}) where T = normalize(random_vec3_in_sphere(T))
30+
31+
@inline function random_vec2_in_disk(::Type{T}) where T # equiv to random_in_unit_disk()
32+
while true
33+
p = random_vec2(T(-1), T(1))
34+
if pp <= 1
35+
return p
36+
end
37+
end
38+
end

0 commit comments

Comments
 (0)