I think you can do that using a screen-reading shader, on a node covering the screen (because any light can be distorted). For that you need to put a big sprite with the shader on it, and that shader will only reproduce the pixels of the game world and add the black hole distortion to them.
I did an experiment like that too by starting from the official Screen-Reading shaders demo, and then I added my own black hole shader to them. It's in no way a "physically correct" black hole, but it looks like one:
You can download the project here to have a look:
Possible improvements: the way I did it doesn't use a node for the black hole itself, but it can certainly be improved so that a simple Node2D with a script can tell the screen-reading shader where to bend the light. Also it's not black inside because the shader doesn't cuts to black above a distance (and also the texture returns buggy coloured pixels beyond the screen). Finally, it can be optimized so that only a subset of the screen is concerned, to reduce the amount of pixels to process (doing that on the whole screen has a cost).
Sorry if it's not that user-friendly, it's a rough test but that's a start^^ (the fact is, yes, you can do black holes :p)
I hope this helps :)
Edit: comments for the shader:
// Center of the black hole in normalized screen coordinates
vec2 center = vec2(0.5, 0.5);
// Some factor to set the size of the black hole animating over time,
// you can set it to a constant value really
float p = abs(sin(4.0*TIME)) * 0.01;
// Get direction and distance from the center using texture coordinates
vec2 diff = center - SCREEN_UV;
float d = length(diff);
vec2 dir = normalize(diff);
// Distort the texture coordinates of the screen:
// Warning, unchecked experimental formula.
// the main idea is that we want to "attract" light to the center the closer we are to it,
// which will distort UVs towards the center of the black hole.
// This appears to work well, and in fact looks like gravity attraction formula applied to pixels
vec2 uv = SCREEN_UV + dir * (p / (d*d + 0.01));
// Finally, get the color of the pixel at the distorted location,
// and output it at the current location.
vec3 col = texscreen(uv);
COLOR.rgb = col;
If you understand the tutorial you linked, you can surely reproduce it using Godot's shaders and some adjustments.