скайбоксы, рендер воды, документация
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
extends RefCounted
|
||||
class_name WowLiquidMaterial
|
||||
|
||||
static var _shader: Shader
|
||||
static var _cache: Dictionary = {}
|
||||
|
||||
|
||||
static func clear_cache() -> void:
|
||||
_cache.clear()
|
||||
|
||||
|
||||
static func build(liquid_id: int) -> ShaderMaterial:
|
||||
var key := "adt:%d" % liquid_id
|
||||
if _cache.has(key):
|
||||
return _cache[key]
|
||||
|
||||
var style := _style_for_liquid(liquid_id)
|
||||
var mat := _create_material(style)
|
||||
_cache[key] = mat
|
||||
return mat
|
||||
|
||||
|
||||
static func build_wmo(material_id: int) -> ShaderMaterial:
|
||||
var key := "wmo:%d" % material_id
|
||||
if _cache.has(key):
|
||||
return _cache[key]
|
||||
|
||||
var style := {
|
||||
"color": Color(0.10, 0.30, 0.48, 0.60),
|
||||
"foam": Color(0.58, 0.80, 1.00, 0.22),
|
||||
"wave_strength": 0.045,
|
||||
"wave_scale": 0.095,
|
||||
"wave_speed": 0.38,
|
||||
"fresnel_power": 2.2,
|
||||
"emission_strength": 0.025,
|
||||
"magma_mode": 0.0,
|
||||
}
|
||||
var mat := _create_material(style)
|
||||
_cache[key] = mat
|
||||
return mat
|
||||
|
||||
|
||||
static func _create_material(style: Dictionary) -> ShaderMaterial:
|
||||
var mat := ShaderMaterial.new()
|
||||
mat.shader = _get_shader()
|
||||
mat.render_priority = 1
|
||||
mat.set_shader_parameter("liquid_color", style["color"])
|
||||
mat.set_shader_parameter("foam_color", style["foam"])
|
||||
mat.set_shader_parameter("wave_strength", float(style["wave_strength"]))
|
||||
mat.set_shader_parameter("wave_scale", float(style["wave_scale"]))
|
||||
mat.set_shader_parameter("wave_speed", float(style["wave_speed"]))
|
||||
mat.set_shader_parameter("alpha_base", (style["color"] as Color).a)
|
||||
mat.set_shader_parameter("fresnel_power", float(style["fresnel_power"]))
|
||||
mat.set_shader_parameter("emission_strength", float(style["emission_strength"]))
|
||||
mat.set_shader_parameter("magma_mode", float(style["magma_mode"]))
|
||||
return mat
|
||||
|
||||
|
||||
static func _style_for_liquid(liquid_id: int) -> Dictionary:
|
||||
match liquid_id:
|
||||
3, 15, 19:
|
||||
return {
|
||||
"color": Color(0.78, 0.22, 0.03, 0.78),
|
||||
"foam": Color(1.00, 0.66, 0.10, 0.38),
|
||||
"wave_strength": 0.025,
|
||||
"wave_scale": 0.12,
|
||||
"wave_speed": 0.22,
|
||||
"fresnel_power": 1.7,
|
||||
"emission_strength": 0.42,
|
||||
"magma_mode": 1.0,
|
||||
}
|
||||
4, 20:
|
||||
return {
|
||||
"color": Color(0.16, 0.38, 0.12, 0.66),
|
||||
"foam": Color(0.50, 0.80, 0.32, 0.24),
|
||||
"wave_strength": 0.035,
|
||||
"wave_scale": 0.11,
|
||||
"wave_speed": 0.28,
|
||||
"fresnel_power": 2.0,
|
||||
"emission_strength": 0.05,
|
||||
"magma_mode": 0.0,
|
||||
}
|
||||
2, 14:
|
||||
return {
|
||||
"color": Color(0.05, 0.16, 0.30, 0.64),
|
||||
"foam": Color(0.48, 0.72, 1.00, 0.20),
|
||||
"wave_strength": 0.060,
|
||||
"wave_scale": 0.075,
|
||||
"wave_speed": 0.32,
|
||||
"fresnel_power": 2.5,
|
||||
"emission_strength": 0.025,
|
||||
"magma_mode": 0.0,
|
||||
}
|
||||
_:
|
||||
return {
|
||||
"color": Color(0.08, 0.28, 0.46, 0.58),
|
||||
"foam": Color(0.58, 0.82, 1.00, 0.24),
|
||||
"wave_strength": 0.050,
|
||||
"wave_scale": 0.085,
|
||||
"wave_speed": 0.36,
|
||||
"fresnel_power": 2.3,
|
||||
"emission_strength": 0.025,
|
||||
"magma_mode": 0.0,
|
||||
}
|
||||
|
||||
|
||||
static func _get_shader() -> Shader:
|
||||
if _shader:
|
||||
return _shader
|
||||
|
||||
_shader = Shader.new()
|
||||
_shader.code = """
|
||||
shader_type spatial;
|
||||
render_mode blend_mix, cull_disabled, unshaded;
|
||||
|
||||
uniform vec4 liquid_color : source_color = vec4(0.08, 0.28, 0.46, 0.58);
|
||||
uniform vec4 foam_color : source_color = vec4(0.58, 0.82, 1.00, 0.24);
|
||||
uniform float wave_strength = 0.05;
|
||||
uniform float wave_scale = 0.085;
|
||||
uniform float wave_speed = 0.36;
|
||||
uniform float alpha_base = 0.58;
|
||||
uniform float fresnel_power = 2.3;
|
||||
uniform float emission_strength = 0.025;
|
||||
uniform float magma_mode = 0.0;
|
||||
|
||||
varying vec3 world_pos;
|
||||
|
||||
float hash21(vec2 p) {
|
||||
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);
|
||||
}
|
||||
|
||||
float noise21(vec2 p) {
|
||||
vec2 i = floor(p);
|
||||
vec2 f = fract(p);
|
||||
vec2 u = f * f * (3.0 - 2.0 * f);
|
||||
float a = hash21(i);
|
||||
float b = hash21(i + vec2(1.0, 0.0));
|
||||
float c = hash21(i + vec2(0.0, 1.0));
|
||||
float d = hash21(i + vec2(1.0, 1.0));
|
||||
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
float t = TIME * wave_speed;
|
||||
float wave_a = sin(world_pos.x * wave_scale + t);
|
||||
float wave_b = cos(world_pos.z * wave_scale * 1.37 - t * 1.21);
|
||||
VERTEX.y += (wave_a + wave_b) * wave_strength;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec3 n = normalize(NORMAL);
|
||||
vec3 v = normalize(VIEW);
|
||||
float facing = clamp(abs(dot(n, v)), 0.0, 1.0);
|
||||
float fresnel = pow(1.0 - facing, fresnel_power);
|
||||
|
||||
vec2 p = world_pos.xz * wave_scale;
|
||||
float n1 = noise21(p * 0.70 + vec2(TIME * wave_speed, -TIME * wave_speed * 0.60));
|
||||
float n2 = noise21(p * 1.80 + vec2(-TIME * wave_speed * 0.35, TIME * wave_speed * 0.45));
|
||||
float ripple = smoothstep(0.52, 0.86, n1 * 0.65 + n2 * 0.35);
|
||||
|
||||
vec3 color = mix(liquid_color.rgb, foam_color.rgb, ripple * foam_color.a);
|
||||
color += fresnel * foam_color.rgb * 0.35;
|
||||
|
||||
if (magma_mode > 0.5) {
|
||||
float glow = smoothstep(0.45, 1.0, ripple + fresnel * 0.45);
|
||||
color += vec3(1.0, 0.35, 0.05) * glow * 0.45;
|
||||
EMISSION = color * max(emission_strength, 0.35);
|
||||
} else {
|
||||
EMISSION = color * emission_strength;
|
||||
}
|
||||
|
||||
ALBEDO = color;
|
||||
ALPHA = clamp(alpha_base + fresnel * 0.18 + ripple * 0.06, 0.0, 1.0);
|
||||
}
|
||||
"""
|
||||
return _shader
|
||||
Reference in New Issue
Block a user