
Genesis 入門 (2) - 視覚化 と レンダリング
「Genesis」の視覚化とレンダリングについてまとめました。
前回
1. 視覚化とレンダリング
「Genesis」の視覚化システムは、シーンの「visualizer」 (scene.visualizer)で管理します。
シーンを視覚化する方法は、次の2つがあります。
(1) インタラクティブビューアを使用
(2) シーンにカメラを追加して画像をレンダリング
2. インタラクティブビューア
ディスプレイに接続している場合は、「インタラクティブビューア」でシーンを視覚化できます。
シーンの作成時に「ビューアオプション」 (viewer_options) と「視覚化オプション」 (vis_options) を指定します。
scene = gs.Scene(
show_viewer = True,
# ビューアオプション
viewer_options = gs.options.ViewerOptions(
res = (1280, 960),
camera_pos = (3.5, 0.0, 2.5),
camera_lookat = (0.0, 0.0, 0.5),
camera_fov = 40,
max_FPS = 60,
),
# 視覚化オプション
vis_options = gs.options.VisOptions(
show_world_frame = True, # world の座標フレームを原点で視覚化
world_frame_size = 1.0, # ワールドフレームの長さ (メートル)
show_link_frame = False, # エンティティリンクの座標フレームを視覚化しない
show_cameras = False, # 追加されたカメラのメッシュと錐台を視覚化しない
plane_reflection = True, # 平面反射をオン
ambient_light = (0.1, 0.1, 0.1), # 周囲光の設定
),
renderer = gs.renderers.Rasterizer(), # カメラレンダリングにラスタライザを使用
)
「ビューアオプション」では、カメラのポーズ (pose) と視野 (fov) を指定します。max_FPS が None の場合、ビューアは可能な限り高速に実行されます。res が None の場合、4:3 ウィンドウを作成し、高さはディスプレイの高さの半分に設定されます。また、上記の設定では、カメラのレンダリングにgs.renderers.Rasterizer() を使用するように設定しています。
「Genesis」は、gs.renderers.Rasterizer() と gs.renderers.RayTracer() の2つのレンダリングバックエンドを提供します。ビューアは常にRasterizerを使用します。カメラもデフォルトではRasterizerを使用します。
シーンが作成されると、scene.visualizer.viewer またはショートカットとして scene.viewer を介してビューアにアクセスできます。
# カメラポーズの取得
cam_pose = scene.viewer.camera_pose()
# カメラポーズの指定
scene.viewer.set_camera_pose(cam_pose)
3. カメラ
3-1. カメラ
カメラを手動でシーンに追加します。カメラは、必要なときにのみレンダリング画像を返します。そのため、ヘッドレスモードで動作します。
cam = scene.add_camera(
res = (1280, 960),
pos = (3.5, 0.0, 2.5),
lookat = (0, 0, 0.5),
fov = 30,
GUI = False
)
パラメータは、次のとおりです。
・visualizer (genesis.Visualizer)
カメラが関連付けられているvisualizer。
・idx (int)
カメラのインデックス。
・model (str)
カメラモデル ('pinhole'/'thinlens')。
・res (tuple of int, shape (2,))
カメラの解像度を (幅, 高さ) のタプルで指定。
・pos (tuple of float, shape (3,))
シーン内でのカメラの位置を (x, y, z) の形式で指定。
・lookat (tuple of float, shape (3,))
カメラが注視しているシーン内のポイントを (x, y, z) の形式で指定。
・up (tuple of float, shape (3,))
カメラの「上方向」を定義するベクトルを (x, y, z) の形式で指定。
・fov (float)
カメラの垂直視野角を度単位で指定。
・aperture (float)
カメラの絞りサイズを指定。被写界深度を制御。
・focus_dist (float | None)
カメラの焦点距離を指定。Noneの場合、pos と lookat で自動計算。
・GUI (bool)
カメラのレンダリング画像を別のGUIウィンドウで表示。
・spp (int, optional)
ピクセルあたりのサンプル数 (デフォルト:256)。
・denoise (bool)
カメラのレンダリング画像をノイズ除去するかどうか。
・near (float)
カメラの近接平面。
・far (float)
カメラの遠方平面。
・transform (np.ndarray, shape (4, 4), optional)
カメラの変換行列。
メソッドは、次のとおりです。
・render() : カメラビューのレンダリング。
・set_pose() : カメラポーズの指定。
・set_params() : パラメータの指定。
・start_recording() : カメラ録画の開始。
・pause_recording() : カメラ録画の一時停止。
・stop_recording() : カメラ録画の停止。
GUI=True の場合、カメラはレンダリングされた画像を動的に表示する OpenCV ウィンドウを作成します。これはビューア GUI とは異なります。
シーンを構築したら、カメラで画像をレンダリングできます。カメラは、「RGB」「深度」「セグメンテーションマスク」「表面法線」のレンダリングをサポートします。デフォルトでは「RGB」のみがレンダリングされますが、camera.render() を呼び出すときにパラメータを設定することで、他のモードを有効化できます。
scene.build()
# RGB・深度・セグメンテーションマスク・法線マップをレンダリング
rgb, depth, segmentation, normal = cam.render(depth=True, segmentation=True, normal=True)
4つのウィンドウが表示されます (opencv ウィンドウには追加の遅延が発生することがあるため、ウィンドウが黒い場合は cv2.waitKey(1) を追加で呼び出すか、render() を再度呼び出してウィンドウを更新します)。

3-2. ビデオ録画
「RGB」のみをレンダリングし、カメラを動かしてビデオを録画します。「Genesis」には、ビデオを録画するための便利なユーティリティが提供されています。
# カメラ録画を開始
cam.start_recording()
import numpy as np
for i in range(120):
scene.step()
# カメラの位置を変更
cam.set_pose(
pos = (3.0 * np.sin(i / 60), 3.0 * np.cos(i / 60), 2.5),
lookat = (0, 0, 0.5),
)
cam.render()
# カメラ録画を停止してビデオを保存
cam.stop_recording(save_to_filename='video.mp4', fps=60)
ビデオは「video.mp4」に保存されます。

Genesisの動作確認 (2)https://t.co/Tn6YeLRy5w pic.twitter.com/19DNjxBJn3
— 布留川英一 / Hidekazu Furukawa (@npaka123) December 21, 2024
以下は、完全なコードです。
import genesis as gs
# 初期化
gs.init(backend=gs.cpu)
# シーンの作成
scene = gs.Scene(
show_viewer = True,
viewer_options = gs.options.ViewerOptions(
res = (1280, 960),
camera_pos = (3.5, 0.0, 2.5),
camera_lookat = (0.0, 0.0, 0.5),
camera_fov = 40,
max_FPS = 60,
),
vis_options = gs.options.VisOptions(
show_world_frame = True,
world_frame_size = 1.0,
show_link_frame = False,
show_cameras = False,
plane_reflection = True,
ambient_light = (0.1, 0.1, 0.1),
),
renderer=gs.renderers.Rasterizer(),
)
# シーンにエンティティを追加
plane = scene.add_entity(
gs.morphs.Plane(),
)
franka = scene.add_entity(
gs.morphs.MJCF(file='xml/franka_emika_panda/panda.xml'),
)
cam = scene.add_camera(
res = (640, 480),
pos = (3.5, 0.0, 2.5),
lookat = (0, 0, 0.5),
fov = 30,
GUI = False,
)
# シーンのビルド
scene.build()
# RGB・深度・セグメンテーションマスク・法線マップをレンダリング
# rgb, depth, segmentation, normal = cam.render(rgb=True, depth=True, segmentation=True, normal=True)
# カメラ録画を開始
cam.start_recording()
import numpy as np
for i in range(120):
scene.step()
# カメラの位置を変更
cam.set_pose(
pos = (3.0 * np.sin(i / 60), 3.0 * np.cos(i / 60), 2.5),
lookat = (0, 0, 0.5),
)
cam.render()
# カメラ録画を停止してビデオを保存
cam.stop_recording(save_to_filename='video.mp4', fps=60)
4. レイトレーシングレンダリング
「Genesis」は、フォトリアリスティックなレンダリングのためのRayTracerバックエンドを提供します。シーンを作成するときに renderer=gs.renderers.RayTracer() を設定することで、このバックエンドに切り替えることができます。このカメラでは「spp」「aperture」「model」など、より多くのパラメータ調整が可能です。
【おまけ】 Mac版のコード
import genesis as gs
import numpy as np
def main():
# 初期化
gs.init(backend=gs.cpu)
# シーンの作成
scene = gs.Scene(
show_viewer = True,
viewer_options = gs.options.ViewerOptions(
res = (1280, 960),
camera_pos = (3.5, 0.0, 2.5),
camera_lookat = (0.0, 0.0, 0.5),
camera_fov = 40,
max_FPS = 60,
),
vis_options = gs.options.VisOptions(
show_world_frame = True,
world_frame_size = 1.0,
show_link_frame = False,
show_cameras = False,
plane_reflection = True,
ambient_light = (0.1, 0.1, 0.1),
),
renderer=gs.renderers.Rasterizer(),
)
# シーンにエンティティを追加
plane = scene.add_entity(
gs.morphs.Plane(),
)
franka = scene.add_entity(
gs.morphs.MJCF(file='xml/franka_emika_panda/panda.xml'),
)
cam = scene.add_camera(
res = (640, 480),
pos = (3.5, 0.0, 2.5),
lookat = (0, 0, 0.5),
fov = 30,
GUI = False,
)
# シーンのビルド
scene.build()
# スレッドの開始
gs.tools.run_in_another_thread(fn=run_sim, args=(scene, cam))
# シミュレータの開始
scene.viewer.start()
def run_sim(scene, cam):
# カメラ録画を開始
cam.start_recording()
for i in range(120):
scene.step()
# カメラの位置を変更
cam.set_pose(
pos = (3.0 * np.sin(i / 60), 3.0 * np.cos(i / 60), 2.5),
lookat = (0, 0, 0.5),
)
cam.render()
# カメラ録画を停止してビデオを保存
cam.stop_recording(save_to_filename='video.mp4', fps=60)
# シミュレータの停止
scene.viewer.stop()
if __name__ == "__main__":
main()