@tool class_name ProceduralCloudTexture extends Resource @export var size: int = 512 @export var octaves: int = 6 @export var persistence: float = 0.5 @export var lacunarity: float = 2.0 @export var scale: float = 4.0 @export var seed_value: int = 0 @export var cloud_threshold: float = 0.4 @export var cloud_softness: float = 0.3 var _noise: FastNoiseLite var _texture: ImageTexture func _init() -> void: _setup_noise() func _setup_noise() -> void: _noise = FastNoiseLite.new() _noise.noise_type = FastNoiseLite.TYPE_SIMPLEX _noise.seed = seed_value _noise.frequency = 1.0 / (scale * 64.0) _noise.fractal_type = FastNoiseLite.FRACTAL_FBM _noise.fractal_octaves = octaves _noise.fractal_lacunarity = lacunarity _noise.fractal_gain = persistence func generate() -> ImageTexture: _setup_noise() var image := Image.create(size, size, false, Image.FORMAT_RGBA8) for y in size: for x in size: var noise_value := (_noise.get_noise_2d(float(x), float(y)) + 1.0) * 0.5 var cloud_value := smoothstep(cloud_threshold - cloud_softness, cloud_threshold + cloud_softness, noise_value) var color := Color(cloud_value, cloud_value, cloud_value, cloud_value) image.set_pixel(x, y, color) _texture = ImageTexture.create_from_image(image) return _texture func get_texture() -> ImageTexture: if _texture == null: return generate() return _texture static func create_default_cloud_texture(layer_type: int = 0) -> ImageTexture: var generator := ProceduralCloudTexture.new() generator.size = 512 match layer_type: 0: # Low clouds - larger, denser generator.scale = 3.0 generator.octaves = 4 generator.cloud_threshold = 0.35 generator.cloud_softness = 0.25 1: # Mid clouds - medium generator.scale = 4.0 generator.octaves = 5 generator.cloud_threshold = 0.4 generator.cloud_softness = 0.3 2: # High clouds - wispy generator.scale = 6.0 generator.octaves = 6 generator.cloud_threshold = 0.5 generator.cloud_softness = 0.35 3: # Wisps - very thin generator.scale = 8.0 generator.octaves = 7 generator.cloud_threshold = 0.55 generator.cloud_softness = 0.4 return generator.generate() static func create_shadow_texture() -> ImageTexture: var generator := ProceduralCloudTexture.new() generator.size = 256 generator.scale = 4.0 generator.octaves = 4 generator.cloud_threshold = 0.3 generator.cloud_softness = 0.4 return generator.generate()