TwistedTwigleg,
@TwistedTwigleg said:
Sorry the delay in replying, I was busy with other stuff :smile: .
no need to apologize -- I am so grateful that there are any people at all like you who apparently have time for and patience with Godot beginners like me... :)
Anyway, I think I know why you are having a problem with the shader. Right now your shader is getting the texture from the screen and displaying it. If you use this shader on a normal sprite outside of a Viewport node, you will not be able to see it because it will look just like the texture that is being rendered to the screen. It would seem to be completely transparent, while in reality it's not but rather it is showing the scene at that exact position.
Right, I guess understand that now. I just thought that pixels modified by draw_*
functions would appear on the screen before any custom shader materials kick in.
The reason it is black instead of transparent in your scene is because there is nothing drawn to the viewport yet. Because by default viewports have a black background (though you can set it to transparent in the Transparent BG
flag), that is why you are getting a black screen.
No, i don't get a black screen (or a black rectangle where the Mesh is) -- it's just the pixels touched by the draw_*
functions which appear black, all other pixels look transparent.
Anyway...
Have you looked at the 2D shaders demo on the GitHub Godot repository? I think there is a glow shader that may work. The only potential snag there is, if I recall correctly, the shaders in the demo require there to be a texture for sampling purposes.
...this seems to work only with canvas_item
shaders on pixels already on-screen; I tried like a million variations of the textureLod
approach to get some blurring, but I just couldn't get any effect -- not in the setup described above, nor in my new scene which looks like follows:
Spatial
+ Sprite3D # <- uses the Viewport as ViewportTexture and the ShaderMaterial described below
+ Viewport # <- with transparent_bg = true
+ Node2D # <- this is where the pixels are drawn to
Shader code:
shader_type spatial;
render_mode unshaded;
uniform vec2 dx = vec2(1, 0);
uniform vec2 dy = vec2(0, 1);
uniform float offset = 0.05;
uniform float strength = 0.1;
uniform sampler2D texturemap : hint_albedo;
void fragment() {
ALBEDO = (
0.0625 * strength * texture(texturemap, UV + offset * (-dx +dy))
+ 0.125 * strength * texture(texturemap, UV + offset * (+dy))
+ 0.0625 * strength * texture(texturemap, UV + offset * (+dx +dy))
+ 0.125 * strength * texture(texturemap, UV + offset * (-dx))
+ 1.25 * texture(texturemap, UV)
+ 0.125 * strength * texture(texturemap, UV + offset * (+dx))
+ 0.0625 * strength * texture(texturemap, UV + offset * (-dx -dy))
+ 0.125 * strength * texture(texturemap, UV + offset * (-dy))
+ 0.0625 * strength * texture(texturemap, UV + offset * (+dx -dy))
).rgb;
ALPHA = min(length(ALBEDO.rgb) * 5.0, 1.0);
}
The shader's texturemap
uniform gets bound to the same ViewportTexture
as the Sprite itself; the latter seems actually only necessary due to the issue described in https://github.com/godotengine/godot/issues/7998
This setup kind of works, but since the ViewportTexture
's background turns out to be black (in spite of the Viewports
's transparent_bg
property set to true
) the glow also fades towards black rather than transparency. I need to do some additional fiddling here...
One more problem is that I use a fixed 3x3 kernel for blurring, which has rather limited blurring capacity. Instead, I'd prefer to use the established horizontal/vertical gaussian blurring technique, but this seems to require some means to temporarily store intermediary textures. I couldn't find anything, though, about the possibility to create and use additional texture buffers in fragment shaders -- or did I miss something?
So things are still exciting and under heavy development... Latest version pushed to https://gitlab.com/tcrass/angstrom
Cheers --
Torsten