скайбоксы, рендер воды, документация

This commit is contained in:
2026-06-27 18:33:55 +04:00
parent 579b9e10c9
commit b051012920
14 changed files with 1775 additions and 101 deletions
+25 -41
View File
@@ -2,6 +2,8 @@
extends RefCounted
class_name ADTBuilder
const WOW_LIQUID_MATERIAL := preload("res://addons/mpq_extractor/loaders/wow_liquid_material.gd")
const TILE_SIZE := 533.33333
const CHUNK_SIZE := 33.33333
const UNIT_SIZE := CHUNK_SIZE / 8.0
@@ -18,7 +20,6 @@ static var _single_texture_material_cache: Dictionary = {}
static var _baked_texture_material_cache: Dictionary = {}
static var _alpha_texture_cache: Dictionary = {}
static var _layered_material_cache: Dictionary = {}
static var _liquid_material_cache: Dictionary = {}
## Build a Node3D with 256 terrain chunk meshes.
## `extracted_dir` must be an absolute path to the extracted/ folder so BLPs can be loaded.
@@ -780,6 +781,7 @@ static func _build_tile_water_root(data: Dictionary, origin_offset: Vector3) ->
var mi := MeshInstance3D.new()
mi.mesh = mesh
mi.name = "Liquid_%d" % int(liquid_id)
mi.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
root.add_child(mi)
return root if root.get_child_count() > 0 else null
@@ -817,6 +819,10 @@ static func _append_liquid_geometry(
var y10 := liquid_heights[z * 9 + x + 1] - origin_offset.y
var y01 := liquid_heights[(z + 1) * 9 + x] - origin_offset.y
var y11 := liquid_heights[(z + 1) * 9 + x + 1] - origin_offset.y
var u0 := x0 / TILE_SIZE
var u1 := x1 / TILE_SIZE
var v0 := z0 / TILE_SIZE
var v1 := z1 / TILE_SIZE
verts.append(Vector3(x0, y00, z0))
verts.append(Vector3(x0, y01, z1))
@@ -828,10 +834,10 @@ static func _append_liquid_geometry(
nrms.append(Vector3.UP)
nrms.append(Vector3.UP)
uvs_arr.append(Vector2(float(x) / 8.0, float(z) / 8.0))
uvs_arr.append(Vector2(float(x) / 8.0, float(z + 1) / 8.0))
uvs_arr.append(Vector2(float(x + 1) / 8.0, float(z + 1) / 8.0))
uvs_arr.append(Vector2(float(x + 1) / 8.0, float(z) / 8.0))
uvs_arr.append(Vector2(u0, v0))
uvs_arr.append(Vector2(u0, v1))
uvs_arr.append(Vector2(u1, v1))
uvs_arr.append(Vector2(u1, v0))
indices.append(base)
indices.append(base + 1)
@@ -912,6 +918,7 @@ static func _build_liquid_mesh(
var mi := MeshInstance3D.new()
mi.mesh = mesh
mi.position = chunk_origin - origin_offset
mi.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
mi.name = "Liquid_%d_%d_%d" % [
chunk.get("index_x", 0),
chunk.get("index_y", 0),
@@ -938,33 +945,8 @@ static func _build_chunk_material(
return _build_fallback_material()
static func _build_liquid_material(liquid_id: int) -> StandardMaterial3D:
if _liquid_material_cache.has(liquid_id):
return _liquid_material_cache[liquid_id]
var color := _get_liquid_color(liquid_id)
var mat := StandardMaterial3D.new()
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
mat.albedo_color = color
mat.cull_mode = BaseMaterial3D.CULL_DISABLED
mat.roughness = 0.08
mat.metallic = 0.0
mat.emission_enabled = true
mat.emission = Color(color.r, color.g, color.b) * 0.08
_liquid_material_cache[liquid_id] = mat
return mat
static func _get_liquid_color(liquid_id: int) -> Color:
match liquid_id:
2, 14:
return Color(0.08, 0.20, 0.34, 0.62)
3, 15, 19:
return Color(0.75, 0.28, 0.03, 0.72)
4, 20:
return Color(0.24, 0.45, 0.14, 0.68)
_:
return Color(0.12, 0.33, 0.50, 0.58)
static func _build_liquid_material(liquid_id: int) -> Material:
return WOW_LIQUID_MATERIAL.build(liquid_id)
static func _build_terrain_material(
@@ -1287,18 +1269,20 @@ uniform float ambient = 0.62;
uniform float diffuse = 0.38;
uniform float hemi = 0.12;
vec3 sample_layer(float layer, vec2 local_uv) {
return texture(terrain_tex, vec3(local_uv * uv_scale, layer), mip_bias).rgb;
vec3 sample_layer(float layer, vec2 continuous_chunk_uv) {
return texture(terrain_tex, vec3(continuous_chunk_uv * uv_scale, layer), mip_bias).rgb;
}
void fragment() {
vec2 tile_uv = clamp(UV, vec2(0.0), vec2(0.999999));
vec2 chunk_f = floor(tile_uv * 16.0);
vec2 local_uv = fract(tile_uv * 16.0);
vec2 chunk_uv = tile_uv * 16.0;
vec2 chunk_f = floor(chunk_uv);
vec2 local_uv = chunk_uv - chunk_f;
vec4 packed_ids = COLOR;
vec4 layers = floor(packed_ids * 255.0 + vec4(0.5));
vec3 alpha = texture(alpha_atlas, (chunk_f * 64.0 + local_uv * 64.0 + vec2(0.5)) / 1024.0).rgb;
vec2 alpha_px = clamp(local_uv * 64.0, vec2(0.5), vec2(63.5));
vec3 alpha = texture(alpha_atlas, (chunk_f * 64.0 + alpha_px) / 1024.0).rgb;
float w1 = alpha.r;
float w2 = alpha.g;
@@ -1311,10 +1295,10 @@ void fragment() {
w3 /= sum;
vec3 albedo =
sample_layer(layers.x, local_uv) * w0 +
sample_layer(layers.y, local_uv) * w1 +
sample_layer(layers.z, local_uv) * w2 +
sample_layer(layers.w, local_uv) * w3;
sample_layer(layers.x, chunk_uv) * w0 +
sample_layer(layers.y, chunk_uv) * w1 +
sample_layer(layers.z, chunk_uv) * w2 +
sample_layer(layers.w, chunk_uv) * w3;
vec3 n = normalize(NORMAL);
if (!FRONT_FACING) {