Completely closing the door on custom nodes really sucks. I’m glad that sub-nodes are becoming more powerful, but unless you embed a full visual scripting system inside of subnodes, it will never be as powerful as custom nodes can be no matter how much work you put into it.
The main things that not having code running when generating shader code prevents is the density of functionality a given node can have. As a simple example, lets say our node needs to sample a texture and select some data from it. In code, it trivial to have an option on the node which the user can set, and write the code accordingly, such that there is no runtime cost incurred.
However, in a subgraph I cannot do this. My choices are to either write multiple copies of the node and have the user select the correct one, or have runtime properties and code select the correct data, which is less performant.
This easily compounds as subgraphs are nested or functions gain more options. I use code generation like this in MicroSplat, and have several hundred options- a level of complexity simply not possible in any commercial shader graph, with the type of optimizations which just aren’t possible in a graph either.
A possible improvement would be a way to expose enums and options to the use of the node, along with an internal branching structure which decides which graph gets chosen based on these settings, but that still ends up in duplicating graph nodes all over the place.
Given the removal of surface shaders, the introduction of SRPs that make hand written shaders a nightmare, and the removal of custom code from the shader graph, it really feels like Unity is trying it’s best to make it hard to write shaders in their engine. I would suggest, if they think that the graph is a fully capable replacement for our ability to write shaders, that they re-write their entire shader library using a graph and see if it holds up to the task. Rewrite Lit, LayeredLit, the Standard Shader, a decent terrain shader, etc. Also rewrite any complex node you have without using the internal API - because that is what you are asking us to do. Because until you can do that, with overall better workflow, your graph is not a replacement for code.
Also, as a side note, the idea presented in that GDC talk that shaders should become entirely driven by artists and not require code is a foolish notion. The best work with graph based systems comes when coders and artists are able to work together, not when one is shut out from the process. In any visual scripting system, the ideal case is that coders can solve hard code-centric problems and expose the results as simple nodes for the graph user. If this wasn’t the case, then the only nodes you would ever add to a shader graph would be the language intrinsics themselves, right?
Imagine if this same set of outcomes was pushed on visual scripting:
- Make writing C# in the engine extremely hard and unmaintainable with new Unity versions
- Make C# not portable unless you use visual scripting
- Focus on artists and designers writing all game code to the point of shutting out coders from the process
- No way to write custom nodes
Sounds pretty crazy, right? But this is effectively the approach being taken here.