Scatter Examples

The goal of these examples are to provide common use cases for scattering in Omniverse Replicator.

Below are a few demonstrations of scatter applied within a scene using Replicator APIs.

Learning Objectives

Through this page you will see some highlighted scattering examples and how to use them.

However, for all information about replicator camera use consult the API documentation .

Scattering objects in a surface

In this example we show you how to scatter objects in a 2D surface using the function randomizer.scatter_2d().

import omni.graph.core as og
import omni.replicator.core as rep

# create a plane to sample on
plane_samp = rep.create.plane(scale=4, rotation=(20, 0, 0))


def randomize_spheres():
    # create small spheres to sample inside the plane
    spheres = rep.create.sphere(scale=0.4, count=30)

    # randomize
    with spheres:
        rep.randomizer.scatter_2d(plane_samp)
        # Add color to small spheres
        rep.randomizer.color(colors=rep.distribution.uniform((0.2, 0.2, 0.2), (1, 1, 1)))
    return spheres.node


rep.randomizer.register(randomize_spheres)

with rep.trigger.on_frame(num_frames=10):
    rep.randomizer.randomize_spheres()
Scatter 2D

The spheres are scattered on the plane, but you should notice that they will intersect with each other.

Scatter 2D with collisions

Altering the code above, we can add check_for_collisions=True to ensure that none of the spheres overlap.

import omni.graph.core as og
import omni.replicator.core as rep

# create a plane to sample on
plane_samp = rep.create.plane(scale=4, rotation=(20, 0, 0))


def randomize_spheres():
    # create small spheres to sample inside the plane
    spheres = rep.create.sphere(scale=0.4, count=30)

    # randomize
    with spheres:
        rep.randomizer.scatter_2d(plane_samp, check_for_collisions=True)
        # Add color to small spheres
        rep.randomizer.color(colors=rep.distribution.uniform((0.2, 0.2, 0.2), (1, 1, 1)))
    return spheres.node


rep.randomizer.register(randomize_spheres)

with rep.trigger.on_frame(num_frames=10):
    rep.randomizer.randomize_spheres()
Scatter 2D without collisions

The spheres are now scattered without intersecting with each other.

Note

An error will be raised if no collision solution can be found within a reasonable amount of time (for instance: having too many objects)

Multi-Surface Scatter 2D

In this example, the Scatter 2D node can be used for sampling on multiple surfaces.

We create a second surface, a large sphere, and sample 40 small spheres distributed across both surfaces.

Scatter 2D with multiple surfaces
import omni.replicator.core as rep

# A light to see
distance_light = rep.create.light(rotation=(-45, 0, 0), light_type="distant")

# Create a plane to sample on
plane_samp = rep.create.plane(scale=3, rotation=(20, 0, 0))

# Create a larger sphere to sample on the surface of
sphere_samp = rep.create.sphere(scale=2.4, position=(0, 100, -180))


def randomize_spheres():
    # create small spheres to sample inside the plane
    spheres = rep.create.sphere(scale=0.4, count=40)

    # scatter small spheres
    with spheres:
        rep.randomizer.scatter_2d(surface_prims=[plane_samp, sphere_samp], check_for_collisions=True)
        # Add color to small spheres
        rep.randomizer.color(colors=rep.distribution.uniform((0.2, 0.2, 0.2), (1, 1, 1)))
    return spheres.node


rep.randomizer.register(randomize_spheres)

with rep.trigger.on_frame(num_frames=10):
    rep.randomizer.randomize_spheres()

Scatter 2D avoiding objects

In this example we show the Scatter 2D node can allow for collision checking with other prims besides the ones created for sampling.

We create a large cylinder and check for collisions by adding it to the parameter list no_coll_prims.

The scattered spheres will now avoid placement where the cylinder is located. Multiple extra prims can be added for collision checking with this parameter.

import omni.replicator.core as rep

# A light to see
distance_light = rep.create.light(rotation=(-45, 0, 0), light_type="distant")

# Create a plane to sample on
plane_samp = rep.create.plane(scale=3, rotation=(20, 0, 0))

# Create a larger sphere to sample on the surface of
sphere_samp = rep.create.sphere(scale=2.4, position=(0, 100, -180))

# Create a larger cylinder we do not want to collide with
cylinder = rep.create.cylinder(
    semantics=[("class", "cylinder")], scale=(2, 1, 2))


def randomize_spheres():
    # create small spheres to sample inside the plane
    spheres = rep.create.sphere(scale=0.4, count=60)

    # scatter small spheres
    with spheres:
        rep.randomizer.scatter_2d(
            surface_prims=[plane_samp, sphere_samp], no_coll_prims=[cylinder], check_for_collisions=True
        )
        # Add color to small spheres
        rep.randomizer.color(colors=rep.distribution.uniform((0.2, 0.2, 0.2), (1, 1, 1)))
    return spheres.node

rep.randomizer.register(randomize_spheres)

with rep.trigger.on_frame(num_frames=10):
    rep.randomizer.randomize_spheres()
Scatter 2D with collision

Scatter 2D with limits

In this example, we show that the Scatter 2D node can take in extra parameters for the min_samp and max_samp sampling bounds.

For example, you might want to stop sampling for everything beyond a certain value, i.e. y > 100.

To do this, specify min_samp=(X, Y, Z) and/or max_samp=(X, Y, Z) in the Scatter 2D node parameters. The X,Y,Z values are all in world-space units.

import omni.replicator.core as rep

# A light to see
distance_light = rep.create.light(rotation=(-45, 0, 0), light_type="distant")

# Create a plane to sample on
plane_samp = rep.create.plane(scale=3, rotation=(20, 0, 0))

# Create a larger sphere to sample on the surface of
sphere_samp = rep.create.sphere(scale=2.4, position=(0, 100, -180))

def randomize_spheres():
    # create small spheres to sample inside the plane
    spheres = rep.create.sphere(scale=0.4, count=60)

    # scatter small spheres
    with spheres:
        rep.randomizer.scatter_2d(
            [plane_samp, sphere_samp],
            min_samp=(None, None, None),
            # Small spheres will not go beyond 0 in X, 110 in Y, 30 in Z world space
            max_samp=(0, 110, 30),
            check_for_collisions=False,
        )
        rep.randomizer.color(colors=rep.distribution.uniform((0.2, 0.2, 0.2), (1, 1, 1)))
    return spheres.node


rep.randomizer.register(randomize_spheres)

with rep.trigger.on_frame(num_frames=10):
    rep.randomizer.randomize_spheres()
Scatter 2D with limits