@tool
extends Node3D
## Phase 8: proc-nodes / dc-terrain integration test
##
## Side-by-side comparison:
## Left: DCTerrain with ProcTerrainGenerator (GDScript density function)
## Right: ProcGeometryNode with MeshGrid+Displace (proc-nodes mesh generation)
##
## Setup:
## 1. Create a Node3D scene, attach this script
## 2. Add a DCTerrain child named "DCTerrain"
## 3. Add a ProcGeometryNode child named "ProcTerrain"
## 4. Run the scene — this script configures both
@export var spacing: float = 60.0
@export_group("DC Terrain (Script Generator)")
@export var dc_terrain_size: float = 64.0
@export var dc_voxel_size: float = 0.5
@export var dc_octree_depth: int = 4
@export_group("Proc-Nodes Terrain (MeshGrid + Displace)")
@export var proc_grid_size: float = 50.0
@export var proc_grid_resolution: int = 300
@export var proc_noise_strength: float = 8.0
@export var proc_noise_scale: float = 0.05
@export var proc_noise_octaves: int = 6
@export_group("Actions")
@export var rebuild: bool = false:
set(v):
if v:
_setup()
rebuild = false
func _ready() -> void:
call_deferred("_setup")
func _setup() -> void:
_setup_dc_terrain()
_setup_proc_terrain()
print("Phase 8 test: DC terrain (left) vs proc-nodes terrain (right)")
func _setup_dc_terrain() -> void:
var dc = get_node_or_null("DCTerrain")
if not dc:
push_warning("proc_nodes_terrain_test: add a DCTerrain child named 'DCTerrain'")
return
# Position on the left
dc.position.x = -spacing * 0.5
# Assign the ProcTerrainGenerator resource
var gen = ProcTerrainGenerator.new()
gen.ground_height = 0.0
gen.primary_frequency = 0.02
gen.primary_amplitude = 15.0
gen.primary_octaves = 4
gen.detail_frequency = 0.08
gen.detail_amplitude = 3.0
gen.ridge_enabled = true
gen.ridge_frequency = 0.015
gen.ridge_amplitude = 20.0
dc.generator = gen
# Configure terrain parameters
dc.terrain_size = dc_terrain_size
dc.voxel_size = dc_voxel_size
dc.octree_depth = dc_octree_depth
dc.use_noise = false # We're using the script generator, not built-in noise
dc.rebuild()
print(" DC terrain: script generator, size=", dc_terrain_size, " voxel=", dc_voxel_size)
func _setup_proc_terrain() -> void:
var proc = get_node_or_null("ProcTerrain")
if not proc:
push_warning("proc_nodes_terrain_test: add a ProcGeometryNode child named 'ProcTerrain'")
return
# Position on the right
proc.position.x = spacing * 0.5
# Build proc-nodes graph: MeshGrid -> Displace
var g = ProcNodeGraph.new()
# 0: Grid
var grid = MeshGridNode.new()
g.add_node(grid)
# 1-2: Grid size
var sx = ValueNode.new()
sx.value = proc_grid_size
g.add_node(sx)
var sy = ValueNode.new()
sy.value = proc_grid_size
g.add_node(sy)
# 3-4: Grid resolution
var vx = ValueNode.new()
vx.value = float(proc_grid_resolution)
g.add_node(vx)
var vy = ValueNode.new()
vy.value = float(proc_grid_resolution)
g.add_node(vy)
# 5: Displace (noise-based terrain displacement)
var displace = DisplaceNode.new()
g.add_node(displace)
# 6-9: Noise parameters
var strength = ValueNode.new()
strength.value = proc_noise_strength
g.add_node(strength)
var nscale = ValueNode.new()
nscale.value = proc_noise_scale
g.add_node(nscale)
var ndetail = ValueNode.new()
ndetail.value = float(proc_noise_octaves)
g.add_node(ndetail)
var nrough = ValueNode.new()
nrough.value = 0.5
g.add_node(nrough)
# Connections
g.connect_sockets(1, 0, 0, 0) # sx -> grid.SizeX
g.connect_sockets(2, 0, 0, 1) # sy -> grid.SizeY
g.connect_sockets(3, 0, 0, 2) # vx -> grid.VertsX
g.connect_sockets(4, 0, 0, 3) # vy -> grid.VertsY
g.connect_sockets(0, 0, 5, 0) # grid -> displace.geometry
g.connect_sockets(6, 0, 5, 1) # strength -> displace.strength
g.connect_sockets(7, 0, 5, 2) # scale -> displace.scale
g.connect_sockets(8, 0, 5, 3) # detail -> displace.detail
g.connect_sockets(9, 0, 5, 4) # roughness -> displace.roughness
proc.graph = g
var verts = proc_grid_resolution * proc_grid_resolution
print(" Proc terrain: MeshGrid+Displace, ", verts, " verts, GPU-accelerated")
# Apply terrain material
call_deferred("_apply_proc_material")
func _apply_proc_material() -> void:
var proc = get_node_or_null("ProcTerrain")
if not proc:
return
var mesh_child = proc.get_node_or_null("MeshOutput")
if mesh_child and mesh_child is MeshInstance3D:
var mat = StandardMaterial3D.new()
mat.albedo_color = Color(0.35, 0.5, 0.3)
mat.roughness = 0.8
mesh_child.material_override = mat