Cameras#

Camera sensors in ovrtx simulate physically accurate imaging and produce rendered outputs through RenderVar prims attached to a RenderProduct.

For how to configure RenderProducts and RenderVars, see Sensor Configuration.

Example USD#

A RenderProduct that outputs both LdrColor and HdrColor from a camera:

def "Render" {
    def RenderProduct "Camera" {
        int2 resolution = (1920, 1080)
        rel camera = </World/Camera>
        rel orderedVars = [<LdrColor>, <HdrColor>]

        def RenderVar "LdrColor" {
            string sourceName = "LdrColor"
        }

        def RenderVar "HdrColor" {
            string sourceName = "HdrColor"
        }
    }
}
render_scope = stage.DefinePrim("/Render")
camera_product = UsdRender.Product.Define(stage, "/Render/Camera")
camera_product.GetResolutionAttr().Set(Gf.Vec2i(1920, 1080))
camera_product.GetCameraRel().SetTargets(["/World/Camera"])

ldr_var = UsdRender.Var.Define(stage, "/Render/Camera/LdrColor")
ldr_var.GetSourceNameAttr().Set("LdrColor")

hdr_var = UsdRender.Var.Define(stage, "/Render/Camera/HdrColor")
hdr_var.GetSourceNameAttr().Set("HdrColor")

camera_product.GetOrderedVarsRel().SetTargets([
    "/Render/Camera/LdrColor",
    "/Render/Camera/HdrColor",
])

Accessing Outputs in Code#

After stepping the renderer with a RenderProduct path, the outputs are available by name:

products = renderer.step(
    render_products={"/Render/Camera"},
    delta_time=1.0 / 60,
)

for product_name, product in products.items():
    for frame in product.frames:
        # LdrColor: uint8 sRGB image
        var = frame.render_vars["LdrColor"].map(device=ovrtx.Device.CPU)
        ldr_pixels = np.from_dlpack(var)  # shape: (H, W, 4), dtype: uint8
        assert ldr_pixels.shape == (1080, 1920, 4)
        assert ldr_pixels.dtype == np.uint8
        Image.fromarray(ldr_pixels).save(output_dir / "test_camera_sensors.LdrColor.png")

        # HdrColor: float16 linear image
        var = frame.render_vars["HdrColor"].map(device=ovrtx.Device.CPU)
        hdr_pixels = np.from_dlpack(var)  # shape: (H, W, 4), dtype: float16
        assert hdr_pixels.shape == (1080, 1920, 4)
        assert hdr_pixels.dtype == np.float16
ovrtx_render_var_output_handle_t ldr_handle = find_output(outputs, "LdrColor");
ovrtx_render_var_output_handle_t hdr_handle = find_output(outputs, "HdrColor");
ASSERT_NE(ldr_handle, OVRTX_INVALID_HANDLE);
ASSERT_NE(hdr_handle, OVRTX_INVALID_HANDLE);

// Map LdrColor to CPU
ovrtx_map_output_description_t map_desc = {};
map_desc.device_type = OVRTX_MAP_DEVICE_TYPE_CPU;

ovrtx_render_var_output_t ldr_output = {};
result = ovrtx_map_render_var_output(renderer, ldr_handle, &map_desc,
                                     ovrtx_timeout_infinite, &ldr_output);
ASSERT_API_SUCCESS(result.status);

DLTensor const& ldr_tensor = *ldr_output.tensors[0].dl;
// ldr_tensor.data: RGBA uint8 pixels
// ldr_tensor.shape[0]: height, ldr_tensor.shape[1]: width

save_ldr_png("CameraSensors.LdrColor",
             ldr_tensor.data,
             static_cast<int>(ldr_tensor.shape[1]),
             static_cast<int>(ldr_tensor.shape[0]));

ovrtx_cuda_sync_t no_sync = {};
ovrtx_unmap_render_var_output(renderer, ldr_output.map_handle, no_sync);