godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.15k stars 97 forks source link

Add an HSL modulation property to CanvasItem (to complement RGBA modulation) #96

Open jsena42 opened 5 years ago

jsena42 commented 5 years ago

Describe the project you are working on: I'm working on a combat focused 2d platformer with a dark tone like Hollow Knight but with a combat more like Dead Cells.

Describe how this feature / enhancement will help your project: Being able to change the color of an asset to fit a specific area without generating an image variation or writing a shader for it (specially for assets that may have another shader already) would be very nice.

Describe implementation detail for your proposal (in code), if possible: Imagine the modulate property but actually being able to change HSL instead of just adding a tinted look.

If this enhancement will not be used often, can it be worked around with a few lines of script?: It can be done with a simple shader but such a feature is very useful (specially on the polishing stage).

Is there a reason why this should be core and not an add-on in the asset library?: I think this is a much needed feature.

Calinou commented 5 years ago

Is there a reason why this should be core and not an add-on in the asset library?: I think this is a much needed feature.

Actually, someone could very much upload a shader to do this on the Asset Library :slightly_smiling_face:

jsena42 commented 5 years ago

Is there a reason why this should be core and not an add-on in the asset library?: I think this is a much needed feature.

Actually, someone could very much upload a shader to do this on the Asset Library

Just like the modulate feature (which is less useful). HSL adjusments is something very basic and very used.

Calinou commented 5 years ago

@jsena42 From what I've seen, you're the first user to request it since I joined the Godot community in 2015. This doesn't strike me as "very basic and very used".

Sorry, but we have to draw a line somewhere to avoid adding unnecessary bloat to the engine.

reduz commented 5 years ago

This is very easy to do with a few lines of shader code, then you simply drop the material into the node and it will automatically affect all children nodes too, like modulate does.

I suggest opening a ticket in the documentation or demos repository requesting such example for your use case.

reduz commented 5 years ago

Here is some code, you can check the screen space shaders demo and adjust them to use something like this (code not necessarily correct, but could be used as reference, just check the ones i mentioned and use a combination of both):

uniform float hue_rot_angle = 0.0;

void main() {

    float hue_rot_c = cos(hue_rot_angle);
    float hue_rot_s = sin(hue_rot_angle);
    mat4 hue_rot_mat =  mat4(vec4(0.299, 0.587, 0.114, 0.0),
                    vec4(0.299, 0.587, 0.114, 0.0),
                    vec4(0.299, 0.587, 0.114, 0.0),
                    vec4(0.000, 0.000, 0.000, 1.0)) +
                mat4(vec4(0.701, -0.587, -0.114, 0.0),
                    vec4(-0.299, 0.413, -0.114, 0.0),
                    vec4(-0.300, -0.588, 0.886, 0.0),
                    vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_c +
                mat4(vec4(0.168, 0.330, -0.497, 0.0),
                    vec4(-0.328, 0.035,  0.292, 0.0),
                    vec4(1.250, -1.050, -0.203, 0.0),
                    vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;

    COLOR =  hue_rot_mat * texture(TEXTURE,UV);

}

Once this works for you, please either submit a PR to the demos or your asset to the asset library so others can benefit, too.

golddotasksquestions commented 5 years ago

https://github.com/godotengine/godot/issues/31742

reduz commented 5 years ago

@golddotasksquestions Nothing that can be done about it, we won't unnecessarily bloat Godot with every single thing that comes to mind.

The shaders are very easy to use once created, even by someone who did not write them, so I think the actual question should be how we could make it easier to find them and share them for other users, or whether we should make a poll and make some official collection of them you can download.

golddotasksquestions commented 5 years ago

@reduz I have never ending respect and appreciation for what you did with Godot by making it open source, in consequence for it's users and what you still do since then every day for Godot. I deeply admire your fight to keep the engine code lean, fun and accessible to work with for contributors. In regards to the inevitability to use shaders for nearly everything that is not color modulation, I feel like this direction is hurting the Godot project as a whole a lot, however. With this direction, you are actively making Godot undesirable for game designers and artists who are reluctant to learning code to say the least and first and foremost want to create quickly and instantly (so 95% of them). If you now say "but then Godot is not the right tool for them", I'm deeply saddened and disappointed, because Godot could very well be the tool for them. As a matter of fact, I think it already is the perfect game engine for game designers and artists who want to produce games. GDScript is incredible accessible and there is hardly a day that goes by without me marveling at how simple yet powerful it is. Often I feel like all Godot misses to become the magnet for designers and artists it deserves is for those people not being required to learn yet another language only to do things they have been accustomed to do with single clicks in the most basic of all design editors that come preinstalled with their OS.

Maybe just a few seconds after I first opened Godot and created my first sprite was an attempt to change it's color. What then happened was immediate confusion and frustration, because I could not get the color or effect I wanted, no matter what I tried. Even if it is just two lines, having to resort to code and more so yet another language to make my sprite fill with a specific solid color seems utterly outdated and absurd for an editor with this wide range of functionality. Modulate behaves like no other color setting I ever used throughout the nearly 20 years of working with visuals. It took me weeks to understand it. Before that, for the longest part, I just thought it's a broken piece of junk in urgent need for replacement. When I was opening up Godot for the first time I expected an HSL slider to jump at me as soon as I look for color. I could not believe it is not included in the editor interface. When I came to terms with the reality of the situation, I thought this surely is a temporary problem, as people will sooner or later add to Godot such obviously missing features.

Now you are saying nothing can be done about it? Shaders are not at all easily created understood or adapted by someone who is new to code. They are not intuitive and not directly and immediately available for basic tasks. You have to online search for them, and if you are lucky you find something you need and that just works. I'm learning Godot now for more than a year and still don't have a grasp on shaders. The only reason I'm still at it is because I am incredibly stubborn. When I show Godot to game design and art colleagues and friends who I know would profit from it, they lose motivation when they try to "make this another color", "add a shadow", " "make an outline", "make this glow".

Your response and those I get from other here is disheartening, because it tells me nothing will change. It means Artists and Designers who could diversify and complete the community will stay away. Game dev is a multi disciplinary endeavor, Godot games dev therefore needs a diverse Godot user base.

reduz commented 5 years ago

@golddotasksquestions Did you even read what I write? What is the difference to you between making this built-in or making it available as an official download?

In no way you need to learn shaders to use it, as you mention.

golddotasksquestions commented 5 years ago

@reduz Of course I read what you wrote. I really appreciate you taking the time to respond to users needs and concerns, so I read everything you write very attentively.

What is the difference to you between making this built-in or making it available as an official download?

The difference is accessibility, ease of use, barrier of entry. If people who are not attracted to learning code very much and see they have to do online searches and deal with yet another language to do simple and basic everyday design stuff, they loose interest. Even if they say "Ok, let's try this at least once", and found a script, they are confronted with an incredibly unintuitive and quite honestly obstructive new user experience when the try to apply it to a game object:

The UI/UX for 2D and 3D are the same. From a new user perspective who is knows little to nothing about shaders, it makes no sense why you would have to look for "Material" when you want to paste a code snippet that is distort my 2D sprite or change it's HSL. But even once you have found the place, you cannot paste anything. You first have to google the difference between a NewShaderMaterial and a NewCanvasItemMaterial because if you click on either, you can still not paste your code anywhere. If you do commit to either option, it's not very intuitive to realize how to go back. You have to click the small downward arrow, click clear out of all these options. That's very different from the majority of Inspector setting which you can revert by just clicking the circular arrow as soon as you diverted from the default.

So lets say new user has figured out NewCanvasItemMaterial is not what they are looking for, it has to be NewShaderMaterial: Even if this is a 2D node all they see now a 3D looking Ball. The logic behind that might be obvious to you (and by now it is for me as well), but for someone who just wants to paste some code to make their 2D Sprite look different. Still, where to paste the code now? There is no indication whatsoever that I would have to click on that 3D ball. After lots of frustration, searching through tutorials to figure out where they clicked between a few pixels and video frames, I finally realize the same small downward arrow that looks just like any other property expand arrow. If I manage not to miss "Edit", I am finally at a place called "Shader [empty]". Clicking that, I am yet confronted with another two options. As a new user I have to google the difference between Visual Shader and Shader again. The difference is not immediately clear, after all I want to paste this shader code to change my sprites visual appearance.

Worst of all, I still see no place anywhere where I could paste the code I have been carrying in my clipboard all this time. Even if I optioned for the Shader [empty] > New Shader, nothing changes in the UI or gives me any indication what to do next. All I can observe is that another option appears "Next pass: [empty]" Since clicking on these [empty] boxes led me this far and I don't have any indication where to paste my code, I am assuming this is the way to go. But clicking this only leads to going through the same steps all over again (with even more options because there is NewParticlesMaterial and NewSpacialMaterial too), seemingly being caught in a loop.

This UX feels like a maze. I amount of times I had to run through this maze and hit my head against it's suddenly appearing walls and exhaust myself in loops until I finally managed to remember the only valid path is infuriating. All that just for a stupid outline or solid color or HSL? Even if you get out there and miraculously make it to the bottom panel where you finally can paste your shader, there is no guarantee for it to work. Many Godot shaders that float around online in the forums, github or reddit are untested comments, work in progress, have a bug, or require some gdscript to run which is not provided along with it. Some won't just work if you past them because you have to set a texture to actually see any effect. If you don't know this and just paste the code and expect it to do something, you will end up AGAIN severely frustrated and reluctant to ever try again.

Godot shaders are an incredible valuable addition to the engine. I love that they exist and make so many amazing effects possible. They are fantastic tool for complex visual effects. But my point being is that they should not be a requirement for the most basic visual edits. The barrier of entry is high, the workflow unintuitive and the learning curve incredibly steep and anything but a fluid flow of creativity if you don't already know Godots shader language and all it's ins and outs. New users need to come into the engine and feel like they can come from vision to result in a direct and fluid motion. When it comes to adding Nodes and GDScript coding, Godot does exactly that. For visuals (and we are really not talking about anything complex here), because of the dependency on shaders for even the utmost basic things, it's the polar opposite.

There are 5 different built in ways you can sort objects in 2D. There are at least 5 different built in ways to connect user input with your project, and I lost count of how many different built in ways there are to swap data between objects. These options are all fantastic and I love that variety. But why on earth would you insist on giving us only one built in way to manipulate color, which in addition is completely unfamiliar and unintuitive to anyone who worked with visuals and missing essential functionality (no solid color option, no way to quickly adjust HSL). And then the engine gets features, though appreciated, but noone asked for.

All this makes argument "bloat" seem like an arbitrary shut down argument for you to use whenever you personally don't see the use of a feature request. I understand that as an experienced coder who knows the engine inside out and as someone who also knows Godot Shader Language you personally don't see much use in these requests. I also understand as humans we are inclined to have less understanding for needs we don't personally have, but I would really hope this bloat shut down argument would happen less frequently in these situations.

Thank you for reading, I know that's a lot of text but I could not hold it any longer. I appreciate you taking the time to read, I know it's not a matter of course.

Calinou commented 5 years ago

@golddotasksquestions Please open separate proposals to improve the shader creation/loading/editing UX instead.

golddotasksquestions commented 5 years ago

@Calinou I will once I find the time. These proposals take a lot of time to write and prepare. I wrote this comment to illustrate why we need HSL built into the inspector (maybe built into modulate), as opposed to a shader, the UX is just one of many reasons for the former.

Zylann commented 5 years ago

@golddotasksquestions I kind of get the point you are making in the sense that this kind of conversation happened a lot in the past. I won't deny some of it, however you seem to complain that users need to know about shaders and paste code. What Reduz suggested above about the asset lib would actually mean the following scenario:

There is no moment in this flow where the user needs to care about code, it's litterally an asset you drag onto the material property of your 2D node (or the sprite itself maybe).

reduz commented 5 years ago

@Zylann, @golddotasksquestions yes indeed, no need to paste code, you just create a Material, set it to the CanvasItem, drag the shader file (likely a .shader already written in your filesystem), to it and tweak the exposed parameters, zero need to even see the code.

We have a lot of example shaders in the demo projects, but I agree it may make more sense to change this demo so shaders are external files and you can simply download this and use them in your project. Same with the screen space shaders demo.

Jummit commented 5 years ago

@jsena42 why is editing the sprite in an image editor not an option? I imagine having sprites look different in game than as asset would be very confusing. If you really need to edit it in Godot, use the shader reduz kindly made.

golddotasksquestions commented 5 years ago

I had no idea if I use the Asset Library from within my project, it will directly load the assets in my project directly. So far I've used the template tab in the Project manager (which seemed identical to the in project Asset Libary) or downloaded from the web.

"screen space shaders" yields no result in the Asset Library. If you just look for "shaders" you also won't find the screen space shader demo. Neither will you find it if you search all in category Shaders. Even though I know what the icon looks like and wasted a lot of time scrolling through all downloadable assets multiple times without finding it. The only way to find it if you go to your browser and online search for "godot screen space shaders" 2D sprite shaders, like shadow, blur, glow, I cannot find at all any more. Neither in the Asset Library, nor through online search and reddit search. (another 2h wasted on that)

The screen spaces shaders demo does not have their shaders saved as individual .shader file, so even if I did import directly in my project, I could not just apply it to my objects.

So to test your proposal I've downloaded the outline shader. The direct download in my project worked fine (thanks for the tip!), but drag and drop as you proposed did not work at all. I could not drop the outline.shader file onto the object in the 2D view, nor on the scene panel, nor in the inspector "Material".

Godot shaders are brilliant and it's worthwhile to go through all that trouble if the payoff is a complex visual effect. Requiring shaders to apply simple commonly needed effects like HSL manipulation, solid color, dropshadow, blur and arguably glow is a creative hindrance.

What comes to this it that it is not immediately obvious what features Godot has hidden in the asset library. Godot has an abundance of build in features that are way more project specific than a HSL color modulation. How would I as a new user know I have to look there when experimenting with Godot? How would I know about the optimal workflow to download it from within a project? It's not mentioned in the docs. I would have to go online to some community and ask and be lucky if they gave me the right advice. If I am unlucky I hear about it a year later.

So while in theory this download + drag and drop workflow would is great for a library of complex shaders, in practice this is anything but a smooth ride and even if it would work it is still not a solution to having no HSV available in Godot from the start.

Zylann commented 5 years ago

The direct download in my project worked fine (thanks for the tip!), but drag and drop as you proposed did not work at all. I could not drop the outline.shader file onto the object in the 2D view, nor on the scene panel, nor in the inspector "Material".

As said before, this is a demo (from the "demo" category), not a material pack, so it was not packaged in the proposed way. The kind of asset you would need here is one specifically made for such re-use, and would consist in material files, not just shaders (shaders would be setup with them already to save you those steps).

KoBeWi commented 5 years ago

I could not drop the outline.shader file onto the object in the 2D view, nor on the scene panel, nor in the inspector "Material".

Oooooh, this totally reminds me of https://github.com/godotengine/godot/issues/27079. We could have more properties like that, particularly, dropping a shader on material slot (or even at CanvasItem) should automatically create a ShaderMaterial.

jsena42 commented 5 years ago

@jsena42 why is editing the sprite in an image editor not an option? I imagine having sprites look different in game than as asset would be very confusing. If you really need to edit it in Godot, use the shader reduz kindly made.

If you're doing an atmospheric game with tons parallax layers and want to simulate depth or different ambient lights having a HSL editor is very handy instead of occupying large amounts of space with variations.

I understand it can be easily done with shaders/materials but it can be very annoying to assign it depending on the amount of objects to tweak.

I just think this could be a nice addition to make Godot more artist friendly without bloating the engine since it could be easily incorporated in the Modulate option.

In any case, thanks for reduz for the shader and I hope Godot find it's way to be more artist friendly without compromising other aspects.

reduz commented 5 years ago

I just think this could be a nice addition to make Godot more artist friendly without bloating the engine since it could be easily incorporated in the Modulate option.

1) It's not "easily" it does have a significant processing cost (modulate is just a multiplication, and you can see in the shader above that hue rotation is significantly more complex) so it's not something you want to enable by default. 2) Dragging an existing material or a shader is effortless, and already takes effect in the children nodes by default, similar to modulate. In fact, with the new class_name system, there is likely no need to even drag it.

Again, if you want to make sure this proposal has any kind of future, I suggest we discuss how it could be easy to distribute and install user-made ones.

We could have a category in the asset library for shaders and materials, and we already have the class_name system, so its easy to make those appear on the inspector upon install.

Maybe the only link missing is to add a feature where, at the time of adding a material to a canvas item, you see an option like "Download Materials", something like this:

image

Then this will lead you to the asset library with a new category, "Materials" selected, where you can see all materials available for download, from drop shadows, blur, dissolves, etc. to hue rotations.

After installing the ones you want, you can see them here automatically, like in this other mockup:

image

We could discuss this workflow for a lot more categories, like particle materials, meshes, etc.

Of course, we could have official-made ones, so if one is requested we can ensure one can be provided so we don't need to bloat the engine unnecessarily.

Calinou commented 5 years ago

We could have a category in the asset library for shaders and materials

We already have a category for each on the Asset Library :slightly_smiling_face:

eimfach commented 1 year ago

I'd like to use hue rotation in Godot. I have hundreds of red toned sprites where I want to hue shift the red tones to a different player color during runtime (strategy game) -> about 8 different colors. The shader script provided here, also shifts grey tones. I checked it in Aseprite how it does adjust hues and it doesn't touch the grey values, which must be the correct thing and exactly what I need in my case. I used a ColorSwap Shader which uses a two pixel height texture to replace the colors but it is taking a lot of performance and is impractical for choosing the right colors (Maintaining Aseprite Script to generate textures etc. ). Can anyone show me a shader script which does what I need ?

Aseprite implementation: https://github.com/aseprite/aseprite/blob/d195561b7f64d26a48146be9c895e7daa495050a/src/filters/hue_saturation_filter.cpp

https://github.com/aseprite/aseprite/blob/0cfeacab5c2876da473adce46ce481bd2b8b940c/src/app/commands/filters/cmd_hue_saturation.cpp

Edit: I am trying the ShiftHSV Shader from this now: https://github.com/arkology/ShaderV

eimfach commented 1 year ago

That's the shader you can use:

Bildschirmfoto 2022-12-31 um 19 30 43