Compare commits
3
Commits
f296b643d4
...
f2e06e9dee
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2e06e9dee | ||
|
|
a1d7007241 | ||
|
|
ed1a9949c8 |
@@ -0,0 +1,25 @@
|
||||
# 2026-10-13 工作日志
|
||||
|
||||
## 修复:toon 材质所有模型联动、无法单独设基础纹理
|
||||
|
||||
**问题**:`shader/toon_apply.gd` 用 `material_override = toon.tres` 把同一个共享 `ShaderMaterial` 实例挂给所有 `MeshInstance3D`,导致
|
||||
1. 改 `toon.tres` 影响全部模型;
|
||||
2. `material_override` 整包覆盖,丢失模型自带贴图,无法给单个模型设 `base_texture`。
|
||||
|
||||
**方案**:重写 `shader/toon_apply.gd`
|
||||
- 为每个 `MeshInstance3D` 的每个 surface **复制独立材质实例**(`cartoon_material.duplicate()`,含 `next_pass` 描边的复制),通过 `set_surface_override_material(i, mat)` 逐面挂载。
|
||||
- 自动从 `mesh.surface_get_material(i)` 提取原始贴图(`BaseMaterial3D.albedo_texture` 或已有 ShaderMaterial 的 `base_texture`)写入各自的 `base_texture`。
|
||||
- 新增导出项:`base_texture_override`(手动指定单模型贴图,优先级最高)、`use_original_texture`、`use_material_override`(兼容旧整包模式,默认关)。
|
||||
- `toon.tres` 降级为"模板":脚本每次应用时拷贝其非贴图参数作为初值,之后各模型独立。
|
||||
|
||||
**关键文件**:`shader/toon_apply.gd`(uid 未变,场景引用 `assets/test/test.tscn` 仍有效)
|
||||
**相关**:`shader/toon.tres`(基础 cel-shader + outline next_pass)、`shader/cel-shader-base.gdshader`、`shader/outline.gdshader`(outline 用 global uniform,全局限定)
|
||||
|
||||
## 修复报错:`get_shader_uniform_list` 不存在
|
||||
|
||||
- 报错:`Nonexistent function 'get_shader_uniform_list' in base 'ShaderMaterial'`。
|
||||
- 原因:该方法属于 **`Shader`**,不属于 `ShaderMaterial`。
|
||||
- 修复:改为 `cartoon_material.shader.get_shader_uniform_list()`(先判空)。
|
||||
- 同时把 `get_surface_override_material(mi.material_override)` 返回的 `Material` 用显式 `is ShaderMaterial` 判断 + 声明式 `var x: ShaderMaterial` 赋值,避免隐式向下转换告警。
|
||||
- 环境:Godot 4.7,Forward Plus,config_version=5。本机未找到 Godot CLI,无法自动语法校验。
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,53 @@
|
||||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://ifqfine3ofh2"
|
||||
path="res://.godot/imported/HotDog.glb-49d3a46fc33ab2ee1e429d21416d8346.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/test/HotDog.glb"
|
||||
dest_files=["res://.godot/imported/HotDog.glb-49d3a46fc33ab2ee1e429d21416d8346.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={
|
||||
"materials": {
|
||||
"PaletteAssetsv1": {
|
||||
"use_external/enabled": false,
|
||||
"use_external/fallback_path": "res://assets/test/tex/PaletteAssetsv1.tres",
|
||||
"use_external/path": "uid://nbt0m5456g0x"
|
||||
}
|
||||
}
|
||||
}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -0,0 +1,44 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dvcdurdl0hrmj"
|
||||
path.s3tc="res://.godot/imported/HotDog_PaletteAssets.png-37872b0cd0700d390f6038dd2dbb27a5.s3tc.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
generator_parameters={
|
||||
"md5": "79256949e4824a5bc8b771d084907c3f"
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/test/HotDog_PaletteAssets.png"
|
||||
dest_files=["res://.godot/imported/HotDog_PaletteAssets.png-37872b0cd0700d390f6038dd2dbb27a5.s3tc.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=true
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
@@ -0,0 +1,11 @@
|
||||
[gd_scene format=3 uid="uid://ouhrovtvstsf"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cyabo07rc0216" path="res://shader/toon_apply.gd" id="2_7gofs"]
|
||||
[ext_resource type="Material" uid="uid://ps5swh44egxb" path="res://shader/toon.tres" id="3_pd47h"]
|
||||
[ext_resource type="PackedScene" uid="uid://ifqfine3ofh2" path="res://assets/test/HotDog.glb" id="4_pd47h"]
|
||||
|
||||
[node name="Node3D" type="Node3D" unique_id=301733971]
|
||||
|
||||
[node name="HotDog2" parent="." unique_id=1370529729 instance=ExtResource("4_pd47h")]
|
||||
script = ExtResource("2_7gofs")
|
||||
cartoon_material = ExtResource("3_pd47h")
|
||||
+1
-1
@@ -107,7 +107,7 @@ rendering_device/driver.windows="d3d12"
|
||||
|
||||
diffuse_curve={
|
||||
"type": "sampler2D",
|
||||
"value": ""
|
||||
"value": "res://shader/new_gradient_texture_1d.tres"
|
||||
}
|
||||
specular_smoothness={
|
||||
"type": "float",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="GradientTexture1D" format=3 uid="uid://b3fs6dwpeg753"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_67fj6"]
|
||||
offsets = PackedFloat32Array(0, 0.25754884, 0.6015394)
|
||||
colors = PackedColorArray(0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1)
|
||||
|
||||
[resource]
|
||||
gradient = SubResource("Gradient_67fj6")
|
||||
@@ -0,0 +1,18 @@
|
||||
[gd_resource type="ShaderMaterial" format=3 uid="uid://ps5swh44egxb"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://bbs8x8ygec4lo" path="res://shader/outline.gdshader" id="1_vdkh7"]
|
||||
[ext_resource type="Shader" uid="uid://wepsb3f7nni" path="res://shader/cel-shader-base.gdshader" id="2_63a2j"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_m5gih"]
|
||||
render_priority = 0
|
||||
shader = ExtResource("1_vdkh7")
|
||||
|
||||
[resource]
|
||||
render_priority = 0
|
||||
next_pass = SubResource("ShaderMaterial_m5gih")
|
||||
shader = ExtResource("2_63a2j")
|
||||
shader_parameter/color = Color(1, 1, 1, 1)
|
||||
shader_parameter/specular = Color(0.3, 0.3, 0.3, 0.5)
|
||||
shader_parameter/fresnel = Color(0.2, 0.2, 0.2, 0.3)
|
||||
shader_parameter/uv_scale = Vector2(1, 1)
|
||||
shader_parameter/uv_offset = Vector2(0, 0)
|
||||
@@ -0,0 +1,62 @@
|
||||
@tool
|
||||
extends Node3D
|
||||
|
||||
@export var refresh_now: bool = false:
|
||||
set(value):
|
||||
if value:
|
||||
refresh_now = false # 自动弹回
|
||||
_apply_materials()
|
||||
|
||||
@export var cartoon_material: ShaderMaterial:
|
||||
set(value):
|
||||
cartoon_material = value
|
||||
_apply_materials()
|
||||
|
||||
@export_group("Instance Overrides")
|
||||
@export var use_custom_color: bool = false:
|
||||
set(value):
|
||||
use_custom_color = value
|
||||
_apply_materials()
|
||||
@export var custom_color: Color = Color(1, 1, 1, 1):
|
||||
set(value):
|
||||
custom_color = value
|
||||
if use_custom_color: # 只有开启时才实时刷新
|
||||
_apply_materials()
|
||||
|
||||
func _ready() -> void:
|
||||
_apply_materials()
|
||||
|
||||
func _apply_materials():
|
||||
if not is_inside_tree() or cartoon_material == null:
|
||||
return
|
||||
|
||||
for node in find_children("*", "MeshInstance3D", true, false):
|
||||
if not node is MeshInstance3D:
|
||||
continue
|
||||
|
||||
# 1. 复制一份全新的独立材质,它自带模板 (toon.tres) 的默认颜色和贴图
|
||||
var unique_mat = cartoon_material.duplicate()
|
||||
|
||||
# 2. 安全地获取原模型自带的贴图,并赋给独立材质
|
||||
if node.mesh != null and node.mesh.get_surface_count() > 0:
|
||||
var original_mat = node.mesh.surface_get_material(0)
|
||||
if original_mat != null:
|
||||
var final_tex: Texture2D = null
|
||||
# 兼容 StandardMaterial3D
|
||||
if original_mat is StandardMaterial3D:
|
||||
final_tex = original_mat.albedo_texture
|
||||
# 兼容原模型自带的其他 ShaderMaterial(如从 Blender 导入的材质)
|
||||
elif original_mat.has_method("get_shader_parameter"):
|
||||
final_tex = original_mat.get_shader_parameter("base_texture")
|
||||
|
||||
if final_tex != null:
|
||||
unique_mat.set_shader_parameter("base_texture", final_tex)
|
||||
|
||||
# 3. 处理颜色覆盖
|
||||
# 如果勾选了自定义颜色,直接在独立材质上修改
|
||||
# 如果没勾选,则什么都不做,保留从模板复制来的默认颜色
|
||||
if use_custom_color:
|
||||
unique_mat.set_shader_parameter("color", custom_color)
|
||||
|
||||
# 4. 最后,把配置好的独立材质一次性赋予模型
|
||||
node.material_override = unique_mat
|
||||
@@ -0,0 +1 @@
|
||||
uid://cyabo07rc0216
|
||||
-3263
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user