ItsKorin / Godot-Post-Process-Plugin

A simple godot 4.2 plugin that adds shader based "post processing"
MIT License
256 stars 18 forks source link

[Feature Request] Add a "weight" property to the PostProcess node #22

Open caiquesassis opened 2 months ago

caiquesassis commented 2 months ago

Hello! I recently started making the switch from Unity to Godot, and the lack of Post Processing options on Godot made me look for options, and that's how I ended up finding this plugin. First of all, thanks for making it! As a former Unity dev, this is really useful and I'm glad it's being worked on.

So, one of the things the Post Processing volumes offered in Unity was a property called "Weight". Basically, it's a multiplier that ranges from 0 to 1 that you can use to control all the Post Processing options of a given volume at once without changing them individually, like this:

Volume Weight at 0 UnityPPVolumeWeightZero

Volume Weight at 0.5 UnityPPVolumeWeightHalf

Volume Weight at 1 UnityPPVolumeWeightFull

Such property is really useful when you want to quickly apply a given effect when something happens, for instance...quickly applying and fading a bloom effect when picking up an item, instead of dealing with the bloom parameters directly, you could just have a separate Volume with a profile that has bloom enabled with the settings you want it to have, but set the Volume Weight to 0, and when the item is picked up, set the Weight to 1 and lerp it back to 0. (I'm not sure if this plugin supports multiple PostProcess nodes at the same time with different configurations...haven't properly tested it but from the quick tests I made it seems to behave in a weird manner so I'm not sure if this is supported or not possible to do - perhaps the Priority property, similar to Unity's one, would also need to be added).

I did try quickly hacking the script to see if it could work, and I think in a basic level it does work, at least with the basic float parameters (I was not sure if such weight property should also be applied to things that deal with Vector2 components or the like, such as "Ascii Size" on the ASCII effect...I guess this is up for debate). What I did was basically going into the post_process.gd script and in lines where _material.set_shader_parameter("name", configuration.Parameter) were written setting a float parameter, I just multiplied the configuration.Parameter by weight (which I @export_range(0, 1) as a variable at the top of the script). Of course, I also had to go to the post_processing_configuration.gd script to explicitly set the type of many of those parameters to float, as otherwise Godot's compiler would complain about multiplying a float by Nil. In any case, the weight approach did work, at least with a single PostProcess node (as I mentioned, weird results with two or more nodes).

Here's how it ended up: GodotPPWeight

So, basically, I'm bringing the request up (and how I quickly tested to check its overall viability) to see if it would be possible for it to be properly integrated according to the standards that are being used by the maintainers, of course, as there are some design decisions (such as which parameters to ignore when applying weight) that would need to be discussed upon.

Thanks once again for the amazing work on the plugin!

Loufe commented 2 months ago

Great idea and thanks for the high quality write-up @caiquesassis. I've hit a point in my game where I've been looking for a means to make transitions smoother between my different presets and have been wondering how to achieve it.

Your point about floats being required is absolutely true. I wonder how many individual shaders will refuse to play nicely even after some tweaking. In any case, I'm 100% for it, but I think we'll need to do a breaking update to support this.

As for the weight system, it's decent, but I think that approach presents some trouble trying to blend from one "post" state to another gracefully. For instance, if I wanted to go from "night" to "dawn" filter, I would have to maybe:

My original thinking was to implement a function which "transitioned" between two presets. You'd select target preset, a transition time, and a transition function (i.e. linear / quadratic / etc.). In the game loop we'd follow the change in the transition function from one preset to the next, just based on the different. That way we wouldn't see weird dips etc. I think this would be preferable as we could easily implement a way to set target as the default values.

However, if you wanted to dynamically play with different levels of your existing preset, this would present some challenges. Most of the underlying code would be similar for our approaches, and I suppose they could live in parallel.

Anyways just some thoughts of mine. What do you think?

I'm on a work trip for another week still but I would be happy to work with you on implemting this when I'm back.


On a side note, if there is a problem with using multiple Post-Processing nodes together, could you submit another issue?

caiquesassis commented 2 months ago

Thanks for the further insight on this issue @Loufe !

As for the weight system, it's decent, but I think that approach presents some trouble trying to blend from one "post" state to another gracefully. For instance, if I wanted to go from "night" to "dawn" filter, I would have to maybe:

* Fade out (decreasing weight) the night filter while

* Fading in (increasing weight) the day filter.

My original thinking was to implement a function which "transitioned" between two presets. You'd select target preset, a transition time, and a transition function (i.e. linear / quadratic / etc.). In the game loop we'd follow the change in the transition function from one preset to the next, just based on the different. That way we wouldn't see weird dips etc. I think this would be preferable as we could easily implement a way to set target as the default values.

Yeah, if we're thinking along the lines of "persistent global post processing states", such as day / night, then the proposal about having a function that can gracefully handle it would be the best option. Still, the weight parameter is really useful when you want to quickly overlay effects in some cases as I mentioned, in an "additive" manner, without changing the "base" active post effect. For this to be handled correctly, I guess a "priority" system of sorts would also need to be implemented.

I don't know if you've used / are familiar the Unity engine and its post processing volume solutions, and I'm aware that it's not always a good idea to force the "Unity way of doing things" upon Godot, but I strongly suggest taking a quick look at it if you want, as it's quite an easy to set up, straightforward and flexible system, despite being very simple - I think it's a clearer way to understand the proposal I made here (and on https://github.com/ItsKorin/Godot-Post-Process-Plugin/issues/23) since what I'm proposing is basically a port of the features found there... so checking it firsthand could also give some ideas on what works and what could be improved. At least for all my use cases from the times I had to use it in my games, it fit the bill nicely and I never felt it was lacking in features or anything (granted, my uses cases weren't overly complex).

I'm on a work trip for another week still but I would be happy to work with you on implemting this when I'm back.

Oh, don't worry about it, there's certainly no rush. Besides, I don't think I could be of much help aside from maybe debating some ideas back and forth...despite knowing how to program, I'm certain my skills aren't up to the task of helping to contribute to the codebase and maintain it in any meaningful way πŸ˜…

On a side note, if there is a problem with using multiple Post-Processing nodes together, could you submit another issue?

Sure! I actually need to test it more thoroughly to see if I can track down the exact reproduction steps. I've also found another unrelated issue, so I'll be creating new issues when I get to it.

Thanks once again for the contributions to the plugin, as it's something Godot is severely lacking at the moment and I do think this might be the post processing plugin for the engine if it keeps being improved πŸ™‡β€β™‚οΈ