шейдеры билбордов

This commit is contained in:
2026-07-07 11:33:57 +04:00
parent 44614a79e4
commit f561e52aa9
6 changed files with 320 additions and 6 deletions
+16 -1
View File
@@ -6,6 +6,7 @@
class_name M2Builder
const WOW_M2_MATERIAL := preload("res://addons/mpq_extractor/loaders/wow_m2_material.gd")
const MATERIAL_FORMAT_VERSION := 1
static var _texture_cache: Dictionary = {}
@@ -67,7 +68,8 @@ static func build(data: Dictionary, extracted_dir: String = "") -> Node3D:
arrays[Mesh.ARRAY_TEX_UV2] = uvs2
arrays[Mesh.ARRAY_INDEX] = batch_indices
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
var surface_flags := _apply_billboard_custom_data(arrays, batch, verts.size())
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays, [], {}, surface_flags)
var surf_idx := mesh.get_surface_count() - 1
var mat_def: Dictionary = materials[mat_id] if mat_id >= 0 and mat_id < materials.size() else {}
@@ -94,6 +96,8 @@ static func build(data: Dictionary, extracted_dir: String = "") -> Node3D:
if mesh.get_surface_count() == 0:
return root
mesh.set_meta("wow_m2_material_refresh_version", MATERIAL_FORMAT_VERSION)
mesh.set_meta("wow_m2_source_path", model_path)
var mi := MeshInstance3D.new()
mi.name = "Mesh"
@@ -163,6 +167,7 @@ static func _build_material(
combiner["vertex_shader_id"] = _m2_vertex_shader_id(texture_count, int(batch.get("shader_id", 0)))
combiner["pixel_shader_id"] = _m2_pixel_shader_id(texture_count, int(batch.get("shader_id", 0)))
combiner["priority_plane"] = int(batch.get("priority_plane", 0))
combiner["billboard_enabled"] = bool(batch.get("has_billboard", false)) or int(batch.get("billboard_vertex_count", 0)) > 0
if _is_soft_waterfall_material(model_path, blend_mode, combiner):
combiner["effect_alpha_scale"] = 1.12
combiner["effect_alpha_power"] = 0.92
@@ -187,9 +192,19 @@ static func _build_material(
mat.set_meta("wow_m2_vertex_shader_id", int(combiner.get("vertex_shader_id", 0)))
mat.set_meta("wow_m2_pixel_shader_id", int(combiner.get("pixel_shader_id", 0)))
mat.set_meta("wow_priority_plane", int(batch.get("priority_plane", 0)))
mat.set_meta("wow_m2_billboard_enabled", bool(combiner.get("billboard_enabled", false)))
mat.set_meta("wow_m2_billboard_bone_flags", int(batch.get("billboard_bone_flags", 0)))
return mat
static func _apply_billboard_custom_data(arrays: Array, batch: Dictionary, vertex_count: int) -> int:
var billboard_data: PackedFloat32Array = batch.get("billboard_data", PackedFloat32Array())
if billboard_data.size() != vertex_count * 4:
return 0
arrays[Mesh.ARRAY_CUSTOM0] = billboard_data
return int(Mesh.ARRAY_CUSTOM_RGBA_FLOAT) << int(Mesh.ARRAY_FORMAT_CUSTOM0_SHIFT)
static func _is_soft_waterfall_material(model_path: String, blend_mode: int, combiner: Dictionary) -> bool:
if blend_mode != 2:
return false