Nyx 渲染器#

Nyx 渲染器为 Genesis World 仿真生成照片级真实感的画面

Nyx 是 Genesis World 自研的 GPU 加速路径追踪器。它生成基于物理、照片级真实感的画面(适用于机器人数据集、演示和合成感知数据),并以相机传感器的形式接入场景,而不是作为场景级渲染器。

其他渲染后端通过 gs.Scene(renderer=...) 为整个场景一次性选定。Nyx 则按相机逐个挂载,使用 scene.add_sensor(NyxCameraOptions(...)),因此同一个场景里可以同时配备用于控制回路的快速光栅化相机,以及用于产出最终画面、具备照片级真实感的 Nyx 相机。渲染在 scene.step() 期间进行,帧通过 cam.read().rgb 读回。

何时使用 Nyx#

Genesis World 提供多种把场景转换为像素的方式(完整列表见渲染)。可根据需求选择:

你想要…

使用

迭代过程中需要交互式窗口

查看器

用于控制和调试的快速、非照片级真实感相机帧

gs.renderers.Rasterizer()(默认)

跨多个环境的高吞吐量渲染

gs.renderers.BatchRenderer(...)

照片级真实感画面:PBR 材质、HDRI 光照、高斯泼溅

Nyx

Genesis World 还提供一个较旧的光线追踪器 gs.renderers.RayTracer()(Luisa),用于生成照片级真实感的静帧。它已被 Nyx 取代并弃用,Nyx 是照片级真实感渲染的推荐方案。

安装#

Nyx 以独立的 gs-nyx 包形式发布:

pip install gs-nyx

Note

在我们为公开发布做准备期间,gs-nyx 目前通过内部包索引分发。待 wheel 上传到 PyPI 后,我们会在 Nyx 仓库 发布公开的安装说明。

与 Genesis World 一起导入插件即可验证安装:

import genesis as gs
import gs_nyx.nyx_py_renderer as npr
import gs_nyx.nyx_py_sdk as nps
from gs_nyx_plugin.nyx_camera_options import NyxCameraOptions

功能亮点:

  • 基于物理的路径追踪,PBR 材质从 GLTF/GLB 资产原样传递

  • HDRI 环境贴图和解析光源

  • 3D 高斯泼溅(“光场”)资产与仿真几何体一同渲染

  • 挂载式相机与多相机配置,以及多环境渲染

  • 逐像素对象拾取

Note

下文中的 gs_nyx / gs_nyx_plugin 符号(NyxCameraOptions、LightFieldAsset、EnvironmentMapAsset、nps.*、npr.*)随 gs-nyx 包提供,并不在核心 genesis 代码树中。scene.add_sensor(...) 是 Nyx 所接入的核心传感器接口。

最小示例#

下面的代码片段渲染一个平面上的 PBR 球体,光照完全来自 HDRI 环境贴图。这是 Nyx 的经典“hello world”,与 Nyx 仓库中的 examples/01_hello_nyx.py 对应。

在 HDRI 环境贴图下用 Nyx 渲染的 PBR 球体
import os
from PIL import Image

import genesis as gs
import gs_nyx.nyx_py_renderer as npr
import gs_nyx.nyx_py_sdk as nps
from gs_nyx_plugin.nyx_camera_options import NyxCameraOptions


HERE = os.path.dirname(__file__)
PBR_BALL = os.path.join(HERE, "assets", "PBR_Ball.glb")
ENV_MAP = os.path.join(HERE, "assets", "kloppenheim_07_puresky_4k.hdr")
OUTPUT_PATH = os.path.join(HERE, "out", "01_hello_nyx.png")


def main():
    gs.init()

    scene = gs.Scene(
        sim_options=gs.options.SimOptions(dt=0.01),
        show_viewer=False,
    )

    scene.add_entity(morph=gs.morphs.Plane(plane_size=(10.0, 10.0)))
    scene.add_entity(
        morph=gs.morphs.Mesh(file=PBR_BALL, pos=(0.0, 0.0, 0.0)),
        surface=gs.surfaces.Gold(),
    )

    # describe how the env map is encoded
    env_map = nps.EnvironmentMapAsset()
    env_map.texture = ENV_MAP
    env_map.layout = nps.EEnvMapLayout.LongLat
    env_map.multiplier = 8

    # attach a Nyx camera sensor
    cam = scene.add_sensor(
        NyxCameraOptions(
            res=(1920, 1080),
            pos=(-1.0, 1.0, 1.2),
            lookat=(0.0, 0.0, 0.1),
            fov=20.0,
            spp=64,
            render_mode=npr.ERenderMode.FastPathTracer,
            env_maps=(env_map,),
        )
    )

    scene.build(n_envs=1)
    scene.step()  # rendering happens during the sim step

    rgb = cam.read().rgb[0].cpu().numpy()
    os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
    Image.fromarray(rgb).save(OUTPUT_PATH)
    print(f"Saved {OUTPUT_PATH}")


if __name__ == "__main__":
    main()

与其他后端相比有两点不同:

  • 渲染发生在 scene.step() 期间。 通过 cam.read().rgb 读回帧,这是一个 torch 张量,每个环境对应一张图像。

  • spp(每像素采样数)和 render_mode 用于在质量与速度之间权衡;迭代阶段用 FastPathTracer 是很好的默认选择。

渲染高斯泼溅#

除标准网格之外,Nyx 还能把采集得到的 3D 高斯泼溅与仿真几何体渲染在同一张路径追踪画面中。泼溅以 LightFieldAsset 的形式声明在 Nyx 相机上,而不是作为 Genesis World 实体:Nyx 在 scene.build() 时收集每个传感器的 light_fields,并在每一步渲染它们。采集数据本身已烘焙了随视角变化的颜色,因此环境贴图只需照亮它旁边的仿真几何体。

一个采集得到的植物高斯泼溅放置在 Genesis World 平面上,由 Nyx 渲染

下面的代码片段来自 Nyx 仓库的 examples/05_gaussian_splat.py。它在 green_sanctuary HDRI 下把一个采集得到的 plant.ply 泼溅渲染到一个 Plane 上。

import os
from PIL import Image

import genesis as gs
import gs_nyx.nyx_py_renderer as npr
import gs_nyx.nyx_py_sdk as nps
from gs_nyx_plugin.nyx_camera_options import NyxCameraOptions


HERE = os.path.dirname(__file__)
PLANT_PLY = os.path.join(HERE, "assets", "plant.ply")
ENV_MAP = os.path.join(HERE, "assets", "green_sanctuary_4k.hdr")
OUTPUT_PATH = os.path.join(HERE, "out", "05_gaussian_splat.png")


def main():
    gs.init()
    os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)

    scene = gs.Scene(
        sim_options=gs.options.SimOptions(dt=0.01),
        show_viewer=False,
    )

    scene.add_entity(morph=gs.morphs.Plane(plane_size=(2.0, 2.0)))

    # The splat is declared on the camera as a LightFieldAsset, not as a
    # Genesis World entity. Every Nyx sensor's light_fields are gathered at
    # scene.build() and rendered alongside simulated geometry.
    plant = nps.LightFieldAsset()
    plant.type = nps.ELightFieldType.GaussianField
    plant.uri = PLANT_PLY
    # Rotate 90deg about Z to stand the capture upright in Genesis World's Z-up world.
    plant.rotation = nps.quaternion(0.0, 0.0, -0.70710678, 0.70710678)

    # HDRI env map lighting the simulated plane. The splat already bakes in
    # view-dependent color, so only the geometry needs an external light.
    env_map = nps.EnvironmentMapAsset()
    env_map.texture = ENV_MAP
    env_map.layout = nps.EEnvMapLayout.LongLat
    env_map.multiplier = 2.0

    cam = scene.add_sensor(
        NyxCameraOptions(
            res=(1920, 1080),
            pos=(1.0, 1.5, 0.8),
            lookat=(0.0, 0.0, 0.1),
            fov=30.0,
            spp=64,
            render_mode=npr.ERenderMode.FastPathTracer,
            env_maps=[env_map],
            light_fields=[plant],
        )
    )

    scene.build(n_envs=1)
    scene.step()  # rendering happens during the sim step

    rgb = cam.read().rgb[0].cpu().numpy()  # env 0 frame, shape (H, W, 3)
    Image.fromarray(rgb).save(OUTPUT_PATH)
    print(f"Saved {OUTPUT_PATH}")


if __name__ == "__main__":
    main()

另请参阅#

更多示例位于 Nyx 示例文件夹,涵盖挂载式相机、材质、灯光类型、对象拾取,以及多相机和多环境渲染。完整的选项参考和高级功能请参阅 Nyx 文档。