## High-altitude cirrus cloud layer with abs-noise fBM and curl warp.
class_name CirrusLayer
extends CloudLayer
const CLOUD_CIRRUS_SHADER = preload("res://addons/sky3d_extended/shaders/cloud_cirrus.gdshader")
var _mesh: MeshInstance3D
var _material: ShaderMaterial
var altitude: float = 3000.0
var coverage: float = 0.55
var uv_stretch: float = 5.0
var curl_strength: float = 0.6
var octaves: int = 4
var persistence: float = 0.45
var lacunarity: float = 2.5
## Wind multiplier relative to main layer
var wind_multiplier: float = 2.5
func _init() -> void:
name = "Cirrus"
func get_params() -> Array[Dictionary]:
return [
{"name": "coverage", "min": 0.0, "max": 1.0, "step": 0.01, "value": coverage},
{"name": "uv_stretch", "min": 1.0, "max": 8.0, "step": 0.1, "value": uv_stretch},
{"name": "curl_strength", "min": 0.0, "max": 2.0, "step": 0.01, "value": curl_strength},
{"name": "octaves", "min": 2.0, "max": 8.0, "step": 1.0, "value": float(octaves)},
{"name": "persistence", "min": 0.2, "max": 0.7, "step": 0.01, "value": persistence},
{"name": "lacunarity", "min": 1.5, "max": 4.0, "step": 0.1, "value": lacunarity},
{"name": "wind_multiplier", "min": 0.5, "max": 5.0, "step": 0.1, "value": wind_multiplier},
]
func set_param(param_name: String, value: float) -> void:
match param_name:
"coverage":
coverage = value
if _material:
_material.set_shader_parameter("coverage", value)
"uv_stretch":
uv_stretch = value
if _material:
_material.set_shader_parameter("uv_stretch", value)
"curl_strength":
curl_strength = value
if _material:
_material.set_shader_parameter("curl_strength", value)
"octaves":
octaves = int(value)
if _material:
_material.set_shader_parameter("octaves", octaves)
"persistence":
persistence = value
if _material:
_material.set_shader_parameter("persistence", value)
"lacunarity":
lacunarity = value
if _material:
_material.set_shader_parameter("lacunarity", value)
"wind_multiplier":
wind_multiplier = value
func get_param(param_name: String) -> float:
match param_name:
"coverage": return coverage
"uv_stretch": return uv_stretch
"curl_strength": return curl_strength
"octaves": return float(octaves)
"persistence": return persistence
"lacunarity": return lacunarity
"wind_multiplier": return wind_multiplier
return 0.0
func create(parent: Node3D) -> void:
_mesh = MeshInstance3D.new()
_mesh.name = "CloudLayer_Cirrus"
var plane := PlaneMesh.new()
plane.size = Vector2(100000, 100000)
plane.subdivide_width = 128
plane.subdivide_depth = 128
_mesh.mesh = plane
_mesh.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
_material = ShaderMaterial.new()
_material.shader = CLOUD_CIRRUS_SHADER
_material.render_priority = -2 # Behind main clouds
_mesh.material_override = _material
_mesh.position.y = altitude
parent.add_child(_mesh)
_material.set_shader_parameter("coverage", coverage)
_material.set_shader_parameter("uv_stretch", uv_stretch)
_material.set_shader_parameter("curl_strength", curl_strength)
_material.set_shader_parameter("octaves", octaves)
_material.set_shader_parameter("persistence", persistence)
_material.set_shader_parameter("lacunarity", lacunarity)
func destroy() -> void:
if is_instance_valid(_mesh):
_mesh.queue_free()
_mesh = null
_material = null
func update(shared: CloudSharedState, delta: float) -> void:
if not _mesh:
return
_mesh.global_position = Vector3(shared.camera_pos.x, altitude, shared.camera_pos.z)
if _material:
_material.set_shader_parameter("wind_offset", shared.wind_offset * wind_multiplier)
func update_lighting(shared: CloudSharedState) -> void:
if not _material:
return
_material.set_shader_parameter("sun_direction", shared.sun_direction)
_material.set_shader_parameter("sun_color", shared.sun_color)
_material.set_shader_parameter("sun_energy", shared.sun_energy)
_material.set_shader_parameter("moon_direction", shared.moon_direction)
_material.set_shader_parameter("moon_energy", shared.moon_energy)
func set_visible(value: bool) -> void:
if _mesh:
_mesh.visible = value