Lighting and ShadowsΒΆ
Example adding lights and enabling shadow rendering.
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 print(mesh)
20
21 # Start Viser server with mesh.
22 server = viser.ViserServer()
23
24 server.scene.add_mesh_simple(
25 name="/simple",
26 vertices=vertices,
27 faces=faces,
28 wxyz=tf.SO3.from_x_radians(np.pi / 2).wxyz,
29 position=(0.0, 2.0, 0.0),
30 )
31 server.scene.add_mesh_trimesh(
32 name="/trimesh",
33 mesh=mesh,
34 wxyz=tf.SO3.from_x_radians(np.pi / 2).wxyz,
35 position=(0.0, -2.0, 0.0),
36 )
37 server.scene.add_grid(
38 "grid",
39 width=20.0,
40 height=20.0,
41 position=np.array([0.0, 0.0, -2.0]),
42 )
43
44 # adding controls to custom lights in the scene
45 server.scene.add_transform_controls(
46 "/control0", position=(0.0, 10.0, 5.0), scale=2.0
47 )
48 server.scene.add_label("/control0/label", "Directional")
49 server.scene.add_transform_controls(
50 "/control1", position=(0.0, -5.0, 5.0), scale=2.0
51 )
52 server.scene.add_label("/control1/label", "Point")
53
54 directional_light = server.scene.add_light_directional(
55 name="/control0/directional_light",
56 color=(186, 219, 173),
57 )
58 point_light = server.scene.add_light_point(
59 name="/control1/point_light",
60 color=(192, 255, 238),
61 intensity=30.0,
62 )
63
64 # Create default light toggle.
65 gui_default_lights = server.gui.add_checkbox("Default lights", initial_value=True)
66 gui_default_shadows = server.gui.add_checkbox(
67 "Default shadows", initial_value=False
68 )
69
70 gui_default_lights.on_update(
71 lambda _: server.scene.enable_default_lights(gui_default_lights.value)
72 )
73 gui_default_shadows.on_update(
74 lambda _: server.scene.enable_default_lights(gui_default_lights.value)
75 )
76
77 # Create light control inputs.
78 with server.gui.add_folder("Directional light"):
79 gui_directional_color = server.gui.add_rgb(
80 "Color", initial_value=directional_light.color
81 )
82 gui_directional_intensity = server.gui.add_slider(
83 "Intensity",
84 min=0.0,
85 max=20.0,
86 step=0.01,
87 initial_value=directional_light.intensity,
88 )
89
90 @gui_directional_color.on_update
91 def _(_) -> None:
92 directional_light.color = gui_directional_color.value
93
94 @gui_directional_intensity.on_update
95 def _(_) -> None:
96 directional_light.intensity = gui_directional_intensity.value
97
98 with server.gui.add_folder("Point light"):
99 gui_point_color = server.gui.add_rgb("Color", initial_value=point_light.color)
100 gui_point_intensity = server.gui.add_slider(
101 "Intensity",
102 min=0.0,
103 max=200.0,
104 step=0.01,
105 initial_value=point_light.intensity,
106 )
107
108 @gui_point_color.on_update
109 def _(_) -> None:
110 point_light.color = gui_point_color.value
111
112 @gui_point_intensity.on_update
113 def _(_) -> None:
114 point_light.intensity = gui_point_intensity.value
115
116 # Create GUI elements for controlling environment map.
117 with server.gui.add_folder("Environment map"):
118 gui_env_preset = server.gui.add_dropdown(
119 "Preset",
120 (
121 "None",
122 "apartment",
123 "city",
124 "dawn",
125 "forest",
126 "lobby",
127 "night",
128 "park",
129 "studio",
130 "sunset",
131 "warehouse",
132 ),
133 initial_value="city",
134 )
135 gui_background = server.gui.add_checkbox("Background", False)
136 gui_bg_blurriness = server.gui.add_slider(
137 "Bg Blurriness",
138 min=0.0,
139 max=1.0,
140 step=0.01,
141 initial_value=0.0,
142 )
143 gui_bg_intensity = server.gui.add_slider(
144 "Bg Intensity",
145 min=0.0,
146 max=1.0,
147 step=0.01,
148 initial_value=1.0,
149 )
150 gui_env_intensity = server.gui.add_slider(
151 "Env Intensity",
152 min=0.0,
153 max=1.0,
154 step=0.01,
155 initial_value=0.3,
156 )
157
158 def update_environment_map(_) -> None:
159 server.scene.set_environment_map(
160 gui_env_preset.value if gui_env_preset.value != "None" else None,
161 background=gui_background.value,
162 background_blurriness=gui_bg_blurriness.value,
163 background_intensity=gui_bg_intensity.value,
164 environment_intensity=gui_env_intensity.value,
165 )
166
167 update_environment_map(None)
168 gui_env_preset.on_update(update_environment_map)
169 gui_background.on_update(update_environment_map)
170 gui_bg_blurriness.on_update(update_environment_map)
171 gui_bg_intensity.on_update(update_environment_map)
172 gui_env_intensity.on_update(update_environment_map)
173
174 while True:
175 time.sleep(10.0)
176
177
178if __name__ == "__main__":
179 main()