Raytracing a Triangular Mesh
using Krang
import GLMakie as GLMk
using GeometryBasics
using FileIO
metric = Krang.Kerr(0.99) # Kerr metric with a spin of 0.99
θo = 90 / 180 * π # Inclination angle of the observer
ρmax = 12.0 # Horizontal and Vertical extent of the screen
sze = 100 # Resolution of the screen is sze x sze
camera = Krang.SlowLightIntensityCamera(metric, θo, -ρmax, ρmax, -ρmax, ρmax, sze)SlowLightIntensityCamera{Krang.SlowLightIntensityScreen{Float64, Matrix{Float64}, Matrix{ComplexF64}}}(Kerr{Float64}(1.0, 0.99), Krang.SlowLightIntensityScreen{Float64, Matrix{Float64}, Matrix{ComplexF64}}((-12.0, 12.0), (-12.0, 12.0), Kerr{Float64}(1.0, 0.99), 1.5707963267948966, [-12.0 -12.0 … -12.0 -12.0; -11.757575757575758 -11.757575757575758 … -11.757575757575758 -11.757575757575758; … ; 11.757575757575758 11.757575757575758 … 11.757575757575758 11.757575757575758; 12.0 12.0 … 12.0 12.0], [-12.0 -11.757575757575758 … 11.757575757575758 12.0; -12.0 -11.757575757575758 … 11.757575757575758 12.0; … ; -12.0 -11.757575757575758 … 11.757575757575758 12.0; -12.0 -11.757575757575758 … 11.757575757575758 12.0], ComplexF64[-17.811393086775468 - 3.6622313808008166e-17im -17.638476027306 - 2.5119566969130612e-17im … -17.638476027306 - 2.5119566969130612e-17im -17.811393086775468 - 3.6622313808008166e-17im; -17.640437321470174 - 2.4530065262927847e-17im -17.465724293757646 - 2.5252190636852947e-17im … -17.465724293757646 - 2.5252190636852947e-17im -17.640437321470174 - 2.4530065262927847e-17im; … ; -17.781479386402786 - 4.969222631444887e-17im -17.609506000215994 - 3.408011043629016e-17im … -17.609506000215994 - 3.408011043629016e-17im -17.781479386402786 - 4.969222631444887e-17im; -17.952668704272526 - 3.2765377669138564e-17im -17.7824416240653 - 5.053263097256706e-17im … -17.7824416240653 - 5.053263097256706e-17im -17.952668704272526 - 3.2765377669138564e-17im], ComplexF64[0.3222351305493678 + 1.2554506945771609e-15im 0.31478822909250326 + 8.454330522229745e-16im … 0.31478822909250326 + 8.454330522229745e-16im 0.3222351305493678 + 1.2554506945771609e-15im; 0.3305713202666123 + 8.454985646270429e-16im 0.32306161221907637 + 8.542281192425115e-16im … 0.32306161221907637 + 8.542281192425115e-16im 0.3305713202666123 + 8.454985646270429e-16im; … ; 0.26163540322435885 + 1.2663858277683034e-15im 0.25504723925106276 + 8.529391086302426e-16im … 0.25504723925106276 + 8.529391086302426e-16im 0.26163540322435885 + 1.2663858277683034e-15im; 0.25561836422800255 + 8.357723444881215e-16im 0.24910086974177226 + 1.2662896490723065e-15im … 0.24910086974177226 + 1.2662896490723065e-15im 0.25561836422800255 + 8.357723444881215e-16im], ComplexF64[1.5419781346644301 - 1.2759301128716357e-15im 1.5466851612338912 - 8.596354078342111e-16im … 1.5466851612338912 - 8.596354078342111e-16im 1.5419781346644301 - 1.2759301128716357e-15im; 1.534155704198171 - 8.593965268063112e-16im 1.5388774673628065 - 8.68697217553463e-16im … 1.5388774673628065 - 8.68697217553463e-16im 1.534155704198171 - 8.593965268063112e-16im; … ; 1.9482024385129888 - 1.3015057232471788e-15im 1.959574258655218 - 8.774316195876013e-16im … 1.959574258655218 - 8.774316195876013e-16im 1.9482024385129888 - 1.3015057232471788e-15im; 1.9534780245174446 - 8.5861149839102065e-16im 1.9646605627738465 - 1.3020934455761203e-15im … 1.9646605627738465 - 1.3020934455761203e-15im 1.9534780245174446 - 8.5861149839102065e-16im], ComplexF64[15.947179821561672 + 5.7101732102483e-17im 15.777002636979606 + 3.932192258036724e-17im … 15.777002636979606 + 3.932192258036724e-17im 15.947179821561672 + 5.7101732102483e-17im; 15.775710297005393 + 3.8428027442196094e-17im 15.603785214175762 + 3.9721288947804355e-17im … 15.603785214175762 + 3.9721288947804355e-17im 15.775710297005393 + 3.8428027442196094e-17im; … ; 15.57164154466544 + 8.48121217933244e-17im 15.394884502309713 + 5.857262139364886e-17im … 15.394884502309713 + 5.857262139364886e-17im 15.57164154466544 + 8.48121217933244e-17im; 15.743572315527079 + 5.560453157203775e-17im 15.568680191549678 + 8.63364274763809e-17im … 15.568680191549678 + 8.63364274763809e-17im 15.743572315527079 + 5.560453157203775e-17im], [0.10027124075812203 0.101372414125879 … 0.101372414125879 0.10027124075812203; 0.10138231105047828 0.10251985582662305 … 0.10251985582662305 0.10138231105047828; … ; 0.103156828843341 0.10437921921156745 … 0.10437921921156745 0.103156828843341; 0.10200223134145532 0.1031843291537721 … 0.1031843291537721 0.10200223134145532], [0.20054248151624407 0.202744828251758 … 0.202744828251758 0.20054248151624407; 0.20276462210095655 0.2050397116532461 … 0.2050397116532461 0.20276462210095655; … ; 0.206313657686682 0.2087584384231349 … 0.2087584384231349 0.206313657686682; 0.20400446268291064 0.2063686583075442 … 0.2063686583075442 0.20400446268291064], [3.1948265198800945 3.16735588607714 … 3.16735588607714 3.1948265198800945; 3.2477381116067816 3.219288486870959 … 3.219288486870959 3.2477381116067816; … ; -1.7925822533610245 -1.7722671921105388 … -1.7722671921105388 -1.7925822533610245; -1.7809590013311702 -1.7612081103544948 … -1.7612081103544948 -1.7809590013311702], [7.300113474580925 7.200050727203687 … 7.200050727203687 7.300113474580925; 7.025903203700694 6.925957571906117 … 6.925957571906117 7.025903203700694; … ; 23.940178550610653 23.738179537197063 … 23.738179537197063 23.940178550610653; 24.074212683041594 23.875316012316453 … 23.875316012316453 24.074212683041594], [-2.1933076951002244 -2.1843464618842914 … -2.1843464618842914 -2.1933076951002244; -2.1829743720202877 -2.173824128209073 … -2.173824128209073 -2.1829743720202877; … ; -2.2062469640588125 -2.1976301247423478 … -2.1976301247423478 -2.2062469640588125; -2.2160995622595325 -2.207649485347096 … -2.207649485347096 -2.2160995622595325], [-13.17634564256269 -13.041084896738482 … -13.041084896738482 -13.17634564256269; -13.040840967779726 -12.90416625189135 … -12.90416625189135 -13.040840967779726; … ; -12.984004311673242 -12.845399511775305 … -12.845399511775305 -12.984004311673242; -13.12017807786004 -12.98305147895367 … -12.98305147895367 -13.12017807786004], [-0.2458426263266534 -0.24555855578357275 … -0.24555855578357275 -0.2458426263266534; -0.25354899357595045 -0.2532463985867102 … -0.2532463985867102 -0.25354899357595045; … ; -0.12329863072332145 -0.12290682708752478 … -0.12290682708752478 -0.12329863072332145; -0.12114996795799929 -0.12077580730248855 … -0.12077580730248855 -0.12114996795799929], [-0.14259682643912724 -0.1430989095121752 … -0.1430989095121752 -0.14259682643912724; -0.14584785744144405 -0.14637960398006836 … -0.14637960398006836 -0.14584785744144405; … ; -0.090263065858183 -0.09028812494436153 … -0.09028812494436153 -0.090263065858183; -0.08885191284558384 -0.08887616558388427 … -0.08887616558388427 -0.08885191284558384], [0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0; … ; 0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0], [0.18519854383797515 0.18708517002259342 … 0.18708517002259342 0.18519854383797515; 0.1870752210771927 0.18902039059495818 … 0.18902039059495818 0.1870752210771927; … ; 0.1870752210771927 0.18902039059495818 … 0.18902039059495818 0.1870752210771927; 0.18519854383797515 0.18708517002259342 … 0.18708517002259342 0.18519854383797515], [5.102694996447269e-18 5.207905202559688e-18 … 5.207905202559688e-18 5.102694996447269e-18; 5.102694996447354e-18 5.207905202559685e-18 … 5.207905202559685e-18 5.102694996447354e-18; … ; 5.102694996447354e-18 5.207905202559685e-18 … 5.207905202559685e-18 5.102694996447354e-18; 5.102694996447269e-18 5.207905202559688e-18 … 5.207905202559688e-18 5.102694996447269e-18], [0.2621141790545372 0.26212388077819737 … 0.26212388077819737 0.2621141790545372; 0.26752176320486787 0.2675319714243842 … 0.2675319714243842 0.26752176320486787; … ; 0.26752176320486787 0.2675319714243842 … 0.2675319714243842 0.26752176320486787; 0.2621141790545372 0.26212388077819737 … 0.26212388077819737 0.2621141790545372], [1.4968675014460734e-15 1.497074218783015e-15 … 1.497074218783015e-15 1.4968675014460734e-15; 1.4669344203343482e-15 1.4665239682731889e-15 … 1.4665239682731889e-15 1.4669344203343482e-15; … ; 1.4669344203343482e-15 1.4665239682731889e-15 … 1.4665239682731889e-15 1.4669344203343482e-15; 1.4968675014460734e-15 1.497074218783015e-15 … 1.497074218783015e-15 1.4968675014460734e-15], [0.04636852782576966 0.04588827118022064 … 0.04588827118022064 0.04636852782576966; 0.047793721890844104 0.04732833874262533 … 0.04732833874262533 0.047793721890844104; … ; 0.047793721890844104 0.04732833874262533 … 0.04732833874262533 0.047793721890844104; 0.04636852782576966 0.04588827118022064 … 0.04588827118022064 0.04636852782576966], [144.0 138.24058769513314 … 138.24058769513314 144.0; 144.0 138.24058769513314 … 138.24058769513314 144.0; … ; 144.0 138.24058769513314 … 138.24058769513314 144.0; 144.0 138.24058769513314 … 138.24058769513314 144.0], [12.0 12.0 … 12.0 12.0; 11.757575757575758 11.757575757575758 … 11.757575757575758 11.757575757575758; … ; -11.757575757575758 -11.757575757575758 … -11.757575757575758 -11.757575757575758; -12.0 -12.0 … -12.0 -12.0]), (Inf, 1.5707963267948966))Import external mesh
bunny_mesh = rotate(
translate(
rotate(
scale(MeshGeometry(load(joinpath(pkgdir(Krang), "assets", "bunny.obj"))), 100),
π / 2,
0.0,
0.0,
1.0,
),
10.0,
2.0,
-8.0,
),
π / 2,
0.0,
1.0,
0.0,
);Ray trace the mesh embedded in the Kerr space time. The emission picked up by a ray will be the sum of all the intersections of the ray with the mesh The mesh is embedded in the space-time by assuming the world coordinates of the mesh is the same as the Boyer-Lindquist coordinates of the space time. The ray tracing is done by scanning over the image one line at a time
Let us now ray trace the image to see what the mesh looks like from the observer's perspective.
raytrace takes a Krang.Mesh, which pairs the geometry with a material. Materials are functors of (pixel, intersection); this one contributes 1 per intersection, so the image counts how many times each ray crosses the mesh.
struct IntersectionCounter <: Krang.AbstractMaterial end
(::IntersectionCounter)(pixel, intersection) = 1.0
bunny = Krang.Mesh(bunny_mesh, IntersectionCounter())
intersections = raytrace(camera, bunny; res = 10);And plot the image with GLMakie,
fig = GLMk.Figure();
ax = GLMk.Axis(fig[1, 1], aspect = 1)
GLMk.heatmap!(ax, intersections, colormap = :afmhot);
save("mesh_geometry_example.png", fig);
Below is a short plotting routine that generates a video showing the scene from three different perspectives, and live renders the image.
fig = GLMk.Figure()
ax1 = GLMk.Axis3(
fig[1, 1],
aspect = (1, 1, 1),
title = "Top view of scene",
elevation = π / 2,
azimuth = π,
)
ax2 = GLMk.Axis3(
fig[1, 2],
aspect = (1, 1, 1),
title = "Side view of scene",
elevation = 0.0,
azimuth = 3π / 2,
)
ax3 = GLMk.Axis3(fig[2, 1], aspect = (1, 1, 1), title = "Isometric view of scene")
ax = GLMk.Axis(fig[2, 2], aspect = 1, title = "Heatmap of ray intersections with mesh")
for a in [ax1, ax2, ax3]
GLMk.xlims!(a, (-20, 20))
GLMk.ylims!(a, (-20, 20))
GLMk.zlims!(a, (-20, 20))
GLMk.hidedecorations!(a)
end
GLMk.hidedecorations!(ax)
sphere = GLMk.Sphere(GLMk.Point(0.0, 0.0, 0.0), horizon(metric)) # Sphere to represent black hole
lines_to_plot = Krang.generate_ray.(camera.screen.pixels, 100) # 100 is the number of steps to take along the ray
img = zeros(sze, sze)
recording = GLMk.record(fig, "mesh.mp4", 1:(sze*sze), framerate = 120) do i
line = lines_to_plot[i]
img[i] = intersections[i]
GLMk.empty!(ax)
GLMk.empty!(ax1)
GLMk.empty!(ax2)
GLMk.empty!(ax3)
for a in [ax1, ax2, ax3]
GLMk.mesh!(
a,
bunny_mesh.geometryBasicsMesh,
color = [
parse(GLMk.Colorant, "rgba(0%, 50%, 70%,1.0)") for
tri in bunny_mesh.geometryBasicsMesh.position
],
colormap = :blues,
transparency = true,
)
GLMk.mesh!(a, sphere, color = :black)
end
cart_line = map(
x -> Krang.boyer_lindquist_to_quasi_cartesian_kerr_schild_fast_light(
metric,
x.rs,
x.θs,
x.ϕs,
),
line,
)
GLMk.lines!(ax3, cart_line, color = :red)
GLMk.heatmap!(ax, img, colormap = :afmhot, colorrange = (0, 8))
end"mesh.mp4"This page was generated using Literate.jl.