To be able to edit code and run cells, you need to run the notebook yourself. Where would you like to run the notebook?

In the cloud (experimental)

Binder is a free, open source service that runs scientific notebooks in the cloud! It will take a while, usually 2-7 minutes to get a session.

On your computer

(Recommended if you want to store your changes.)

  1. Copy the notebook URL:
  2. Run Pluto

    (Also see: How to install Julia and Pluto)

  3. Paste URL in the Open box

Frontmatter

If you are publishing this notebook on the web, you can set the parameters below to provide HTML metadata. This is useful for search engines and social media.

Author 1

0123456789 www

Pluto notebook adaptation of https://github.com/leios/simuleios/tree/master/raytracing

See https://www.youtube.com/watch?v=JwyQezsQkkw

👀 Reading hidden code
5.7 ms
👀 Reading hidden code
begin
import Pkg
Pkg.activate(mktempdir())
Pkg.add([
Pkg.PackageSpec(name="Plots", version="1"),
Pkg.PackageSpec(name="Images", version="0.23"),
Pkg.PackageSpec(name="ImageMagick"),
Pkg.PackageSpec(name="PlutoUI", version="0.6.8-0.6"),
Pkg.PackageSpec(name="ThreadsX"),
])
using Images
using Plots
using PlutoUI
using ThreadsX
end
❔
  Activating new project at `/tmp/jl_UC5bFu`
    Updating registry at `~/.julia/registries/General.toml`
   Resolving package versions...
   Installed ImageMagick ────── v1.3.0
   Installed Accessors ──────── v0.1.41
   Installed Referenceables ─── v0.1.3
   Installed InitialValues ──── v0.3.1
   Installed GR_jll ─────────── v0.72.8+0
   Installed Images ─────────── v0.23.3
   Installed DefineSingletons ─ v0.1.2
   Installed SpecialFunctions ─ v1.8.8
   Installed MicroCollections ─ v0.2.0
   Installed StatsBase ──────── v0.33.21
   Installed BangBang ───────── v0.4.3
   Installed ArgCheck ───────── v2.4.0
   Installed Libtiff_jll ────── v4.4.0+0
   Installed ImageShow ──────── v0.2.3
   Installed ColorVectorSpace ─ v0.8.7
   Installed CompositionsBase ─ v0.1.2
   Installed ThreadsX ───────── v0.1.12
   Installed OpenSSL_jll ────── v1.1.23+1
   Installed ColorTypes ─────── v0.10.12
   Installed Transducers ────── v0.4.84
   Installed Plots ──────────── v1.40.7
   Installed WoodburyMatrices ─ v0.5.6
   Installed SplittablesBase ── v0.1.15
   Installed Baselet ────────── v0.1.1
   Installed Interpolations ─── v0.13.6
   Installed GR ─────────────── v0.72.8
   Installed FFMPEG_jll ─────── v4.4.2+2
    Updating `/tmp/jl_UC5bFu/Project.toml`
  [6218d12a] + ImageMagick v1.3.0
  [916415d5] + Images v0.23.3
  [91a5bcdd] + Plots v1.40.7
  [7f904dfe] + PlutoUI v0.6.11
  [ac1d9e8a] + ThreadsX v0.1.12
    Updating `/tmp/jl_UC5bFu/Manifest.toml`
  [621f4979] + AbstractFFTs v1.5.0
  [7d9f7c33] + Accessors v0.1.41
  [79e6a3ab] + Adapt v4.3.0
  [dce04be8] + ArgCheck v2.4.0
  [13072b0f] + AxisAlgorithms v1.0.1
  [39de3d68] + AxisArrays v0.4.7
  [198e06fe] + BangBang v0.4.3
  [9718e550] + Baselet v0.1.1
  [d1d4a3ce] + BitFlags v0.1.9
  [aafaddc9] + CatIndices v0.2.2
  [d360d2e6] + ChainRulesCore v1.25.1
  [9e997f8a] + ChangesOfVariables v0.1.10
  [944b1d66] + CodecZlib v0.7.8
  [35d6a980] + ColorSchemes v3.26.0
  [3da002f7] + ColorTypes v0.10.12
  [c3611d14] + ColorVectorSpace v0.8.7
  [5ae59095] + Colors v0.12.11
  [34da2185] + Compat v4.16.0
  [a33af91c] + CompositionsBase v0.1.2
  [ed09eef8] + ComputationalResources v0.3.2
  [f0e56b4a] + ConcurrentUtilities v2.5.0
  [187b0558] + ConstructionBase v1.5.8
  [d38c429a] + Contour v0.6.3
  [150eb455] + CoordinateTransformations v0.6.3
  [dc8bdbbb] + CustomUnitRanges v1.0.2
  [9a962f9c] + DataAPI v1.16.0
  [864edb3b] + DataStructures v0.18.22
  [e2d170a0] + DataValueInterfaces v1.0.0
  [244e2a9f] + DefineSingletons v0.1.2
  [b4f34e82] + Distances v0.10.12
  [ffbed154] + DocStringExtensions v0.9.5
  [460bff9d] + ExceptionUnwrapping v0.1.11
  [c87230d0] + FFMPEG v0.4.2
  [4f61f5a4] + FFTViews v0.3.2
  [7a1cc6ca] + FFTW v1.9.0
  [5789e2e9] + FileIO v1.17.0
  [53c48c17] + FixedPointNumbers v0.8.5
  [1fa38f19] + Format v1.3.7
  [28b8d3ca] + GR v0.72.8
  [a2bd30eb] + Graphics v1.1.3
  [42e2da0e] + Grisu v1.0.2
  [cd3eb016] + HTTP v1.10.16
  [bbac6d45] + IdentityRanges v0.3.1
  [2803e5a7] + ImageAxes v0.6.9
  [f332f351] + ImageContrastAdjustment v0.3.7
  [a09fc81d] + ImageCore v0.8.22
  [51556ac3] + ImageDistances v0.2.13
  [6a3955dd] + ImageFiltering v0.6.21
  [6218d12a] + ImageMagick v1.3.0
  [bc367c6b] + ImageMetadata v0.9.5
  [787d08f9] + ImageMorphology v0.2.11
  [2996bd0c] + ImageQualityIndexes v0.2.2
  [4e3cecfd] + ImageShow v0.2.3
  [02fcd773] + ImageTransformations v0.8.13
  [916415d5] + Images v0.23.3
  [9b13fd28] + IndirectArrays v0.5.1
  [22cec73e] + InitialValues v0.3.1
  [a98d9a8b] + Interpolations v0.13.6
  [8197267c] + IntervalSets v0.7.11
  [3587e190] + InverseFunctions v0.1.17
  [92d709cd] + IrrationalConstants v0.1.1
  [c8e1da08] + IterTools v1.4.0
  [82899510] + IteratorInterfaceExtensions v1.0.0
  [1019f520] + JLFzf v0.1.11
  [692b3bcd] + JLLWrappers v1.7.0
  [682c06a0] + JSON v0.21.4
  [b964fa9f] + LaTeXStrings v1.4.0
  [23fbe1c1] + Latexify v0.16.8
  [2ab3a3ac] + LogExpFunctions v0.3.28
  [e6f89c97] + LoggingExtras v1.1.0
  [1914dd2f] + MacroTools v0.5.16
  [dbb5928d] + MappedArrays v0.4.2
  [739be429] + MbedTLS v1.1.9
  [442fdcdd] + Measures v0.3.2
  [128add7d] + MicroCollections v0.2.0
  [e1d29d7a] + Missings v1.2.0
  [e94cdb99] + MosaicViews v0.3.4
  [77ba4419] + NaNMath v1.0.3
  [6fe1bfb0] + OffsetArrays v1.17.0
  [4d8831e6] + OpenSSL v1.5.0
  [bac558e1] + OrderedCollections v1.8.1
  [5432bcbf] + PaddedViews v0.5.12
  [d96e819e] + Parameters v0.12.3
  [69de0a69] + Parsers v2.8.3
  [ccf2f8ad] + PlotThemes v3.3.0
  [995b91a9] + PlotUtils v1.4.3
  [91a5bcdd] + Plots v1.40.7
  [7f904dfe] + PlutoUI v0.6.11
  [aea7be01] + PrecompileTools v1.2.1
  [21216c6a] + Preferences v1.4.3
  [94ee1d12] + Quaternions v0.7.6
  [b3c3ace0] + RangeArrays v0.3.2
  [c84ed2f1] + Ratios v0.4.5
  [c1ae055f] + RealDot v0.1.0
  [3cdcf5f2] + RecipesBase v1.3.4
  [01d81517] + RecipesPipeline v0.6.12
  [189a3867] + Reexport v1.2.2
  [42d2dcc6] + Referenceables v0.1.3
  [05181044] + RelocatableFolders v1.0.1
  [ae029012] + Requires v1.3.1
  [6038ab10] + Rotations v1.7.1
  [6c6a2e73] + Scratch v1.2.1
  [efcf1570] + Setfield v1.1.2
  [992d4aef] + Showoff v1.0.3
  [777ac1f9] + SimpleBufferStream v1.2.0
  [699a6c99] + SimpleTraits v0.9.4
  [a2af1166] + SortingAlgorithms v1.2.1
  [276daf66] + SpecialFunctions v1.8.8
  [171d559e] + SplittablesBase v0.1.15
  [860ef19b] + StableRNGs v1.0.3
  [cae243ae] + StackViews v0.1.2
  [90137ffa] + StaticArrays v1.9.13
  [1e83bf80] + StaticArraysCore v1.4.3
  [82ae8749] + StatsAPI v1.7.1
  [2913bbd2] + StatsBase v0.33.21
  [fd094767] + Suppressor v0.2.8
  [3783bdb8] + TableTraits v1.0.1
  [bd369af6] + Tables v1.12.1
  [ac1d9e8a] + ThreadsX v0.1.12
  [06e1c1a7] + TiledIteration v0.3.1
  [3bb67fe8] + TranscodingStreams v0.11.3
  [28d57a85] + Transducers v0.4.84
  [5c2747f8] + URIs v1.5.2
  [3a884ed6] + UnPack v1.0.2
  [1cfade01] + UnicodeFun v0.4.1
  [1986cc42] + Unitful v1.23.1
  [45397f5d] + UnitfulLatexify v1.7.0
  [41fe7b60] + Unzip v0.2.0
  [efce3f68] + WoodburyMatrices v0.5.6
  [6e34b625] + Bzip2_jll v1.0.9+0
  [83423d85] + Cairo_jll v1.18.5+0
  [ee1fde0b] + Dbus_jll v1.16.2+0
  [2702e6a9] + EpollShim_jll v0.0.20230411+1
  [2e619515] + Expat_jll v2.6.5+0
  [b22a6f82] + FFMPEG_jll v4.4.2+2
  [f5851436] + FFTW_jll v3.3.11+0
  [a3f928ae] + Fontconfig_jll v2.16.0+0
  [d7e528f0] + FreeType2_jll v2.13.4+0
  [559328eb] + FriBidi_jll v1.0.17+0
  [0656b61e] + GLFW_jll v3.4.0+2
  [d2c73de3] + GR_jll v0.72.8+0
  [78b55507] + Gettext_jll v0.21.0+0
  [7746bdde] + Glib_jll v2.84.0+0
  [3b182d85] + Graphite2_jll v1.3.15+0
  [2e76f6c2] + HarfBuzz_jll v8.5.1+0
  [c73af94c] + ImageMagick_jll v6.9.10-12+3
  [1d5cc7b8] + IntelOpenMP_jll v2025.0.4+0
  [aacddb02] + JpegTurbo_jll v3.1.1+0
  [c1c5ebd0] + LAME_jll v3.100.2+0
  [88015f11] + LERC_jll v3.0.0+1
  [1d63c593] + LLVMOpenMP_jll v18.1.8+0
  [dd4b983a] + LZO_jll v2.10.3+0
  [e9f186c6] + Libffi_jll v3.4.7+0
  [7e76a0d4] + Libglvnd_jll v1.7.1+1
  [94ce4f54] + Libiconv_jll v1.18.0+0
  [4b2f31a3] + Libmount_jll v2.41.0+0
  [89763e89] + Libtiff_jll v4.4.0+0
  [38a345b3] + Libuuid_jll v2.41.0+0
  [856f044c] + MKL_jll v2025.0.1+1
  [e7412a2a] + Ogg_jll v1.3.5+1
  [458c3c95] + OpenSSL_jll v1.1.23+1
  [efe28fd5] + OpenSpecFun_jll v0.5.6+0
  [91d4177d] + Opus_jll v1.3.3+0
  [36c8627f] + Pango_jll v1.56.3+0
  [30392449] + Pixman_jll v0.44.2+0
  [ea2cea3b] + Qt5Base_jll v5.15.3+2
  [a2964d1f] + Wayland_jll v1.23.1+0
  [2381bf8a] + Wayland_protocols_jll v1.44.0+0
  [02c8fc9c] + XML2_jll v2.13.6+1
  [4f6342f7] + Xorg_libX11_jll v1.8.12+0
  [0c0b7dd1] + Xorg_libXau_jll v1.0.13+0
  [935fb764] + Xorg_libXcursor_jll v1.2.4+0
  [a3789734] + Xorg_libXdmcp_jll v1.1.6+0
  [1082639a] + Xorg_libXext_jll v1.3.7+0
  [d091e8ba] + Xorg_libXfixes_jll v6.0.1+0
  [a51aa0fd] + Xorg_libXi_jll v1.8.3+0
  [d1454406] + Xorg_libXinerama_jll v1.1.6+0
  [ec84b674] + Xorg_libXrandr_jll v1.5.5+0
  [ea2f1a96] + Xorg_libXrender_jll v0.9.12+0
  [c7cfdc94] + Xorg_libxcb_jll v1.17.1+0
  [cc61e674] + Xorg_libxkbfile_jll v1.1.3+0
  [12413925] + Xorg_xcb_util_image_jll v0.4.1+0
  [2def613f] + Xorg_xcb_util_jll v0.4.1+0
  [975044d2] + Xorg_xcb_util_keysyms_jll v0.4.1+0
  [0d47668e] + Xorg_xcb_util_renderutil_jll v0.3.10+0
  [c22f9ab0] + Xorg_xcb_util_wm_jll v0.4.2+0
  [35661453] + Xorg_xkbcomp_jll v1.4.7+0
  [33bec58e] + Xorg_xkeyboard_config_jll v2.44.0+0
  [c5fb5394] + Xorg_xtrans_jll v1.6.0+0
  [3161d3a3] + Zstd_jll v1.5.7+1
  [214eeab7] + fzf_jll v0.61.1+0
  [a4ae2306] + libaom_jll v3.11.0+0
  [0ac62f75] + libass_jll v0.15.2+0
  [1183f4f0] + libdecor_jll v0.2.2+0
  [f638f0a6] + libfdk_aac_jll v2.0.3+0
  [b53b4c65] + libpng_jll v1.6.49+0
  [f27f6e37] + libvorbis_jll v1.3.7+2
  [1317d2d5] + oneTBB_jll v2022.0.0+0
  [1270edf5] + x264_jll v2021.5.5+0
  [dfaa095f] + x265_jll v3.5.0+0
  [d8fb68d0] + xkbcommon_jll v1.8.1+0
  [0dad84c5] + ArgTools
  [56f22d72] + Artifacts
  [2a0f44e3] + Base64
  [ade2ca70] + Dates
  [8bb1440f] + DelimitedFiles
  [8ba89e20] + Distributed
  [f43a241f] + Downloads
  [7b1f6079] + FileWatching
  [9fa8497b] + Future
  [b77e0a4c] + InteractiveUtils
  [4af54fe1] + LazyArtifacts
  [b27032c2] + LibCURL
  [76f85450] + LibGit2
  [8f399da3] + Libdl
  [37e2e46d] + LinearAlgebra
  [56ddb016] + Logging
  [d6f4376e] + Markdown
  [a63ad114] + Mmap
  [ca575930] + NetworkOptions
  [44cfe95a] + Pkg
  [de0858da] + Printf
  [3fa0cd96] + REPL
  [9a3f8284] + Random
  [ea8e919c] + SHA
  [9e88b42a] + Serialization
  [1a1011a3] + SharedArrays
  [6462fe0b] + Sockets
  [2f01184e] + SparseArrays
  [10745b16] + Statistics
  [fa267f1f] + TOML
  [a4e569a6] + Tar
  [8dfed614] + Test
  [cf7118a7] + UUIDs
  [4ec0a83e] + Unicode
  [e66e0078] + CompilerSupportLibraries_jll
  [deac9b47] + LibCURL_jll
  [29816b5a] + LibSSH2_jll
  [c8ffd9c3] + MbedTLS_jll
  [14a3606d] + MozillaCACerts_jll
  [4536629a] + OpenBLAS_jll
  [05823500] + OpenLibm_jll
  [efcefdf7] + PCRE2_jll
  [83775a58] + Zlib_jll
  [8e850b90] + libblastrampoline_jll
  [8e850ede] + nghttp2_jll
  [3f19e933] + p7zip_jll
Precompiling project...
CompositionsBase
ArgCheck
WoodburyMatrices
DefineSingletons
InitialValues
Referenceables
OpenSSL_jll
Baselet
SplittablesBase
Libtiff_jll
AxisAlgorithms
OpenSSL
Accessors
Qt5Base_jll
FFMPEG_jll
StatsBase
ImageMagick_jll
BangBang
FFMPEG
SpecialFunctions
GR_jll
MicroCollections
HTTP
Interpolations
ColorTypes
Transducers
GR
ThreadsX
Colors
Graphics
ColorVectorSpace
ImageCore
ImageShow
ImageAxes
ImageMorphology
ImageMagick
ImageMetadata
ImageTransformations
ImageDistances
ColorSchemes
ImageContrastAdjustment
PlotUtils
PlotThemes
RecipesPipeline
ImageFiltering
ImageQualityIndexes
Images
Plots
  48 dependencies successfully precompiled in 81 seconds (161 already precompiled)
94.0 s
👀 Reading hidden code
using LinearAlgebra
286 μs
👀 Reading hidden code
using Test
234 μs
👀 Reading hidden code
# TODO: get refraction to work without offsets in quadratic / inside_of fxs
# Also, use dot product to see if exiting lens

function Base.isapprox(n1::Nothing, n2::Nothing)
return true
end
337 μs
# For now, all cameras are aligned on the z axis
struct Camera
# Set of all pixels, counts as scene resolution
pixels

# physical size of aperture
size::Vector{Float64}

# camera's distance from screen
focal_length::Float64

# camera's position
p::Vector{Float64}
end
👀 Reading hidden code
1.4 ms
struct Ray
# Velocity vector
v::Vector{Float64}

# Position vector
p::Vector{Float64}

# Color
c::RGB
end
👀 Reading hidden code
1.4 ms
struct Surface

# Reflectivity
r::Float64

# Transmission
t::Float64

# Color
c::RGBA

# index of refraction
ior::Float64

function Surface(in_r, in_t, in_c, in_ior)
if !isapprox(in_r+in_t+in_c.alpha, 1)
error("invalid surface definition, RTC < 1")
end
new(in_r,in_t,in_c, in_ior)
end

Surface(in_r, in_t, in_c::Float64, in_ior) =
new(in_r, in_t, RGBA(0,0,0,0), in_ior)
end
👀 Reading hidden code
1.7 ms
abstract type Object end
👀 Reading hidden code
329 μs
struct Sphere <: Object
# Lens position
p::Vector{Float64}

# Lens radius
r::Float64

s::Surface
end
👀 Reading hidden code
1.3 ms
Lens (generic function with 1 method)
function Lens(p, r, ior)
return Sphere(p, r, Surface(0,1,RGBA(0,0,0,0),ior))
end
👀 Reading hidden code
430 μs
ReflectingSphere (generic function with 1 method)
function ReflectingSphere(p, r)
return Sphere(p,r,Surface(1,0,RGBA(0,0,0,0),0))
end
👀 Reading hidden code
440 μs
ColoredSphere (generic function with 1 method)
function ColoredSphere(p, r, c::RGB)
return Sphere(p, r, Surface(0,0,RGBA(c), 0))
end
👀 Reading hidden code
452 μs
mutable struct SkyBox <: Object
# Skybox position
p::Vector{Float64}

# Skybox radius
r::Float64
end
👀 Reading hidden code
1.3 ms
sphere_normal_at (generic function with 1 method)
function sphere_normal_at(ray, sphere)
n = normalize(ray.p .- sphere.p)

return n
end
👀 Reading hidden code
509 μs
inside_of (generic function with 1 method)
function inside_of(ray::Ray, sphere)
return inside_of(ray.p, sphere)
end
👀 Reading hidden code
429 μs
inside_of (generic function with 2 methods)
function inside_of(pos, sphere)
x = sphere.p[1] - pos[1]
y = sphere.p[2] - pos[2]
if (x^2 + y^2 <= sphere.r^2)
return true
else
return false
end
end
👀 Reading hidden code
884 μs
refract (generic function with 1 method)
function refract(ray, lens::Sphere, ior)
# note: light moves at a particular speed with respect to the medium it is
# moving through, so...
# n_2*v = n_1*l + (n_1*cos(theta_1) - n_2*cos(theta_2))*n
# Other approximations: ior = n_1/n_2, c = -n*l
n = sphere_normal_at(ray, lens)

if dot(n, ray.v) > 0
n .*= -1
end
c = dot(-n, ray.v);
d = 1.0 - ior^2 * (1.0 - c^2);

if (d < 0.0)
reflect!(ray, n)
return
end

ray_vel = ior * ray.v + (ior * c - sqrt(d)) * n;
return Ray(ray_vel, ray.p, ray.c)
end
👀 Reading hidden code
1.2 ms
abstract type Wall <: Object end;
👀 Reading hidden code
352 μs
mutable struct Mirror <: Wall
# Normal vector
n::Vector{Float64}

# Position of mirror
p::Vector{Float64}

# Mirror size
scale::Float64

Mirror(in_n, in_p) = new(in_n, in_p, 2.5)
end
👀 Reading hidden code
1.1 ms
is_behind (generic function with 1 method)
function is_behind(ray, mirror)
if dot(ray.p.-mirror.p, mirror.n) >= 0
return true
else
return false
end
end
👀 Reading hidden code
581 μs
reflect (generic function with 1 method)
# note: for reflection, l_x -> l_x, but l_y -> -l_y
# In this case, the y component of l = cos(theta)*n
# so new vector: v = l + 2cos(theta)*n
function reflect(ray, n)
ray_vel = ray.v .- 2*dot(ray.v, n).*n
ray_pos = ray.p .+ 0.001*ray.v
return Ray(ray_vel, ray_pos, ray.c)
end
👀 Reading hidden code
780 μs
draw_circle (generic function with 1 method)
👀 Reading hidden code
1.0 ms
plot_rays (generic function with 1 method)
👀 Reading hidden code
2.7 ms
step (generic function with 1 method)
function step(ray::Ray, dt)
ray.p .+= .+ ray.v.*dt
return ray
end
👀 Reading hidden code
556 μs
intersection(
Ray([1.0, 0.0, 0.0], [0.0, 0.0, 0.0], RGB(0,0,0)),
SkyBox([2.0,0,0], 10000)
)
👀 Reading hidden code
24.8 ms
# begin
# function intersection(ray::Ray, skybox::SkyBox;
# threshold = 0.01)

# return skybox.r * ray.v
# end
# function intersection(ray::Ray, sphere::Sphere;
# threshold = 0.01)
# relative_dist = ray.p-sphere.p

# a = dot(ray.v, ray.v)
# b = 2.0 * dot(relative_dist, ray.v)
# c = dot(relative_dist, relative_dist) - sphere.r*sphere.r
# discriminant = b*b - 4*a*c

# if discriminant < 0
# return nothing
# elseif discriminant > 0
# roots = [(-b + sqrt(discriminant)) / (2*a),
# (-b - sqrt(discriminant)) / (2*a)]
# min = minimum(roots)
# max = maximum(roots)

# if min > threshold
# return (min)*ray.v
# elseif max > threshold
# return (max)*ray.v
# else
# return nothing
# end
# else
# # Returns nothing if tangential
# return nothing
# #return (-b/(2*a))*ray.v
# end
# end
# end
👀 Reading hidden code
9.1 μs
intersection (generic function with 1 method)
function intersection(ray::Ray, sphere::S;
threshold = 0.01) where
{S <: Union{Sphere, SkyBox}}
relative_dist = ray.p-sphere.p
a = dot(ray.v, ray.v)
b = 2.0 * dot(relative_dist, ray.v)
c = dot(relative_dist, relative_dist) - sphere.r*sphere.r
discriminant = b*b - 4*a*c

if discriminant < 0
return nothing
elseif discriminant > 0
roots = [(-b + sqrt(discriminant)) / (2*a),
(-b - sqrt(discriminant)) / (2*a)]
min = minimum(roots)
max = maximum(roots)
if min > threshold
return (min)*ray.v
elseif max > threshold
return (max)*ray.v
else
return nothing
end
else
# Returns nothing if tangential
return nothing
#return (-b/(2*a))*ray.v
end
end
👀 Reading hidden code
2.7 ms
intersection (generic function with 2 methods)
function intersection(ray::Ray, wall::W) where {W <: Wall}
intersection_pt = -dot((ray.p .- wall.p),wall.n)/dot(ray.v, wall.n)

if isfinite(intersection_pt) && intersection_pt > 0 &&
intersection_pt != NaN
return intersection_pt*ray.v
else
return nothing
end
end
👀 Reading hidden code
909 μs
propagate (generic function with 1 method)
function propagate(rays::Array{Ray}, objects::Vector{O},
num_intersections) where {O <: Object}
Threads.@threads for j = 1:length(rays)
rays[j] = propagate(rays[j], objects, num_intersections)
end

return rays
end
👀 Reading hidden code
29.7 ms
propagate (generic function with 2 methods)
function propagate(ray::Ray, objects::Vector{O},
num_intersections) where {O <: Object}

for i = 1:num_intersections
if ray.v != zeros(length(ray.v))
intersect_final = [Inf, Inf]
intersected_object = nothing
for object in objects
intersect = intersection(ray, object)
if intersect != nothing &&
sum(intersect[:].^2) < sum(intersect_final[:].^2)
intersect_final = intersect
intersected_object = object
end
end

if intersected_object != nothing
ray.p .+= intersect_final
if intersected_object isa Sphere
if !isapprox(intersected_object.s.t, 0)
ior = 1/intersected_object.s.ior
if dot(ray.v,
sphere_normal_at(ray,
intersected_object)) > 0
ior = intersected_object.s.ior
end

ray = refract(ray, intersected_object, ior)
elseif !isapprox(intersected_object.s.r, 0)
n = sphere_normal_at(ray, intersected_object)
ray = reflect(ray, n)
elseif !isapprox(intersected_object.s.c.alpha, 0)
ray_color = RGB(intersected_object.s.c)
ray_vel = zeros(length(ray.v))
ray = Ray(ray_vel, ray.p, ray_color)
end

elseif intersected_object isa Mirror
ray = reflect(ray, intersected_object.n)
elseif intersected_object isa SkyBox
ray_color = pixel_color(ray.p)
ray_vel = zeros(length(ray.v))
ray = Ray(ray_vel, ray.p, ray_color)
end
else
println("hit nothing")
end
end
end

return ray
end
👀 Reading hidden code
3.4 ms
pixel_color (generic function with 1 method)
function pixel_color(position)
extents = 1000.0
c = RGB(0)
if position[1] < extents && position[1] > -extents
c += RGB((position[1]+extents)/(2.0*extents), 0, 0)
else
println(position)
end

if position[2] < extents && position[2] > -extents
c += RGB(0,0,(position[2]+extents)/(2.0*extents))
else
println(position)
end

if position[3] < extents && position[3] > -extents
c += RGB(0,(position[3]+extents)/(2.0*extents), 0)
else
println(position)
end

return c
end
👀 Reading hidden code
1.4 ms
convert_to_img (generic function with 1 method)
function convert_to_img(rays::Array{Ray}, filename)
color_array = Array{RGB}(undef, size(rays)[2], size(rays)[1])
for i = 1:length(color_array)
color_array[i] = rays[i].c
end

save(filename, color_array)
end
👀 Reading hidden code
1.0 ms
CartesianIndex(1, 2)
CartesianIndex(1,2)
👀 Reading hidden code
11.7 μs
init_rays (generic function with 1 method)
function init_rays(cam::Camera)

res = size(cam.pixels)
dim = cam.size

pixel_width = dim ./ res

# create a set of rays that go through every pixel in our grid.
rays = map(CartesianIndices(cam.pixels)) do I
pixel_loc = [cam.p[1] + 0.5*dim[1] - I[1]*dim[1]/res[1] +
0.5*pixel_width[1],
cam.p[2] + 0.5*dim[2] - I[2]*dim[2]/res[2] +
0.5*pixel_width[2],
cam.p[3]+cam.focal_length]
l = normalize(pixel_loc - cam.p)
Ray(l, pixel_loc, RGB(0))
end

return rays

end
👀 Reading hidden code
2.2 ms
ray_trace (generic function with 1 method)
function ray_trace(objects::Vector{O}, cam::Camera; filename="check.png",
num_intersections = 10) where {O <: Object}

rays = init_rays(cam)

rays = propagate(rays, objects, num_intersections)

# convert_to_img(rays, filename)

return rays
end
👀 Reading hidden code
1.7 ms
as_image (generic function with 1 method)
function as_image(rays::Array{Ray})
[r.c for r in rays]
end
👀 Reading hidden code
831 μs
sky = [SkyBox([0.0, 0.0, 0.0], 1000)]
👀 Reading hidden code
17.3 μs
objects (generic function with 1 method)
objects(t) = vcat(sky, spheres(t))
👀 Reading hidden code
385 μs
Error message

UndefVarError: t not defined

Stack trace

Here is what happened, the most recent locations are first:

  1. t
C'est la vie !
t
👀 Reading hidden code
---

👀 Reading hidden code
80.1 μs
spheres (generic function with 1 method)
spheres(t) = [
ReflectingSphere([0,0,-25], 10),
# ColoredSphere([0,0,-25], 5, RGB(0.75, .65, 0.1)),
# ReflectingSphere([50 * sin(t), 0, 50 * cos(t) - 25], 15),
Lens([50 * sin(t), 0, 50 * cos(t) - 25], 15, 1.5),
Lens([-50 * sin(t), 0, -50*cos(t) - 25], 15, 1.5),
Lens([-50 * sin(t + 2pi/3), 0, -50*cos(t + 2pi/3) - 25], 15, 1.5),
Lens([-50 * sin(t + 4pi/3), 0, -50*cos(t + 4pi/3) - 25], 15, 1.5),
]
👀 Reading hidden code
1.6 ms
doit (generic function with 1 method)
doit(T, highres) = let
# blank_img = Array{RGB}(undef, 1920,1080)
blank_img = if highres
Array{RGB}(undef, 800, 320)
else
Array{RGB}(undef, 200, 80)
end
repeat
blank_img[:] .= RGB(0)

cam = Camera(blank_img, [16,6], -10, [0,0,100])

ray_trace(objects(T / 100), cam) |> as_image
end |> transpose
👀 Reading hidden code
941 μs
@bind T Slider(1:200)
👀 Reading hidden code
209 ms

High resolution:

👀 Reading hidden code
45.7 ms
doit(T, highres)
👀 Reading hidden code
917 ms
👀 Reading hidden code
8.6 μs
👀 Reading hidden code
70.2 μs
👀 Reading hidden code
67.0 μs