-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Environment
- Operating System: Windows 11
- Python Version:
3.10 - Relevant Libraries:
stable-baselines3,panda3d
Bug Description
When running the vlm_tsc_zh/vlmlight_decision.py script on Windows, the program crashes during the initialization of the TSC3DEnvironment.
The traceback shows a sequence of errors:
- A shader error indicates a file cannot be found, but the path format is incorrect for Windows (e.g.,
/d/l1ner/...instead ofD:\L1ner\...). - This leads to a
TypeError: NodePath.set_shader() argument 1 must be Shader, not NoneTypebecause the shader object failed to load and isNone. - The child process running the environment crashes, which in turn causes an
EOFErrorin the main process waiting for it.
Full Traceback:
'2025-08-19 16:15:07.354 | INFO | tshub.tshub_env3d.vis3d_renderer._showbase_instance:init:103 - SIM: 初始化 ShowBase 实例'
:shader(error): Could not find shader file: /d/l1ner/tsinghua/vlmlight-main/transsimhub/tshub/tshub_env3d/_assets_3d/shader/unlit_shader.vert
Process SpawnProcess-1:
Traceback (most recent call last):
...
TypeError: NodePath.set_shader() argument 1 must be Shader, not NoneType
...
EOFError
Root Cause Analysis
The issue stems from how shader file paths are loaded in transsimhub/tshub/tshub_env3d/vis3d_renderer/_showbase_instance.py (or a related file).
The Shader.load() function from Panda3D seems to have trouble resolving relative paths containing .. on Windows. It incorrectly converts a native Windows path like D:\path\to\project into a POSIX-like path /d/path/to/project, which is invalid on Windows and causes the file lookup to fail.
The original failing code is likely similar to this:
# This code fails on Windows
unlit_shader = Shader.load(
Shader.SL_GLSL,
vertex=current_file_path("../_assets_3d/shader/unlit_shader.vert"),
fragment=current_file_path("../_assets_3d/shader/unlit_shader.frag"),
)Suggested Solution & Workaround
A robust, cross-platform solution is to use Python's os module to resolve the path natively before passing the shader's content (not its path) to Panda3D using Shader.make(). This bypasses Panda3D's path resolution issues on Windows.
This implementation works correctly on Windows:
import os
from panda3d.core import Shader
# Assuming 'current_file_path' and 'logger' are defined in the context
# Normalize to an absolute OS-specific path to resolve ".." and separator issues
_v_path = os.path.normpath(current_file_path("../_assets_3d/shader/unlit_shader.vert"))
_f_path = os.path.normpath(current_file_path("../_assets_3d/shader/unlit_shader.frag"))
# Read the shader source code directly using Python's robust I/O
try:
with open(_v_path, 'r', encoding='utf-8') as f:
_v_src = f.read()
with open(_f_path, 'r', encoding='utf-8') as f:
_f_src = f.read()
except Exception as e:
logger.error(f"Failed to read shader sources. v={_v_path}, f={_f_path}, err={e}")
raise
# Create the shader from its source code, avoiding path issues
unlit_shader = Shader.make(
Shader.SL_GLSL,
vertex=_v_src,
fragment=_f_src,
)
# This now works correctly
root_np.setShader(unlit_shader, priority=10)It is recommended to adopt this more robust method for loading shaders to ensure cross-platform compatibility, especially for Windows users.
Thank you for your great work on this project!