Godot version:
3.1 stable
OS/device including version:
Win7 / NVIDIA GTX 765M
Issue description:
WE glow will not appear on thin lines of the same brightness and thickness vertically while the glow will appear horizontally.
Steps to reproduce:
Note: if the lines are thicker, this effect either becomes unnoticeable or not not existent. This is a problem for graphics of a few pixel width.
This related to how bloom is downsampled. It's basically a performance vs precision tradeoff.
This makes glow for integrate UI and pixel art pretty much unusable.
Any chance this might change with new 4.0 rendering engine?
Well I haven't tested it but it should be possible to improve the filtering without much impact on performance.
'filtering'
I suppose that's nothing I can do with GDScript, or is it?
I don't think so. It's dependent on the implementation in the engine.
There's a Bicubic Upscale option available in the Glow settings, but it will likely not solve the issue you're experiencing (since it can't fix missing glow in some areas).
There's a Bicubic Upscale option available in the Glow settings, but it will likely not solve the issue you're experiencing (since it can't fix missing glow in some areas).
Unfortunately not, I tried with and without Bicubic Upscale before posting the issue.
Workaround: HDR Threshold ≈ 0.5, HDR Luminance Cap ≈ 0.2
Zooming artifacts: (Using this config)
I also had lots of issues with this in my topdown 3d game. If bullets had any glow on them they would look vastly different depending on the direction they were travelling. In the end I had to work around it by using sprites with transparency around the 3d bullets to fake glows. Would be great if this issue could be resolved!
I'm not sure anything can be done. This is what HDR Threshold is meant for, if you reduce HDR Threshold to 0.2 or so it will pick up everything wider than 1 pixel. I am not sure if Glow can be made to work with single pixel thickness meshes.
_edit:_ I'll look more into this limitation as I port Glow to GLES2. Maybe I can figure something out.
@clayjohn it is more related to to the orientation of the pixels than the thickness. I am having this issue on meshes that are much larger than 1 pixel in thickness. If a bullet is orientated horizontally it gets more glow than if vertical.
I had assumed it was something to do with the aspect ratio of the screen being rectangular. Have always been meaning to try a test with a screen ratio that was square, to see if it still exhibits the same problem.
@fracteed So Godot uses an implementation of glow that uses separate passes for horizontal and vertical. Normally when computing glow you do two passes for each mip level. Mip levels decrease in size from screen size by a power of two (so for screen size of 128 you would have mips of 64, 32, 16, 8 and 4). As an optimization, Godot decreases the mip level on each pass. So you start with a screen size (again assume its a 128 pixel screen) of 128, the first horizontal pass is done onto a 64 bit framebuffer, then the next pass is vertical and it is on the 32 bit framebuffer. So already, with a 128 pixel screen before the vertical pass takes place you have already lost half the resolution (the vertical pass reads from the 64 pixel mip). So features of 2 pixels or less can be lost completely.
Because of this method, it is entirely possible that horizontal objects receive more glow than vertical because they are always reading from a larger buffer.
The aspect ratio may have some effect, but it is not likely very large. I think the solution is going to be making some modification to the way sampling happens to ensure that features are not lost.
Just had a bit of a play around with this. Screen aspect ratio didn't make any difference, but if you put the hdr threshold down to 0 they look almost identical. Here is a screencap of a scene with 3 capsules of the same size, but at 3 angles. You can clearly see the glow being different depending on the orientation.
Also, a sidenote that the "softlight" blendmode is broken in 3.1.1 and master. I seem to remember this breaking in the past.
@clayjohn I was making the previous post at the same time you were posting! Thanks for the explanation. If you come up with any solutions they would be most welcome :)
Setting the HDR threshhold to anything below 1 unfortunately is not a workaround, as most artwork (unless its black/white bitmap graphics like in fracteed's example) will contain pixels with raw values between 0 and 1 @fracteed @nathanwfranke @clayjohn
Setting HDR threshhold to 0 should mean: Make every pixel which is not pitch black glow.
Setting HDR threshhold to 0.5 should mean: Make every pixel which has a raw value of more than 0.5 glow.
What we want is to trigger glow intentionally. We know image data can contain pixels with values between 0 and 1. So for glow not to appear unplanned and blow out highlights, in most cases we only want to start glow from a 1 threshold (which is also why I assume this is the preset). So consequentially glow is archived by raising the raw value above 1 set_modulate(Color(1.1, 1.1, 1.1, 1))
. This should affect both vertical and horizontal lines pixels the same, starting with 1 pixel width, imho. I think a single pixel with a value above the HDR threshold should have glow. Otherwise WE makes no sense for pixelart, which would be a shame.
If this is a performance vs precision question, we need a setting for that.
If this is a performance vs precision question, we need a setting for that.
It probably makes sense to add a pixel-perfect setting in that case.
I ended up implemented Glow in GLES2 the same way as in GLES3. So this issue is relevant for both backends.
@fracteed what has been your solution for working around this issue?
@FeralBytes I am only using glow on objects that aren't too thin. I ended up using sprite 3d with alpha to fake the glow on projectiles.
I found that when a thin line is curved, the glow effect is applied to the parts that nearly horizontal but not the other parts of the curve.
So it seems that WorldEnvironment is working unevenly on each part of gradual curves too.
Not only on straight perpendicular lines.
This issue is significant since thin lines can be in any projects and for some people, bloom/glow effect is the key art decision. Especially when it comes to UI, there are borders everywhere and a lot of them have pretty thin lines in modern UI design trends. Just like GitHub's UI.
Especially when it comes to UI, there are borders everywhere and a lot of them have pretty thin lines in modern UI design trends. Just like GitHub's UI.
You can use a CanvasLayer node to make glow not apply to your UI. Also, the current trend in UI design is to use as few borders as possible :slightly_smiling_face:
I wonder if the white pop up flashing glow on the ground here at 1:25 and 1:26: https://youtu.be/qafqRSdojk4?t=83 is related to this issue or if this is a problem with the reflection probe and should be it's own issue.
@golddotasksquestions that looks like a separate issue
Is it though? Quoting @CptPotato :
This related to how bloom is downsampled. It's basically a performance vs precision tradeoff.
To me it looks like the bloom "jumps" into existence. I'm assuming we are seeing this white bloom flash because the reflection renders a 3by3 pixel area that suddenly has bloom while a 1x1 pixel would not, whereas in other engines this would fade in and out more, or downsampling would be handled differently all together (gust guessing here)
I wonder if the white pop up flashing glow on the ground here at 1:25 and 1:26: https://youtu.be/qafqRSdojk4?t=83 is related to this issue or if this is a problem with the reflection probe and should be it's own issue.
These looks like #19175
@clayjohn nice work on the HQ glow mode! Is there any chance of getting this backported to 3.2?
@fracteed there is a chance yes, but no guarantee. I plan on looking into it this week. It turns out that fixing the issue was surprisingly easy in 4.0 and I hope that a similar approach can be taken in 3.2.
@clayjohn sounds promising, thanks for letting me know!
Most helpful comment
@FeralBytes I am only using glow on objects that aren't too thin. I ended up using sprite 3d with alpha to fake the glow on projectiles.