M2.5: ShaderMaterial + texture resolution + fog; multi-skeleton verified

- m2_material: Metin2-style ShaderMaterial. blend_mix shader (opaque /
  alpha-blend / alpha-test-cutout via `mode` uniform) + blend_add shader
  (additive glow). modulate(tex, COORD) * COLOR, diffuse_lambert.
- Metin2Model: material_mode prop ("metin2" ShaderMaterial | "standard");
  _resolve_texture does filename-convention + case-insensitive dir scan of
  *.dds (face/hair keyword slots, stem match, fallback); set_surface_texture
  override; guess_blend heuristic (hair->cutout, cape->alpha, effect->add).
  Texture cache. Fixed opaque path to NOT alpha-discard (was hiding bodies).
- harness: AABB-based camera framing, engine depth fog (MTGODOT_FOG=1),
  MTGODOT_ANIM_T fixed-pose capture (needs explicit anim reload first),
  MTGODOT_AUTOSHOT batch screenshot.

Verified: warrior 5/5 surfaces textured under the shader (t=9 dance pose,
lit, fogged). assassin 17/17 textured via dir scan. shaman_lord (gr2 v7)
renders. Screenshots test/golden/m25-*.png, m2c-t*.png.

Gap (M2.5 gate not closed): libgr2 POD API exposes no material/texture-name/
blend data, so multi-slot -> texture/blend mapping is heuristic only. Needs
a libgr2 material API (gr2_material.cpp walking the type tree) — same gap as
xrender-poc M1 T5. Documented in docs/GODOT-POC-PLAN.md §M2.5 T2.5.6.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaHYEY9rwLWt21PULiYjeJ
This commit is contained in:
Claude
2026-08-29 09:35:01 +09:00
parent 27e39993f7
commit eeffa2a730
29 changed files with 368 additions and 54 deletions
+35
View File
@@ -0,0 +1,35 @@
#pragma once
// m2_material — Metin2-style forward material as a Godot ShaderMaterial.
//
// M2.5 infrastructure. The gr2 fixed-function texture-stage / blend data is not
// yet exposed by libgr2's POD API (see docs/GODOT-POC-PLAN.md §M2.5 gap list),
// so callers pick the blend mode heuristically for now. The shader itself
// already covers the common Metin2 cases: modulate(tex, vertex_color) + light,
// alpha-test, alpha-blend, additive.
#include <godot_cpp/classes/ref.hpp>
namespace godot {
class ShaderMaterial;
class Texture2D;
} // namespace godot
namespace mtgodot {
enum class BlendMode {
Opaque, // blend_mix, ALPHA=1, no discard
Alpha, // blend_mix, sorted, uses texture alpha
AlphaTest, // blend_mix, discard below alpha_scissor (cutout)
Add, // blend_add (glow / effects)
};
struct MaterialDesc {
godot::Ref<godot::Texture2D> albedo; // null -> flat white
BlendMode blend = BlendMode::Opaque;
float alpha_scissor = 0.5f;
bool two_sided = true; // winding not yet verified per-model
};
godot::Ref<godot::ShaderMaterial> make_material(const MaterialDesc &d);
} // namespace mtgodot