OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / addons / sky3d_extended / src / cloud_layers / cirrus_layer.gd

130 lines · gd ref:
## 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