FiniteSingularity / obs-stroke-glow-shadow

An OBS plugin to provide efficient Stroke, Glow, and Shadow effects on masked sources.
GNU General Public License v2.0
121 stars 11 forks source link

[BUG] - Inner Stroke not applied correctly to the outline if specific other effects were applied previously #30

Open YorVeX opened 1 year ago

YorVeX commented 1 year ago

Describe the bug I have a text source I am applying various animated effects to, then I want to apply a stroke and glow effect at the end. When doing this with StreamFX SDF effects with just inner glow (used as sort of stroke) and outer glow it's working fine, but trying to replicate the stroke with the Stroke filter from this plugin seems to be impossible, because the outer edges are not detected correctly.

To Reproduce Create a text source with some text, apply the fire.shader from Exeldros Shaderfilter plugin, then the Inner Stroke.

Expected behavior Detect the edges/outline correctly and apply the stroke based on them on the inside.

Screenshots StreamFX variant: image

Variant with Stroke filter from this plugin, note how the stroke is applied only partially within the K: image

Only fire effect and a green Inner Stroke for an easier repro scenario: image

Environment

GPU

Additional context Setting it to Outer Stroke makes it detect the edges correctly: image

YorVeX commented 1 year ago

More relevant info on the Discord convo here. Feel free to ping me on Discord any time about this. Also happy to help testing versions with potential fixes.

YorVeX commented 1 year ago

Maybe it's just related to how this plugin does alpha detection, it seems to be significantly different from how shaders or StreamFX filters are doing it. E.g. when I have a text source with a 16% opacity black background and apply a StreamFX SDF Glow or a glow shader to it, that effect is mostly applied to the text and only a little bit to the background. When I use the Glow effect from this plugin it's also applied to the text background.

Text without effects: image

With StreamFX inner glow: image

With a glow shader I had lying around: image

With Inner Glow from this plugin (Outer Glow being not much different): image

FiniteSingularity commented 1 year ago

Thank you for opening the detailed issue. The last post makes perfect sense- the way the edge detection is currently done is significantly different from SDF. For an arbitrary mask, SDF ends up being an O(N^2) algorithm, as to find the nearest edge, you do a full search in the x and y directions. Something like this pseudocode:

for(I=-N; I<=N; I++) {
    for (j=-N; I<=N; j++) {
      // Check to see if we are in a region with a different alpha than our current pixel
    }
}

This plugin searches a bit differently- it uses a cone filter which can be applied in 2 passes, which make it an O(N). Currently it just looks for pixels with any alpha greater than zero. In order to get glow on a text source like that, we can add a slider for the threshold alpha value. E.g.- consider anything with an alpha of less than 0.18 to be transparent for the sake of the glow/stroke/shadow dimensions.

For the first issue you're seeing, I'll take a look and see what I can figure out.

FiniteSingularity commented 1 year ago

In the short term, can you do a test for me? Try doing all the filters on your fire text except the inner stroke. Then create a "stroke" source in the same scene, and select your fire text as the stroke source, and see if that looks correct (You may need to align the stroke source with your text). It almost looks like the fire effect is being used for finding the edge which is strange.

FiniteSingularity commented 1 year ago

I think I have figured out what is going on with your first issue @YorVeX. It looks like the fire shader has regions with partial alpha values (e.g.- alpha of 0.5). Due to how my edge detection works, funny things happen. It's a "how do you define an edge where alpha is to be applied?" question. In order to do things efficiently, I am essentially searching for an edge were alpha is near 1.0, next to where alpha is near 0.0. Those in-between values cause the search to break down, and the behavior you're seeing.

One workaround I see is to offer a checkbox to use the non-filter-applied original source to do the edge finding (but still composite the resulting stroke with the source as it has come through the filter chain). This would allow the user to choose if they want behavior like you're seeing, or behavior like you want (using the edge of the characters as the edge to draw a stroke). I'll be working on this a bit, and hopefully will come to something that is useful in your situation.

I'll update this issue as I have PRs to try out.

FiniteSingularity commented 1 year ago

Another potential fix- take the input alpha channel and step it to alpha 1.0 for the sake of edge finding. That way the user could provide a threshold value to step up and this would fix your issue with the non-zero alpha background text.

YorVeX commented 1 year ago

Monday's are usually my "off PC days", so I am only seeing that now. Since you now already figured out what's most probably going on including potential solutions for both behaviors users might want, I guess I don't need to do the above mentioned tests anymore?

FiniteSingularity commented 1 year ago

No worries, and correct- no need to do the requested tests. (I really should do something like your “no PC Monday.” That sounds quite nice!)

FiniteSingularity commented 1 year ago

So you dont think I've forgotten about you...

I've figured out how to refactor things to fix these issues. That said, it is a somewhat significant refactor of the rendering pipeline for the filters, so it'll take a little while to implement. I'm going to finish up v1.0 of the mask plugin, and then will get this cranked out.

YorVeX commented 1 year ago

While you're at it, I get some memory leaks from both this plugin and your composite blur plugin (the message in the OBS log at the end of a session). Let me know if you see them too. If not, and it's something only I have here with my current setup, I will try to narrow it further down and create a GH issue with repro steps.

FiniteSingularity commented 1 year ago

Thanks for letting me know. I'll take a look later today, and see if I can replicate.

FiniteSingularity commented 1 year ago

I am seeing the memory leak. I have a PR ready to go that gets the memory leaks for both plugins down to 1. That last one is a pesky one, but we will find it. (I'm not noticing any noticeable change in memory usage, so I'm guessing it is something quite small, like a string, that I'm not freeing).

FiniteSingularity commented 1 year ago

@YorVeX can you give this PR a try and see if it fixes the memory leaks in stroke/glow/shadow? https://github.com/FiniteSingularity/obs-stroke-glow-shadow/pull/33

YorVeX commented 1 year ago

@YorVeX can you give this PR a try and see if it fixes the memory leaks in stroke/glow/shadow? #33

I guess you were also able to fix the last one, as I am down to 0 now from both of your plugins with the latest master builds. Good job!

FiniteSingularity commented 11 months ago

@YorVeX just wanted to let you know I haven't forgotten about this. About to release my Advanced Mask plugin, then will try to get this PR put together and out the door.