OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / proc_nodes_gpu_test.gd

134 lines · gd ref:
@tool
extends ProcGeometryNode

## GPU compute test for proc-nodes Phase 4
## Toggle use_gpu in inspector to compare GPU vs CPU timing.
## Grid resolution/size changes rebuild the entire graph.
## Noise parameter changes update ValueNodes in place (no graph rebuild).

@export var grid_resolution: int = 500:
	set(v):
		grid_resolution = v
		_rebuild()

@export var grid_size: float = 20.0:
	set(v):
		grid_size = v
		_rebuild()

@export var noise_strength: float = 2.0:
	set(v):
		noise_strength = v
		_update_noise_param(_val_strength, v)

@export var noise_scale: float = 0.3:
	set(v):
		noise_scale = v
		_update_noise_param(_val_scale, v)

@export var noise_octaves: int = 6:
	set(v):
		noise_octaves = v
		_update_noise_param(_val_detail, float(v))

@export var noise_roughness: float = 0.5:
	set(v):
		noise_roughness = v
		_update_noise_param(_val_roughness, v)

var _ready_done := false

# Cached ValueNode references (avoid full graph rebuild for param tweaks)
var _val_strength: ValueNode
var _val_scale: ValueNode
var _val_detail: ValueNode
var _val_roughness: ValueNode

func _ready():
	_ready_done = true
	_rebuild()
	call_deferred("_apply_material")

func _apply_material():
	var mesh_child = 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

func _update_noise_param(val_node: ValueNode, new_value: float):
	if val_node:
		val_node.value = new_value
		mark_dirty()
	else:
		_rebuild()

func _rebuild():
	if not _ready_done:
		return
	var verts = grid_resolution * grid_resolution
	print("--- proc-nodes: rebuilding ", grid_resolution, "x", grid_resolution, " = ", verts, " verts ---")
	self.graph = _create_graph()

func _create_graph() -> ProcNodeGraph:
	var g = ProcNodeGraph.new()

	# 0: Grid
	var grid = MeshGridNode.new()
	g.add_node(grid)

	# 1-2: Grid size
	var sx = ValueNode.new()
	sx.value = grid_size
	g.add_node(sx)
	var sy = ValueNode.new()
	sy.value = grid_size
	g.add_node(sy)

	# 3-4: Grid resolution
	var vx = ValueNode.new()
	vx.value = float(grid_resolution)
	g.add_node(vx)
	var vy = ValueNode.new()
	vy.value = float(grid_resolution)
	g.add_node(vy)

	# 5: Displace
	var displace = DisplaceNode.new()
	g.add_node(displace)

	# 6-9: Noise params — cache references for in-place updates
	var strength = ValueNode.new()
	strength.value = noise_strength
	g.add_node(strength)
	_val_strength = strength

	var nscale = ValueNode.new()
	nscale.value = noise_scale
	g.add_node(nscale)
	_val_scale = nscale

	var ndetail = ValueNode.new()
	ndetail.value = float(noise_octaves)
	g.add_node(ndetail)
	_val_detail = ndetail

	var nrough = ValueNode.new()
	nrough.value = noise_roughness
	g.add_node(nrough)
	_val_roughness = 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

	return g