fix(rendering): checkpoint main-character recovery and visual regression work

Handle late main-character data, guarded model construction, bounded retries and map correction. Validate player model sources and add lifecycle and real-asset visual regressions.

Include pending material and character-selection changes, updated A1 screenshot, and the detailed rendering repair plan. Hair occlusion, full UI parity and final macOS package acceptance remain unfinished.
This commit is contained in:
shen
2026-09-08 08:52:30 +08:00
parent 8092ff44e2
commit c3a6fb973e
11 changed files with 620 additions and 23 deletions
+21 -2
View File
@@ -183,8 +183,24 @@ Ref<Shader> s_mix_2s;
Ref<Shader> s_add_2s;
Ref<Shader> s_skin_2s;
Ref<Shader> s_add_skin_2s;
Ref<Shader> s_opaque[4];
Ref<Shader> shader_for(bool additive, bool skinned, bool two_sided) {
Ref<Shader> shader_for(bool additive, bool skinned, bool two_sided, bool opaque) {
if (opaque) {
Ref<Shader> &solid = s_opaque[(skinned ? 2 : 0) + (two_sided ? 1 : 0)];
if (solid.is_null()) {
String code = skinned ? SRC_SKIN : SRC_MIX;
// Writing ALPHA puts even alpha=1 into Godot's transparent pass.
// Solid faces must write depth before the hair cutout is drawn.
code = code.replace("ALPHA = ((mode == 1) ? c.a : 1.0) * lod_fade;",
"if (lod_fade < fract(sin(dot(FRAGCOORD.xy, vec2(12.9898, 78.233))) * 43758.5453)) { discard; }");
if (two_sided)
code = code.replace("cull_back", "cull_disabled");
solid.instantiate();
solid->set_code(code);
}
return solid;
}
Ref<Shader> &slot = two_sided
? (additive ? (skinned ? s_add_skin_2s : s_add_2s) : (skinned ? s_skin_2s : s_mix_2s))
: (additive ? (skinned ? s_add_skin : s_add) : (skinned ? s_skin : s_mix));
@@ -206,7 +222,8 @@ Ref<ShaderMaterial> make_material(const MaterialDesc &d) {
const bool additive = (d.blend == BlendMode::Add);
const bool skinned = d.skinned;
m->set_shader(shader_for(additive, skinned, d.two_sided));
m->set_shader(shader_for(additive, skinned, d.two_sided,
d.blend == BlendMode::Opaque || d.blend == BlendMode::AlphaTest));
if (skinned && d.bones_tex.is_valid()) {
m->set_shader_parameter("bones_tex", d.bones_tex);
}
@@ -244,6 +261,8 @@ Ref<ShaderMaterial> make_material(const MaterialDesc &d) {
}
void cleanup_material_shaders() {
for (auto &shader : s_opaque)
shader.unref();
s_mix.unref();
s_add.unref();
s_skin.unref();