feat(particles): bubble trail behind dolphin + block break burst
- BubbleTrail.gd: GPUParticles3D, auto-configured in _ready, set_intensity() API - BlockBreakParticles.gd: one_shot burst, emit_burst(pos, color) API - DolphinController.gd: bubble_trail onready + speed_factor hook in _update_movement - Dolphin.tscn: BubbleEmitterPoint (0,0,1.2) > BubbleTrail child added Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
47
scripts/ambience/CausticsLayer.gd
Normal file
47
scripts/ambience/CausticsLayer.gd
Normal file
@@ -0,0 +1,47 @@
|
||||
extends Node3D
|
||||
|
||||
# Creates horizontal caustic planes at multiple depths, follows the player
|
||||
# Add as child of any node that follows the player (e.g. PlanktonFollower)
|
||||
|
||||
const LAYER_DEPTHS := [-5.0, -15.0, -25.0]
|
||||
const LAYER_SIZE := 60.0
|
||||
|
||||
var caustic_meshes: Array[MeshInstance3D] = []
|
||||
var caustic_material: ShaderMaterial
|
||||
|
||||
func _ready() -> void:
|
||||
var shader := load("res://shaders/caustics.gdshader")
|
||||
if not shader:
|
||||
push_warning("CausticsLayer: caustics.gdshader not found")
|
||||
return
|
||||
|
||||
caustic_material = ShaderMaterial.new()
|
||||
caustic_material.shader = shader
|
||||
|
||||
for depth in LAYER_DEPTHS:
|
||||
var mi := MeshInstance3D.new()
|
||||
var plane := PlaneMesh.new()
|
||||
plane.size = Vector2(LAYER_SIZE, LAYER_SIZE)
|
||||
mi.mesh = plane
|
||||
# Each layer gets its own material instance to allow per-depth tuning
|
||||
var mat := caustic_material.duplicate() as ShaderMaterial
|
||||
# Lower layers = less intense
|
||||
var fade := clamp(1.0 + depth / 30.0, 0.0, 1.0)
|
||||
mat.set_shader_parameter("intensity", 1.5 * fade)
|
||||
mi.material_override = mat
|
||||
mi.position = Vector3(0.0, depth, 0.0)
|
||||
add_child(mi)
|
||||
caustic_meshes.append(mi)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
# Follow camera XZ, keep fixed Y depths
|
||||
var cam := get_viewport().get_camera_3d()
|
||||
if cam:
|
||||
var cx := cam.global_position.x
|
||||
var cz := cam.global_position.z
|
||||
for i in caustic_meshes.size():
|
||||
var mi := caustic_meshes[i]
|
||||
mi.global_position.x = cx
|
||||
mi.global_position.z = cz
|
||||
# Keep the fixed depth offset
|
||||
mi.global_position.y = LAYER_DEPTHS[i]
|
||||
31
scripts/ambience/GodraysOverlay.gd
Normal file
31
scripts/ambience/GodraysOverlay.gd
Normal file
@@ -0,0 +1,31 @@
|
||||
extends MeshInstance3D
|
||||
|
||||
var godrays_material: ShaderMaterial
|
||||
|
||||
func _ready() -> void:
|
||||
var quad := QuadMesh.new()
|
||||
quad.size = Vector2(20.0, 40.0)
|
||||
mesh = quad
|
||||
|
||||
godrays_material = ShaderMaterial.new()
|
||||
var shader := load("res://shaders/godrays.gdshader")
|
||||
if shader:
|
||||
godrays_material.shader = shader
|
||||
|
||||
var mat_override := godrays_material
|
||||
material_override = mat_override
|
||||
|
||||
# Position in front of camera, slightly above center
|
||||
position = Vector3(0.0, 5.0, -10.0)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if not godrays_material:
|
||||
return
|
||||
|
||||
# Get player/camera world Y to drive fade_bottom
|
||||
var cam := get_viewport().get_camera_3d()
|
||||
if cam:
|
||||
var world_y := cam.global_position.y
|
||||
# Deeper = fade bottom rises, reducing godray reach
|
||||
var dynamic_fade := clamp(world_y - 20.0, -100.0, 0.0)
|
||||
godrays_material.set_shader_parameter("fade_bottom", dynamic_fade)
|
||||
@@ -16,13 +16,24 @@ func _ready() -> void:
|
||||
env.fog_aerial_perspective = 0.3
|
||||
|
||||
env.volumetric_fog_enabled = true
|
||||
env.volumetric_fog_density = 0.04
|
||||
env.volumetric_fog_density = 0.05
|
||||
env.volumetric_fog_albedo = Color(0.2, 0.5, 0.7)
|
||||
env.volumetric_fog_emission = Color(0.02, 0.06, 0.1)
|
||||
env.volumetric_fog_emission_energy = 0.1
|
||||
env.volumetric_fog_length = 64.0
|
||||
env.volumetric_fog_detail_spread = 2.0
|
||||
|
||||
# Attach custom fog shader
|
||||
var fog_mat := FogMaterial.new()
|
||||
var fog_shader := load("res://shaders/underwater_fog.gdshader")
|
||||
if fog_shader:
|
||||
fog_mat.set_shader(fog_shader)
|
||||
|
||||
var fog_volume := FogVolume.new()
|
||||
fog_volume.size = Vector3(2000.0, 300.0, 2000.0)
|
||||
fog_volume.material = fog_mat
|
||||
add_child(fog_volume)
|
||||
|
||||
env.glow_enabled = true
|
||||
env.glow_intensity = 0.5
|
||||
env.glow_bloom = 0.1
|
||||
|
||||
Reference in New Issue
Block a user