高级渲染添加
This commit is contained in:
parent
83fcb3ced4
commit
ea8e340c33
@ -11,8 +11,5 @@
|
||||
"enable_ssr": false,
|
||||
"shadow_quality": "medium",
|
||||
"ao_quality": "low"
|
||||
},
|
||||
"anti_aliasing": "4x",
|
||||
"refresh_rate": "144Hz",
|
||||
"async_reprojection": true
|
||||
}
|
||||
}
|
||||
@ -45,6 +45,7 @@ class VRJoystickConfig:
|
||||
self.teleport_arc_resolution = 50 # 抛物线精度
|
||||
self.teleport_initial_velocity = 10.0 # 传送初始速度
|
||||
self.min_teleport_distance = 1.0 # 最小传送距离
|
||||
self.player_height_offset = 1.7 # 玩家站立高度偏移(米)
|
||||
|
||||
# 反馈设置
|
||||
self.haptic_feedback_enabled = True # 是否启用震动反馈
|
||||
@ -151,6 +152,15 @@ class VRJoystickConfig:
|
||||
self.teleport_range = max(5.0, min(50.0, range_meters))
|
||||
print(f"✓ 传送范围设置为: {self.teleport_range}米")
|
||||
|
||||
def set_player_height(self, height_meters: float):
|
||||
"""设置玩家站立高度偏移
|
||||
|
||||
Args:
|
||||
height_meters: 站立高度偏移(米),推荐范围1.5-2.0米
|
||||
"""
|
||||
self.player_height_offset = max(1.0, min(2.5, height_meters))
|
||||
print(f"✓ 玩家站立高度偏移设置为: {self.player_height_offset}米")
|
||||
|
||||
def enable_haptic_feedback(self, enabled: bool):
|
||||
"""启用或禁用震动反馈
|
||||
|
||||
@ -200,6 +210,7 @@ class VRJoystickConfig:
|
||||
teleport_sys.arc_resolution = self.teleport_arc_resolution
|
||||
teleport_sys.initial_velocity = self.teleport_initial_velocity
|
||||
teleport_sys.min_teleport_distance = self.min_teleport_distance
|
||||
teleport_sys.player_height_offset = self.player_height_offset
|
||||
|
||||
print("✅ 配置已成功应用到摇杆管理器")
|
||||
|
||||
|
||||
@ -913,6 +913,10 @@ class VRManager(DirectObject):
|
||||
|
||||
self.render_pipeline_enabled = True
|
||||
print("✅ VR Pipeline控制器已初始化(将在相机设置时创建完整管线)")
|
||||
|
||||
# 检查天空盒状态
|
||||
self._check_skybox_status()
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
@ -942,6 +946,130 @@ class VRManager(DirectObject):
|
||||
except Exception as e:
|
||||
print(f"⚠️ 应用RenderPipeline VR效果失败: {e}")
|
||||
|
||||
def _check_skybox_status(self):
|
||||
"""检查并报告天空盒状态"""
|
||||
try:
|
||||
print("\n🌌 检查天空盒状态...")
|
||||
|
||||
# 方法1:在render节点下搜索所有名字包含skybox的节点
|
||||
skybox_nodes = self.world.render.findAllMatches("**/skybox*")
|
||||
if skybox_nodes and skybox_nodes.getNumPaths() > 0:
|
||||
print(f" ✓ 找到 {skybox_nodes.getNumPaths()} 个天空盒节点(使用名称搜索)")
|
||||
for i in range(skybox_nodes.getNumPaths()):
|
||||
skybox = skybox_nodes.getPath(i)
|
||||
print(f" 天空盒 #{i+1}:")
|
||||
print(f" 名称: {skybox.getName()}")
|
||||
print(f" 位置: {skybox.getPos()}")
|
||||
print(f" 缩放: {skybox.getScale()}")
|
||||
print(f" 父节点: {skybox.getParent().getName()}")
|
||||
|
||||
# 检查是否有shader
|
||||
if skybox.hasShader():
|
||||
print(f" ✓ 已应用shader效果")
|
||||
else:
|
||||
print(f" ⚠️ 未应用shader效果")
|
||||
|
||||
# 检查bin设置
|
||||
if skybox.hasBin():
|
||||
print(f" Bin: {skybox.getBinName()}")
|
||||
else:
|
||||
print(" ⚠️ 未找到天空盒(名称搜索)")
|
||||
|
||||
# 方法2:搜索所有GeomNode(几何节点),天空盒通常是一个大的几何体
|
||||
print(" 搜索所有几何节点...")
|
||||
all_geoms = self.world.render.findAllMatches("**/+GeomNode")
|
||||
print(f" 找到 {all_geoms.getNumPaths()} 个几何节点")
|
||||
|
||||
# 查找大型几何体(缩放值很大,可能是天空盒)
|
||||
skybox_candidates = []
|
||||
for i in range(all_geoms.getNumPaths()):
|
||||
geom_node = all_geoms.getPath(i)
|
||||
scale = geom_node.getScale()
|
||||
# 天空盒通常缩放很大(如40000)
|
||||
if scale[0] > 1000 or scale[1] > 1000 or scale[2] > 1000:
|
||||
print(f" ✓ 找到大型几何体(可能是天空盒):")
|
||||
print(f" 名称: {geom_node.getName()}")
|
||||
print(f" 缩放: {scale}")
|
||||
print(f" 位置: {geom_node.getPos()}")
|
||||
if geom_node.hasShader():
|
||||
print(f" ✓ 已应用shader")
|
||||
skybox_candidates.append(geom_node)
|
||||
|
||||
# 方法3:检查render节点的所有直接子节点(显示全部)
|
||||
print(" 检查render的所有直接子节点...")
|
||||
render_children = self.world.render.getChildren()
|
||||
print(f" render有 {render_children.getNumPaths()} 个直接子节点:")
|
||||
for i in range(render_children.getNumPaths()):
|
||||
child = render_children.getPath(i)
|
||||
scale = child.getScale()
|
||||
# 标记大型节点(可能是天空盒)
|
||||
if scale[0] > 1000 or scale[1] > 1000 or scale[2] > 1000:
|
||||
print(f" - {child.getName()} ⭐ (大型节点,缩放: {scale})")
|
||||
else:
|
||||
print(f" - {child.getName()}")
|
||||
|
||||
# 报告结果但不自动创建
|
||||
if len(skybox_candidates) == 0:
|
||||
print(" ⚠️ 未找到明显的天空盒(缩放>1000的几何体)")
|
||||
print(" 💡 RenderPipeline的天空盒可能在上述列表中,但缩放值不同")
|
||||
print(" 💡 或者可能RenderPipeline未在VR模式下自动创建天空盒")
|
||||
else:
|
||||
print(f" ✓ 找到 {len(skybox_candidates)} 个可能的天空盒")
|
||||
|
||||
print("🌌 天空盒状态检查完成\n")
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ 天空盒状态检查失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def _create_vr_skybox(self):
|
||||
"""为VR创建天空盒"""
|
||||
try:
|
||||
print(" 🎨 创建VR天空盒...")
|
||||
|
||||
# 检查RenderPipeline是否可用
|
||||
if hasattr(self.world, 'render_pipeline') and self.world.render_pipeline:
|
||||
pipeline = self.world.render_pipeline
|
||||
|
||||
# 使用RenderPipeline的load_default_skybox方法
|
||||
print(" 使用RenderPipeline方法创建天空盒...")
|
||||
skybox = pipeline.common_resources.load_default_skybox()
|
||||
|
||||
if skybox:
|
||||
# 设置天空盒属性
|
||||
skybox.set_scale(40000) # 大型缩放
|
||||
skybox.reparent_to(self.world.render)
|
||||
skybox.set_bin("unsorted", 10000) # 最后渲染
|
||||
|
||||
# 应用天空盒shader效果
|
||||
pipeline.set_effect(skybox, "effects/skybox.yaml", {
|
||||
"render_shadow": False,
|
||||
"render_envmap": False,
|
||||
"render_voxelize": False,
|
||||
"alpha_testing": False,
|
||||
"normal_mapping": False,
|
||||
"parallax_mapping": False
|
||||
}, 1000)
|
||||
|
||||
print(f" ✅ VR天空盒已创建")
|
||||
print(f" 名称: {skybox.getName()}")
|
||||
print(f" 缩放: {skybox.getScale()}")
|
||||
print(f" 位置: {skybox.getPos()}")
|
||||
return skybox
|
||||
else:
|
||||
print(" ❌ 无法加载天空盒模型")
|
||||
return None
|
||||
else:
|
||||
print(" ❌ RenderPipeline未初始化,无法创建天空盒")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ 创建VR天空盒失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return None
|
||||
|
||||
def _setup_vr_cameras(self):
|
||||
"""设置VR相机 - 使用锚点层级系统"""
|
||||
try:
|
||||
|
||||
@ -74,6 +74,29 @@ class VRGBufferStage:
|
||||
self.target.prepare_render(vr_camera)
|
||||
self._camera = vr_camera
|
||||
|
||||
# 🌌 关键修复:确保VR相机能看到天空盒
|
||||
# RenderPipeline的天空盒在render节点下,使用unsorted bin和shader effects
|
||||
if self.target._source_region:
|
||||
# 确保DisplayRegion支持所有bin排序
|
||||
self.target._source_region.setSort(20) # 设置合理的sort值
|
||||
print(f" ✓ DisplayRegion sort已设置")
|
||||
|
||||
# 🔑 关键:设置VR相机的initial state为render的state
|
||||
# 这样VR相机才能继承RenderPipeline应用在render节点上的所有shader effects(包括天空盒shader)
|
||||
if vr_camera and vr_camera.node():
|
||||
# 使用Panda3D的内置render节点(通过builtins)
|
||||
try:
|
||||
from panda3d.core import NodePath
|
||||
import builtins
|
||||
if hasattr(builtins, 'render'):
|
||||
render = builtins.render
|
||||
vr_camera.node().setInitialState(render.getState())
|
||||
print(f" ✓ VR相机initial state已设置为render的state")
|
||||
else:
|
||||
print(f" ⚠️ builtins.render不存在,跳过initial state设置")
|
||||
except Exception as e:
|
||||
print(f" ⚠️ 设置VR相机initial state失败: {e}")
|
||||
|
||||
# 设置正常的背景色(与主窗口一致的天空色)
|
||||
if self.target.internal_buffer:
|
||||
buffer = self.target.internal_buffer
|
||||
|
||||
@ -38,6 +38,7 @@ class VRTeleportSystem(DirectObject):
|
||||
self.gravity = -9.8 # 重力系数
|
||||
self.initial_velocity = 10.0 # 初始速度
|
||||
self.min_teleport_distance = 1.0 # 最小传送距离
|
||||
self.player_height_offset = 1.7 # 玩家站立高度偏移(米)
|
||||
|
||||
# 可视化元素
|
||||
self.teleport_arc_node = None # 抛物线节点
|
||||
@ -359,13 +360,23 @@ class VRTeleportSystem(DirectObject):
|
||||
# 计算传送偏移
|
||||
if self.vr_manager.tracking_space:
|
||||
current_pos = self.vr_manager.tracking_space.getPos()
|
||||
target_offset = self.teleport_target_pos - self.active_controller.get_world_position()
|
||||
new_pos = current_pos + target_offset
|
||||
|
||||
# 计算水平偏移(只考虑XY平面)
|
||||
controller_pos = self.active_controller.get_world_position()
|
||||
horizontal_offset = Vec3(
|
||||
self.teleport_target_pos.x - controller_pos.x,
|
||||
self.teleport_target_pos.y - controller_pos.y,
|
||||
0
|
||||
)
|
||||
|
||||
# 计算新位置:保持水平偏移,设置固定站立高度
|
||||
new_pos = current_pos + horizontal_offset
|
||||
new_pos.z = self.teleport_target_pos.z + self.player_height_offset
|
||||
|
||||
# 执行传送
|
||||
self.vr_manager.tracking_space.setPos(new_pos)
|
||||
|
||||
print(f"✅ 传送成功: {current_pos} → {new_pos}")
|
||||
print(f"✅ 传送成功: {current_pos} → {new_pos} (高度偏移: {self.player_height_offset}m)")
|
||||
|
||||
# 停止预览
|
||||
self.stop_teleport_preview()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user