Entity renderer: add framerate-independent position lerping so entities slide between tiles instead of snapping. Tuned for Sprint snappiness and Walk/Careful fluidity. Fog shader: set ColorRect to transparent fallback so a shader load failure doesn't paint solid white over the world. Track camera position (not player position) so fog stays synced during smooth camera pan. Restructure GLSL to avoid early return (some GPU drivers miscompile it). Minor type fixes: typed Array[Vector2] in cursor_renderer tick drawing, untyped Array in inventory_grid to avoid Godot typed-array cast issues. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
72 lines
2.7 KiB
GDScript
72 lines
2.7 KiB
GDScript
extends Node2D
|
|
|
|
## Fog overlay controller — manages ColorRect + shader uniforms for D-059 fog.
|
|
## Reads textures from FogState autoload, positions rect to cover viewport.
|
|
## Architecture: docs/architecture/fog-shader-spec.md
|
|
|
|
var _fog_rect: ColorRect
|
|
var _shader_mat: ShaderMaterial
|
|
|
|
const TILE_SIZE := float(Constants.TILE_SIZE)
|
|
|
|
|
|
func _ready() -> void:
|
|
# Create the fog overlay ColorRect — transparent fallback so a shader failure
|
|
# doesn't paint solid white over the entire world (z:900 covers everything).
|
|
_fog_rect = ColorRect.new()
|
|
_fog_rect.name = "FogRect"
|
|
_fog_rect.color = Color.TRANSPARENT
|
|
add_child(_fog_rect)
|
|
|
|
# Load shader and create material
|
|
var shader := load("res://shaders/fog.gdshader") as Shader
|
|
if shader == null:
|
|
push_error("FogShader: failed to load res://shaders/fog.gdshader — fog disabled")
|
|
return
|
|
_shader_mat = ShaderMaterial.new()
|
|
_shader_mat.shader = shader
|
|
_fog_rect.material = _shader_mat
|
|
|
|
# Create seamless noise texture for fog animation
|
|
var noise := FastNoiseLite.new()
|
|
noise.noise_type = FastNoiseLite.TYPE_PERLIN
|
|
noise.frequency = 0.03
|
|
var noise_tex := NoiseTexture2D.new()
|
|
noise_tex.noise = noise
|
|
noise_tex.width = 256
|
|
noise_tex.height = 256
|
|
noise_tex.seamless = true
|
|
_shader_mat.set_shader_parameter("noise_tex", noise_tex)
|
|
_shader_mat.set_shader_parameter("tile_size", TILE_SIZE)
|
|
|
|
print("FogShader: Initialized (D-059 5-layer)")
|
|
|
|
|
|
func update_fog() -> void:
|
|
if _shader_mat == null:
|
|
return # Shader failed to load — fog disabled
|
|
|
|
# 1. Update FogState textures from GameState
|
|
FogState.update_from_state()
|
|
|
|
# 2. Position ColorRect to cover the current viewport.
|
|
# Use the camera's actual position (not player position) so the fog rect
|
|
# tracks the smoothed camera and never desynchronizes during smooth pan.
|
|
var vp_size := get_viewport().get_visible_rect().size
|
|
var cam := get_viewport().get_camera_2d()
|
|
var zoom := cam.zoom if cam else Vector2(2.0, 2.0)
|
|
var camera_pos := cam.global_position if cam else GameState.player_position * TILE_SIZE
|
|
var half_view := vp_size / (2.0 * zoom)
|
|
_fog_rect.position = camera_pos - half_view
|
|
_fog_rect.size = vp_size / zoom
|
|
|
|
# 3. Update shader uniforms
|
|
_shader_mat.set_shader_parameter("visibility_tex", FogState.visibility_texture)
|
|
_shader_mat.set_shader_parameter("exploration_tex", FogState.exploration_texture)
|
|
_shader_mat.set_shader_parameter("zone_tint_tex", FogState.zone_tint_texture)
|
|
_shader_mat.set_shader_parameter("rect_pos", _fog_rect.position)
|
|
_shader_mat.set_shader_parameter("rect_sz", _fog_rect.size)
|
|
_shader_mat.set_shader_parameter("map_offset", Vector2(FogState.map_bounds.position))
|
|
_shader_mat.set_shader_parameter("map_size", Vector2(FogState.map_bounds.size))
|
|
_shader_mat.set_shader_parameter("time", Time.get_ticks_msec() / 1000.0)
|