скайбоксы, рендер воды, документация
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user