# CharShadow —— 角色脚下阴影(첫 버전). # # 参考端 `GameLib/MapOutdoorCharacterShadow.cpp` 把角色渲到小 RT + 投一张模糊暗贴图 # 到脚下。这里按「结果」对齐,不复刻 RT: # 1) 强制角色所有 MeshInstance3D `cast_shadow = ON`(挡住 world 里 OFF 的误伤) # 2) 脚下一张径向渐变 `Decal`,投影到地形/物体上 —— 太阳接近正午投影很短时也有接触暗影 # # CharShadow.attach(entity_root_node3d) # 传实体根(不是内部 make_conv 的 Metin2Model) extends RefCounted class_name CharShadow static var _tex: Texture2D static func _blob_tex() -> Texture2D: if _tex != null: return _tex var sz := 64 var img := Image.create_empty(sz, sz, false, Image.FORMAT_RGBA8) var c := sz * 0.5 for y in sz: for x in sz: var d := Vector2(x + 0.5 - c, y + 0.5 - c).length() / c var a: float = clampf(1.0 - d, 0.0, 1.0) img.set_pixel(x, y, Color(0.0, 0.0, 0.0, a * a * 0.55)) _tex = ImageTexture.create_from_image(img) return _tex static func attach(root: Node3D, footprint := 1.4) -> void: if root == null: return for m in root.find_children("*", "MeshInstance3D", true, false): (m as MeshInstance3D).cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_ON if root.has_node("BlobShadow"): return var dec := Decal.new() dec.name = "BlobShadow" dec.texture_albedo = _blob_tex() # size = 投影盒 (x,z 足印;y 向下够到地面即可) dec.size = Vector3(footprint, 2.5, footprint) dec.modulate = Color(1, 1, 1, 0.55) dec.position = Vector3(0, 0.6, 0) # 盒中心略高于脚,向下投 dec.cull_mask = 0xFFFFF root.add_child(dec)