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.
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())
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.
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())
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, .