Godot 3 to 4 rename

VisualShaderNodeScalarClamp in Godot 4: it is VisualShaderNodeClamp now

VisualShaderNodeScalarClamp is VisualShaderNodeClamp in Godot 4.7.2. Godot 3's scalar and vector clamp nodes are one node now, and its op_type picks float, int, uint or a 2D, 3D or 4D vector.

What Godot prints

A Godot 3 script that builds a float clamp node for a visual shader in code.

repro.gd
extends Node

func _ready():
	var shader = VisualShader.new()
	var clamp_node = VisualShaderNodeScalarClamp.new()
	shader.add_node(VisualShader.TYPE_FRAGMENT, clamp_node, Vector2(0, 0), 2)
	print(shader.get_code())
Output, Godot 4.7.2
Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

SCRIPT ERROR: Parse Error: Identifier "VisualShaderNodeScalarClamp" not declared in the current scope. Did you mean to use "VisualShaderNodeClamp"?
   at: GDScript::reload (res://answers/visualshadernodescalarclamp-in-godot-4/repro.gd:5)
ERROR: Failed to load script "res://answers/visualshadernodescalarclamp-in-godot-4/repro.gd" with error "Parse error".
   at: load (modules/gdscript/gdscript_resource_format.cpp:46)

The fix

One VisualShaderNodeClamp, set to floats with op_type, between a float parameter and the fragment output. The fix prints the lines of generated shader code that clamp.

fix.gd
extends Node

func _ready() -> void:
	var shader := VisualShader.new()
	var strength := VisualShaderNodeFloatParameter.new()
	strength.parameter_name = "strength"
	shader.add_node(VisualShader.TYPE_FRAGMENT, strength, Vector2(0, 0), 2)
	var clamp_node := VisualShaderNodeClamp.new()
	clamp_node.op_type = VisualShaderNodeClamp.OP_TYPE_FLOAT
	shader.add_node(VisualShader.TYPE_FRAGMENT, clamp_node, Vector2(200, 0), 3)
	shader.connect_nodes(VisualShader.TYPE_FRAGMENT, 2, 0, 3, 0)
	shader.connect_nodes(VisualShader.TYPE_FRAGMENT, 3, 0, 0, 0)
	for line in shader.get_code().split("\n"):
		if "clamp(" in line or line.begins_with("uniform"):
			print(line.strip_edges())
Output, Godot 4.7.2
Godot Engine v4.7.2.stable.mono.official.ed1daf0bf - https://godotengine.org

uniform float strength;
float n_out3p0 = clamp(n_out2p0, n_in3p1, n_in3p2);

Why it happens

GDScript's analyzer resolves every identifier when the script loads. VisualShaderNodeScalarClamp is not a class in Godot 4.7.2, so the script fails to parse and Godot does not load it. The editor build adds the new name from Godot's 3 to 4 rename table: Did you mean to use "VisualShaderNodeClamp"?

The table maps both VisualShaderNodeScalarClamp and VisualShaderNodeVectorClamp to VisualShaderNodeClamp.

VisualShaderNodeClamp constrains a value to lie between its min and max inputs. Its op_type is one of OP_TYPE_FLOAT, OP_TYPE_INT, OP_TYPE_UINT, OP_TYPE_VECTOR_2D, OP_TYPE_VECTOR_3D and OP_TYPE_VECTOR_4D.

Set to floats and connected between a float parameter and the fragment output, the node generated one call to clamp() in the shader code, with the parameter's value as its first argument.

Sources

Run on Godot 4.7.2, .

Related