Godot Version
4.3.stable.mono.arch_linux
Question
In my game, the player is able to move level pieces with the mouse, and I currently have a “ghost” copy of the level piece as a kind of preview while the player is dragging it. Currently, to have this preview, I make a deep copy of the node and disable physics and collision layers on every child, but I feel this eventually might break things if some level component within the piece has some extra behavior
I’ve been trying to get the same effect with shaders, but I don’t know how to go about it (as I’m not experienced in that part in Godot specially). After experimenting a bit, I think I would be able to do it by putting the pieces in subviewports and copying their texture, but editing levels with them seems like a huge pain.
Using BackBufferCopy also wouldn’t be ideal as the background pixels would also be copied afaik, and I don’t want that.
Here’s the desired effect, that I currently achieve with the copy:
Could somebody give me an idea on what to do?
1 Like
Is there a particular reason you are trying to do this in shader?
You could try by reading pixels from CanvasGroup
node and using what is known as mix blend mode to apply it to the whole viewport.
1 Like
Not really. It just seemed to me that it would be the thing that would allow me to get that effect without copying nodes (and more efficient).
And how do I do that? Sorry I’m not finding how to do this…
Not really seeing how to do that either, but one thing at a time
Not really. It just seemed to me that it would be the thing that would allow me to get that effect without copying nodes (and more efficient).
If you have very little experience with shaders, I would encourage you to avoid using it if your priority is to ship fast. Otherwise if you still want to proceed here are answers to your questions:
In Godot shading language there is something called uniforms which you can think of as equivalents of @export in gdscript, but in shader language. You can add uniform of type sampler2D, and when you need it via code add texture of canvasgroup as parameter. Alternatively, you could place shader on CanvasGroup itself to read from its TEXTURE
directly.
NOTE: Just read docs about this, and it seems that CanvasGroup itself is just wrapper around BackbufferCopy, so if you will probably need to use that instead of CanvasGroup. Otherwise the quirk with CanvasGroup is that node itself applies shader on its children, so you need to add that behaviour yourself as well if you are applying a shader there.
Doing basic operations (most importantly blend modes) is must have knowledge for doing with shaders. It comes down to applying a formula over 2 different textures to “merge” them in some way (I mentioned mix blend mode since it is the one used for layering things), for more detailed explanation I wholeheartedly recommend this video on that topic.
Hope this helps!
1 Like
I’m here to learn
I know about uniforms, but I couldn’t figure out how to get the texture from the CanvasGroup node to pass as the uniform, as it doesn’t seem to have any methods for that.
I don’t know if that’ll be a problem, as I’m already using the snippet for that, available on the CabvasGroup documentation:
shader_type canvas_item;
render_mode unshaded;
uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
void fragment() {
vec4 c = textureLod(screen_texture, SCREEN_UV, 0.0);
if (c.a > 0.0001) {
c.rgb /= c.a;
}
COLOR *= c;
}
My issue with using BackBufferCopy is that the entire screen region would be copied, not just the texture from the desired nodes, no? So the level background or other things on that region would be copied as well, right?