Cryptic error when converting Visual Shader plugin example from official documentation

Godot Version

4.3 rc3

Question

So I took this official code example and converted it to use this algorithm, but I get these errors.

I suspect it’s in the final line of the script, because if I just put the quoted parts into a .gdshader they work, but does anyone know what’s wrong with it?

# https://github.com/patriciogonzalezvivo/lygia/blob/main/generative/snoise.glsl
@tool
extends VisualShaderNodeCustom
class_name VisualShaderNodeSimplexNoise3D
 
 
func _get_name():
    return "SimplexNoise3D"
 
 
func _get_category():
    return "LygiaShaderNodes"
 
 
func _get_description():
    return "Simplex Noise 3D function (by Stefan Gustavson, Ian McEwan)"
 
 
func _init():
    set_input_port_default_value(0, Vector3(0, 0, 0))
 
 
func _get_return_icon_type():
    return VisualShaderNode.PORT_TYPE_VECTOR_3D
 
 
func _get_input_port_count():
    return 1
 
 
func _get_input_port_name(port):
    return "position"
 
 
func _get_input_port_type(port):
    return VisualShaderNode.PORT_TYPE_VECTOR_3D
 
 
func _get_output_port_count():
    return 1
 
 
func _get_output_port_name(port):
    return "result"
 
 
func _get_output_port_type(port):
    return VisualShaderNode.PORT_TYPE_VECTOR_3D
 
 
func _get_global_code(mode):
    return """
        vec3 mod289_3(vec3 x) {
            return x - floor(x * (1.0 / 289.0)) * 289.0;
        }
 
        vec4 mod289_4(vec4 x) {
            return x - floor(x * (1.0 / 289.0)) * 289.0;
        }
 
        vec4 permute(vec4 x) {
            return mod289_4(((x * 34.0) + 1.0) * x);
        }
 
        vec4 taylorInvSqrt(vec4 r) {
            return 1.79284291400159 - 0.85373472095314 * r;
        }

 
        float snoise(vec3 v) {
            const vec2 C = vec2(1.0/6.0, 1.0/3.0);
            const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
 
            // First corner
            vec3 i  = floor(v + dot(v, C.yyy));
            vec3 x0 = v - i + dot(i, C.xxx);
 
            // Other corners
            vec3 g = step(x0.yzx, x0.xyz);
            vec3 l = 1.0 - g;
            vec3 i1 = min(g.xyz, l.zxy);
            vec3 i2 = max(g.xyz, l.zxy);
 
            vec3 x1 = x0 - i1 + C.xxx;
            vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
            vec3 x3 = x0 - D.yyy;      // -1.0+3.0*C.x = -0.5 = -D.y
 
            // Permutations
            i = mod289_3(i);
            vec4 p = permute(permute(permute(i.z + vec4(0.0, i1.z, i2.z, 1.0))
            + i.y + vec4(0.0, i1.y, i2.y, 1.0))
            + i.x + vec4(0.0, i1.x, i2.x, 1.0));
 
            // Gradients: 7x7 points over a square, mapped onto an octahedron.
            // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
            float n_ = 0.142857142857; // 1.0/7.0
            vec3  ns = n_ * D.wyz - D.xzx;
 
            vec4 j = p - 49.0 * floor(p * ns.z * ns.z);  //  mod(p,7*7)
 
            vec4 x_ = floor(j * ns.z);
            vec4 y_ = floor(j - 7.0 * x_);    // mod(j,N)
 
            vec4 x = x_ * ns.x + ns.yyyy;
            vec4 y = y_ * ns.x + ns.yyyy;
            vec4 h = 1.0 - abs(x) - abs(y);
 
            vec4 b0 = vec4(x.xy, y.xy);
            vec4 b1 = vec4(x.zw, y.zw);
 
            vec4 s0 = floor(b0) * 2.0 + 1.0;
            vec4 s1 = floor(b1) * 2.0 + 1.0;
            vec4 sh = -step(h, vec4(0.0));
 
            vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
            vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
 
            vec3 p0 = vec3(a0.xy,h.x);
            vec3 p1 = vec3(a0.zw,h.y);
            vec3 p2 = vec3(a1.xy,h.z);
            vec3 p3 = vec3(a1.zw,h.w);
 
            //Normalise gradients
            vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
            p0 *= norm.x;
            p1 *= norm.y;
            p2 *= norm.z;
            p3 *= norm.w;
 
            // Mix final noise value
            vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
            m = m * m;
            return 42.0 * dot(m * m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));
        }
    """
 
 
func _get_code(input_vars, output_vars, mode, type):
    return output_vars[0] + " = vec3(snoise(vec3(%s)), snoise(vec3(%s.y - 19.1, %s.z + 33.4, %s.x + 47.2)), snoise(vec3(%s.z + 74.2, %s.x - 124.5, %s.y + 99.4)));" % [input_vars[0]]

Ok, I think the last line should be this:

return output_vars[0] + " = vec3(snoise(vec3(%s)), snoise(vec3(%s.y - 19.1, %s.z + 33.4, %s.x + 47.2)), snoise(vec3(%s.z + 74.2, %s.x - 124.5, %s.y + 99.4)));" % [input_vars[0],input_vars[0],input_vars[0],input_vars[0],input_vars[0],input_vars[0],input_vars[0]]

…because I get something showing up in the viewport now… but the error is not going away for some reason…

Weird… in the first shader I created, I can use the custom node despite, errors… but when I try to use it in different shaders, I get all sorts of new errors and they don’t work…

res://materials/noisetestshader.tres:39 - No matching function found for: 'snoise'.

Node not found: "37" (relative to "/root/@EditorNode@16879/@Panel@13/@VBoxContainer@14/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@25/DockVSplitCenter/@EditorBottomPanel@6653/@VBoxContainer@6642/@WindowWrapper@13502/@HSplitContainer@13481/@TabContainer@13501/@VisualShaderEditor@37626/@GraphEdit@37392").

Is it because I used copy and paste? Are there issues with copy and paste and visual shaders? (I noticed that shortcuts do not work, only context menus.)

I will literally pay someone to solve this for me. I’m a visual person with slight dyslexia, so I’m completely lost when it comes to syntactic idiosyncrasies.

A kind soul on Discord gave me the solution:

func _get_code(input_vars, output_vars, mode, type):
    var noise01:String = "snoise(vec3(%s))"%[input_vars[0]]
    var noise02:String = "snoise(vec3(%s.y - 19.1, %s.z + 33.4, %s.x + 47.2))"%[input_vars[0],input_vars[0],input_vars[0]]
    var noise03:String = "snoise(vec3(%s.z + 74.2, %s.x - 124.5, %s.y + 99.4))"%[input_vars[0],input_vars[0],input_vars[0]]
    return "%s = vec3(%s,%s,%s);"%[output_vars[0],noise01,noise02,noise03]

Please go and support them if this also helped you!

Note that you have to restart Godot at least once, and probably update your materials because there seems to be some aggressive caching going on behind the scenes in Godot which delays the removal of the errors.