оптимизация рендера

This commit is contained in:
2026-06-25 17:10:07 +04:00
parent 8c6cd88e31
commit af5e1f4d6c
26 changed files with 2691 additions and 171 deletions
+105 -8
View File
@@ -11,6 +11,7 @@ const USE_GEOMETRY_NORMALS := true
static var _terrain_shader: Shader
static var _single_texture_shader: Shader
static var _empty_alpha_texture: Texture2D
static var _native_adt_baker: Object
static var _fallback_material: StandardMaterial3D
static var _single_texture_material_cache: Dictionary = {}
static var _baked_texture_material_cache: Dictionary = {}
@@ -109,6 +110,24 @@ static func build_baked_tile_render_payload(
return _build_baked_tile_payload(data, image_cache, extracted_dir, lod, texture_size)
static func build_baked_tile_render_payload_pair(
data: Dictionary,
image_cache: Dictionary,
extracted_dir: String = "",
full_lod: int = 0,
full_texture_size: int = 2048,
coarse_lod: int = 3,
coarse_texture_size: int = 512) -> Dictionary:
return _build_baked_tile_payload_pair(
data,
image_cache,
extracted_dir,
full_lod,
full_texture_size,
coarse_lod,
coarse_texture_size)
static func get_tile_origin(data: Dictionary) -> Vector3:
var found := false
var min_x := 0.0
@@ -441,6 +460,48 @@ static func _build_baked_tile_payload(
lod: int,
texture_size: int) -> Dictionary:
var payload := _build_baked_tile_geometry_payload(data, lod)
if payload.is_empty():
return {}
var baked_image := _build_tile_baked_albedo(data, image_cache, extracted_dir, texture_size)
_apply_baked_albedo_material(payload.get("mesh", null), baked_image)
return payload
static func _build_baked_tile_payload_pair(
data: Dictionary,
image_cache: Dictionary,
extracted_dir: String,
full_lod: int,
full_texture_size: int,
coarse_lod: int,
coarse_texture_size: int) -> Dictionary:
var full_payload := _build_baked_tile_geometry_payload(data, full_lod)
if full_payload.is_empty():
return {}
var coarse_payload := _build_baked_tile_geometry_payload(data, coarse_lod)
var full_image := _build_tile_baked_albedo(data, image_cache, extracted_dir, full_texture_size)
var coarse_image: Image = null
if full_image != null:
coarse_image = full_image.duplicate()
var coarse_size := _get_baked_albedo_size(coarse_texture_size)
if coarse_image.get_width() != coarse_size or coarse_image.get_height() != coarse_size:
coarse_image.resize(coarse_size, coarse_size, Image.INTERPOLATE_BILINEAR)
_apply_baked_albedo_material(full_payload.get("mesh", null), full_image)
if not coarse_payload.is_empty():
_apply_baked_albedo_material(coarse_payload.get("mesh", null), coarse_image)
return {
"full": full_payload,
"coarse": coarse_payload,
}
static func _build_baked_tile_geometry_payload(data: Dictionary, lod: int) -> Dictionary:
var tile_origin := get_tile_origin(data)
var verts := PackedVector3Array()
var nrms := PackedVector3Array()
@@ -491,7 +552,16 @@ static func _build_baked_tile_payload(
var mesh := ArrayMesh.new()
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
var baked_image := _build_tile_baked_albedo(data, image_cache, extracted_dir, texture_size)
return {
"mesh": mesh,
"position": Vector3.ZERO,
"name": "TileLOD%d" % lod,
}
static func _apply_baked_albedo_material(mesh: Mesh, baked_image: Image) -> void:
if mesh == null:
return
if baked_image:
baked_image.generate_mipmaps()
var baked_texture := ImageTexture.create_from_image(baked_image)
@@ -499,12 +569,6 @@ static func _build_baked_tile_payload(
else:
mesh.surface_set_material(0, _build_fallback_material())
return {
"mesh": mesh,
"position": Vector3.ZERO,
"name": "TileLOD%d" % lod,
}
static func _build_mesh_instance_from_payload(payload: Dictionary) -> MeshInstance3D:
if payload.is_empty():
@@ -881,7 +945,15 @@ static func _build_tile_baked_albedo(
extracted_dir: String,
texture_size: int) -> Image:
var chunk_pixels := maxi(8, int(ceil(float(maxi(texture_size, 16)) / 16.0)))
var native_image := _build_tile_baked_albedo_native(
data,
image_cache,
extracted_dir,
texture_size)
if native_image != null:
return native_image
var chunk_pixels := int(_get_baked_albedo_size(texture_size) / 16)
var size := chunk_pixels * 16
var image := Image.create(size, size, false, Image.FORMAT_RGB8)
image.fill(Color(0.4, 0.55, 0.3))
@@ -914,6 +986,30 @@ static func _build_tile_baked_albedo(
return image
static func _build_tile_baked_albedo_native(
data: Dictionary,
image_cache: Dictionary,
extracted_dir: String,
texture_size: int) -> Image:
if not ClassDB.class_exists("ADTBaker"):
return null
if _native_adt_baker == null:
_native_adt_baker = ClassDB.instantiate("ADTBaker")
if _native_adt_baker == null:
return null
return _native_adt_baker.call(
"bake_tile_albedo",
data,
image_cache,
extracted_dir,
texture_size) as Image
static func _get_baked_albedo_size(texture_size: int) -> int:
return maxi(8, int(ceil(float(maxi(texture_size, 16)) / 16.0))) * 16
static func _sample_chunk_baked_albedo(
chunk: Dictionary,
tex_names: PackedStringArray,
@@ -1110,6 +1206,7 @@ static func _load_texture(
cache[blp_path] = null
return null
img.generate_mipmaps()
var tex := ImageTexture.create_from_image(img)
cache[blp_path] = tex
return tex