1
0
forked from Rowland/EG

漫反射和法线贴图修正

This commit is contained in:
Hector 2025-07-30 14:52:59 +08:00
parent 5b7a1505cf
commit 0846a60d36
22 changed files with 2969 additions and 246 deletions

10
.idea/AugmentWebviewStateStore.xml generated Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,12 +8,12 @@ pipeline:
# it will also disable the hotkeys, and give a small performance boost.
# Most likely you also don't want to show it in your own game, so set
# it to false in that case.
display_debugger: true
display_debugger: False
# Affects which debugging information is displayed. If this is set to false,
# only frame time is displayed, otherwise much more information is visible.
# Has no effect when display_debugger is set to false.
advanced_debugging_info: true
advanced_debugging_info: False
# Whether to use the GL_R11F_G11F_B10F texture format to save memory
# and bandwidth. Usually you want to enable this, however it can

View File

@ -0,0 +1,35 @@
# Debug metallic texture effect
# This effect visualizes metallic texture directly for debugging
fragment:
defines: |
#define DEBUG_METALLIC_TEXTURE 1
inout: |
uniform sampler2D p3d_Texture5; // Metallic texture
material: |
// Debug: Show metallic texture directly
#if DEBUG_METALLIC_TEXTURE
// Sample metallic from texture
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
// For debugging: show texture value as colored visualization
// Blue tint for non-metallic, yellow tint for metallic
vec3 debug_color = mix(vec3(0.2, 0.2, 1.0), vec3(1.0, 1.0, 0.2), sampled_metallic);
// Apply to material
m.basecolor = debug_color; // Show texture as color for debugging
m.roughness = 0.5; // Fixed roughness for clear visualization
m.metallic = sampled_metallic; // Also apply to metallic
m.specular_ior = 1.5;
m.shading_model_param0 = 0.0;
#else
// Fallback
m.basecolor = mInput.color;
m.roughness = mInput.roughness;
m.metallic = mInput.metallic;
m.specular_ior = mInput.specular_ior;
m.shading_model_param0 = mInput.arbitrary0;
#endif

View File

@ -0,0 +1,35 @@
# Debug roughness texture effect
# This effect visualizes roughness texture directly for debugging
fragment:
defines: |
#define DEBUG_ROUGHNESS_TEXTURE 1
inout: |
uniform sampler2D p3d_Texture3; // Roughness texture
material: |
// Debug: Show roughness texture directly
#if DEBUG_ROUGHNESS_TEXTURE
// Sample roughness from texture
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
// For debugging: show texture value as grayscale color
// This helps verify the texture is being read correctly
vec3 debug_color = vec3(sampled_roughness);
// Apply to material
m.basecolor = debug_color; // Show texture as color for debugging
m.roughness = sampled_roughness; // Also apply to roughness
m.metallic = 0.0; // Keep metallic low for clear visualization
m.specular_ior = 1.5;
m.shading_model_param0 = 0.0;
#else
// Fallback
m.basecolor = mInput.color;
m.roughness = mInput.roughness;
m.metallic = mInput.metallic;
m.specular_ior = mInput.specular_ior;
m.shading_model_param0 = mInput.arbitrary0;
#endif

View File

@ -0,0 +1,39 @@
# Metallic-only PBR effect
# This effect specifically handles metallic textures correctly
# Ensures metallic texture is not confused with diffuse texture
fragment:
defines: |
#define USE_METALLIC_TEXTURE_ONLY 1
#define DONT_FETCH_DEFAULT_TEXTURES 0
inout: |
uniform sampler2D p3d_Texture5; // Metallic texture only
material: |
// Only handle metallic texture, ignore others to avoid confusion
#if USE_METALLIC_TEXTURE_ONLY
// Sample metallic from p3d_Texture5
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
// Direct control: texture value directly controls metallic
// This gives Blender-like behavior where texture has full control
m.metallic = sampled_metallic;
// Clamp to valid range
m.metallic = clamp(m.metallic, 0.0, 1.0);
// Keep other properties from material (no texture interference)
m.basecolor = mInput.color; // Use material color, not texture
m.roughness = mInput.roughness;
m.specular_ior = mInput.specular_ior;
m.shading_model_param0 = mInput.arbitrary0;
#else
// Fallback to material values only
m.basecolor = mInput.color;
m.roughness = mInput.roughness;
m.metallic = mInput.metallic;
m.specular_ior = mInput.specular_ior;
m.shading_model_param0 = mInput.arbitrary0;
#endif

View File

@ -0,0 +1,29 @@
# PBR effect with additive metallic texture control
# This effect adds metallic texture values to material metallic values
# Final metallic = material_metallic + texture_value (clamped to 0-1)
fragment:
defines: |
#define USE_ADDITIVE_METALLIC_TEXTURE 1
inout: |
uniform sampler2D p3d_Texture5; // Metallic texture (additive control)
material: |
// Additive metallic texture control
#if USE_ADDITIVE_METALLIC_TEXTURE
// Sample metallic value from texture
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
// Add texture value to material metallic value
// This allows enhancing existing metallic areas
m.metallic = clamp(mInput.metallic + sampled_metallic, 0.0, 1.0);
// Debug: This mode is useful for:
// - Adding metallic details to non-metallic materials
// - Enhancing existing metallic areas
// - Creating metallic highlights on top of base material
#else
// Fallback to material metallic value
m.metallic = mInput.metallic;
#endif

View File

@ -0,0 +1,29 @@
# PBR effect with direct metallic texture control
# This effect allows metallic textures to directly control metallic values
# instead of multiplying with material metallic value
fragment:
defines: |
#define USE_DIRECT_METALLIC_TEXTURE 1
inout: |
uniform sampler2D p3d_Texture5; // Metallic texture (direct control)
material: |
// Direct metallic texture control
#if USE_DIRECT_METALLIC_TEXTURE
// Sample metallic value directly from texture
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
// Use texture value directly instead of multiplying
// This allows the texture to have full control over metallic values
m.metallic = sampled_metallic;
// Debug: Ensure we're using the texture value
// White areas = 1.0 (fully metallic)
// Gray areas = 0.5 (semi-metallic)
// Black areas = 0.0 (non-metallic)
#else
// Fallback to material metallic value
m.metallic = mInput.metallic;
#endif

View File

@ -0,0 +1,38 @@
# PBR effect with direct roughness texture control
# This effect allows roughness textures to directly control roughness values
# instead of multiplying with material roughness value
fragment:
defines: |
#define USE_DIRECT_ROUGHNESS_TEXTURE 1
inout: |
uniform sampler2D p3d_Texture3; // Roughness texture (direct control)
material: |
// Direct roughness texture control
#if USE_DIRECT_ROUGHNESS_TEXTURE
// Sample roughness value directly from texture
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
// Use texture value directly instead of multiplying
// This allows the texture to have full control over roughness values
m.roughness = sampled_roughness;
// Ensure minimum roughness to avoid rendering issues
m.roughness = max(m.roughness, 0.01);
// Debug: Ensure we're using the texture value
// White areas = 1.0 (fully rough)
// Gray areas = 0.5 (semi-rough)
// Black areas = 0.01 (smooth, but not zero to avoid issues)
#else
// Fallback to material roughness value
m.roughness = mInput.roughness;
#endif
// Keep all other properties unchanged for stability
m.basecolor = mInput.color;
m.metallic = mInput.metallic;
m.specular_ior = mInput.specular_ior;
m.shading_model_param0 = mInput.arbitrary0;

View File

@ -0,0 +1,51 @@
# Extended PBR effect with support for additional texture types
# This effect supports metallic, emission, AO, detail, and gloss textures
fragment:
defines: |
#define USE_EXTENDED_TEXTURES 1
inout: |
uniform sampler2D p3d_Texture5; // Metallic texture
uniform sampler2D p3d_Texture6; // Emission texture
uniform sampler2D p3d_Texture7; // AO texture
uniform sampler2D p3d_Texture8; // Alpha texture
uniform sampler2D p3d_Texture9; // Detail texture
uniform sampler2D p3d_Texture10; // Gloss texture
material: |
#if USE_EXTENDED_TEXTURES
// Metallic texture (p3d_Texture5)
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
m.metallic = mInput.metallic * sampled_metallic;
// Emission texture (p3d_Texture6)
vec3 sampled_emission = texture(p3d_Texture6, texcoord).xyz;
if (mInput.shading_model == SHADING_MODEL_EMISSIVE) {
m.basecolor += sampled_emission * 2.0; // Boost emission intensity
}
// AO texture (p3d_Texture7) - multiply with base color
float sampled_ao = texture(p3d_Texture7, texcoord).x;
m.basecolor *= sampled_ao;
// Alpha texture (p3d_Texture8) - for transparency
float sampled_alpha = texture(p3d_Texture8, texcoord).x;
if (mInput.shading_model == SHADING_MODEL_TRANSPARENT) {
// Apply alpha testing
if (sampled_alpha < 0.5) discard;
}
// Detail texture (p3d_Texture9) - blend with base color
vec3 sampled_detail = texture(p3d_Texture9, texcoord * 4.0).xyz; // Tiled detail
m.basecolor = mix(m.basecolor, m.basecolor * sampled_detail, 0.5);
// Gloss texture (p3d_Texture10) - affects roughness
float sampled_gloss = texture(p3d_Texture10, texcoord).x;
m.roughness = m.roughness * (1.0 - sampled_gloss); // Gloss is inverse of roughness
#else
// Standard behavior when extended textures are not used
m.metallic = mInput.metallic;
#endif

View File

@ -0,0 +1,19 @@
# PBR effect with emission texture support
# This effect extends the default PBR pipeline to support emission textures
fragment:
defines: |
#define USE_EMISSION_TEXTURE 1
inout: |
uniform sampler2D p3d_Texture6; // Emission texture
material: |
// Fetch emission value from texture if available
#if USE_EMISSION_TEXTURE
vec3 sampled_emission = texture(p3d_Texture6, texcoord).xyz;
// For emissive materials, add the texture emission to the base color
if (mInput.shading_model == SHADING_MODEL_EMISSIVE) {
m.basecolor += sampled_emission * 2.0; // Boost emission intensity
}
#endif

View File

@ -0,0 +1,45 @@
# PBR effect with metallic texture support
# This effect extends the default PBR pipeline to support metallic textures
# Provides both multiplicative and direct control modes
fragment:
defines: |
#define USE_METALLIC_TEXTURE 1
#define METALLIC_CONTROL_MODE 0 // 0=multiply, 1=direct, 2=additive
inout: |
uniform sampler2D p3d_Texture5; // Metallic texture
material: |
// Complete material processing with metallic texture support
#if USE_METALLIC_TEXTURE
// Sample metallic texture
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
// Apply metallic texture based on control mode
#if METALLIC_CONTROL_MODE == 0
// Multiplicative mode (original behavior)
m.metallic = mInput.metallic * sampled_metallic;
#elif METALLIC_CONTROL_MODE == 1
// Direct control mode
m.metallic = sampled_metallic;
#elif METALLIC_CONTROL_MODE == 2
// Additive mode
m.metallic = clamp(mInput.metallic + sampled_metallic, 0.0, 1.0);
#else
// Fallback to multiplicative
m.metallic = mInput.metallic * sampled_metallic;
#endif
#else
m.metallic = mInput.metallic;
#endif
// Process other material properties normally
m.basecolor = mInput.color * sampled_diffuse.xyz;
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
m.roughness = mInput.roughness * sampled_roughness;
m.shading_model_param0 = mInput.arbitrary0;
// Ensure valid ranges
m.roughness = max(m.roughness, 0.01);
m.metallic = clamp(m.metallic, 0.0, 1.0);

View File

@ -0,0 +1,31 @@
# PBR effect with normal mapping support
# This effect ensures proper material color handling when only normal maps are applied
fragment:
defines: |
#define USE_NORMAL_MAPPING_ONLY 1
material: |
// Handle normal mapping without requiring diffuse texture
#if USE_NORMAL_MAPPING_ONLY
// Use material color directly, don't multiply with sampled_diffuse
// This prevents the black color issue when no diffuse texture is present
m.basecolor = mInput.color;
// Handle other textures normally if they exist
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
m.roughness = mInput.roughness * sampled_roughness;
m.metallic = mInput.metallic;
// Ensure minimum roughness
m.roughness = max(m.roughness, 0.01);
#else
// Standard material processing
m.basecolor = mInput.color * sampled_diffuse.xyz;
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
m.roughness = mInput.roughness * sampled_roughness;
m.metallic = mInput.metallic;
#endif
m.shading_model_param0 = mInput.arbitrary0;

View File

@ -0,0 +1,33 @@
# Stable PBR effect with roughness texture support
# Simplified version to avoid rendering issues and flickering
fragment:
defines: |
#define USE_STABLE_ROUGHNESS_TEXTURE 1
inout: |
uniform sampler2D p3d_Texture3; // Roughness texture only
material: |
// Simple and stable roughness texture handling
#if USE_STABLE_ROUGHNESS_TEXTURE
// Sample roughness from texture
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
// Use simple multiplication - stable and predictable
// This ensures the texture effect is always visible
m.roughness = mInput.roughness * sampled_roughness;
// Ensure minimum roughness to avoid rendering issues
m.roughness = max(m.roughness, 0.01);
#else
// Fallback to material roughness
m.roughness = mInput.roughness;
#endif
// Keep all other properties unchanged for stability
m.basecolor = mInput.color;
m.metallic = mInput.metallic;
m.specular_ior = mInput.specular_ior;
m.shading_model_param0 = mInput.arbitrary0;

View File

@ -0,0 +1,37 @@
# Enhanced PBR effect with metallic texture support
# This effect extends the default PBR to support metallic textures
# Avoids redeclaring textures that are already in the base template
fragment:
defines: |
#define USE_METALLIC_TEXTURE 1
inout: |
uniform sampler2D p3d_Texture5; // Metallic texture (not in default template)
material: |
// Enhanced material with metallic texture support
#if USE_METALLIC_TEXTURE
// Sample metallic texture
float sampled_metallic = texture(p3d_Texture5, texcoord).x;
// Apply all material properties
// Use the sampled values from the base template for other textures
m.basecolor = mInput.color * sampled_diffuse.xyz;
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
m.roughness = mInput.roughness * sampled_roughness;
m.metallic = mInput.metallic * sampled_metallic; // Now with metallic texture support!
// Ensure valid ranges
m.roughness = max(m.roughness, 0.01);
m.metallic = clamp(m.metallic, 0.0, 1.0);
#else
// Fallback to standard material processing
m.basecolor = mInput.color * sampled_diffuse.xyz;
m.specular_ior = blend_ior(mInput.specular_ior, sampled_ior);
m.roughness = mInput.roughness * sampled_roughness;
m.metallic = mInput.metallic; // No metallic texture
#endif
m.shading_model_param0 = mInput.arbitrary0;

View File

@ -0,0 +1,39 @@
# Roughness-only PBR effect
# This effect specifically handles roughness textures correctly
# Ensures roughness texture is not confused with diffuse texture
fragment:
defines: |
#define USE_ROUGHNESS_TEXTURE_ONLY 1
#define DONT_FETCH_DEFAULT_TEXTURES 0
inout: |
uniform sampler2D p3d_Texture3; // Roughness texture only
material: |
// Only handle roughness texture, ignore others to avoid confusion
#if USE_ROUGHNESS_TEXTURE_ONLY
// Sample roughness from p3d_Texture3
float sampled_roughness = texture(p3d_Texture3, texcoord).x;
// Apply roughness: material_roughness * texture_value
// This gives Blender-like behavior
m.roughness = mInput.roughness * sampled_roughness;
// Ensure minimum roughness to avoid rendering issues
m.roughness = max(m.roughness, 0.01);
// Keep other properties from material (no texture interference)
m.basecolor = mInput.color; // Use material color, not texture
m.metallic = mInput.metallic;
m.specular_ior = mInput.specular_ior;
m.shading_model_param0 = mInput.arbitrary0;
#else
// Fallback to material values only
m.basecolor = mInput.color;
m.roughness = mInput.roughness;
m.metallic = mInput.metallic;
m.specular_ior = mInput.specular_ior;
m.shading_model_param0 = mInput.arbitrary0;
#endif

View File

@ -52,6 +52,11 @@ class MainApp(ShowBase):
# Load the scene
model = loader.loadModel("scene/scene.bam")
# model = loader.loadModel("scene2/Scene.bam")
model_0 = self.loader.loadModel("/home/tiger/下载/Benci/source/s65/s65/s65.fbx")
model_0.reparentTo(self.render)
model_0.setScale(0.25)
model_0.setPos(-8, 42, 0)
model_0.setHpr(0, 90, 0)
model.reparent_to(render)
self.render_pipeline.prepare_scene(model)

View File

@ -170,9 +170,9 @@ class MaterialEditor(QMainWindow, Ui_MainWindow):
# Basecolor
values = self.basecolor_to_tuple(self.material)
self.basecolor_1.setValue(values[0] * 100.0)
self.basecolor_2.setValue(values[1] * 100.0)
self.basecolor_3.setValue(values[2] * 100.0)
self.basecolor_1.setValue(int(values[0] * 100.0))
self.basecolor_2.setValue(int(values[1] * 100.0))
self.basecolor_3.setValue(int(values[2] * 100.0))
# Shading model
self.cb_shading_model.setCurrentIndex(self.material.shading_model)
@ -184,7 +184,7 @@ class MaterialEditor(QMainWindow, Ui_MainWindow):
# Rest of sliders
for slider, lbl, start, end, prop in self.sliders:
val = getattr(self.material, prop)
slider.setValue((val - start) / (end - start) * 100.0)
slider.setValue(int((val - start) / (end - start) * 100.0))
self.in_update = False
self.update_ui()

View File

@ -14,7 +14,24 @@ class ToolManager:
print(f"当前工具: {tool}")
print(f"选中节点: {self.world.selection.selectedNode.getName() if self.world.selection.selectedNode else ''}")
# 坐标轴现在始终跟随选中状态,不再依赖工具类型
# 根据工具类型启用对应的方法
if tool == "选择":
print(f"当前工具为:{tool}")
#self._enableSelectionTool()
elif tool == "移动":
print(f"当前工具为:{tool}")
#self._enableMoveTool()
elif tool == "旋转":
print(f"当前工具为:{tool}")
#self._enableRotateTool()
elif tool == "缩放":
print(f"当前工具为:{tool}")
#self._enableScaleTool()
elif tool == "光照编辑":
print(f"当前工具为:{tool}")
self.launch_day_time_editor()
# 坐标轴现在始终跟随选中状态,不再依赖工具类型
def getCurrentTool(self):
"""获取当前工具"""
@ -38,9 +55,15 @@ class ToolManager:
def isDayTimeEditorTool(self):
"""光照"""
return self.currentTool=="编辑光照"
return self.currentTool=="光照编辑"
def launch_day_time_editor(self):
# 检查是否已经启动
if hasattr(self, '_day_time_editor_process') and self._day_time_editor_process:
if self._day_time_editor_process.poll() is None: # 进程仍在运行
print("Day Time Editor 已经在运行")
return True
import subprocess
import os
import sys
@ -57,10 +80,8 @@ class ToolManager:
print("错误文件不存在")
return False
subprocess.Popen([sys.executable,editor_path])
print("day time editor启动")
self.setCurrentTool("光照编辑")
self._day_time_editor_process = subprocess.Popen([sys.executable, editor_path])
print("Day Time Editor 已启动")
return True
except Exception as e:
print(f"启动 time editor失败")

View File

@ -1,3 +1,4 @@
import math
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
@ -35,33 +36,37 @@ class CoreWorld(Panda3DWorld):
self._loadFont()
#self.start_day_night_cycle(duration_seconds=300.0)
self.accept("1", lambda: self.set_daytime("4:00")) # 清晨
self.accept("2", lambda: self.set_daytime("6:00")) # 中午
self.accept("3", lambda: self.set_daytime("8:00")) # 傍晚
self.accept("4", lambda: self.set_daytime("10:00")) # 深夜
self.accept("5", lambda: self.set_daytime("12:00")) # 深夜
self.accept("6", lambda: self.set_daytime("14:00")) # 深夜
self.accept("7", lambda: self.set_daytime("16:00")) # 深夜
self.accept("8", lambda: self.set_daytime("18:00")) # 深夜
self.accept("9", lambda: self.set_daytime("20:00")) # 深夜
self.accept("0", lambda: self.set_daytime("22:00")) # 深夜
self.launch_day_time_editor()
# self.accept("1", lambda: self.set_daytime("4:00")) # 清晨
# self.accept("2", lambda: self.set_daytime("6:00")) # 中午
# self.accept("3", lambda: self.set_daytime("8:00")) # 傍晚
# self.accept("4", lambda: self.set_daytime("10:00")) # 深夜
# self.accept("5", lambda: self.set_daytime("12:00")) # 深夜
# self.accept("6", lambda: self.set_daytime("14:00")) # 深夜
# self.accept("7", lambda: self.set_daytime("16:00")) # 深夜
# self.accept("8", lambda: self.set_daytime("18:00")) # 深夜
# self.accept("9", lambda: self.set_daytime("20:00")) # 深夜
# self.accept("0", lambda: self.set_daytime("22:00")) # 深夜
#
#self.createDirectionalLight()
#self._setYCModel()
# 创建示例材质
#self.load_test_models_with_materials()
# 设置材质编辑器网络通信
#self.setup_material_editor_network()
# 启动材质编辑器
#self.launch_material_editor()
print("✓ 核心世界初始化完成")
def launch_day_time_editor(self):
"""启动day time editor 作为独立进程"""
import subprocess
import os
import sys
base_path = self.render_pipeline.mount_mgr.base_path
editor_path = os.path.join(base_path,"文档/EG/RenderPipelineFile/toolkit/day_time_editor/main.py")
subprocess.Popen([sys.executable,editor_path])
print("day time editor 已启动")
def _setYCModel(self):
model = self.loader.loadModel("/home/tiger/文档/Tzjyc_GLTF/tzjyc.gltf")
model.reparentTo(self.render)
model.setScale(0.25)
model.setPos(-8, 42, 0)
model.setHpr(0, 90, 0)
def _setupCamera(self):
"""设置相机位置和朝向"""
@ -102,30 +107,38 @@ class CoreWorld(Panda3DWorld):
self.ground.setZ(-0.1)
self.ground.setColor(0.8, 0.8, 0.8, 1)
# 创建支持贴图的材质
mat = Material()
color = LColor(1, 1, 1, 1)
mat.setName("GroundMaterial") # 设置材质名称,便于材质编辑器识别
color = LColor(0.7, 0.7, 0.7, 1) # 稍微暗一点的灰色
mat.set_base_color(color)
mat.set_roughness(0)
mat.set_metallic(0.8)
#mat.set_normal("/home/tiger/下载/OIP.jpeg")
mat.set_roughness(0.5) # 设置合适的初始粗糙度
mat.set_metallic(0.1) # 设置较低的初始金属性
self.ground.set_material(mat)
# self.render_pipeline.set_effect(self.ground, "RenderPipelineFile/effects/material_blend4.yaml", {
# "parallax_mapping": False, # Not supported
# "alpha_testing": False,
# "normal_mapping": False, # The effect does its own normal mapping
# }, 100)
#
# self.ground.set_shader_input("detail_scale_factor", 4.0)
# self.ground.set_shader_input("material_0_pow", 10.0)
# self.ground.set_shader_input("material_0_add", 0.5)
# self.ground.set_shader_input("material_1_pow", 10.0)
# self.ground.set_shader_input("material_1_add", 0.5)
# self.ground.set_shader_input("material_2_pow", 10.0)
# self.ground.set_shader_input("material_2_add", 0.5)
print("✓ 地板创建完成")
# 应用默认PBR效果确保支持贴图
try:
if hasattr(self, 'render_pipeline') and self.render_pipeline:
self.render_pipeline.set_effect(
self.ground,
"effects/default.yaml",
{
"normal_mapping": True,
"render_gbuffer": True,
"alpha_testing": False,
"parallax_mapping": False,
"render_shadow": True,
"render_envmap": True
},
50
)
print("✓ 地板PBR效果已应用")
else:
print("⚠️ RenderPipeline未初始化地板将使用基础渲染")
except Exception as e:
print(f"⚠️ 地板PBR效果应用失败: {e}")
print("✓ 地板创建完成(支持材质贴图)")
@ -417,21 +430,248 @@ class CoreWorld(Panda3DWorld):
return task.done
def launch_day_time_editor(self):
"""启动day time editor 作为独立进程"""
# 检查是否已经启动
if hasattr(self, '_day_time_editor_process') and self._day_time_editor_process:
if self._day_time_editor_process.poll() is None: # 进程仍在运行
print("Day Time Editor 已经在运行")
return True
import subprocess
import os
import sys
base_path = self.render_pipeline.mount_mgr.base_path
try:
if not hasattr(self.world,'render_pipeline') or not self.world.render_pipeline:
print("错误renderpipeline未初始化")
return False
editor_path = os.path.join(base_path,"toolkit/day_time_editor/main.py")
subprocess.Popen([sys.executable,editor_path])
print("day time editor 已启动")
base_path = self.world.render_pipeline.mount_mgr.base_path
editor_path = os.path.join(base_path,"toolkit/day_time_editor/main.py")
if not os.path.exists(editor_path):
print("错误文件不存在")
return False
self._day_time_editor_process = subprocess.Popen([sys.executable, editor_path])
print("Day Time Editor 已启动")
return True
except Exception as e:
print(f"启动 time editor失败")
def setup_material_editor_network(self):
"""设置材质编辑器网络通信"""
from RenderPipelineFile.rpcore.util.network_communication import NetworkCommunication
def handle_material_requests(message):
"""处理材质编辑器的网络请求"""
try:
print(f"收到材质编辑器请求: {message}")
parts = message.strip().split()
if not parts:
return
command = parts[0]
if command == "dump_materials":
# 处理导出材质列表请求
path = parts[1] if len(parts) > 1 else ""
if path:
self.export_materials_to_file(path)
elif command.startswith("update_material"):
# 处理更新材质请求
data = message[len("update_material "):].strip()
self.update_material_from_editor(data.split())
except Exception as e:
print(f"处理材质编辑器请求失败: {e}")
# 注册网络消息处理器
try:
NetworkCommunication.listen_threaded(
NetworkCommunication.MATERIAL_PORT,
handle_material_requests
)
print("✓ 材质编辑器网络通信已设置")
except Exception as e:
print(f"设置材质编辑器网络通信失败: {e}")
def export_materials_to_file(self, path):
"""导出材质列表到文件"""
try:
print(f"导出材质列表到: {path}")
materials = []
# 收集所有材质
def collect_materials(node):
if node.hasMaterial():
material = node.getMaterial()
if material:
materials.append(material)
for child in node.getChildren():
collect_materials(child)
collect_materials(self.render)
# 写入文件
with open(path, "w") as f:
for i, material in enumerate(materials):
name = f"{i}-{material.getName() or 'unnamed'}"
# 获取材质属性,使用默认值如果不存在
base_color = material.getBaseColor() if hasattr(material, 'getBaseColor') else Vec4(0.6, 0.6, 0.6, 1.0)
roughness = material.getRoughness() if hasattr(material, 'getRoughness') else 0.5
metallic = material.getMetallic() if hasattr(material, 'getMetallic') else 0.0
# 写入材质数据
f.write(("{} " * 11).format(
name,
base_color.x,
base_color.y,
base_color.z,
roughness,
0.5, # refractive_index
metallic,
0, # shading_model
1.0, # normal_strength
0.0, # param1
0.0 # param2
) + "\n")
print(f"✓ 成功导出 {len(materials)} 个材质到 {path}")
except Exception as e:
print(f"导出材质列表失败: {e}")
def update_material_from_editor(self, data):
"""从编辑器更新材质"""
try:
if len(data) < 11:
print(f"材质数据不完整: {data}")
return
name_parts = data[0].split("-")
if len(name_parts) < 2:
print(f"材质名称格式错误: {data[0]}")
return
index = int(name_parts[0])
name = "-".join(name_parts[1:])
# 收集所有材质
materials = []
def collect_materials(node):
if node.hasMaterial():
material = node.getMaterial()
if material:
materials.append(material)
for child in node.getChildren():
collect_materials(child)
collect_materials(self.render)
# 查找匹配的材质
if index < len(materials):
material = materials[index]
# 更新材质属性
material.setBaseColor(Vec4(float(data[1]), float(data[2]), float(data[3]), 1.0))
material.setRoughness(float(data[4]))
material.setMetallic(float(data[6]))
print(f"✓ 更新材质 {name}: 颜色=({data[1]}, {data[2]}, {data[3]}), 粗糙度={data[4]}, 金属度={data[6]}")
else:
print(f"未找到索引为 {index} 的材质")
except Exception as e:
print(f"更新材质失败: {e}")
def launch_material_editor(self):
"""启动材质编辑器"""
import subprocess
import os
import sys
try:
if not self.render_pipeline:
print("错误renderpipeline未初始化")
return False
base_path = self.render_pipeline.mount_mgr.base_path
editor_path = os.path.join(base_path,"toolkit/material_editor/main.py")
if not os.path.exists(editor_path):
print("错误文件不存在")
return False
self._material_editor_process = subprocess.Popen([sys.executable, editor_path])
print("Material Editor 已启动")
return True
except Exception as e:
print(f"启动 Material editor失败")
def create_sample_materials(self):
"""创建一些示例材质供编辑器使用"""
from panda3d.core import Material, Vec4, CardMaker
# 创建几个测试几何体,每个都有不同的材质
sample_materials = [
{"name": "MetalMaterial", "color": Vec4(0.7, 0.7, 0.8, 1.0), "metallic": True, "roughness": 0.2},
{"name": "PlasticMaterial", "color": Vec4(0.8, 0.2, 0.2, 1.0), "metallic": False, "roughness": 0.8},
{"name": "GlassMaterial", "color": Vec4(0.9, 0.9, 1.0, 0.3), "metallic": False, "roughness": 0.1},
{"name": "WoodMaterial", "color": Vec4(0.6, 0.4, 0.2, 1.0), "metallic": False, "roughness": 0.7},
{"name": "TestPlaneMaterial", "color": Vec4(0.8, 0.8, 0.8, 1.0), "metallic": False, "roughness": 1.0}
]
for i, mat_data in enumerate(sample_materials):
# 创建几何体
if mat_data["name"] == "TestPlaneMaterial":
# 创建一个大的测试平面类似Blender中的平面
cm = CardMaker('test_plane')
cm.setFrame(-5, 5, -5, 5) # 更大的平面
geom_node = self.render.attachNewNode(cm.generate())
geom_node.setPos(0, 15, 0) # 放在前面显眼位置
geom_node.setP(-90) # 水平放置
print("✓ 创建大型测试平面,适合测试粗糙度贴图")
else:
cm = CardMaker(f'sample_geom_{i}')
cm.setFrame(-1, 1, -1, 1)
geom_node = self.render.attachNewNode(cm.generate())
geom_node.setPos(i * 3 - 6, 10, 1)
geom_node.setP(-90) # 水平放置
# 创建材质并确保名称正确设置
material = Material()
material.setName(mat_data["name"]) # 明确设置材质名称
material.setBaseColor(mat_data["color"])
material.setRoughness(mat_data["roughness"])
material.setMetallic(1.0 if mat_data["metallic"] else 0.0)
# 应用材质
geom_node.setMaterial(material)
print(f"✓ 创建示例材质: {mat_data['name']}")
# 延迟一下确保材质完全创建
import time
time.sleep(0.1)
def load_test_models_with_materials(self):
"""加载一些测试模型以提供更多材质供编辑"""
try:
# 你可以在这里加载你的模型文件
# test_model = self.loader.loadModel("models/your_model.gltf")
# if test_model:
# test_model.reparentTo(self.render)
# test_model.setPos(5, 0, 0)
# test_model.setScale(1.0)
# print(f"✓ 测试模型已加载")
# 创建示例材质
self.create_sample_materials()
except Exception as e:
print(f"加载测试模型失败: {e}")
# 创建示例材质作为备选
self.create_sample_materials()

View File

@ -78,6 +78,7 @@ class MainWindow(QMainWindow):
self.moveAction = self.toolsMenu.addAction('移动工具')
self.rotateAction = self.toolsMenu.addAction('旋转工具')
self.scaleAction = self.toolsMenu.addAction('缩放工具')
self.sunsetAction = self.toolsMenu.addAction('光照编辑')
# GUI菜单
self.guiMenu = menubar.addMenu('GUI')
@ -366,6 +367,9 @@ class MainWindow(QMainWindow):
self.buildAction.triggered.connect(lambda: buildPackage(self))
self.exitAction.triggered.connect(QApplication.instance().quit)
#连接工具事件
self.sunsetAction.triggered.connect(lambda : self.world.setCurrentTool("光照编辑"))
# 连接GUI编辑模式事件
self.guiEditModeAction.triggered.connect(lambda: self.world.toggleGUIEditMode())

File diff suppressed because it is too large Load Diff