@DanielKotzer said:
Yes but then you double the amount of geometry in the scene, which is taking a lot of computing power, can't I just save the old shaders in an array/dictionary, assign the masking shaders, take the image I need from the viewport, and then assign the old shader back?
Well, it is true that it doubles the amount of the geometry in the scene, which depending on much geometry you have in the scene, this could be a deal breaker. Are you having performance issues?
The problem with changing materials/shaders is that in Godot, there is no way to tell a Viewport to render an image, whether it be a custom Viewport or the main game Viewport. If there is a way, I have not been able to figure out what it is, despite having kept an eye out and done many Google searches on the topic.
Without the ability to tell the Viewport to render, switching the materials/shaders and caching the old materials/shaders will not work. You can indeed cache the materials/shaders and switch them during run time, but without telling the Viewport to render, you will have to wait a single frame before the color mask texture will be updated, which means the color mask shaders will be visible to the player every other frame. Even at high frame rates, this would give a flicking appearance as the materials constantly change back and forth.
I totally agree with you that changing the shaders would be the idea solution, but as far as I know this cannot work in Godot due to the inability to tell the Viewport to render an image.
That said, I am by no means a Godot expert, so it is quite possible that there is a way, but I am just unaware of it. If you can find a way to workaround/fix the issue, go for it! I just don't personally know what it would be.
(Though if you do find a way, I would be curious to how it works! I have some projects that could benefit from a workaround)
Also, on an aside, I'm not sure it would actually improve computing power, though it would reduce the amount of memory used for a scene.
Even if you could switch the shaders out and tell Godot to render the scene again, you would still be rendering the scene twice, one for the normal/player-viewable image and another for the color mask.
The GPU would still have to render 120 frames a second for a 60 FPS game (60 for normal rendering + 60 for color mask rendering).
However, it would reduce the memory requirements, making the game run better on computers with limited VRAM where the amount of VRAM is the bottleneck.
It would be interesting to test and see if there is a performance benefit.
@Megalomaniak said:
Um, both of you, we have material overrides, and material passes... while I haven't tried to use either for something like this, I have a sneaking suspicion setting and clearing them from code might be worth a closer examination.
True, that is something I have not played around with. If there is a way to specify which render pass gets rendered to which Viewport and/or override materials only for specific Viewports, then that would be a good solution.
Otherwise, as I mentioned above, changing the material wouldn't really help. I do not think it is possible to force a Viewport to render an image, which is necessary if you want to change the materials without the player seeing the material swap in-game.
There very well could be a way, but from what research I have done online and my own personal testing, it doesn't appear to be possible currently in Godot. That said, I am by no means opposed to being wrong and figuring out there is a way! I would definitely be interested in knowing what it is, as I have my own projects that could benefit from a solution to this limitation.