Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Better Shaders - An improved Surface Shader system for Standard, URP, HDRP

Discussion in 'Assets and Asset Store' started by jbooth, Jan 29, 2021.

  1. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457


    Better Shaders is a system which targets the following goals:
    • Write Lit Shaders in a simple format, akin to Unity’s Surface Shader system
    • Shaders automatically compile to Standard, URP, and HDRP pipeline
    • Shaders can be distributed and packaged for the asset store without Better Shaders
    • Shader creation is more modular for developers and users of those shaders
    If you've written a surface shader, Better Shaders will feel right at home to you, and surface shaders can be quickly ported to the system and immediately compile in URP, Standard, and HDRP. Better Shaders cleans up many of the quirks of the surface shader abstraction, massively improves what you can do with includes via it's subshader system, and even lets users graphically stack existing shaders on top of each other to create new shaders.

    For technical information about how this works, consult the online Documentation.

    Stackable Shaders


    Going beyond a surface shader replacement system, Better Shaders allows users to stack shaders together to create complex effects. For instance, this image was created by stacking these shaders on top of each other:



    Let's break down this example. At the top of the stack is the LitTessellation shader, which internally inherits from the Lit shader, and only implements a function to do the tessellation itself. Next we stack a moss effect onto it, which gives us moss based on the angle/height of the height texture. A puddles effect is applied after, followed by a UVShear modifier, which bends the UV coordinates for the two wind effects below it.

    The same can be done via code:

    Code (CSharp):
    1. BEGIN_SUBSHADER
    2.    "LitTessellation.surfshader"
    3.    "Stackable_Moss"
    4.    "Stackable_Puddles"
    5.    "Stackable_UVShear"
    6.    "Stackable_Wind"
    7.    "Stackable_Wind"
    8. END_SUBSHADER
    This lets you write and combine effects in a modular way, from multiple authors. Want to add Vegetation Studio support to your new shader? Simply subshader in its code, or stack it. Sub Shaders don't just include code, but also properties, cbuffer entries, local keywords, etc. And you can even write them to allow multiple inclusion if you need to stack them more than once!

    Better Shaders also includes custom Material Property Drawers to make your materials look better, and works with Shader Graph Markdown. You can even write Custom Editors for individual shaders, and they will be automatically combined into one editor for stacked shaders.



     
    Last edited: Feb 16, 2021
  2. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    183
    Hi, I like the idea as it prevents `reinventing the wheel over and over again`. However, do you combine the subshaders somehow (to a single shader file) and/or do we have some performence drawbacks when using it?
     
  3. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    There's no overhead added by stacking shaders - they get combined into one shader, and the boilerplate that makes it possible gets stripped by the compiler.
     
    firstuser and cxode like this.
  4. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    183
    Nice! :)
     
  5. Emiles

    Emiles

    Joined:
    Jan 22, 2014
    Posts:
    61
    Am i missing something or is there a release date for when this will be available?
     
  6. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    I'll be submitting fairly soon.
     
    FlaxenFlash likes this.
  7. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    Submitted..
     
    bac9-flcl likes this.
  8. Emiles

    Emiles

    Joined:
    Jan 22, 2014
    Posts:
    61
    Look forward to trying it out, As usuall, amazing work!
     
  9. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
  10. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    @jbooth you are the answer to my prayers.
    I was seriously going to stay on built-in forward render forever.
    The shader graph is a joke (it doesn't even have a final color modifier), and direct coding for URP and HDRP is a total nightmare.
    Your plugin could change that completely.
    I'll read the docs in depth.
     
  11. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Does Better Shaders also work for HDRP Unlit shaders? I have a pretty complex unlit atmosphere shader that works in HDRP, but I'm not able to get _ENABLE_FOG_ON_TRANSPARENT working properly with it. I tried porting the shader to a custom Shader Graph node, as HDRP Unlit Shader Graph shaders have a "Receive Fog" toggle, but I was unsuccessful. Is this something Better Shaders supports?
     
  12. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    Well it supports unlit shaders. Not sure about the fog issue though..
     
  13. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Ok I read the docs, but it seems Better Shaders doesn't support custom lighting functions like surface shaders.
    It wouldn't be a big deal for me except for two things: anisotropic shading for hair and "wrap around" diffuse to simulate SSS (with color tint ideally).
    Another advantage of custom lighting functions is to use a simpler shading than PBR for performance.
    So, is there any way to implement that with Better Shaders?

    Great work by the way! Unity should hire you to fix their SRP mess.
     
  14. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    I mean you can make an unlit shader and pipe anything you want into albedo. This is certainly viable for URP or Standard Lighting, where you have forward renderer's and easy access to light data. Or you can write your own templates, for a custom SRP even.

    The problem with having a custom lighting function is it would be entirely different for each pipeline, and by the time you're done with it, it wouldn't be much less code than just implementing your lighting in an unlit shader. That said, the whole point of the surface shader concept was to protect the user from the complexity of complex lighting models.
     
  15. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    So I added abstractions for grab pass/scene color and depth buffer lookups. On standard pipeline, it does a grab pass- on SRPs it samples the opaque texture, which doesn't have the overhead of GrabPass. Looks like this:

    Code (CSharp):
    1.  
    2. BEGIN_OPTIONS
    3.    GrabPass { "_Grab" }
    4.    Alpha "Blend"
    5.    Workflow "Unlit"
    6. END_OPTIONS
    7.  
    8. BEGIN_CODE
    9.     void SurfaceFunction(inout Surface o, ShaderData d)
    10.     {
    11.         o.Albedo = 1 - GetSceneColor(d.screenUV);
    12.         o.Alpha = 1;
    13.     }
    14. END_CODE
    15.  
    16.  

    //The depth texture API is:
    float GetSceneDepth(float2 screenUV);
    float GetLinear01Depth(float2 screenUV);
    float GetLinearEyeDepth(float2 screenUV);
     
  16. Camarent

    Camarent

    Joined:
    Feb 19, 2014
    Posts:
    168
    Hello, @jbooth !
    Will you plan to support 2021.1/2021.2 or only LTS?
    I am working with URP and HDRP in one project do i need to be aware of some caveats related to better shader system?
    If I use scripts for switching pipeline back and forth in editor will it recompile shaders accordingly?
     
    Last edited: Apr 19, 2021
  17. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    Official support is tied to LTS versions, though I may provide support for tech releases to enterprise customers on a case by case basis.

    Better shaders checks for the presence of the render pipeline via an asmdef file and sets a define for which pipeline to use, and compiles shaders for that pipeline. If you have both pipelines installed, it would compile the shader for which ever pipeline it detects first, so you would need to modify the system to determine which pipeline is currently active, and figure out a way to detect when that changes. As far as I know Unity doesn't have any kind of hooks for that stuff. If that was general enough to handle all cases and wasn't brittle, it would be useful to merge that change back.
     
    FM-Productions, Camarent and hopeful like this.
  18. xiao-xxl

    xiao-xxl

    Joined:
    Nov 16, 2018
    Posts:
    48
    Does it supports the URP 2DRenderer ?
     
  19. nasos_333

    nasos_333

    Joined:
    Feb 13, 2013
    Posts:
    13,269
    Hi Jason,

    A few questions, does this cover all possible shader scenarios, e.g does it do grab pass (for refraction) and camera depth sampling in all pipelines automatically and how is this handled ? e.g. do i write the methods in Standard pipeline and convert automatically to URP and HDRP ?

    Also does it support changing the vertex shader and then define the same changes in the shadow passes, e.g for leaf shaders that need wind ? Will the modified shadow casting pass also convert to URP - HDRP similar passes ?

    Do these functionalities have example shaders implemented for direct use ?

    Thanks
     
    Last edited: Apr 27, 2021
  20. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    In the case of depth sampling and grab pass, there are functions you can call that return the appropriate data for each pipeline. In the case of grab pass, this is very different on SRPs than Built in, since SRPs don't really have grab pass but rather an opaque texture that can be sampler. There is also an example of this API like 2 messages above yours.

    By default the vertex shader modifications are used in all passes, but if you want to do different things in different passes you can #if _PASSSHADOW to do pass specific code.

    All the documentation is available online, so you can see all of this for yourself.
     
  21. nasos_333

    nasos_333

    Joined:
    Feb 13, 2013
    Posts:
    13,269
    Great, thanks a lot for the information, great work
     
  22. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    Is it only for shader developers or can it be used for the rest of us?
     
  23. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    It's designed for shader development, primarily.
     
  24. superMario99

    superMario99

    Joined:
    Apr 21, 2021
    Posts:
    38
    i see there is some extensive sample shaders though, so should be nice as example too
     
  25. mailfromthewilds

    mailfromthewilds

    Joined:
    Jan 31, 2020
    Posts:
    217
    Hey man I am wondering, ive been struggling to add Hybrid Renderer V2 to my game, because it requires at least URP or HDRP . I tried adding URP but then my surf shaders were incompatible. I failed to convert them manually. And recreating them in shader graph is something i tried as well but i quickly realized it would take me ages (assuming i didnt fail in the process, and that is very likely too)

    my built-in-pipeline surf shader has about 250 lines - can i make it URP-compatible with your plugin? i saw your video and conversion seemed very easy, basically pasting old SURF method to your surf method, and old VERT method to your vert method, but will work in my case? I need the plugin only for conversion of that specific shader and nothing more so it would be disappointment if I bought it and failed to convert

    I have these methods:
    - struct Input
    - void vert (inout appdata_full v, out Input o)
    - fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten)
    - void surf (Input IN, inout SurfaceOutputStandard o)

    BTW ive never written a shader by myself but if its just copy pasting then i may be able to do it
     
  26. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    It's more than just copy pasting- depending on what the shader does you might need to understand more or less of it to do the conversion. If you can manage that or not isn't something I can really answer..
     
  27. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    It seems like your surface shader uses a lighting function, which Better Shaders didn't support.
    It's still the case, right? @jbooth
     
  28. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    Kind of depends on what is done in that function. You can make an unlit shader and use GetSun() to get the dominant directional light and color, or call any of the SRP specific lighting functions to get the data needed, but in an SRP world there's no such thing as a simple lighting function like this anymore.
     
  29. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    Hello Jason! I just recently purchased BetterShaders, pretty stoked so far!

    I do have a feature request though, I didn't see any thing in the manual about this and haven't had to time thoroughly dig through the source code. Some of my include libraries are automatically generated with my own scripts and would like to be able to do my code generation directly inside better shaders.

    My request is to include a new block "Processors" that lets you define extra shader code processing objects.
    When compiling a shader it loads or creates instance of defined processors and parses the text;

    usage example in surfShader:
    Code (CSharp):
    1. Processors
    2. {
    3.    // load processer saved as object and
    4.    // modify source .surfaceShader txt before compile
    5.    pre instance: "Packages/com.foo/SavedSO.surfProcess"
    6.  
    7.    // create a instance of type 'FloatToHalf' and run
    8.    // before saving as .shader
    9.    post type: "FloatToHalf"
    10. }

    prossesor script example:
    Code (CSharp):
    1. //BetterShaderProssesor derived from ScriptableObject
    2. //replace float types to half
    3. public class FloatToHalf : BetterShaderProssesor
    4. {
    5.    // gets the entire shader as text and lets you make modifications
    6.    public override string Execute(string txt, bool post, bool instance)
    7.    {
    8.       if(post)
    9.       {
    10.          shader = txt.replace("float ", "half ");
    11.          txt = txt.replace("float,", "half,");
    12.          txt = txt.replace("float(", "half(");
    13.          return txt;
    14.       }
    15.       else return txt;
    16.    }
    17. }
    18.  

    pretty simple example but it would allow alot of flexability. One cool thing is you could do this to create defines that do things not possible in current shader syntax.

    example:
    Code (CSharp):
    1.  
    2. REQUIRE(FOO,"fooPath/fooStuff.hlsl")
    3.    //some code..
    4. END_REQUIRE(FOO)
    5.  
    6. // custom processor will replace above with
    7. #ifndef FOO_INCLUDED
    8. #define FOO_INCLUDED
    9. #include "fooPath/fooStuff.hlsl"
    10.    //some code..
    11. #undef FOO_INCLUDED
    12. #endif
    13.  
     
  30. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    So I can see the idea of having some post generation interface that allows you to process the resulting shader code, but everything in your example with the defines you can already do.
     
  31. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    You're right about the Macros, I was a little brain dead from scouring through all the URP shader code yesterday. I mainly meant that you could supply custom syntax for a post shader modification. I ended up modifying better shaders to add a callback right before it saves the shader. I think this might be more reasonably to add than a whole separate block code system, as the needed usage would be fairly small and specific cases. For me, there are a few specific default functions from the URP shader library that I need with a very slight modification, rather than copy and past things I'm just reading from the original and changing the name, adding my small modification and saving it into the shader.
     
  32. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    So I have been really digging in with BetterShaders and have to say... this is probably the best Asset I have ever purchased! It is making my life so much easier, I can't believe Unity didn't bother do something like this themselves.

    I am working on a stylized lighting shader and the stackable system is a godsend! Instead of having all these include files for various functions and stages all over the place I just make stables for each phase of the lighting and it keeps everything tidy and easy to debug, brilliant!

    I do have two small quality of life suggestions, it would be nice if the "Export Pipeline" dropdown remembered that last selection you had, also it would be nice if the shader list in the stackables had a toggle for each shader so you don't have to completely remove a item if you want to toggle one off really quick.

    Thanks for making this awesome asset tool!
     
    atomicjoe likes this.
  33. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Pin this.
     
  34. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,085
    This sounds like it would make excellent content for a review on the Asset Store.

    The more of those Unity sees, the more likely they will be to actually do something about their mess... (the one this asset fixes).
     
    atomicjoe likes this.
  35. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    Hey Jason, I found a bug with custom templates, in ShaderBuilder.cs around line 155 when comparing template names 'tmp.adapterName' will include quotation's while 't.Name' won't making the comparison fail if you follow how it's done in the documentation.

    example:
    like in the documentation this will fail
    but this will work
     
  36. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    Ok, I have purchased it, because I would like to see, if it is something for me.
    Could you please somebody point me in the right direction about how to write NPR shaders
    with this tool, like toon shaders or something similar.
    Thanks in advance for any help with that.
     
  37. Abended

    Abended

    Joined:
    Oct 9, 2018
    Posts:
    142
    Just checking before I buy. I am a super newb when it comes to shaders. I have written a few in shadergraph, but I am not versed in HLSL. I have an issue right now that I feel like this would resolve. I have my own custom shader in shadergraph, and I have an asset I've purchased that is HLSL. I have tried adding them as separate materials to the same mesh, but they both need to rely on the same rendertexture, which I can set manually in the editor, but when I try to do it via a script, it seems to remove the rendertexture from one shader as I add it to the other. I love the idea of stacking, and although I know I couldn't make it work today, it seems like I can figure it out eventually. but could the stacked shaders share a RT, or at least point to the same dynamic RT? Thanks!
     
  38. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    this isn’t something stackables solve- first, to use stackables, everything needs to be authored in Better Shaders. Second, you can share a render texture across multiple shaders, or stackables, shouldn’t matter how the shader is authored.
     
  39. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    As far as I know, it is mostly for creating different terrain shaders - very limited usage for me.
    I have already purchased most of the shaders for terrains and the developer just flood us
    with even more such shaders all the time.
    I was hoping for create toon or similar shaders with this tool, but nobody seams to know how to do it,
    even the developer. I am a bit dissapointed.
     
  40. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    Toon shaders are about modifying lighting- this tool is about abstracting the lighting systems of HDRP/URP/BIRP so you can write one shader and have it work across all of them. If you want to write a custom lighting system, you can do that, with this tool or as raw HLSL code in whatever render pipeline you want - but it's not my responsibility to teach you how to write a custom lighting engine just because you purchased an asset for a few dollars.

    This tool also has nothing to do with writing terrain shaders specifically. You can write whatever type of shader you want in it, including toon shaders. Better Lit Shader, Space Graphics Toolkit, Paint in 3d, and Vegetation Studio among others are written in Better Shaders, and they have little to do with terrains.
     
  41. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    Ok, thank you for the answer. I know, that you are super busy, but I am just looking for the advice.
    I am actually after something similar to such graphics - how to approach that with your tool.
    I would really like to learn, how to write shaders, but just need to get started somehow.
    Maybe somebody else has some ideas about.
    NPRexample01.jpg
     
    Last edited: Jun 25, 2021
  42. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    As far as I know, such shader need to have many different passes: alpha, color, black & white, z depth
    and detail. If I create such passes, is it possible to overlay them with Better Shaders tool?
     
  43. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    I guess, one cannot get any help here. What's a pity, it looks interesting, but one is entirely on your own.
    No support at all.
     
  44. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    People aren't here to teach you how to write shaders, this is a support thread for a product, not your personal training thread. There are thousands of places on the web to learn shaders, please take it out of this thread.
     
    Ziddon, Mohamed-Anis, OCASM and 2 others like this.
  45. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    I do not understand you.
    Are we not allowed to ask questions here at all?
     
  46. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    By the way, the asset is still on the sale:
    https://assetstore.unity.com/packages/tools/visual-scripting/better-shaders-standard-urp-hdrp-187838
    Grab it, while you can. It is definitely an interesting package and probably one of its kind.
    I just want to figure out, what kind of questions, one can ask here in this thread.
    NPR = Non-photorealistic rendering - https://en.wikipedia.org/wiki/Non-photorealistic_rendering
    is out of the question, as well as the questions about how to write shaders in general.
    At least I got some response from the developer and that is a positive thing.
    I believe in team work with Unity and without the developers like the author of this package
    the task of creating a new applications with Unity will be very hard for single creators, like myself.
     
  47. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,457
    Don't play dumb for attention, you know the difference. If you went into a forum about building guitars and started complaining that no one would teach you how to play Metallica songs, would you pretend you didn't know the difference?

    If you want to learn how to write shaders, there are plenty of resources out there to do that. This is a support forum for asking me questions about the asset BETTER SHADERS. It's not a place for you to post photos with a couple of graphics buzz words you overheard and then complain that someone isn't going to write a new render engine for you 20 minutes later. You can easily post your own threads about general questions on the forums, polluting my support thread with this is simply rude.
     
    Mohamed-Anis, Autarkis and OCASM like this.
  48. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    @jbooth It's clear Artini doesn't know shader programming an hence doesn't know what is the use of Better Shaders since it doesn't allow for things like toon shaders because it's not designed to support custom lighting functions.
    Maybe you should just make this point clear in the asset store description and specify Better Shaders is aimed at shader programmers ONLY (because it is).
    Instead of being so harsh, just point people in the right direction.

    @Artini Better Shaders is not what you are looking for. Amplify Shader Editor is much more suited for your use case and you can do custom lighting functions in it without coding.
     
    Last edited: Jun 26, 2021
    Passeridae likes this.
  49. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    Thank you very much, @atomicjoe, for understanding my situation and yes I have purchased Amplify Shader Editor long time ago, as well. I was attracted by Better Shaders, that it can make easier for me to make shaders for different pipelines, but apparently I am not ready for them yet.
    @jbooth Point taken: you just do not want to be disturbed by my dumb questions and you think,
    that I am only rude. I apologize, for all my harsh behavior, because apparently you think,
    that your customers are only bothering you with some stupid questions.
    While I am approaching many different people during my work, I always try to help them with my knowledge,
    as best as I can, even if sometimes is only a matter of searching on the Google with the right keywords.
    And yes, I was hoping, that you just give me some specific advice, but I was wrong.
    Sorry again.
     
    Last edited: Jun 26, 2021
  50. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    No one is. Even Unity isn't LOL.
    Just choose a render pipeline and forget the rest.
    The general consensus seems to be to choose URP and just ignore HDRP if you want something future-proof.
    I personally stick to the built-in render pipeline for compatibility reasons and because it's more flexible and powerful than both URP and HDRP, even if it's harder to optimize. (with URP you have better performance by default but it's much more limited)
     
    tonyomendoza likes this.