General Utilities

General Utilities

List of the General Functions and Types provided by the RayTracer. Most of the other functionalities are built upon these.

Documentation

RayTracer.Vec3Type.
Vec3

This is the central type for RayTracer. All of the other types are defined building upon this.

All the fields of the Vec3 instance contains Arrays. This ensures that we can collect the gradients w.r.t the fields using the Params API of Zygote.

Fields:

  • x
  • y
  • z

The types of x, y, and z must match. Also, if scalar input is given to the constructor it will be cnverted into a 1-element Vector.

Defined Operations for Vec3:

  • +, -, * – These operations will be broadcasted even though there is no explicit mention of broadcasting.
  • dot
  • l2norm
  • cross
  • clamp
  • zero
  • similar
  • one
  • maximum
  • minimum
  • normalize
  • size
  • getindex – This returns a named tuple
source
RayTracer.rgbType.

rgb is an alias for Vec3. It makes more sense to use this while defining colors.

source
get_image(image, width, height)

Reshapes and normalizes a Vec3 color format to the RGB format of Images for easy loading, saving and visualization.

Arguments:

  • image - The rendered image in flattened Vec3 format (i.e., the output of the raytrace, rasterize, etc.)
  • width - Width of the output image
  • height - Height of the output image
source
zeroonenorm(x::AbstractArray)

Normalizes the elements of the array to values between 0 and 1.

Note

This function exists because the version of Zygote we use returns incorrect gradient for 1/maximum(x) function. This has been fixed on the latest release of Zygote.

source
FixedParams

Any subtype of FixedParams is not optimized using the update! API. For example, we don't want the screen size to be altered while inverse rendering, this is ensured by wrapping those parameters in a subtype of FixedParams.

source
RayTracer.bigmulMethod.
bigmul(x)

Returns the output same as typemax. However, in case gradients are computed, it will return the gradient to be 0 instead of nothing as in case of typemax.

source

camera2world(point::Vec3, cameratoworld::Matrix)

Converts a point in 3D Camera Space to the 3D World Space. To obtain the camera_to_world matrix use the get_transformation_matrix function.

source
RayTracer.extractMethod.
extract(cond, x<:Number)
extract(cond, x<:AbstractArray)
extract(cond, x::Vec3)

Extracts the elements of x (in case it is an array) for which the indices corresponding to the cond are true.

Note

extract has a performance penalty when used on GPUs.

Example:

julia> using RayTracer;

julia> a = [1.0, 2.0, 3.0, 4.0]
4-element Array{Float64,1}:
 1.0
 2.0
 3.0
 4.0

julia> cond = a .< 2.5
4-element BitArray{1}:
 1
 1
 0
 0

julia> RayTracer.extract(cond, a)
2-element Array{Float64,1}:
 1.0
 2.0
source
RayTracer.placeMethod.
place(a::Vec3, cond)
place(a::Array, cond, val = 0)

Constructs a new Vec3 or Array depending on the type of a with array length equal to that of cond filled with zeros (or val). Then it fills the positions corresponding to the true values of cond with the values in a.

The length of each array in a must be equal to the number of true values in the cond array.

Example:

julia> using RayTracer;

julia> a = Vec3(1, 2, 3)
x = 1, y = 2, z = 3

julia> cond = [1, 2, 3] .> 2
3-element BitArray{1}:
 0
 0
 1

julia> RayTracer.place(a, cond)
Vec3 Object
    Length = 3
    x = [0, 0, 1]
    y = [0, 0, 2]
    z = [0, 0, 3]
source
place_idx!(a::Vec3, b::Vec3, idx)

Number of trues in idx must be equal to the number of elements in b.

This function involves mutation of arrays. Since the version of Zygote we use does not support mutation we specify a custom adjoint for this function.

Arguments:

  • a - The contents of this Vec3 will be updated
  • b - The contents of b are copied into a
  • idx - The indices of a which are updated. This is a BitArray with length of idx being equal to a.x
source
world2camera(point::Vec3, world_to_camera::Matrix)

Converts a point in 3D World Space to the 3D Camera Space. To obtain the world_to_camera matrix take the inv of the output from the get_transformation_matrix function.

source
@diffops MyType::DataType

Generates functions for performing gradient based optimizations on this custom type. 5 functions are generated.

  1. x::MyType + y::MyType – For Gradient Accumulation
  2. x::MyType - y::MyType – For Gradient Based Updates
  3. x::MyType * η<:Real – For Multiplication of the Learning Rate with Gradient
  4. η<:Real * x::MyType – For Multiplication of the Learning Rate with Gradient
  5. x::MyType * y::MyType – Just for the sake of completeness.

Most of these functions do not make semantic sense. For example, adding 2 PointLight instances do not make sense but in case both of them are gradients, it makes perfect sense to accumulate them in a third PointLight instance.

source
RayTracer.get_paramsFunction.
get_params(x)

Get the parameters from a struct that can be tuned. The output is in the form of an array.

Example:

julia> using RayTracer;

julia> scene = Triangle(Vec3(-1.9f0, 1.6f0, 1.0f0), Vec3(1.0f0, 1.0f0, 0.0f0), Vec3(-0.5f0, -1.0f0, 0.0f0),
                        Material())
Triangle Object:
    Vertex 1 - x = -1.9, y = 1.6, z = 1.0
    Vertex 2 - x = 1.0, y = 1.0, z = 0.0
    Vertex 3 - x = -0.5, y = -1.0, z = 0.0
    Material{Array{Float32,1},Array{Float32,1},Nothing,Nothing,Nothing,Nothing}(x = 1.0, y = 1.0, z = 1.0, x = 1.0, y = 1.0, z = 1.0, x = 1.0, y = 1.0, z = 1.0, Float32[50.0], Float32[0.5], nothing, nothing, nothing, nothing)

julia> RayTracer.get_params(scene)
20-element Array{Float32,1}:
 -1.9
  1.6
  1.0
  1.0
  1.0
  0.0
 -0.5
 -1.0
  0.0
  1.0
  1.0
  1.0
  1.0
  1.0
  1.0
  1.0
  1.0
  1.0
 50.0
  0.5
source
RayTracer.set_params!Function.
set_params!(x, y::AbstractArray)

Sets the tunable parameters of the struct x. The index of the last element set into the struct is returned as output. This may be used to confirm that the size of the input array was as expected.

Example:

julia> using RayTracer;

julia> scene = Triangle(Vec3(-1.9f0, 1.6f0, 1.0f0), Vec3(1.0f0, 1.0f0, 0.0f0), Vec3(-0.5f0, -1.0f0, 0.0f0),
                        Material())
Triangle Object:
    Vertex 1 - x = -1.9, y = 1.6, z = 1.0
    Vertex 2 - x = 1.0, y = 1.0, z = 0.0
    Vertex 3 - x = -0.5, y = -1.0, z = 0.0
    Material{Array{Float32,1},Array{Float32,1},Nothing,Nothing,Nothing,Nothing}(x = 1.0, y = 1.0, z = 1.0, x = 1.0, y = 1.0, z = 1.0, x = 1.0, y = 1.0, z = 1.0, Float32[50.0], Float32[0.5], nothing, nothing, nothing, nothing)

julia> new_params = collect(1.0f0:20.0f0)
20-element Array{Float32,1}:
  1.0
  2.0
  3.0
  4.0
  5.0
  6.0
  7.0
  8.0
  9.0
 10.0
 11.0
 12.0
 13.0
 14.0
 15.0
 16.0
 17.0
 18.0
 19.0
 20.0

julia> RayTracer.set_params!(scene, new_params);

julia> scene
Triangle Object:
    Vertex 1 - x = 1.0, y = 2.0, z = 3.0
    Vertex 2 - x = 4.0, y = 5.0, z = 6.0
    Vertex 3 - x = 7.0, y = 8.0, z = 9.0
    Material{Array{Float32,1},Array{Float32,1},Nothing,Nothing,Nothing,Nothing}(x = 10.0, y = 11.0, z = 12.0, x = 13.0, y = 14.0, z = 15.0, x = 16.0, y = 17.0, z = 18.0, Float32[19.0], Float32[20.0], nothing, nothing, nothing, nothing)
source