OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / dc_terrain_depth7_test.gd

101 lines · gd ref:
@tool
extends Node3D

## Depth-7 terrain: three scales of self-similar mountains + erosion detail.
##
## Same erosion graph as proc_erosion_dc_test (identical gully detail).
## Layered on the adapter's mountain_layer (fractal_noise_2d) with parameters
## tuned for three distinct scales of structure:
##
##   Scale 1 (mega): ~270m ridges (mountain_scale=0.11, base octave)
##   Scale 2 (large): ~135m ridges (fractal octave 2)
##   Scale 3 (medium): ~67m ridges (fractal octave 3)
##   Scale 4 (small): ~34m ridges (fractal octave 4)
##   Erosion detail: ~10m gullies (GradientNoise + ErosionNoise)

var _gen: DCTerrainGeneratorProcNodes

func _ready():
	var terrain = get_node_or_null("DCTerrain")
	if terrain == null:
		push_warning("dc_terrain_depth7_test: no DCTerrain child")
		return

	# Same erosion graph as proc_erosion_dc_test — identical detail pattern
	var g = ProcNodeGraph.new()

	var noise = g.add_node(GradientNoiseNode.new())
	g.get_node(noise).set_input_default(1, 3.0)  # Scale (same as erosion test)
	g.get_node(noise).set_input_default(2, 3)     # Detail (same)
	g.get_node(noise).set_input_default(3, 0.1)   # Gain (same)

	var erosion = g.add_node(ErosionNoiseNode.new())
	g.get_node(erosion).set_input_default(1, 5.0)   # HeightScale (same)
	g.get_node(erosion).set_input_default(2, 0.16)   # ErosionStr (same)
	g.get_node(erosion).set_input_default(3, 0.6)    # SlopePower (same)
	g.get_node(erosion).set_input_default(4, 1.0)    # CellScale (same)
	g.get_node(erosion).set_input_default(5, 5)      # Octaves (same)
	g.get_node(erosion).set_input_default(6, 0.5)    # Gain (same)

	g.connect_sockets(noise, 0, erosion, 7)  # Height
	g.connect_sockets(noise, 1, erosion, 8)  # Slope

	_gen = DCTerrainGeneratorProcNodes.new()

	# terrain_height=30: erosion pattern 3x wider than the 10m test
	_gen.set_terrain_height(30.0)

	# Mountain layer — self-similar structure via many octaves, low amplitude:
	#
	# Mountain layer: large-scale structure the erosion rides on top of
	# mountain_scale=0.33: one mountain ridge per ~90m (30m / 0.33)
	# mountain_height=1.2: mountains displace 1.2x the erosion range
	# mountain_octaves=3: self-similar ridges at 90m, 45m, 22m
	_gen.set_mountain_scale(0.33)
	_gen.set_mountain_height(1.2)
	_gen.set_mountain_octaves(3)

	# Y range: accommodate mountain peaks + erosion on top
	_gen.set_floor_y(-15.0)
	_gen.set_ceiling_y(25.0)

	_gen.set_graph(g)

	var glsl = g.compile_to_glsl_function("terrain_density", true)
	if glsl.contains("erosion_filter"):
		print("[Depth7] PASS: Compiled ", glsl.length(), " chars of GLSL")
	else:
		print("[Depth7] FAIL: GLSL missing erosion functions")
		return

	# Terrain config
	var vs: float = 0.25
	var depth: int = 7

	terrain.set("voxel_size", vs)
	terrain.set("octree_depth", depth)
	terrain.set("use_gpu", true)
	terrain.set("use_noise", true)
	terrain.set("debug_logging", false)
	terrain.set("generator", _gen)

	# Altitude color shader — tighter range around the typical surface
	# to make erosion coloring visible.
	# The erosion surface sits at roughly HeightScale * 0.5 = 2.5 above the
	# mountain offset. Map colors to a range that resolves the gullies.
	var shader = load("res://scenes/maps/dc_erosion_color.gdshader") as Shader
	if shader:
		var mat = ShaderMaterial.new()
		mat.shader = shader
		# Use the full Y range for color mapping so altitude bands track
		# the mountain elevation. Water at 40% of range.
		mat.set_shader_parameter("terrain_params", Vector3(-15.0, 25.0, 0.47))
		terrain.set("custom_material", mat)
		print("[Depth7] Applied altitude color shader")

	var half_ext: float = (1 << (depth - 1)) * 28 * vs
	print("[Depth7] voxel=", vs, " depth=", depth,
		" half_extent=", half_ext, "m (", half_ext * 2, "m total)",
		" mountains: scale=0.11 height=3.6 octaves=4",
		" Y range: [-15, 25]")