@@ -405,27 +405,26 @@ end
405
405
@inline @fastmath function hit (s:: Sphere{T} , r:: Ray{T} , tmin:: T ,
406
406
tmax:: T ):: Union{HitRecord,Nothing} where T
407
407
oc = r. origin - s. center
408
- # a = r.dir ⋅ r.dir # unnecessary since `r.dir` is normalized
409
- a = 1
408
+ a = 1 # r.dir ⋅ r.dir is unnecessary since r.dir is normalized
410
409
half_b = oc ⋅ r. dir
411
410
c = oc⋅ oc - s. radius^ 2
412
411
discriminant = half_b^ 2 - a* c
413
- if discriminant < 0 return nothing end # no hit!
412
+ if discriminant < 0 return nothing end
414
413
sqrtd = √ discriminant
415
414
416
415
# Find the nearest root that lies in the acceptable range
417
416
root = (- half_b - sqrtd) / a
418
417
if root < tmin || tmax < root
419
418
root = (- half_b + sqrtd) / a
420
419
if root < tmin || tmax < root
421
- return nothing # no hit!
420
+ return nothing
422
421
end
423
422
end
424
423
425
424
t = root
426
425
p = point (r, t)
427
426
n⃗ = (p - s. center) / s. radius
428
- return ray_to_HitRecord (t, p, n⃗, r. dir, s. mat)
427
+ ray_to_HitRecord (t, p, n⃗, r. dir, s. mat)
429
428
end
430
429
431
430
# ╔═╡ 05e57afd-6eb9-42c5-9666-7be3771fa6b8
@@ -558,7 +557,7 @@ default_camera(SA[0f0,0f0,0f0]) # Float32 camera
558
557
# ╔═╡ 94081092-afc6-4359-bd2c-15e8407bf70e
559
558
@inline @fastmath function get_ray (c:: Camera{T} , s:: T , t:: T ) where T
560
559
rd = SVector {2,T} (c. lens_radius * random_vec2_in_disk (T))
561
- offset = c. u * rd. x + c. v * rd. y # offset = c.u * rd.x + c.v * rd.y
560
+ offset = c. u * rd. x + c. v * rd. y
562
561
Ray (c. origin + offset, normalize (c. lower_left_corner + s* c. horizontal +
563
562
t* c. vertical - c. origin - offset))
564
563
end
@@ -567,16 +566,14 @@ end
567
566
# example with Float32:
568
567
get_ray (default_camera (SA[0f0 ,0f0 ,0f0 ]), 0.0f0 , 0.0f0 )
569
568
570
- # ╔═╡ 891ce2c8-f8b2-472b-a8d9-389dafddcf22
571
- md " # Render
572
-
573
- (equivalent to final `main`)"
574
-
575
569
# ╔═╡ 90dbe8e5-139d-404a-bfed-177776dc5401
576
570
ELEM_TYPE = Float64 # default Element type
577
571
578
572
# ╔═╡ e4e74dd4-7f0d-4af7-9cf1-a615a0304293
579
- t_default_cam = default_camera (SA{ELEM_TYPE}[0 ,0 ,0 ])
573
+ t_default_cam = default_camera (SA{ELEM_TYPE}[0 ,0 ,0 ]);
574
+
575
+ # ╔═╡ 891ce2c8-f8b2-472b-a8d9-389dafddcf22
576
+ md " # Render"
580
577
581
578
# ╔═╡ 5f1bae02-d425-4a73-8668-d6383faba79d
582
579
md """ # Dielectrics
@@ -594,17 +591,13 @@ Refracted angle `sinθ′ = (η/η′)⋅sinθ`, where η (\eta) are the refract
594
591
Split the parts of the ray into `R′=R′⊥+R′∥` (perpendicular and parallel to n⃗′)."""
595
592
596
593
# ╔═╡ 9dc64353-c41c-45b4-aacd-12d5d6117c58
597
- # """
598
- # Args:
599
- # refraction_ratio: incident refraction index divided by refraction index of
600
- # hit surface. i.e. η/η′ in the figure above"""
601
594
@inline @fastmath function refract (dir:: Vec3{T} , n⃗:: Vec3{T} ,
602
595
refraction_ratio:: T ) where T
603
596
cosθ = min (- dir ⋅ n⃗, one (T))
604
597
r_out_perp = refraction_ratio * (dir + cosθ* n⃗)
605
598
r_out_parallel = -√ (abs (one (T)- squared_length (r_out_perp))) * n⃗
606
599
normalize (r_out_perp + r_out_parallel)
607
- end
600
+ end ;
608
601
609
602
# ╔═╡ bbfd4db5-3650-4f27-9777-2ff981c3d28b
610
603
begin # optional tests
@@ -685,39 +678,29 @@ end
685
678
686
679
687
680
# ╔═╡ 64104df6-4b79-4329-bfed-14619aa73e3c
688
- # """Render an image of `scene` using the specified camera, number of samples.
689
- #
690
- # Args:
691
- # scene: a HittableList, e.g. a list of spheres
692
- # n_samples: number of samples per pixel, eq. to C++ samples_per_pixel
693
- #
694
- # Equivalent to C++'s `main` function."""
695
681
function render (scene:: HittableList , cam:: Camera{T} , image_width= 400 ,
696
682
n_samples= 1 ) where T
697
683
# Image
698
- aspect_ratio = T (16.0 / 9.0 ) # TODO : use cam.aspect_ratio for consistency
684
+ aspect_ratio = T (16.0 / 9.0 )
699
685
image_height = convert (Int64, floor (image_width / aspect_ratio))
700
686
701
687
# Render
702
688
img = zeros (RGB{T}, image_height, image_width)
703
689
f32_image_width = convert (Float32, image_width)
704
690
f32_image_height = convert (Float32, image_height)
705
691
706
- # Reset the random seeds, so we always get the same images...
707
- # Makes comparing performance more accurate.
708
- reseed! ()
692
+ reseed! () # Reset the random seeds, to get same images... easier to compare perf!
709
693
710
- Threads. @threads for i in 1 : image_height
711
- @inbounds for j in 1 : image_width # iterate over each row (FASTER?!)
694
+ Threads. @threads for i in 1 : image_height # Use every allowed thread
695
+ @inbounds for j in 1 : image_width
712
696
accum_color = SA{T}[0 ,0 ,0 ]
713
697
u = convert (T, j/ image_width)
714
698
v = convert (T, (image_height- i)/ image_height) # i is Y-down, v is Y-up!
715
699
716
700
for s in 1 : n_samples
717
701
if s == 1 # 1st sample is always centered
718
702
δu = δv = T (0 )
719
- else
720
- # Supersampling antialiasing.
703
+ else # Supersampling antialiasing.
721
704
δu = trand (T) / f32_image_width
722
705
δv = trand (T) / f32_image_height
723
706
end
@@ -728,13 +711,10 @@ function render(scene::HittableList, cam::Camera{T}, image_width=400,
728
711
end
729
712
end
730
713
img
731
- end
732
-
733
- # ╔═╡ 9fd417cc-afa9-4f12-9c29-748f0522554c
734
- render (scene_2_spheres (; elem_type= ELEM_TYPE), t_default_cam, 200 , 1 ) # 1 sample
714
+ end ;
735
715
736
716
# ╔═╡ aa38117f-45e8-4070-a412-958f0ce19aa5
737
- render (scene_2_spheres (; elem_type= ELEM_TYPE), t_default_cam, 200 , 64 )
717
+ render (scene_2_spheres (; elem_type= ELEM_TYPE), t_default_cam, 200 , 64 ) # took 247ms
738
718
739
719
# ╔═╡ a2221922-31be-42f3-8f70-845fae385d2c
740
720
render (scene_4_spheres (; elem_type= ELEM_TYPE), t_default_cam, 200 , 256 )
@@ -775,7 +755,7 @@ md"# Positioning camera"
775
755
# ╔═╡ 7c75b0d8-578d-4ca9-8d74-935c1ac582b9
776
756
function scene_blue_red_spheres (; elem_type:: Type{T} ) where T
777
757
spheres = Sphere[]
778
- R = cos (pi / 4 )
758
+ R = cos (π / 4 )
779
759
push! (spheres, Sphere ((SA{T}[- R,0 ,- 1 ]), R, Lambertian (SA{T}[0 ,0 ,1 ])))
780
760
push! (spheres, Sphere ((SA{T}[ R,0 ,- 1 ]), R, Lambertian (SA{T}[1 ,0 ,0 ])))
781
761
HittableList (spheres)
@@ -837,13 +817,10 @@ end
837
817
838
818
# ╔═╡ a4b5d575-de27-4b44-a448-bd20be7d73ad
839
819
t_cam1 = default_camera ([13 ,2 ,3 ], [0 ,0 ,0 ], [0 ,1 ,0 ], 20 , 16 / 9 , 0.1 , 10.0 ;
840
- elem_type= ELEM_TYPE)
841
-
842
- # ╔═╡ 541aa3e5-4632-4f74-8088-f08fe24e07f8
843
- render (scene_random_spheres (; elem_type= ELEM_TYPE), t_cam1, 96 , 1 )
820
+ elem_type= ELEM_TYPE);
844
821
845
822
# ╔═╡ da047747-1845-4c2b-b3cb-eaa6534ce5ff
846
- render (scene_random_spheres (; elem_type= ELEM_TYPE), t_cam1, 320 , 64 )
823
+ render (scene_random_spheres (; elem_type= ELEM_TYPE), t_cam1, 320 , 32 ) # 1.1s
847
824
848
825
# ╔═╡ 00000000-0000-0000-0000-000000000001
849
826
PLUTO_PROJECT_TOML_CONTENTS = """
@@ -1857,11 +1834,10 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
1857
1834
# ╠═c1aef1be-79d4-4417-be36-ae8416465986
1858
1835
# ╠═94081092-afc6-4359-bd2c-15e8407bf70e
1859
1836
# ╠═813eaa13-2eb2-4302-9e4d-5d1dab0ac7c4
1860
- # ╟─891ce2c8-f8b2-472b-a8d9-389dafddcf22
1861
- # ╠═64104df6-4b79-4329-bfed-14619aa73e3c
1862
1837
# ╠═90dbe8e5-139d-404a-bfed-177776dc5401
1863
1838
# ╠═e4e74dd4-7f0d-4af7-9cf1-a615a0304293
1864
- # ╠═9fd417cc-afa9-4f12-9c29-748f0522554c
1839
+ # ╟─891ce2c8-f8b2-472b-a8d9-389dafddcf22
1840
+ # ╠═64104df6-4b79-4329-bfed-14619aa73e3c
1865
1841
# ╠═aa38117f-45e8-4070-a412-958f0ce19aa5
1866
1842
# ╠═a2221922-31be-42f3-8f70-845fae385d2c
1867
1843
# ╟─5f1bae02-d425-4a73-8668-d6383faba79d
@@ -1884,7 +1860,6 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
1884
1860
# ╟─3c54cde0-6509-45e1-a4a0-26c6aa840b8e
1885
1861
# ╠═a7d95d91-6571-4696-bad3-2979296d5f84
1886
1862
# ╠═a4b5d575-de27-4b44-a448-bd20be7d73ad
1887
- # ╠═541aa3e5-4632-4f74-8088-f08fe24e07f8
1888
1863
# ╠═da047747-1845-4c2b-b3cb-eaa6534ce5ff
1889
1864
# ╟─00000000-0000-0000-0000-000000000001
1890
1865
# ╟─00000000-0000-0000-0000-000000000002
0 commit comments