OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / ocean_viewer.gd

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