extends SceneTree
## INTERACTIVE view of the water shader ALONE -- no terrain, no map.
##
## Everything about this ocean so far has been judged through screenshots of a
## whole world, where a wrong wave and a wrong colour and a mesh too coarse to
## carry either all look the same. This is just the sheet, a sun and a sky.
##
## DISPLAY=:0 "$HYPER_TPS_GODOT" --path . --rendering-driver vulkan \
## --script res://scenes/test/ocean_viewer.gd
##
## W A S D move Q / E down / up SHIFT 10x speed
## arrows look V debug channel R reset
## [ / ] normal_strength - / = wave scale
## , / . roughness P print all parameters ESC quit
var _ocean
var _cam: Camera3D
var _mat: ShaderMaterial
var _yaw := 0.0
var _pitch := -8.0
var _debug := 0
var _wave_scale := 1.0
var _held := {}
func _initialize() -> void:
_ocean = Ocean.new()
_ocean.water_y = 0.0
root.add_child(_ocean)
_cam = Camera3D.new()
_cam.position = Vector3(0, 25, 0)
_cam.far = 40000.0
_cam.current = true
root.add_child(_cam)
var sun := DirectionalLight3D.new()
sun.rotation_degrees = Vector3(-25, 140, 0)
sun.light_energy = 1.2
root.add_child(sun)
var we := WorldEnvironment.new()
var e := Environment.new()
e.background_mode = Environment.BG_SKY
var sky := Sky.new(); sky.sky_material = ProceduralSkyMaterial.new()
e.sky = sky
e.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
e.reflected_light_source = Environment.REFLECTION_SOURCE_SKY
e.tonemap_mode = Environment.TONE_MAPPER_FILMIC
we.environment = e
root.add_child(we)
var w := root.get_window()
if w:
w.size = Vector2i(1440, 900)
w.title = "ocean — shader only"
print("VIEWER: WASD/QE move · arrows look · V debug · [ ] normals · - = waves · , . roughness · P print · ESC quit")
func _process(dt: float) -> bool:
if Input.is_key_pressed(KEY_ESCAPE):
quit(0); return true
if _mat == null:
_mat = _ocean.material_override as ShaderMaterial
if _mat == null: return false
var look := 70.0 * dt
if Input.is_key_pressed(KEY_LEFT): _yaw += look
if Input.is_key_pressed(KEY_RIGHT): _yaw -= look
if Input.is_key_pressed(KEY_UP): _pitch = clampf(_pitch + look, -89.0, 89.0)
if Input.is_key_pressed(KEY_DOWN): _pitch = clampf(_pitch - look, -89.0, 89.0)
_cam.rotation_degrees = Vector3(_pitch, _yaw, 0.0)
var speed := (300.0 if Input.is_key_pressed(KEY_SHIFT) else 30.0) * dt
var b := _cam.global_transform.basis
var move := Vector3.ZERO
if Input.is_key_pressed(KEY_W): move -= b.z
if Input.is_key_pressed(KEY_S): move += b.z
if Input.is_key_pressed(KEY_A): move -= b.x
if Input.is_key_pressed(KEY_D): move += b.x
if Input.is_key_pressed(KEY_E): move += Vector3.UP
if Input.is_key_pressed(KEY_Q): move -= Vector3.UP
_cam.global_position += move * speed
if Input.is_key_pressed(KEY_R):
_cam.global_position = Vector3(0, 25, 0); _yaw = 0.0; _pitch = -8.0
_edge(KEY_V, func():
_debug = (_debug + 1) % 6
_mat.set_shader_parameter(&'ocean_debug', _debug)
print(" debug channel %d (%s)" % [_debug,
["shaded", "normal", "foam", "wave height", "depth", "fresnel"][_debug]]))
_edge(KEY_BRACKETLEFT, func(): _nudge(&'normal_strength', -0.1, 0.0, 1.0))
_edge(KEY_BRACKETRIGHT, func(): _nudge(&'normal_strength', 0.1, 0.0, 1.0))
_edge(KEY_COMMA, func(): _nudge(&'roughness', -0.05, 0.0, 1.0))
_edge(KEY_PERIOD, func(): _nudge(&'roughness', 0.05, 0.0, 1.0))
_edge(KEY_MINUS, func(): _scale_waves(0.8))
_edge(KEY_EQUAL, func(): _scale_waves(1.25))
_edge(KEY_P, func():
print(" cam %s normal_strength %.2f roughness %.2f wave_scale %.2f"
% [str(_cam.global_position.round()),
_param(&'normal_strength', 1.0), _param(&'roughness', 0.4), _wave_scale]))
return false
func _param(n: StringName, dflt: float) -> float:
var v = _mat.get_shader_parameter(n)
return dflt if v == null else float(v)
func _nudge(n: StringName, d: float, lo: float, hi: float) -> void:
var v := clampf(_param(n, 0.5) + d, lo, hi)
_mat.set_shader_parameter(n, v)
print(" %s = %.2f" % [n, v])
func _scale_waves(f: float) -> void:
_wave_scale *= f
var scales: PackedVector4Array = _mat.get_shader_parameter(&'map_scales')
for i in scales.size():
var s := scales[i]
scales[i] = Vector4(s.x, s.y, s.z * f, s.w)
_mat.set_shader_parameter(&'map_scales', scales)
print(" wave displacement scale x%.2f" % _wave_scale)
func _edge(key: int, fn: Callable) -> void:
var down: bool = Input.is_key_pressed(key)
if down and not _held.get(key, false): fn.call()
_held[key] = down