LightsΒΆ

Visualize a mesh under different lighting conditions. To get the demo data, see ./assets/download_dragon_mesh.sh.

  1import time
  2from pathlib import Path
  3
  4import numpy as np
  5import trimesh
  6
  7import viser
  8import viser.transforms as tf
  9
 10
 11def main() -> None:
 12    # Load mesh.
 13    mesh = trimesh.load_mesh(str(Path(__file__).parent / "assets/dragon.obj"))
 14    assert isinstance(mesh, trimesh.Trimesh)
 15    mesh.apply_scale(0.05)
 16    vertices = mesh.vertices
 17    faces = mesh.faces
 18    print(f"Loaded mesh with {vertices.shape} vertices, {faces.shape} faces")
 19
 20    # Start Viser server with mesh.
 21    server = viser.ViserServer()
 22
 23    server.scene.add_mesh_simple(
 24        name="/simple",
 25        vertices=vertices,
 26        faces=faces,
 27        wxyz=tf.SO3.from_x_radians(np.pi / 2).wxyz,
 28        position=(0.0, 0.0, 0.0),
 29    )
 30    server.scene.add_mesh_trimesh(
 31        name="/trimesh",
 32        mesh=mesh,
 33        wxyz=tf.SO3.from_x_radians(np.pi / 2).wxyz,
 34        position=(0.0, 5.0, 0.0),
 35    )
 36
 37    # adding controls to custom lights in the scene
 38    server.scene.add_transform_controls("/control0", position=(0.0, 10.0, 5.0))
 39    server.scene.add_label("/control0/label", "Directional")
 40    server.scene.add_transform_controls("/control1", position=(0.0, -5.0, 5.0))
 41    server.scene.add_label("/control1/label", "Point")
 42
 43    directional_light = server.scene.add_light_directional(
 44        name="/control0/directional_light",
 45        color=(186, 219, 173),
 46    )
 47    point_light = server.scene.add_light_point(
 48        name="/control1/point_light",
 49        color=(192, 255, 238),
 50        intensity=30.0,
 51    )
 52
 53    # Create default light toggle.
 54    gui_default_lights = server.gui.add_checkbox("Default lights", initial_value=True)
 55    gui_default_lights.on_update(
 56        lambda _: server.scene.enable_default_lights(gui_default_lights.value)
 57    )
 58
 59    # Create light control inputs.
 60    with server.gui.add_folder("Directional light"):
 61        gui_directional_color = server.gui.add_rgb(
 62            "Color", initial_value=directional_light.color
 63        )
 64        gui_directional_intensity = server.gui.add_slider(
 65            "Intensity",
 66            min=0.0,
 67            max=20.0,
 68            step=0.01,
 69            initial_value=directional_light.intensity,
 70        )
 71
 72        @gui_directional_color.on_update
 73        def _(_) -> None:
 74            directional_light.color = gui_directional_color.value
 75
 76        @gui_directional_intensity.on_update
 77        def _(_) -> None:
 78            directional_light.intensity = gui_directional_intensity.value
 79
 80    with server.gui.add_folder("Point light"):
 81        gui_point_color = server.gui.add_rgb("Color", initial_value=point_light.color)
 82        gui_point_intensity = server.gui.add_slider(
 83            "Intensity",
 84            min=0.0,
 85            max=200.0,
 86            step=0.01,
 87            initial_value=point_light.intensity,
 88        )
 89
 90        @gui_point_color.on_update
 91        def _(_) -> None:
 92            point_light.color = gui_point_color.value
 93
 94        @gui_point_intensity.on_update
 95        def _(_) -> None:
 96            point_light.intensity = gui_point_intensity.value
 97
 98    # Create GUI elements for controlling environment map.
 99    with server.gui.add_folder("Environment map"):
100        gui_env_preset = server.gui.add_dropdown(
101            "Preset",
102            (
103                "None",
104                "apartment",
105                "city",
106                "dawn",
107                "forest",
108                "lobby",
109                "night",
110                "park",
111                "studio",
112                "sunset",
113                "warehouse",
114            ),
115            initial_value="city",
116        )
117        gui_background = server.gui.add_checkbox("Background", False)
118        gui_bg_blurriness = server.gui.add_slider(
119            "Bg Blurriness",
120            min=0.0,
121            max=1.0,
122            step=0.01,
123            initial_value=0.0,
124        )
125        gui_bg_intensity = server.gui.add_slider(
126            "Bg Intensity",
127            min=0.0,
128            max=1.0,
129            step=0.01,
130            initial_value=1.0,
131        )
132        gui_env_intensity = server.gui.add_slider(
133            "Env Intensity",
134            min=0.0,
135            max=1.0,
136            step=0.01,
137            initial_value=0.1,
138        )
139
140    def update_environment_map(_) -> None:
141        server.scene.set_environment_map(
142            gui_env_preset.value if gui_env_preset.value != "None" else None,
143            background=gui_background.value,
144            background_blurriness=gui_bg_blurriness.value,
145            background_intensity=gui_bg_intensity.value,
146            environment_intensity=gui_env_intensity.value,
147        )
148
149    update_environment_map(None)
150    gui_env_preset.on_update(update_environment_map)
151    gui_background.on_update(update_environment_map)
152    gui_bg_blurriness.on_update(update_environment_map)
153    gui_bg_intensity.on_update(update_environment_map)
154    gui_env_intensity.on_update(update_environment_map)
155
156    while True:
157        time.sleep(10.0)
158
159
160if __name__ == "__main__":
161    main()