Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to "overlay" different ShaderMaterials on top of each other (e.g. vertex and fragment from different shaders) #2595

Open
lukostello opened this issue Apr 12, 2021 · 4 comments

Comments

@lukostello
Copy link

lukostello commented Apr 12, 2021

Bugsquad edit: Related to #2589.

Describe the project you are working on

I'm trying to do the 1000 fish multimesh demo

Describe the problem or limitation you are having in your project

I'm having trouble putting a vertex shader over the fish while the mesh resource is still able to use the textures from its materials.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Perhaps rather than override it should be overlay.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

you could apply a translucent material over the material from the mesh resource. for example you could just apply a layer of blue over a selected object with an alpha of .5. You could still have a boolean with the option to over ride but I think having the option to overlay would be extremely powerful. Because you aren't getting rid of the previous information I could use the material overlay function inherited from the geometry class to overlay a vertex shader, that way I can still use all the textures from the materials from the mesh resource

If this enhancement will not be used often, can it be worked around with a few lines of script?

You could use a vertex shader for each material in the next pass in the mesh resource. But this has several issues

  1. its very ineffecient its a sign of bad design if you have the same code copied and pasted several places.
  2. if you needed to overlay a shader or vertex shader on just a single mesh then that prevents you from using the next pass in the mesh instance materials. As far as I know trying to use the the next pass from the material over ride in the mesh instance would result in making the original material from the mesh resource unavailable.
  3. If the geometry material override overlayed instead then you wouldn't need 3 seperate shaders in each next pass. You could just retain the materials being used and overlay a vertex shader on top. This could be handy for if there are enemies with multiple surfaces that all fade to red when hit and similar usages.

so long as you have a boolean option to over ride then you retain all advantages of the previous methodology but now with much more flexibility.

Is there a reason why this should be core and not an add-on in the asset library?

I think the ability to fade to an overlayed material would be used very frequently. If my understanding of how materials currently work is correct this seems like a necessary upgrade.

@mortarroad
Copy link

It is not exactly clear to me, what you mean with this.
I understand it like this:
You want an "overlay material" to be able to "inherit" from a base material.
Implementing it like that is not practical in my opinion, because it would require you to compose the shaders at runtime (or have a way to predict all combinations).
We already have an issue with shader-compilation causing stutters, and this would make the situation even more difficult.

However, I think this feature request is mainly motivated by the desire for code reuse.
A much better solution is something like godotengine/godot#41583.
That would allow you to put the "base material" in a function, and then have the "overlay material" import that function and simply call it.

@lukostello
Copy link
Author

lukostello commented Apr 13, 2021

I dont know much about how a gpu works but I was imagining the materials from the mesh resource being passed by reference while the materials from the mesh instance would be local to the instance. It would be as if you did mesh resource material for a surface then the mesh instance override for the same surface on the next pass after that then do the geometry material override as the last pass. Then if the over ride boolean is checked for any material the previous materials are not computed

@mortarroad
Copy link

I think I understand you a little better now.
Correct me if I'm wrong, but your concern is mostly about being able to reuse the settings of an existing material (e.g. the associated textures) in an "overlay" material.

Solving that cleanly is tricky, indeed.

@lukostello
Copy link
Author

lukostello commented Apr 14, 2021

I think I understand you a little better now.
Correct me if I'm wrong, but your concern is mostly about being able to reuse the settings of an existing material (e.g. the associated textures) in an "overlay" material.

Solving that cleanly is tricky, indeed.

well the existing material would be under the one being overlayed. Lets give a practical example:
Say you've got an enemy with several surfaces. But only one surface is flammable. It is hit with fire. But you only want the portion of that surface hit with fire to be shown as flammable. So you need to preserve the material coming in from the mesh resource surface material and since only this enemy is getting hit by fire you need it on the mesh instance material overlay. If in addition to that any selected unit has a blue tint you'd want to overlay that blue tint using the material overlay from the geometry inheritance. Right now if you tried to do this I believe when you put the fire texture on the instance it would effectively erase the base texture and when you put on the selected texture it would effectively erase the fire texture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants