Start dynamic sky
This commit is contained in:
310
dynamic-sky/scripts/post_process_controller.gd
Normal file
310
dynamic-sky/scripts/post_process_controller.gd
Normal file
@@ -0,0 +1,310 @@
|
||||
@tool
|
||||
class_name PostProcessController
|
||||
extends Node
|
||||
|
||||
@export_group("Profile")
|
||||
@export var profile: PostProcessProfile:
|
||||
set(value):
|
||||
profile = value
|
||||
_apply_profile()
|
||||
|
||||
@export_group("Environment")
|
||||
@export var target_environment: Environment
|
||||
|
||||
@export_group("Sky Gradient")
|
||||
@export var sky_top_color: Color = Color(0.2, 0.4, 0.8)
|
||||
@export var sky_horizon_color: Color = Color(0.6, 0.7, 0.9)
|
||||
@export var sky_bottom_color: Color = Color(0.4, 0.5, 0.6)
|
||||
@export var gradient_intensity: float = 1.0
|
||||
|
||||
@export_group("Skybox")
|
||||
@export var skybox_texture: Texture2D:
|
||||
set(value):
|
||||
skybox_texture = value
|
||||
_update_sky_material()
|
||||
@export var skybox_blend: float = 1.0:
|
||||
set(value):
|
||||
skybox_blend = clampf(value, 0.0, 1.0)
|
||||
_update_sky_material()
|
||||
|
||||
@export_group("Fog Shaping")
|
||||
@export var fog_enabled: bool = true
|
||||
@export var fog_color: Color = Color(0.7, 0.8, 0.9)
|
||||
@export var fog_density: float = 0.01
|
||||
@export var height_fog_enabled: bool = true
|
||||
@export var height_fog_min: float = 0.0
|
||||
@export var height_fog_max: float = 100.0
|
||||
@export var height_fog_curve: float = 1.0
|
||||
|
||||
@export_group("Sun Glow")
|
||||
@export var sun_glow_enabled: bool = true
|
||||
@export var sun_glow_intensity: float = 0.5
|
||||
@export var sun_glow_size: float = 0.2
|
||||
@export var sun_glow_falloff: float = 2.0
|
||||
@export var sun_glow_color: Color = Color(1.0, 0.95, 0.8)
|
||||
@export var sun_direction: Vector3 = Vector3(0.0, 1.0, 0.0)
|
||||
|
||||
@export_group("Dawn/Dusk Enhancement")
|
||||
@export var dawn_dusk_enabled: bool = true
|
||||
@export var dawn_dusk_intensity: float = 0.5
|
||||
@export var dawn_dusk_blend: float = 0.0
|
||||
|
||||
@export_group("Performance")
|
||||
@export var effects_enabled: bool = true
|
||||
|
||||
var _sky_material: ShaderMaterial
|
||||
var _post_process_quad: MeshInstance3D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if profile == null:
|
||||
profile = PostProcessProfile.new()
|
||||
_apply_profile()
|
||||
_setup_environment()
|
||||
|
||||
|
||||
func _apply_profile() -> void:
|
||||
if profile == null:
|
||||
return
|
||||
|
||||
gradient_intensity = profile.gradient_intensity
|
||||
fog_enabled = profile.fog_enabled
|
||||
height_fog_enabled = profile.height_fog_enabled
|
||||
height_fog_min = profile.height_fog_start
|
||||
height_fog_max = profile.height_fog_end
|
||||
height_fog_curve = profile.height_fog_curve
|
||||
sun_glow_enabled = profile.sun_glow_enabled
|
||||
sun_glow_intensity = profile.sun_glow_intensity
|
||||
sun_glow_size = profile.sun_glow_size
|
||||
sun_glow_falloff = profile.sun_glow_falloff
|
||||
sun_glow_color = profile.sun_glow_color
|
||||
dawn_dusk_enabled = profile.dawn_dusk_enabled
|
||||
dawn_dusk_intensity = profile.dawn_dusk_intensity
|
||||
|
||||
|
||||
func _setup_environment() -> void:
|
||||
if target_environment == null:
|
||||
return
|
||||
|
||||
_update_fog()
|
||||
_update_sky()
|
||||
|
||||
|
||||
func _update_fog() -> void:
|
||||
if target_environment == null:
|
||||
return
|
||||
|
||||
target_environment.fog_enabled = fog_enabled and effects_enabled
|
||||
|
||||
if fog_enabled:
|
||||
target_environment.fog_light_color = fog_color
|
||||
target_environment.fog_density = fog_density
|
||||
|
||||
if height_fog_enabled:
|
||||
target_environment.fog_height = height_fog_min
|
||||
target_environment.fog_height_density = height_fog_curve * 0.1
|
||||
|
||||
|
||||
func _update_sky() -> void:
|
||||
if target_environment == null:
|
||||
return
|
||||
|
||||
if target_environment.sky == null:
|
||||
target_environment.sky = Sky.new()
|
||||
|
||||
if target_environment.sky.sky_material == null or not target_environment.sky.sky_material is ShaderMaterial:
|
||||
_create_sky_material()
|
||||
|
||||
_sky_material = target_environment.sky.sky_material as ShaderMaterial
|
||||
if _sky_material:
|
||||
_update_sky_material()
|
||||
|
||||
|
||||
func _create_sky_material() -> void:
|
||||
_sky_material = ShaderMaterial.new()
|
||||
_sky_material.shader = _get_sky_shader()
|
||||
|
||||
if target_environment and target_environment.sky:
|
||||
target_environment.sky.sky_material = _sky_material
|
||||
|
||||
|
||||
func _get_sky_shader() -> Shader:
|
||||
var shader := Shader.new()
|
||||
shader.code = """
|
||||
shader_type sky;
|
||||
|
||||
uniform sampler2D skybox_texture : source_color, filter_linear_mipmap, repeat_enable;
|
||||
uniform bool skybox_enabled = false;
|
||||
uniform float skybox_blend = 1.0;
|
||||
|
||||
uniform vec4 sky_top_color : source_color = vec4(0.2, 0.4, 0.8, 1.0);
|
||||
uniform vec4 sky_horizon_color : source_color = vec4(0.6, 0.7, 0.9, 1.0);
|
||||
uniform vec4 sky_bottom_color : source_color = vec4(0.4, 0.5, 0.6, 1.0);
|
||||
uniform float gradient_intensity = 1.0;
|
||||
uniform float horizon_blend = 0.5;
|
||||
|
||||
uniform bool sun_glow_enabled = true;
|
||||
uniform vec3 sun_direction = vec3(0.0, 1.0, 0.0);
|
||||
uniform vec4 sun_glow_color : source_color = vec4(1.0, 0.95, 0.8, 1.0);
|
||||
uniform float sun_glow_intensity = 0.5;
|
||||
uniform float sun_glow_size = 0.2;
|
||||
uniform float sun_glow_falloff = 2.0;
|
||||
|
||||
uniform bool dawn_dusk_enabled = true;
|
||||
uniform vec4 dawn_dusk_color : source_color = vec4(1.0, 0.6, 0.4, 1.0);
|
||||
uniform float dawn_dusk_intensity = 0.5;
|
||||
uniform float dawn_dusk_blend = 0.0;
|
||||
|
||||
uniform float stars_visibility = 0.0;
|
||||
uniform vec4 stars_tint : source_color = vec4(1.0);
|
||||
|
||||
float hash(vec2 p) {
|
||||
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
||||
}
|
||||
|
||||
float stars(vec3 dir) {
|
||||
vec2 uv = dir.xz / (abs(dir.y) + 0.001) * 50.0;
|
||||
vec2 cell = floor(uv);
|
||||
vec2 local = fract(uv) - 0.5;
|
||||
|
||||
float star = 0.0;
|
||||
float h = hash(cell);
|
||||
if (h > 0.97) {
|
||||
float dist = length(local);
|
||||
star = smoothstep(0.1, 0.0, dist) * (h - 0.97) / 0.03;
|
||||
star *= step(0.0, dir.y);
|
||||
}
|
||||
return star;
|
||||
}
|
||||
|
||||
vec2 pano_uv(vec3 dir) {
|
||||
dir = normalize(dir);
|
||||
float u = atan(dir.x, dir.z) / (2.0 * PI) + 0.5;
|
||||
float v = acos(clamp(dir.y, -1.0, 1.0)) / PI;
|
||||
return vec2(u, v);
|
||||
}
|
||||
|
||||
void sky() {
|
||||
vec3 dir = EYEDIR;
|
||||
float y = dir.y;
|
||||
|
||||
vec3 color;
|
||||
if (y > 0.0) {
|
||||
float t = pow(y, horizon_blend);
|
||||
color = mix(sky_horizon_color.rgb, sky_top_color.rgb, t);
|
||||
} else {
|
||||
float t = pow(-y, horizon_blend);
|
||||
color = mix(sky_horizon_color.rgb, sky_bottom_color.rgb, t);
|
||||
}
|
||||
|
||||
color = mix(vec3(0.5), color, gradient_intensity);
|
||||
|
||||
if (skybox_enabled) {
|
||||
vec3 pano_color = texture(skybox_texture, pano_uv(dir)).rgb;
|
||||
color = mix(color, pano_color, skybox_blend);
|
||||
}
|
||||
|
||||
if (sun_glow_enabled && sun_direction.y > -0.2) {
|
||||
float sun_dot = max(0.0, dot(dir, normalize(sun_direction)));
|
||||
float glow = pow(sun_dot, 1.0 / max(0.001, sun_glow_size));
|
||||
glow = pow(glow, sun_glow_falloff);
|
||||
color += sun_glow_color.rgb * glow * sun_glow_intensity;
|
||||
}
|
||||
|
||||
if (dawn_dusk_enabled && dawn_dusk_blend > 0.0) {
|
||||
float horizon_factor = 1.0 - abs(y);
|
||||
horizon_factor = pow(horizon_factor, 2.0);
|
||||
color = mix(color, dawn_dusk_color.rgb, horizon_factor * dawn_dusk_intensity * dawn_dusk_blend);
|
||||
}
|
||||
|
||||
if (stars_visibility > 0.0 && y > 0.0) {
|
||||
float star_value = stars(dir) * stars_visibility;
|
||||
color += stars_tint.rgb * star_value;
|
||||
}
|
||||
|
||||
COLOR = color;
|
||||
}
|
||||
"""
|
||||
return shader
|
||||
|
||||
|
||||
func _update_sky_material() -> void:
|
||||
if _sky_material == null:
|
||||
return
|
||||
|
||||
if skybox_texture:
|
||||
_sky_material.set_shader_parameter("skybox_enabled", true)
|
||||
_sky_material.set_shader_parameter("skybox_texture", skybox_texture)
|
||||
_sky_material.set_shader_parameter("skybox_blend", skybox_blend)
|
||||
else:
|
||||
_sky_material.set_shader_parameter("skybox_enabled", false)
|
||||
_sky_material.set_shader_parameter("skybox_blend", skybox_blend)
|
||||
|
||||
_sky_material.set_shader_parameter("sky_top_color", sky_top_color)
|
||||
_sky_material.set_shader_parameter("sky_horizon_color", sky_horizon_color)
|
||||
_sky_material.set_shader_parameter("sky_bottom_color", sky_bottom_color)
|
||||
_sky_material.set_shader_parameter("gradient_intensity", gradient_intensity)
|
||||
|
||||
_sky_material.set_shader_parameter("sun_glow_enabled", sun_glow_enabled and effects_enabled)
|
||||
_sky_material.set_shader_parameter("sun_direction", sun_direction)
|
||||
_sky_material.set_shader_parameter("sun_glow_color", sun_glow_color)
|
||||
_sky_material.set_shader_parameter("sun_glow_intensity", sun_glow_intensity)
|
||||
_sky_material.set_shader_parameter("sun_glow_size", sun_glow_size)
|
||||
_sky_material.set_shader_parameter("sun_glow_falloff", sun_glow_falloff)
|
||||
|
||||
_sky_material.set_shader_parameter("dawn_dusk_enabled", dawn_dusk_enabled and effects_enabled)
|
||||
_sky_material.set_shader_parameter("dawn_dusk_blend", dawn_dusk_blend)
|
||||
_sky_material.set_shader_parameter("dawn_dusk_intensity", dawn_dusk_intensity)
|
||||
|
||||
|
||||
func set_sky_colors(top: Color, horizon: Color, bottom: Color) -> void:
|
||||
sky_top_color = top
|
||||
sky_horizon_color = horizon
|
||||
sky_bottom_color = bottom
|
||||
_update_sky_material()
|
||||
|
||||
|
||||
func set_fog_settings(color: Color, density: float) -> void:
|
||||
fog_color = color
|
||||
fog_density = density
|
||||
_update_fog()
|
||||
|
||||
|
||||
func set_sun_glow(direction: Vector3, color: Color, intensity: float, size: float) -> void:
|
||||
sun_direction = direction.normalized()
|
||||
sun_glow_color = color
|
||||
sun_glow_intensity = intensity
|
||||
sun_glow_size = size
|
||||
_update_sky_material()
|
||||
|
||||
|
||||
func set_dawn_dusk_blend(blend: float) -> void:
|
||||
dawn_dusk_blend = clampf(blend, 0.0, 1.0)
|
||||
_update_sky_material()
|
||||
|
||||
|
||||
func set_stars_visibility(visibility: float, tint: Color = Color.WHITE) -> void:
|
||||
if _sky_material:
|
||||
_sky_material.set_shader_parameter("stars_visibility", visibility)
|
||||
_sky_material.set_shader_parameter("stars_tint", tint)
|
||||
|
||||
|
||||
func set_effects_enabled(enabled: bool) -> void:
|
||||
effects_enabled = enabled
|
||||
_update_fog()
|
||||
_update_sky_material()
|
||||
|
||||
|
||||
func apply_config(config: SkyConfig) -> void:
|
||||
sky_top_color = config.sky_top_color
|
||||
sky_horizon_color = config.sky_horizon_color
|
||||
sky_bottom_color = config.sky_bottom_color
|
||||
fog_color = config.fog_color
|
||||
fog_density = config.fog_density
|
||||
sun_glow_intensity = config.sun_glow_intensity
|
||||
sun_glow_size = config.sun_glow_size
|
||||
gradient_intensity = config.gradient_intensity
|
||||
|
||||
_update_fog()
|
||||
_update_sky_material()
|
||||
set_stars_visibility(config.stars_visibility, config.stars_tint)
|
||||
Reference in New Issue
Block a user