Low-level API

Contents

Colors and images

We use the ColorTypes.RGB from ColorTypes.jl. Our package extends the methods of this type, for example by implementing sum and difference between two color instances. We also add iterability and broadcasting.

Colors

Base.Math.clampMethod
clamp(c::RGB)

Return a clamped RGB color, with each component x obtained with the formula:

\[\frac{x}{1 + x}\]

Examples

julia> clamp(RGB(1f0, 2f0, 3f0))
RGB color with eltype Float32
R: 0.5, G: 0.6666667, B: 0.75
source
Raytracer.luminosityMethod
luminosity(c::RGB)

Return the mean value between the maximum component and the minumum component of a color:

\[\frac{\mathrm{max}(c) + \mathrm{min}(c)}{2}\]

Examples

julia> luminosity(RGB(1f0, 2f0, 3f0))
2.0f0
source
Raytracer.γ_correctionMethod
γ_correction(c::RGB, γ::Float32)

Return a RGB color, with each component x corrected with the formula:

\[x^{1 / \gamma}\]

Examples

julia> c = RGB(1f0, 2f0, 3f0);

julia> γ_correction(c, 1f0)
RGB color with eltype Float32
R: 1.0, G: 2.0, B: 3.0

julia> γ_correction(c, 0.8f0)
RGB color with eltype Float32
R: 1.0, G: 2.3784142, B: 3.948222

julia> γ_correction(c, 2.4f0)
RGB color with eltype Float32
R: 1.0, G: 1.3348398, B: 1.580522
source

HDR image

Raytracer.HdrImageType
HdrImage

Wrapper of a Matrix of elements of type RGB{Float32}, used to represent an image in hdr format.

source
Raytracer.HdrImageMethod
HdrImage(arr::AbstractArray{<:Any, 1}, im_width::Integer, im_height::Integer)
HdrImage(arr::AbstractArray{<:Any, 1}, shape)

Construct an HdrImage wrapping a matrix obtained from reshape.

Examples

julia> arr = [RGB( 1.,  2.,  3.), RGB( 4.,  5.,  6.), RGB( 7.,  8.,  9.),
              RGB(10., 11., 12.), RGB(13., 14., 15.), RGB(16., 17., 18.)];

julia> HdrImage(arr, 3, 2)
3x2 HdrImage:
 (1.0 2.0 3.0)  (10.0 11.0 12.0)
 (4.0 5.0 6.0)  (13.0 14.0 15.0)
 (7.0 8.0 9.0)  (16.0 17.0 18.0)
source
Raytracer.HdrImageMethod
HdrImage(img_width::Integer, img_height::Integer)

Construct an HdrImage wrapping a zero-initialized matrix of size (img_width, img_height).

Examples

julia> HdrImage(3, 2)
3x2 HdrImage:
 (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.0 0.0)
source
Base.Math.clampMethod
clamp(image::HdrImage)

Adjust the color levels of the brightest pixels of a HdrImage, by applying the clamp(::RGB) function to each pixel.

Examples

julia> arr = [RGB( 1.,  2.,  3.), RGB( 4.,  5.,  6.), RGB( 7.,  8.,  9.),
              RGB(10., 11., 12.), RGB(13., 14., 15.), RGB(16., 17., 18.)];

julia> clamp(HdrImage(arr, 3, 2))
3x2 HdrImage:
 (0.5 0.6666667 0.75)        (0.90909094 0.9166667 0.9230769)
 (0.8 0.8333333 0.85714287)  (0.9285714 0.93333334 0.9375)
 (0.875 0.8888889 0.9)       (0.9411765 0.9444444 0.94736844)
source
LinearAlgebra.normalizeMethod
normalize(image::HdrImage, α::Float32
          ; luminosity::Float32 = average_luminosity(image))

Normalize a HdrImage for a given luminosity.

If the luminosity parameter is not specified, the image will be normalized according to the result of luminosity(::HdrImage; ::Float32).

Examples

julia> arr = [RGB( 1.,  2.,  3.), RGB( 4.,  5.,  6.), RGB( 7.,  8.,  9.),
              RGB(10., 11., 12.), RGB(13., 14., 15.), RGB(16., 17., 18.)];

julia> normalize(HdrImage(arr, 3, 2), 1f0)
3x2 HdrImage:
 (0.12976472 0.25952944 0.38929415)  (1.2976472 1.4274119 1.5571766)
 (0.5190589 0.6488236 0.7785883)     (1.6869414 1.8167061 1.9464709)
 (0.90835303 1.0381178 1.1678824)    (2.0762355 2.2060003 2.335765)
source
Raytracer.luminosityMethod
luminosity(image::HdrImage; δ::Float32 = eps(Float32))

Return the average luminosity an HdrImage as the logaritmic mean of the luminosity(::RGB) $l_i$ of each pixel:

\[\left< l \right> = 10^{\frac{\sum_i \log_{10}(\delta + l_i)}{N}}\]

The parameter δ avoid singularities for $l_i = 0$ (black pixels).

Examples

julia> arr = [RGB( 1.,  2.,  3.), RGB( 4.,  5.,  6.), RGB( 7.,  8.,  9.),
              RGB(10., 11., 12.), RGB(13., 14., 15.), RGB(16., 17., 18.)];

julia> luminosity(HdrImage(arr, 3, 2))
7.706255f0
source
Raytracer.γ_correctionMethod
γ_correction(image::HdrImage, γ::Float32)

Compute the γ correction of a HdrImage, by applying the γ_correction(::RGB, ::Float32) function to each pixel.

Before calling this function, you should apply a tone-mapping algorithm to the image and be sure that the R, G, and B values of the colors in the image are all in the range $[0, 1]$. Use normalize(::HdrImage, ::Float32; ::Float32) and clamp(image::HdrImage) to do this.

Examples

julia> arr = [RGB( 1.,  2.,  3.), RGB( 4.,  5.,  6.), RGB( 7.,  8.,  9.),
              RGB(10., 11., 12.), RGB(13., 14., 15.), RGB(16., 17., 18.)];

julia> image = normalize(HdrImage(arr, 3, 2), 1f0) |> clamp;

julia> γ_correction(image, 1f0)
3x2 HdrImage:
 (0.11485995 0.20605269 0.28021002)  (0.5647722 0.58803856 0.6089437)
 (0.34169766 0.393507 0.43775633)    (0.6278296 0.64497536 0.660611)
 (0.47598794 0.5093512 0.53872037)   (0.67492735 0.6880849 0.7002187)

julia> γ_correction(image, 0.8f0)
3x2 HdrImage:
 (0.06686684 0.13882665 0.20387058)  (0.48960024 0.51494074 0.53792465)
 (0.26124772 0.31166682 0.35607424)  (0.558859 0.57800144 0.5955692)
 (0.39536202 0.43030033 0.4615346)   (0.6117462 0.6266897 0.64053386)

julia> γ_correction(image, 2.4f0)
3x2 HdrImage:
 (0.40588558 0.5177947 0.58855206)  (0.7881591 0.8015287 0.8132807)
 (0.63926977 0.6780008 0.7087834)   (0.82369685 0.83299613 0.8413514)
 (0.73394746 0.7549599 0.77280176)  (0.8489011 0.8557578 0.86201346)
source

Geometry

Raytracer.NormalType
Normal{V} <: StaticArrays.FieldVector{3, Float32}

A pseudo-vector in 3D space with 3 fields x, y, and z of type Float32. The parameter V tells if the normal is normalized or not.

For inherited properties and constructors see StaticArrays.FieldVector.

source
Raytracer.NormalMethod
Normal(x, y, z)

Construct a non-normalized Normal{false} with given coordinates. All values are converted in Float32.

Examples

julia> Normal(1.2, 3.3, 5)
Normal with eltype Float32, not normalized
x = 1.2, y = 3.3, z = 5.0
source
Raytracer.PointType
Point

A point in a 3D space. Implemented as a wrapper struct around a SVector{3, Float32}.

source
Raytracer.PointMethod
Point(x, y, z)

Construct a Point with given coordinates. All values are converted in Float32.

Examples

julia> Point(1.2, 3.3, 5)
Point with eltype Float32
x = 1.2, y = 3.3, z = 5.0
source
Raytracer.VecType
Vec <: StaticArrays.FieldVector{3, Float32}

A vector in 3D space with 3 fields x, y, and z of type Float32.

For inherited properties and constructors see StaticArrays.FieldVector.

source
LinearAlgebra.normalizeMethod
normalize(n::Normal)

Normalize n and return a Normal{true}. If n is already a Normal{true} instance, no normalization is computed and n is returned.

Examples

julia> n = normalize(Normal(1,2,4))
Normal with eltype Float32, normalized
x = 0.21821788, y = 0.43643576, z = 0.8728715

julia> normalize(n)
Normal with eltype Float32, normalized
x = 0.21821788, y = 0.43643576, z = 0.8728715
source
Raytracer.create_onb_from_zMethod
create_onb_from_z(input_normal::Normal)

Create an orthonormal base from a input Normal representing the z-axis using the Duff et al. 2017 algorithm.

Examples

julia> n = Normal(0,0,5);

julia> nn = normalize(Normal(0,0,5));

julia> create_onb_from_z(n)
(Vec(1.0, -0.0, -0.0), Vec(-0.0, 1.0, -0.0), Vec(0.0, 0.0, 1.0))

julia> create_onb_from_z(nn)
(Vec(1.0, -0.0, -0.0), Vec(-0.0, 1.0, -0.0), Vec(0.0, 0.0, 1.0))

Note that create_onb_from_z(n) and create_onb_from_z(nn) give the same result.

source
Raytracer.norm²Method
norm²(n::Normal)

Compute the squared norm of a Normal. If n is a Normal{true} instance then 1f0 is returned.

Examples

julia> n = Normal(1, 2, 3);

julia> norm²(n)
14.0f0

julia> norm²(normalize(n))
1.0f0
source

Transformations

Raytracer.TransformationType
Transformation

A wrapper around two 4x4 matrices representing a transformation for Vec, Normal, and Point instances.

A 4x4 matrix is needed to use the properties of homogeneous coordinates in 3D space. Storing the inverse of the transformation significantly increases performance at the cost of memory space.

Fields

  • m::SMatrix{4, 4, Float32}: the homogeneous matrix representation of the transformation.
  • invm::SMatrix{4, 4, Float32}: the homogeneous matrix representation of the inverse transformation.
source
Raytracer.TransformationMethod
Transformation(m::AbstractMatrix)
Transformation(m::AbstractMatrix, invm::AbstractMatrix)

Construct a Transformation instance from m and invm. The elements of the matrix will be casted to Float32.

If any argument is an AbstractMatrix, it will be implicitly casted to a StaticArrays.SMatrix to increase performance.

Examples

julia> Transformation(StaticArrays.SMatrix{4,4}([1 0 0 0; 0 2 0 0; 0 0 4 0; 0 0 0 1]))
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  0.0f0
 0.0f0  2.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  4.0f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0   0.0f0
 0.0f0  0.5f0  0.0f0   0.0f0
 0.0f0  0.0f0  0.25f0  0.0f0
 0.0f0  0.0f0  0.0f0   1.0f0

julia> Transformation([1 0 0 0; 0 2 0 0; 0 0 4 0; 0 0 0 1])
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  0.0f0
 0.0f0  2.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  4.0f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0   0.0f0
 0.0f0  0.5f0  0.0f0   0.0f0
 0.0f0  0.0f0  0.25f0  0.0f0
 0.0f0  0.0f0  0.0f0   1.0f0
julia> Transformation(LinearAlgebra.Diagonal([1,2,4,1]))
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  0.0f0
 0.0f0  2.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  4.0f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0   0.0f0
 0.0f0  0.5f0  0.0f0   0.0f0
 0.0f0  0.0f0  0.25f0  0.0f0
 0.0f0  0.0f0  0.0f0   1.0f0
source
Raytracer.TransformationMethod
Transformation(m::SMatrix{4, 4, Float32} = SMatrix{4, 4, Float32}(I(4)),
               invm::SMatrix{4, 4, Float32} = inv(m))

Constructor for a Transformation instance.

If no parameter is specified, then an identity transformation is returned. If only the direct matrix is specified, then the inverse matrix is automatically computed.

Examples

julia> Transformation()
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  0.0f0
 0.0f0  1.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  1.0f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  0.0f0
 0.0f0  1.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  1.0f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
source
Raytracer.isconsistentMethod
isconsistent(t::Transformation)

Return true if t.m * t.invm is similar to the identity matrix and so the Transformation is consistent.

Mainly used for testing and to verify matrices haven't been mutated.

source
Raytracer.rotationXFunction
rotationX(θ::Real)

Return a Transformation that rotates a 3D vector field of the given angle in radians around the X-axis.

If an AbstractVector is provided as argument it must have a size = (3,).

Examples

julia> rotationX(π/4)
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0          0.0f0         0.0f0
 0.0f0  0.70710677f0  -0.70710677f0  0.0f0
 0.0f0  0.70710677f0   0.70710677f0  0.0f0
 0.0f0  0.0f0          0.0f0         1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0   0.0f0         0.0f0         0.0f0
 0.0f0   0.70710677f0  0.70710677f0  0.0f0
 0.0f0  -0.70710677f0  0.70710677f0  0.0f0
 0.0f0   0.0f0         0.0f0         1.0f0
source
Raytracer.rotationYFunction
rotationY(θ::Real)

Return a Transformation that rotates a 3D vector field of the given angle in radians around the Y-axis.

If an AbstractVector is provided as argument it must have a size = (3,).

Examples

julia> rotationY(π/4)
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
  0.70710677f0  0.0f0  0.70710677f0  0.0f0
  0.0f0         1.0f0  0.0f0         0.0f0
 -0.70710677f0  0.0f0  0.70710677f0  0.0f0
  0.0f0         0.0f0  0.0f0         1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 0.70710677f0  0.0f0  -0.70710677f0  0.0f0
 0.0f0         1.0f0   0.0f0         0.0f0
 0.70710677f0  0.0f0   0.70710677f0  0.0f0
 0.0f0         0.0f0   0.0f0         1.0f0
source
Raytracer.rotationZFunction
rotationZ(θ::Real)

Return a Transformation that rotates a 3D vector field of the given angle in radians around the Z-axis.

If an AbstractVector is provided as argument it must have a size = (3,).

Examples

julia> rotationZ(π/4)
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 0.70710677f0  -0.70710677f0  0.0f0  0.0f0
 0.70710677f0   0.70710677f0  0.0f0  0.0f0
 0.0f0          0.0f0         1.0f0  0.0f0
 0.0f0          0.0f0         0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
  0.70710677f0  0.70710677f0  0.0f0  0.0f0
 -0.70710677f0  0.70710677f0  0.0f0  0.0f0
  0.0f0         0.0f0         1.0f0  0.0f0
  0.0f0         0.0f0         0.0f0  1.0f0
source
Raytracer.scalingMethod
scaling(x::Real, y::Real, z::Real)
scaling(s::Real)
scaling(v::AbstractVector)

Return a Transformation that scales a 3D vector field of a given factor for each axis.

If a single Real is provided as argument then the scaling is considered uniform. If an AbstractVector is provided as argument it must have a size = (3,).

Examples

julia> scaling(1, 2, 3)
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  0.0f0
 0.0f0  2.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  3.0f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0         0.0f0
 0.0f0  0.5f0  0.0f0         0.0f0
 0.0f0  0.0f0  0.33333334f0  0.0f0
 0.0f0  0.0f0  0.0f0         1.0f0
julia> scaling(2)
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 2.0f0  0.0f0  0.0f0  0.0f0
 0.0f0  2.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  2.0f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 0.5f0  0.0f0  0.0f0  0.0f0
 0.0f0  0.5f0  0.0f0  0.0f0
 0.0f0  0.0f0  0.5f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
julia> scaling([1, 2, 3])
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  0.0f0
 0.0f0  2.0f0  0.0f0  0.0f0
 0.0f0  0.0f0  3.0f0  0.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0         0.0f0
 0.0f0  0.5f0  0.0f0         0.0f0
 0.0f0  0.0f0  0.33333334f0  0.0f0
 0.0f0  0.0f0  0.0f0         1.0f0
source
Raytracer.translationMethod
translation(v::AbstractVector)
translation(x::Real, y::Real, z::Real)

Return a Transformation that translates a 3D vector field of the given coordinates.

If an AbstractVector is provided as argument it must have a size = (3,).

Examples

julia> translation(1, 2, 3)
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  1.0f0
 0.0f0  1.0f0  0.0f0  2.0f0
 0.0f0  0.0f0  1.0f0  3.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  -1.0f0
 0.0f0  1.0f0  0.0f0  -2.0f0
 0.0f0  0.0f0  1.0f0  -3.0f0
 0.0f0  0.0f0  0.0f0   1.0f0
julia> translation([1, 2, 3])
4x4 Transformation:
Matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  1.0f0
 0.0f0  1.0f0  0.0f0  2.0f0
 0.0f0  0.0f0  1.0f0  3.0f0
 0.0f0  0.0f0  0.0f0  1.0f0
Inverse matrix of type StaticArrays.SMatrix{4, 4, Float32, 16}:
 1.0f0  0.0f0  0.0f0  -1.0f0
 0.0f0  1.0f0  0.0f0  -2.0f0
 0.0f0  0.0f0  1.0f0  -3.0f0
 0.0f0  0.0f0  0.0f0   1.0f0
source

Ray

Raytracer.RayType
Ray

A ray of light propagating in space.

Fields

  • origin::Point: the (Point) where the ray originated.
  • dir::Vec: a (Vec) representing the direction along which this ray propagates.
  • tmin::Float32: the minimum distance travelled by the ray is this number times dir.
  • tmax::Float32: the maximum distance travelled by the ray is this number times dir.
  • depth::Int: number of times this ray was reflected/refracted.

See also: Ray(::Float32)

source
Raytracer.RayMethod
(r::Ray)(t::Float32)

Return a Point lying on the given Ray at t.

An instance of Ray can be called as a function returning a Point given the position parameter t:

\[\mathrm{ray\_origin} + \mathrm{ray\_direction} \cdot t\]

Argument t must be included between r.tmin and r.tmax or be equal to 0. If t is zero, then the returned point is the origin of r.

Examples

julia> ray = Ray(ORIGIN, VEC_X)
Ray
 ↳ origin = Point(0.0, 0.0, 0.0)
 ↳ dir    = Vec(1.0, 0.0, 0.0)
 ↳ tmin   = 1.0e-5
 ↳ tmax   = Inf
 ↳ depth  = 0

julia> ray(5f0)
Point with eltype Float32
x = 5.0, y = 0.0, z = 0.0
source
Raytracer.RayMethod
Ray(origin::Point, dir::Vec, tmin::Float32, tmax::Float32, depth::Int)

Constructor for a Ray instance.

source
Raytracer.RayMethod
Ray(origin::Point, dir::Vec
    ; tmin::Float32 = 1f-5,
      tmax::Float32 = Inf32,
      depth::Int = 0)

Constructor for a Ray instance.

source

Cameras

Raytracer.OrthogonalCameraMethod
OrthogonalCamera(; aspect_ratio::Float32 = 1f0,
                   transformation::Transformation = Transformation())

Keyword-based constructor for an OrthogonalCamera instance.

If no parameter is specified, it return a camera with square aspect ratio and an identity transformation.

source
Raytracer.PerspectiveCameraType
PerspectiveCamera <: Camera

A Camera implementing a perspective 3D → 2D projection.

Fields

  • aspect_ratio::Float32: defines how larger than the height is the image (16/9, 4/3, ...).
  • transformation::Transformation: define the Transformation applied to the rays generated by the camera.
  • screen_distance::Float32: tells how much far from the eye of the observer is the screen and it influences the FOV (field-of-view).

See also: fire_ray(::PerspectiveCamera, ::Float32, ::Float32), aperture_deg

source
Raytracer.PerspectiveCameraMethod
PerspectiveCamera(; aspect_ratio::Float32 = 1f0,
                    transformation::Transformation = Transformation(),
                    screen_distance::Float32 = 1f0)

Keyword-based constructor for a PerspectiveCamera instance.

If no parameter is specified, it return a camera with square aspect ratio, an identity transformation, and a screen distance of 1, giving a FOV of 90°.

source
Raytracer.aperture_degMethod
aperture_deg(camera::PerspectiveCamera)

Compute the FOV of the camera in degrees for a PerspectiveCamera.

Examples

FOV for a camera with screen distance of 1 and aspect ratio of 1:

julia> aperture_deg(PerspectiveCamera())
90.0f0

FOV for a camera with screen distance of 1 and aspect ratio of 16/9:

julia> aperture_deg(PerspectiveCamera(aspect_ratio = 16//9))
58.715508f0
source
Raytracer.fire_rayMethod
fire_ray(camera::OrthogonalCamera, u::Float32, v::Float32)

Fire a Ray through an OrthogonalCamera at a position $(u, v)$ on the screen, using an orthogonal projection.

Parameters u and v are bound between 0 and 1:

(0, 1)                            (1, 1)
    +------------------------------+
    |                              |
    |                              |
    |                              |
    +------------------------------+
(0, 0)                            (1, 0)
source
Raytracer.fire_rayMethod
fire_ray(camera::PerspectiveCamera, u::Float32, v::Float32)

Fire a Ray through a PerspectiveCamera at a position $(u, v)$ on the screen, using a perspective projection.

Parameters u and v are bound between 0 and 1:

(0, 1)                            (1, 1)
    +------------------------------+
    |                              |
    |                              |
    |                              |
    +------------------------------+
(0, 0)                            (1, 0)
source

Materials, BRDF and pigments

Raytracer.BRDFType
BRDF

An abstract type representing a Bidirectional Reflectance Distribution Function.

Each subtype of this type must include a field pigment::Pigment storing the pigment on which the BRDF operates. Each subtype of this type must implement an at(::NewBRDF, ::Normal, in_dir::Vec, out_dir::Vec, uv::Vec2D) function, where NewBRDF should be swubstituted with your new type name. This function evaluates the BRDF of a point with given normal, input and output directions and uv coordinates (which are used to evaluate)

See also: DiffuseBRDF, SpecularBRDF,

source
Raytracer.CheckeredPigmentType
CheckeredPigment{N} <: Pigment

A checkered Pigment. The number of rows/columns in the checkered pattern is tunable with N, but you cannot have a different number of repetitions along the u/v directions.

source
Raytracer.ImagePigmentMethod
(ip::ImagePigment)(u::Float32, v::Float32)

Return the color of the surface in the given point $(u,v)$.

source
Raytracer.MaterialMethod
Material(; brdf::BRDF = DiffuseBRDF(), emitted_radiance::Pigment = UniformPigment(BLACK))

Constructor for a Material instance.

source
Raytracer.PigmentType
Pigment

This abstract type represents a pigment, i.e., a function that associates a color with each point on a parametric surface $(u,v)$.

Each subtype of this type must be a callable like (p::Pigment)(uv::Vec2D) and must return the color of the surface as a RGB{Float32} in a given Vec2D point.

See also: UniformPigment, CheckeredPigment, ImagePigment

source
Raytracer.atMethod
at(brdf::DiffuseBRDF, normal::Normal, in_dir::Vec, out_dir::Vec, uv::Vec2D)

Get the radiance, given a point uv (Vec2D) on the surface with a DiffuseBRDF., an incoming direction in_dir and outcoming direction (Vec), a normal of the surface point (Normal).

source
Raytracer.atMethod
at(brdf::SpecularBRDF, normal::Normal, in_dir::Vec, out_dir::Vec, uv::Vec2D)

Get the radiance, given a point uv (Vec2D) on the surface with a SpecularBRDF., an incoming direction in_dir and outcoming direction (Vec), a normal of the surface point (Normal).

source

Shapes

Raytracer.HitRecordType
HitRecord

A struct representing the result of an intersection between a Ray and a Shape.

Fields

  • world_point::Point: a Point representing the world coordinates of the hit point.
  • normal::Normal: a Normal representing the orientation of the normal to the surface where the hit happened.
  • surface_point::Vec2D: a Vec2D representing the position of the hit point on the surface of the object.
  • t::Float32: distance from the origin of the ray where the hit happened.
  • ray::Ray: a Ray representing the the ray that hit the surface.
  • material::Material: a Material representing the material of the point where the hit happened.
source
Raytracer.get_all_tsMethod
get_all_ts(s::Shape, ray::Ray)

Return a Vector of the hit parameter t against the given Shape, even outside of the ray domain.

source
Raytracer.get_all_tsMethod
get_all_ts(::Type{<:SimpleShape}, ray::Ray)

Return a Vector of the hit parameter t against the unitary shape of the given SimpleShape type, even outside of the ray domain.

source
Raytracer.get_normalMethod
get_normal(::Type{<:SimpleShape}, ::Point, ::Ray)

Return the Normal{true} of a shape given a point on its surface and the ray that hits it.

source
Raytracer.get_uvMethod
get_uv(::Type{<:SimpleShape}, ::Point)

Return the uv coordinates of a shape associated with the given point on its surface.

source

Simple shapes

Raytracer.CubeType
Cube <: SimpleShape

A SimpleShape representing a cube of unitary size.

Members

  • transformation::Transformation: the Transformation associated with the cube.
  • material::Material: the Material of the cube.
source
Raytracer.CubeMethod
Cube(transformation::Transformation = Transformation(),
       material::Material = Material())

Constructor for a Cube instance.

source
Raytracer.CylinderType
Cylinder <: SimpleShape

A SimpleShape representing a cylinder of unitary height and diameter.

Members

  • transformation::Transformation: the Transformation associated with the cylinder.
  • material::Material: the Material of the cylinder.
source
Raytracer.CylinderMethod
Cylinder(transformation::Transformation = Transformation(),
       material::Material = Material())

Constructor for a Cylinder instance.

source
Raytracer.PlaneType
Plane <: SimpleShape

A SimpleShape representing an infinite plane.

Members

  • transformation::Transformation: the Transformation associated with the plane.
  • material::Material: the Material of the plane.
source
Raytracer.PlaneMethod
Plane(transformation::Transformation = Transformation(),
       material::Material = Material())

Constructor for a Plane instance.

source
Raytracer.SphereType
Sphere <: SimpleShape

A SimpleShape representing a sphere.

This is a unitary sphere centered in the origin. A generic sphere can be specified by applying a Transformation.

Members

  • transformation::Transformation: the Transformation associated with the sphere.
  • material::Material: the Material of the spere.
source
Raytracer.SphereMethod
Sphere(transformation::Transformation = Transformation(),
       material::Material = Material())

Constructor for a Sphere instance.

source

Composite shapes

Raytracer.CSGType
CSG{R} <: CompositeShape

A Shape representing a Constructive Solid Geometry tree.

The behavior of the CSG tree is determined by the Rule R.

Members

  • rbranch::Shape: represents the right branch of the tree
  • lbranch::Shape: represents the left branch of the tree
  • transformation::Transformation: represents the Transformation of the whole composite shape

External references

  • Constructive Solid Geometry: https://en.wikipedia.org/wiki/Constructivesolidgeometry
source
Raytracer.RuleType
Rule

Enum type representing the hit point selection of a CSG.

Instances

  • UniteRule: indicates that every hit point is valid
  • IntersectRule: indicates that only hit points located inside of other shapes are valid
  • DiffRule: indicates that only hit points outside of the lbranch and inside the rbranch are valid
  • FuseRule: indicates that every hit point outside of other shapes is valid

See also: CSG.

source
Raytracer.fuseMethod
fuse(s1::Shape, s2::Shape); transformation::Transformation = Transformation())

Construct a FusionCSG with the given shapes as rbranch and lbranch repectively.

source
Raytracer.fuseMethod
fuse(s::Shape, ss::Shape...); transformation::Transformation = Transformation())

Construct a FusionCSG binary tree, by recursively calling intersect(::Shape, ::Shape).

source

AABB

Raytracer.get_tMethod
get_t(ray::Ray, aabb::AABB)

Return the parameter t at which Ray first hits the AABB. If no hit exists, return Inf32.

source

Lights

Raytracer.PointLightType
PointLight

A point light (used by PointLightRenderer).

This type holds information about a point light.

Fields

  • position::Point: a Point object holding the position of the point light in 3D space.
  • color::RGB{Float32}: the color of the point light.
  • linear_radius::Float32: radius of the source, used to compute solid angle subtended by the light.

If linear_radius is non-zero, it is used to compute the solid angle subtended by the light at a given distance d through the formula:

\[\left(\frac{\mathrm{linear\_radius}}{d}\right)^2\]

source
Raytracer.PointLightMethod
PointLight(; position::Point = ORIGIN,
             color::RGB{Float32} = WHITE,
             linear_radius::Float32 = 0f0)

Constructor for a PointLight instance.

If no parameter is specified, it return a white point light in the origin with no radius.

source

PCG random number generator

Raytracer.PCGType
mutable struct PCG <: AbstractRNG

Random number generator that implement the Permuted Congruential Generator, a simple fast space-efficient statistically good algorithms for random number generation. See O'Neill (2014).

Fields

  • state::UInt64: the state of the generator.
  • inc::UInt64: sequence identifier.
source
Raytracer.PCGMethod
PCG(state::UInt64 = UInt64(42), inc::UInt64 = UInt64(54))

Constructor for a PCG instance.

If no parameter is specified, the generated instance will have a state of 42 and a sequence identifier of 54.

source

Renderer

Raytracer.FlatRendererType
FlatRenderer <: Renderer

A basic Renderer that returns the color of the Shape first hit by a given Ray.

This renderer returns the color stored in the material field of the Shape first hit by the given Ray at the hit point. To this renderer there is no difference between radiated light and reflected color. There are no shades, diffusions or reflections. If there are no hits this renderer returns the value of its field background_color.

Fields

  • world::World: the World to render.
  • background_color::RGB{Float32}: color if the ray do not collide.
source
Raytracer.OnOffRendererType
OnOffRenderer <: Renderer

A basic bichrome Renderer that checks whether a Ray has collided or not.

This renderer returns its field off_color when the given Ray is nothing, else it returns its field on_color.

Fields

  • world::World: the World to render.
  • on_color::RGB{Float32}: color if the ray collide.
  • off_color::RGB{Float32}: color if the ray do not collide.
source
Raytracer.PathTracerType
PathTracer <: Renderer

A path-tracing Renderer that considers the optical path of a Ray from the observer to a light source.

Fields

  • world::World: the World to render.
  • background_color::RGB{Float32}: color if the ray do not collide.
  • rng::PCG: a PCG random number generator to appropriately scatter rays.
  • n::Int: how many scattered rays should be generated for the mc integration.
  • max_depth::Int: the maximum number of scatters a ray should be subjected to before stopping.
  • roulette_depth::Int: the depth at which the russian roulette algorithm should start (if > 'max_depth` then it will never start).
source
Raytracer.PathTracerMethod
PathTracer(world::World, background_color::RGB{Float32}, rng::PCG, n::Int, max_depth::Int, roulette_depth::Int)

Constructor for a PathTracer instance.

source
Raytracer.PathTracerMethod
PathTracer(world::World
           ; background_color::RGB{Float32} = BLACK,
             rng::PCG = PCG(),
             n::Int = 10,
             max_depth::Int = 2,
             roulette_depth::Int = 3)

Constructor for a PathTracer instance.

source
Raytracer.PointLightRendererType
PointLightRenderer <: Renderer

Point-light tracing Renderer. This renderer is similar to what POV-Ray provides by default.

Fields

  • world::World: the World to render.
  • lights::Lights: a Lights instance that contain a list of lights.
  • background_color::RGB{Float32}: color if the ray do not collide.
  • ambient_color::RGB{Float32}: the ambient color of the scene.
source

Image tracer

Raytracer.ImageTracerType
ImageTracer

Trace an image by shooting light rays through each of its pixels.

To fill an image store it into ImageTracer along with the desired camera and apply fire_all_rays! to it. Alternatively apply iteratively fire_ray(::ImageTracer, ::Int, ::Int; ::Float32, ::Float32) on the desired ranges.

Fields

  • image::HdrImage: a HdrImage in which save the rendered image.
  • camera::Camera: a Camera holding the observer informations.
  • samples_per_side::Int: the number of samples per side of a pixel for antialiasing algorithm.
  • rng::PCG: a PCG random number generator for antialiasing algorithm.

If samples_per_side is larger than zero, antialiasing will be applied to each pixel in the image, using the random number generator rng.

source
Raytracer.ImageTracerMethod
ImageTracer(image::HdrImage, camera::Camera
            ; samples_per_side::Int = 0,
              rng::PCG = PCG())

Construct a ImageTracer.

If samples_per_side is not specified, antialiasing will be disabled and rng is ignored.

source
Raytracer.fire_all_rays!Method
fire_all_rays!(tracer::ImageTracer, renderer::Renderer
               ; use_threads::Bool = true,
                 enable_progress_bar::Bool = true)

Render an image with informations stored in an ImageTracer using the specified Renderer.

This function apply iteratively fire_ray(::ImageTracer, ::Int, ::Int; ::Float32, ::Float32) for each pixel in the image contained in tracer using its camera, and then render the point using renderer.

If use_threads is true, the function will use the Threads.@threads macro to parallelize the computation.

If enable_progress_bar is true, the function will display a progress bar during the computation; this is thread safe.

See also: fire_ray(::ImageTracer, ::Int, ::Int; ::Float32, ::Float32)

source
Raytracer.fire_rayMethod
fire_ray(tracer::ImageTracer, col::Int, row::Int
         ; u_pixel::Float32 = 0.5f0,
           v_pixel::Float32 = 0.5f0)

Shoot a Ray through the pixel (col, row) of the image contained in an [ImageTracer], using its camera informations.

The function use the fire_ray function of the associated camera (fire_ray(::OrthogonalCamera, ::Float32, ::Float32), fire_ray(::PerspectiveCamera, ::Float32, ::Float32))

The parameters col and row are measured in the same way as they are in HdrImage: the bottom left corner is placed at $(0, 0)$. The values of u_pixel and v_pixel are floating-point numbers in the range $[0, 1]$: they specify where the ray should cross the pixel; passing 0.5 to both means that the ray will pass through the pixel's center.

See also: fire_all_rays!

source

Index