My current plan is to write unit tests using Sub-Viewports that each have a small wrapper shader to draw the result of the tested functions to e.g. 256x256px textures, which I can then compare against snapshots. Depending on the effects of different hardware/driver environments, it might be necessary to check that for some threshold t:
vec3 res = abs(result - snapshot); // residuals
max(res.r, res.g, res.b) < t
This could technically also allow for assertion functions (one condition per pixel), but getting any kind of usable error messages would mean a ton of work, so I don't think that it'd be worth it - though I am tempted :)
Edit: turns out Godot has native support for comparing two images, even better! https://docs.godotengine.org/en/stable/classes/class_image.html#class-image-method-compute-image-metrics