This may be very slow if there are many objects in the scene (i.e. more than five). One solution to this problem is to use space subdivision. This consists of dividing the scene up into blocks, and then only tracing the ray against the objects that lie in the blocks which the ray intersects with.
Mirage provides this ability by including 'clusters', which are objects that you can wrap around a collection of objects to provide space subdivision. Mirage requires a cluster to be placed around the top-level scene before preparing it for rendering.
You can nest clusters to provide extra subdivision where it is required. However, too large a depth of clusters can slow down the Mirage considerably.
There are three kinds of clusters: StupidCluster, UniformCluster and OctreeCluster.
A StupidCluster does not divide space at all. However a cluster must be placed around the entire scene and the StupidCluster is the default.
// StupidClusters take no parameters for subdivision. // Only the object in the cluster is required. cluster1 = new_stupid_cluster(bind(scene));
UniformClusters divide a space into a uniform grid. The variables required are the object in the cluster, the bounds of the cluster, the level of subdivision and a flag. The bounds of the box to be subdivided are defined by minimum and maximum values for x, y and z. This can be specified as six values or two vectors. The level of subdivision is the number of times each axis is divided in half. Thus the number of cells along one edge of the uniform cluster is where n is the level of subdivision and the total number of cells in the volume is . The flag says whether or not to stop at the first intersection (this increases the speed of the raytracer, but means that you cannot, for example, subtract the front half of the cluster and see the back half).
object new_uniform_cluster(object obj, vector min, vector max, int level, int stop_at_first); object new_uniform_cluster(object obj, double x_min, double y_min, double z_min, double x_max, double y_max, double z_max, int level, int stop_at_first); //Example uniform cluster cluster2 = new_uniform_cluster(bind(scene),-2, -2, -2, +2, +2, +2, 5, TRUE);
An OctreeCluster stops subdividing when the number of primitives in a cell is less than a maximum defined number. OctreeClusters need the same parameters as a UniformCluster, and also a number that gives the maximum number of primitives that can be placed in a node of the octree.
object new_octree_cluster(object obj, vector min, vector max, int limit, int max_prims, int stop_at_first); object new_octree_cluster(object obj, double x_min, double y_min, double z_min, double x_max, double y_max, double z_max, int limit, int max_prims, int stop_at_first); //Example octree cluster cluster3 = new_octree_cluster(bind(scene), -2, -2, -2, +2, +2, +2, 5, 3, TRUE);
Space subdivision generally will give much faster raytracing times at the expense of more memory. An increase of 1 in the subdivision level may be an increase by a factor of 8 in memory usage.