From 3e1525c94611feb39abfd70eb9dafc0325cabc25 Mon Sep 17 00:00:00 2001 From: Rong Liu <102014841+RongLiu-Leo@users.noreply.github.com> Date: Tue, 20 May 2025 16:25:59 -0700 Subject: [PATCH 1/8] Update render_panel.py --- nerfview/render_panel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nerfview/render_panel.py b/nerfview/render_panel.py index bce9cb5..f9fef81 100644 --- a/nerfview/render_panel.py +++ b/nerfview/render_panel.py @@ -1124,7 +1124,7 @@ def play() -> None: play_thread.join() dump_video_button.disabled = not preview_save_camera_path_button.visible - # Play the camera trajectory when the play button is pressed. + # Pause the camera trajectory when the pause button is pressed. @pause_button.on_click def _(_) -> None: play_button.visible = True From 8939f2dcfe3a783dd3dddb2deb73643681cbde4c Mon Sep 17 00:00:00 2001 From: Rong Liu <102014841+RongLiu-Leo@users.noreply.github.com> Date: Tue, 20 May 2025 19:01:55 -0700 Subject: [PATCH 2/8] change time.time() to time.perf_counter() --- examples/01_dummy_training.py | 4 ++-- examples/04_gsplat_training.py | 12 ++++++------ nerfview/_renderer.py | 4 ++-- nerfview/viewer.py | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/01_dummy_training.py b/examples/01_dummy_training.py index 5bf13d7..469d586 100644 --- a/examples/01_dummy_training.py +++ b/examples/01_dummy_training.py @@ -97,10 +97,10 @@ def training_step(): while viewer.state == "paused": time.sleep(0.01) # Do the training step and compute the number of training rays per second. - tic = time.time() + tic = time.perf_counter() with viewer.lock: num_train_rays_per_step = training_step() - num_train_steps_per_sec = 1.0 / (max(time.time() - tic, 1e-10)) + num_train_steps_per_sec = 1.0 / (time.perf_counter() - tic) num_train_rays_per_sec = num_train_rays_per_step * num_train_steps_per_sec # Update the viewer state. viewer.render_tab_state.num_train_rays_per_sec = num_train_rays_per_sec diff --git a/examples/04_gsplat_training.py b/examples/04_gsplat_training.py index 85cb0de..65e5d11 100644 --- a/examples/04_gsplat_training.py +++ b/examples/04_gsplat_training.py @@ -403,14 +403,14 @@ def train(self): trainloader_iter = iter(trainloader) # Training loop. - tic = time.time() + tic = time.perf_counter() pbar = tqdm.tqdm(range(init_step, max_steps)) for step in pbar: if not cfg.disable_viewer: while self.viewer.state.status == "paused": time.sleep(0.01) self.viewer.lock.acquire() - tic = time.time() + tic = time.perf_counter() try: data = next(trainloader_iter) @@ -607,7 +607,7 @@ def train(self): # save checkpoint if step in [i - 1 for i in cfg.save_steps] or step == max_steps - 1: mem = torch.cuda.max_memory_allocated() / 1024**3 - toc = time.time() + toc = time.perf_counter() stats = { "mem": mem, "ellipse_time": toc - tic, @@ -631,7 +631,7 @@ def train(self): if not cfg.disable_viewer: self.viewer.lock.release() - num_train_steps_per_sec = 1.0 / (max(time.time() - tic, 1e-10)) + num_train_steps_per_sec = 1.0 / (time.perf_counter() - tic) num_train_rays_per_sec = ( num_train_rays_per_step * num_train_steps_per_sec ) @@ -810,7 +810,7 @@ def eval(self, step: int): height, width = pixels.shape[1:3] torch.cuda.synchronize() - tic = time.time() + tic = time.perf_counter() colors, _, _ = self.rasterize_splats( camtoworlds=camtoworlds, Ks=Ks, @@ -822,7 +822,7 @@ def eval(self, step: int): ) # [1, H, W, 3] colors = torch.clamp(colors, 0.0, 1.0) torch.cuda.synchronize() - ellipse_time += max(time.time() - tic, 1e-10) + ellipse_time += time.perf_counter() - tic # write images canvas = torch.cat([pixels, colors], dim=2).squeeze(0).cpu().numpy() diff --git a/nerfview/_renderer.py b/nerfview/_renderer.py index ad17ca3..2fb2ef6 100644 --- a/nerfview/_renderer.py +++ b/nerfview/_renderer.py @@ -145,7 +145,7 @@ def run(self): assert task.camera_state is not None try: with self.lock, set_trace_context(self._may_interrupt_trace): - tic = time.time() + tic = time.perf_counter() W, H = img_wh = self._get_img_wh(task.camera_state.aspect) self.viewer.render_tab_state.viewer_width = W self.viewer.render_tab_state.viewer_height = H @@ -171,7 +171,7 @@ def run(self): else: img, depth = rendered, None self.viewer.render_tab_state.num_view_rays_per_sec = (W * H) / ( - max(time.time() - tic, 1e-10) + time.perf_counter() - tic ) except InterruptRenderException: continue diff --git a/nerfview/viewer.py b/nerfview/viewer.py index 8cf3229..ca57d80 100644 --- a/nerfview/viewer.py +++ b/nerfview/viewer.py @@ -206,7 +206,7 @@ def _connect_client(self, client: viser.ClientHandle): @client.camera.on_update def _(_: viser.CameraHandle): - self._last_move_time = time.time() + self._last_move_time = time.perf_counter() with self.server.atomic(): camera_state = self.get_camera_state(client) self._renderers[client_id].submit(RenderTask("move", camera_state)) @@ -240,7 +240,7 @@ def update(self, step: int, num_train_rays_per_step: int): if len(self._renderers) == 0: return # Stop training while user moves camera to make viewing smoother. - while time.time() - self._last_move_time < 0.1: + while time.perf_counter() - self._last_move_time < 0.1: time.sleep(0.05) if ( self.state == "training" From 5bf0ceefe8e9090680f1b52dfb789bfbc695e518 Mon Sep 17 00:00:00 2001 From: Rong Liu <102014841+RongLiu-Leo@users.noreply.github.com> Date: Tue, 20 May 2025 19:30:27 -0700 Subject: [PATCH 3/8] Update render_panel.py fix jumping green camera vis --- nerfview/render_panel.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/nerfview/render_panel.py b/nerfview/render_panel.py index f9fef81..9948dfb 100644 --- a/nerfview/render_panel.py +++ b/nerfview/render_panel.py @@ -977,18 +977,17 @@ def _(_) -> None: pose, fov, time = maybe_pose_and_fov_rad else: pose, fov = maybe_pose_and_fov_rad - - preview_camera_handle = server.scene.add_camera_frustum( - "/preview_camera", - fov=fov, - aspect=render_res_vec2.value[0] / render_res_vec2.value[1], - scale=0.35, - wxyz=pose.rotation().wxyz, - position=pose.translation(), - color=(10, 200, 30), - ) - if render_tab_state.preview_render: - with server.atomic(): + with server.atomic(): + preview_camera_handle = server.scene.add_camera_frustum( + "/preview_camera", + fov=fov, + aspect=render_res_vec2.value[0] / render_res_vec2.value[1], + scale=0.35, + wxyz=pose.rotation().wxyz, + position=pose.translation(), + color=(10, 200, 30), + ) + if render_tab_state.preview_render: for client in server.get_clients().values(): # aspect ratio is not assignable, pass args in get_render instead client.camera.wxyz = pose.rotation().wxyz From 23b3b452d009826d2399c4e1b0b99ee72b0602fd Mon Sep 17 00:00:00 2001 From: Rong Liu <102014841+RongLiu-Leo@users.noreply.github.com> Date: Wed, 21 May 2025 18:52:36 -0700 Subject: [PATCH 4/8] Update render_panel.py Update the slider using fps accurately --- nerfview/render_panel.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/nerfview/render_panel.py b/nerfview/render_panel.py index 9948dfb..daf626e 100644 --- a/nerfview/render_panel.py +++ b/nerfview/render_panel.py @@ -20,6 +20,7 @@ import os import threading import time +from time import perf_counter as perf_counter from pathlib import Path from typing import Dict, List, Literal, Optional, Tuple, Union @@ -912,7 +913,7 @@ def get_max_frame_index() -> int: return max(1, int(framerate_number.value * duration_number.value) - 1) preview_camera_handle: Optional[viser.SceneNodeHandle] = None - + _last_send = 0.0 def remove_preview_camera() -> None: nonlocal preview_camera_handle if preview_camera_handle is not None: @@ -1113,10 +1114,14 @@ def play() -> None: max_frame = int(framerate_number.value * duration_number.value) if max_frame > 0: assert preview_frame_slider is not None + nonlocal _last_send + now = perf_counter() + if now - _last_send < 1.0 / framerate_number.value: + continue + _last_send = now preview_frame_slider.value = ( preview_frame_slider.value + 1 ) % max_frame - time.sleep(1.0 / framerate_number.value) play_thread = threading.Thread(target=play) play_thread.start() @@ -1365,7 +1370,13 @@ def dump() -> None: max_frame = int(framerate_number.value * duration_number.value) assert max_frame > 0 and preview_frame_slider is not None preview_frame_slider.value = 0 - for _ in range(max_frame): + render_count = 0 + while True: + nonlocal _last_send + now = perf_counter() + if now - _last_send < 1.0 / framerate_number.value: + continue + _last_send = now preview_frame_slider.value = ( preview_frame_slider.value + 1 ) % max_frame @@ -1375,6 +1386,9 @@ def dump() -> None: width=render_res_vec2.value[0], ) writer.append_data(image) + render_count += 1 + if render_count >= max_frame: + break writer.close() print(f"Video saved to {video_outfile}") From b96172bf39a77d7ac9a3d62caa770938920fe071 Mon Sep 17 00:00:00 2001 From: Rong Liu Date: Thu, 22 May 2025 17:13:31 -0700 Subject: [PATCH 5/8] Update render_panel.py black format --- nerfview/render_panel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nerfview/render_panel.py b/nerfview/render_panel.py index daf626e..95af8fb 100644 --- a/nerfview/render_panel.py +++ b/nerfview/render_panel.py @@ -914,6 +914,7 @@ def get_max_frame_index() -> int: preview_camera_handle: Optional[viser.SceneNodeHandle] = None _last_send = 0.0 + def remove_preview_camera() -> None: nonlocal preview_camera_handle if preview_camera_handle is not None: From e2d74228fc480ad748099b1dba16950eb61d4535 Mon Sep 17 00:00:00 2001 From: Rong Liu Date: Thu, 22 May 2025 17:15:40 -0700 Subject: [PATCH 6/8] Update render_panel.py --- nerfview/render_panel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nerfview/render_panel.py b/nerfview/render_panel.py index 95af8fb..42730fc 100644 --- a/nerfview/render_panel.py +++ b/nerfview/render_panel.py @@ -20,8 +20,8 @@ import os import threading import time -from time import perf_counter as perf_counter from pathlib import Path +from time import perf_counter as perf_counter from typing import Dict, List, Literal, Optional, Tuple, Union import imageio From 57a357225c46e44bac7b1e84a4cb3986944e1c53 Mon Sep 17 00:00:00 2001 From: Rong Liu <102014841+RongLiu-Leo@users.noreply.github.com> Date: Mon, 26 May 2025 18:22:59 -0700 Subject: [PATCH 7/8] Update _renderer.py It seems the resolution adjustment only makes fps worse and renders more blurry. Disable it temporarily. --- nerfview/_renderer.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/nerfview/_renderer.py b/nerfview/_renderer.py index 2fb2ef6..3440ec6 100644 --- a/nerfview/_renderer.py +++ b/nerfview/_renderer.py @@ -91,26 +91,25 @@ def _may_interrupt_trace(self, frame, event, arg): def _get_img_wh(self, aspect: float) -> Tuple[int, int]: # we always trade off speed for quality max_img_res = self.viewer.render_tab_state.viewer_res - if self._state in ["high"]: - # if True: - H = max_img_res - W = int(H * aspect) - if W > max_img_res: - W = max_img_res - H = int(W / aspect) - elif self._state in ["low_move", "low_static"]: - num_view_rays_per_sec = self.viewer.render_tab_state.num_view_rays_per_sec - target_fps = self._target_fps - num_viewer_rays = num_view_rays_per_sec / target_fps - H = (num_viewer_rays / aspect) ** 0.5 - H = int(round(H, -1)) - H = max(min(max_img_res, H), 30) - W = int(H * aspect) - if W > max_img_res: - W = max_img_res - H = int(W / aspect) - else: - raise ValueError(f"Unknown state: {self._state}.") + # if self._state in ["high"]: + H = max_img_res + W = int(H * aspect) + if W > max_img_res: + W = max_img_res + H = int(W / aspect) + # elif self._state in ["low_move", "low_static"]: + # num_view_rays_per_sec = self.viewer.render_tab_state.num_view_rays_per_sec + # target_fps = self._target_fps + # num_viewer_rays = num_view_rays_per_sec / target_fps + # H = (num_viewer_rays / aspect) ** 0.5 + # H = int(round(H, -1)) + # H = max(min(max_img_res, H), 30) + # W = int(H * aspect) + # if W > max_img_res: + # W = max_img_res + # H = int(W / aspect) + # else: + # raise ValueError(f"Unknown state: {self._state}.") return W, H def submit(self, task: RenderTask): @@ -173,6 +172,7 @@ def run(self): self.viewer.render_tab_state.num_view_rays_per_sec = (W * H) / ( time.perf_counter() - tic ) + # print("FPS:", 1 / (time.perf_counter() - tic)) except InterruptRenderException: continue except Exception: From 9d085c5bdf15e7b8d518eb53d2900b9f2e36a683 Mon Sep 17 00:00:00 2001 From: Rong Liu <102014841+RongLiu-Leo@users.noreply.github.com> Date: Mon, 26 May 2025 18:31:19 -0700 Subject: [PATCH 8/8] 0.1.4 --- nerfview/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nerfview/version.py b/nerfview/version.py index ae73625..bbab024 100644 --- a/nerfview/version.py +++ b/nerfview/version.py @@ -1 +1 @@ -__version__ = "0.1.3" +__version__ = "0.1.4" diff --git a/pyproject.toml b/pyproject.toml index 485682f..b881556 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "nerfview" -version = "0.1.3" +version = "0.1.4" description = "Interactive NeRF rendering web viewer" readme = "README.md" license = { text = "MIT" }