@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