I’d like geometry shaders to be skipped in shader graph / surface shaders and mesh shaders to be given their rightful engineering time. Mostly because only intel wanted them, and there’s better ways to do it, and apple is right tbh.
I don’t think it’s a good idea to develop for essentially, a dead technology like geometry shaders. A far better way is empowering compute and bringing that much closer. You can do better more performant “geometry” shaders this way.
TLDR:
Mesh Shaders = yes
Geometry Shaders = no
Better compute shader support = yes
We’ve played with C# shaders a bit, and personally I like them a lot. You can have proper public API and interface declarations and visibility control to manage the complexity. With the right setup, the basic syntax is very close to HLSL. Most of the conversion work goes into replacing all of the macros with interfaces or static branches. I think the resulting code is actually easier to read, and you can use all of the fancy C# IDE features to jump around the code and refactor things as well. Major downsides are: you can only use a subset of C# (similar to burst), and it isn’t 100% compatible with standard HLSL.
Yes!
#1 is what ShaderGraph does. And what we could easily expose in a Surface Shader system relatively quickly. Then it’s a question of what functionality we could expand easily from there.
#2 is internal and tightly coupled to the SRPs, like you say. We would have to start a larger discussion with SRP teams about making that more modular.
#3 is basically what the SubShader backends did. The new Targets and Stacks system is designed to replace that and make it more flexible. A Surface Shader would have to provide the desired Target and settings for that Target, to generate all of the passes necessary.
I think the key there is to take several people who have pushed surface shaders hard and let them port to the new system. MicroSplat is a good use case here because it covers a lot of ground, and I’m betting it would be pretty easy to get a few other people to do that as well. It’s hard to know exactly what you’re missing until you try to do something reasonably complex…
It definitely feels like a future place of research such that you could do a lot more without modifying the underlying SRP, as well as allow asset store authors to provide really custom lighting systems that automatically integrate with other systems. That’s potentially super cool. It’s great to have source access, but it’s not great to own a ton of source code, and in general SRP requires large amounts of ownership once you customize it. Thus, I don’t think we’ll see custom SRPs in the store- but we would see custom lighting and rendering models which can be plugged into an SRP, much like another post processing effect.
Do you have more information on this yet? For instance, I always want to generate my shaders with support the widest range of features available, especially since I don’t necessarily have the hardware to check everything on. When a user says “I’m having this issue in single pass VR”, I can say “surface shader” and know it’s most likely not in my code. I don’t see a need to generate a version of the shader without VR support, for instance, except maybe to not have to strip its variants later. I guess there are areas people might want to disable, like shadow passes or motion buffer passes, but by default it kind of just wants to work for the SRP it’s installed into.
It’s funny, because my own coding style has drifted towards top down code over the years, where there’s some code that just runs everything- and DOTS and SRP are both an attempt to move Unity in that direction. However, the asset store and I’d argue many Unity users want the opposite of this- they want systems that plug in, override, or add to things to existing systems in a friendly way. While I’m not going to advocate bringing something like Grab Pass back, the more things can plug into an SRP or shader system to extend and modify it, the more useful they become. And I’d gladly sacrifice a little performance for more usability in this area (gains can be made elsewhere).
It’s all about scaffolding layers. At the top layer you could have API that lets you dump in all the surface data into a function and the internals of that function will do all the future-proofing for you in a pipeline-agnostic manner. But then you can have lower-level APIs that expose the different modules and would likely be pipeline-specific, but still abstract the implementation details and keep the user code short and clean. Users could also completely replace a module with their own custom setup if necessary (replace actual shadows with blob shadows).
It actually does. They just don’t call it that in the code.
As long as it has feature-parity, I think this is a fantastic solution. Mimicing the way Burst does it with a [ShaderCompile] attribute and a Shader Inspector would tie in perfect with the new Unity ecosystem.
You won’t have feature-parity to built-in without this, as Built-in has a straightforward way to do NPR that is pretty much closed off in the SRPs.
For what its worth, I actually hated surface shaders. I ran into too many issues trying to find the magic macros, magic variables, and magic functions, most of which had terrible names, and some of which made assumptions about my code structure and own naming conventions that were incorrect. By the time I got anything working, my code looked like the output of a random number generator.
Ha, yeah, well some of the voodoo in there was not great. Like the whole “What space is viewDir in? Oh, did you assign a normal?”, and “what do I have to name my variable to get the second UV coordinate?”. I think the current output of the shader graph where it has very explicitly named TangentSpaceViewDir and WorldSpaceViewDir available makes a lot more sense- just let the compiler strip it if you’re not using it.
But the abstraction level was fantastic compared to dealing with vertex/fragment shaders.
Yeah performance override should be able to be done, short circuiting path so we can get something done with the warning that we are leaving home into the wild west.
Being able to peel away layer progressively to do what we want.
Aside from what already been said, multiple subshaders.
But I think the real problem with Graph is that it is not code. I tried making a relatively simple shader with it and found that it is really time consuming to do simple and common thing like chained arithmetic and swizzle. It’s also difficult to navigate, especially when debugging - when zoomed out, you can’t read anything, and when zoomed in, you can see the equivalent of 4 lines of code.
This pretty much sums up node UIs for me. It’s probably solvable with some innovative design but it’s a big challenge. Maybe all that effort could be spent on making code more approachable to non-coders so they won’t feel the need to shelter in a GUI. Shader code is terrible for boilerplate, repetition and inscrutable jargon. We already know how to make code and APIs readable and easy to learn.
Good Day Everyone I have a Feature Request for Shader Graph.
When working with shader graph I noticed that If my nodes are connected to the Master, everytime I update it in some way, adding more nodes, properties, anything the more effort I put in the slower and slower It gets, so I have to stop, wait for Unity to come back from it’s faint so I can go back to work again. Well It would be normal If I was making a monster shader with mindblowing effects, but It seems more like something inevitable, the fact is, my shader is not that PC killer stuff, In fact, It seems to be more related to the number of nodes Itself. It also happen when creting new properties If you have many, input the property’s name, hit enter and prepare for having to wait for Unity to finish Its seizures. My PC has 8GB RAM, a core i5 and a GTX 1080, so It’s not that bad to have trouble that easily.
I imagine It may be related to the fact that Unity has many systems and sub-systems all working to provide all f It’s features, so when It tries to update the shader It ends up having to make a lot of effort and takes time. If that’s the case, a solution would be to make Shader Graph a separate program, make It standalone. Let it import your mesh in, maybe entangle it directly to the prefab in Unity r something, let me have a simple model viewer so I can swiftly check the results. Make it in a way that It does not have to deal with many stuff to update, just the shader stuff, In fact, what If I want to close Unity altogether and only have shader graph working? It would be interesting to just open the Shader Graph and work on a shader instead of having to open Unity, open your project, waiting for it to load all of It’s thousand functions just to work on that.
Another benefit of that was having Universal shaders, in other words, a shader that works between projects. If I have a project in which I want an especific shader, I could just import It from the new Shader Graph If I have previously made It, instead of having It directly associated to the project files. This way, If I want to make a new project and still have that same shader I wouldn’t need to open my older project and export the package or doing the whole shaderwork all over again, I just pull it from my shader Graph library and that’s It.
This thread is not about the shader graph, but rather Surface Shaders or some replacement for them in the new pipelines. There’s an entire forum for shader graph requests.
Everyone else has already mentioned what I’d like to see for surface shader functionality, especially jbooth. To summarise what I use surface shaders for that isn’t possible with shader graph:
Custom vertex shaders.
Custom light functions/models for stylised shading.
Additional passes, with properties (name, tags, zwrite, blend, etc).
Expose surface properties in the material (opaque/transparent, double-sided, etc). Currently this is locked to the master node, so you have to create multiple shader graphs for opaque and transparent variants.
Multiple sub-shaders for different platforms/variations, though nowadays I’m moving towards using keywords instead.
Also, defining a CustomEditor. I find the default material GUI to be very chunky and messy, especially for complex shaders. Artists are often overwhelmed when dozens of sliders and texture slots pile up in the inspector, so it would be nice to be able to compact things into drop-downs, headers, and collapsible GUIs.
Hi! Thank you for creating this tool, for me it’s awesome. I know i’m a beginner on this, but it’s kind of cool the way you can dinamically create shaders, people who are experienced on creating their own shaders in code will say that “it’s not so much of a deal”, but honestly, the ShaderGraph creates a far more superior understanding of what is happening, than just throwing code and crossing hands to see if it compiles.
Aside from that, i really hope for more maturity and stability for now, the community has to understand the tool before making it more complex. For example, i filled a bug for the Enum properties and keyword nodes, that thing is really buggy, and it’s something that would make my graphs a lot more dynamic, i checked different versions and the beta just for that feature.
Just found this thread and also have some opinions about it. I like using ShaderGraph, but the options it allows for customization are just not good enough. I’m really tired of having to “Copy Code” on a master node and then changing the bits and pieces I need, to the point of having played with automatic “shadergraph post-processing” which feels just stupid given what this system is.
Things that could help in the short term with ShaderGraph:
whoever thought that all those scope checks when connecting nodes would be a good thing was wrong. They prevent so many things that actually work. I had to go into graph files and manually connect nodes just to work around this bad UX decision. I understand this might help beginners, but please just add a toggle “turn scope checks off”, compiler can tell me just fine what I did wrong…
injection points for custom code at different places in the graph. Currently custom functions are added at the top, and to make matters worse they are added in different places in URP and HDRP. Injecting code through custom function works, but not being able to define where that is injected is bad.
(Example: I was able to add procedural instancing support to vanilla URP through injected code in ShaderGraph.)
ability to change input and output types of vert/frag directly. This is necessary for e.g. geometry/hull/domain and in the future mesh shaders. (currently have to do that manually)
I’d like for ShaderGraph to succeed - our artists were able to use it very flexible. However, as tech lead I need the ability to adjust the “template” they work in without having to go all-in and modify SRPs directly. This would be my preferred way - I can properly create custom masters, and they can work on graphs for those. (Yes, this is possible with hacks, as e.g. ShaderGraph Essentials shows)
Here’s an example of the type of workarounds we currently have to do:
This allows our artists to build URP shaders with ShaderGraph that support procedural instancing (“GPU Mesh Particles”). Those subgraphs use a number of really hacky hacks to inject code into the output shader. This kind of stuff must get easier.
@Owers custom editor support is in latest 8.x/9.x on Graphics repo if you want to try it out.