Search Unity

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

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

  1. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    @atomicjoe That is what I am doing right now. I've also sticked to the built-in render pipeline, because I am making apps for WebGL and that is quite easy with almost all assets. I have to try URP with WebGL, to see how it performs.
    My other idea was to convert shaders from URP to built-in render pipeline, because I have purchased some of the assets, that supports only URP and was hoping for easy conversion with Better Shaders. Well, one can dream at least.
     
    Last edited: Jun 26, 2021
  2. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Better Shaders supports custom lighting functions just fine- you can write your own templates for it and completely customize everything about the shaders it can produce. It's no different than amplify in that regard, which supports custom templates, and also supports hacky ways to do custom lighting that only work for some render pathways. But teaching you how to write lighting models across 3 render pipelines when you clearly don't know how to write shaders is WAY out of scope of Better Shaders Support.

    As for being harsh, it not only makes it pretty clear in the asset store description that this is for shader programmers, and I can't make people read things before they buy them. As an asset store developer I regularly get:

    1. People demanding that I fix issues in their projects that have nothing to do with my assets
    2. People threatening me, through email, review systems, etc
    3. People who think I owe them infinite amounts of my time without any compensation because they bought a $5 asset
    4. People who want me to teach them how to do game development, uncompensated, of course
    5. People who can't seem to search google, or read the asset description, and just project whatever they want it to be when purchasing and then blame you for it not being whatever they imagined.

    When I tell someone no and they can't take that as an answer, or act like any of the above, I want them out of my community. Period. Zero tolerance. They are going to do nothing but waste everyones time and bandwidth, as we see right now in this thread.

    This thread is a support thread for Better Shaders, it is the only official way Unity provides for people to get support through Unity channels. I spend a significant amount of time on support each day, and if I let it get clogged up with hundreds of people asking general programing questions and getting resentful when they don't get an answer from me in 3 hours, then I'm not only going to end up spending more time looking for actual questions, but I'm going to miss many as well, and eventually end up like many other developers who simply abandon doing support at all. Think of this like calling me up and asking me a question.

    This forum allows you to create threads on any topic you want, so if you want a general discussion on learning how to program shaders, or anything else, anyone is welcome to create their own threads on whatever they want. They don't need to pollute my support threads with this after being told multiple times that this isn't the right place for that. And I absolutely will not tolerate someone saying I give "No Support" because I wouldn't do their work for them, and wining about why no one will spend hours of their time babying them through game dev 101 when there are hundreds of well written tutorials on every possible subject in game dev out there. Keep in mind when I learned game development Google wasn't even around yet, so I just see not reading the wealth of amazing material out there as pure laziness.
     
    temps, Mohamed-Anis, Autarkis and 2 others like this.
  3. Artini

    Artini

    Joined:
    Jan 29, 2016
    Posts:
    181
    Sorry, sorry and sorry again. I appreciate all of your work for Unity developers.
    Thank you for your response.
     
  4. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    Hey Jason, I've got another question. Is it possible to add custom chain functions via the current API for custom templates? It's looking like the chaining might be hard coded? but I thought I would check before I roll my own.
     
  5. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    The same code insertion/renaming/etc happens on a custom template as it does on the regular templates, so as long as the various %KEYWORD% are in your template, along with the calls to the various chaining functions, it should work the same.
     
  6. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    Ah cool thanks! I'm working on custom lighting stuff but after switching Unity versions there was a whole lot of shader API changes leading me to have to wright an abstraction over the URP lighting. Since I'm already right there I figured "Hey why not just abstract the lighting loops as well and make them chainable"
     
  7. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    Thank you for your reply. It at least saves me from one false assumption and loss of more time trying to figure out how it all works.

    Cheers!

    I'm not going near SRP-land, or Shader Graph. From what I've read and seen, and my own experiments, it's not fun.

    Within Builtin:
    I can't quite grok the different relationships between things like the engine itself and the things its doing to/with shaders, to/with the material inspectors for shaders, how the material inspectors descend from an invisible space inside the engine, how the shaders are getting used by the engine, how cg and the cginc files bind some of this together, how packages come into play with regards their special shader editors, how to prevent them being reset, etc etc...

    It seems nothing about these relationships is well documented, discoverable, nor intuitive. And all the tutorials I've watched are almost exclusively about the shaders themselves, not all the "system-admin" that needs to be done to work with them, that is supposed to somehow be divined.

    I was hoping Better Shaders would eliminate all this "system-admin" of shaders, and the binding and messiness of getting them to do their thing, so I could just focus on figuring out how to use normals to distort textures and create refraction fakery, and effects with shaders, etc.

    I've trawled through the Unity documentation on the shaders/materials/inspector relationships, and their doc quality is at least consistent. Just as bad as their efforts to explain Mecanim, The New Input System and Timeline Signals.

    Am now experimenting with github files of shaders, to see if I can figure out the different ways each user relates to the overarching systems to get their shaders to work the ways they want within material inspectors etc.

    I want to avoid Amplify, because I think I need to actually learn exactly how the shaders work, and can be optimised, because targeting mobile.
     
    Last edited: Jul 20, 2021
  8. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    I'm afraid you will have to either start from the beginning or just go the Amplify Shaders way.
    Video-game programming in itself is a specialization of general programming. And for programming alone there are university careers, so you will not learn all this technical things from tutorials without a solid background.
    Think of it like piloting race cars: there is the driving side of things (the pilot) and there is the technical side of things (the mechanics).
    Being good at one thing will not make you good at the other, and usually they are mutually exclusive, because there is so much expertise required in each field that it takes 100% of the time of a person to master.
    You don't need to be a master mechanic to be an excellent driver.
    If you just want to make games, use the easiest technical way you can find and focus on the game itself.
    You can perfectly do shaders for mobile with any node based solution like Amplify Shaders. Optimization is more about "doing more with less" than about writing code, and a lot of the low level technical optimization is already done by Amplify Shaders under the hood, so don't worry about that.
    I would go the Amplify Shaders way in your place.
    Better Shaders is for shader programmers that want to make their life easier.
     
    Last edited: Jul 20, 2021
    april_4_short likes this.
  9. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    Cheers!

    Another problem, whilst reviewing Amplify... it doesn't work with TextMeshPro shaders. About half of what I need to do is with these shaders. In fact, all up, I'd say most of my issues have been with figuring out how to interact with TextMeshPro shaders. They're done differently, it seems, in terms of structural integration into Unity.
     
  10. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    You will need to ask this on the Amplify Shader thread I'm afraid.
     
  11. april_4_short

    april_4_short

    Joined:
    Jul 19, 2021
    Posts:
    489
    I have spoken with them directly. That's why I'm saying: Amplify doesn't work with TMP.
     
  12. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Hi, I have cleaned up some posts and moved them into their own complaint thread. This thread is for product support only, and the asset is a technical asset - you will need to have some competence or familiarity with shaders and the author will happily guide you to water, just don't make a splash if you aren't taught to swim.
     
    Mohamed-Anis, Rowlan and jbooth like this.
  13. mathsive

    mathsive

    Joined:
    Jul 3, 2013
    Posts:
    3
    FinalColorForward
    only seems to work for me when I specify
    Workflow "Unlit"
    . So if I create a stack with
    Samples/Basic/LitTessellation.surfshader
    and
    Samples/Stackables/Stackable_FinalColor.surfshader
    , the colors aren't inverted like they are when
    Samples/Basic/Unlit.surfshader
    is the first shader in the stack instead.

    Is this expected behavior?
     
  14. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    No, I'll see if I can repro it..
     
  15. mathsive

    mathsive

    Joined:
    Jul 3, 2013
    Posts:
    3
    Thanks! It's HDRP if that's helpful.
     
  16. SuperNewbee

    SuperNewbee

    Joined:
    Jun 2, 2012
    Posts:
    196
    I am probably going to take flak for this noob level question, but can anyone tell me if Better Shaders can automagically convert a simple surface shader to URP?
     
  17. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Not automatically, but the video on the asset store listing is literally me doing exactly that.
     
  18. liqid

    liqid

    Joined:
    Oct 4, 2016
    Posts:
    17
    Hey jbooth, great asset! Thanks a lot!
    It was very easy for me to convert my Standard Surface Shader to a Better Shaders shader. After that I had no problems using it with Built-in AND URP, but sadly it appears NOT to work with HDRP. I get these errors when I use the float4 ComputeScreenPos (float4 clipPos) Built-in shader helper function.
    betterShadersScreenPosError.JPG
    Here is a super simple demonstration of the use of ComputeScreenPos() which ends up in a broken shader. Hopefully you can help me out.

    Code (CSharp):
    1. BEGIN_OPTIONS
    2. END_OPTIONS
    3. BEGIN_PROPERTIES
    4.     _Color ("Main Color", Color) = (0, 1, 0, 1)
    5. END_PROPERTIES
    6. BEGIN_CBUFFER
    7.     half4 _Color;
    8. END_CBUFFER
    9. BEGIN_CODE
    10.     void SurfaceFunction(inout Surface o, ShaderData d)
    11.     {
    12.         //doesn't work
    13.         //float4 clipPos = mul(UNITY_MATRIX_VP, float4(d.worldSpacePosition, 1.0));
    14.         //o.Albedo = ComputeScreenPos(clipPos);
    15.         // also doesn't work
    16.         o.Albedo = ComputeScreenPos(float4(1.0,1.0,1.0,1.0));
    17.         o.Alpha = _Color.a;
    18.     }
    19. END_CODE
    20.  
     
  19. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    ComputeScreenPos is different in HDRP than in URP/BiRP, however you don't need it, as it's already computed for you as screenPos on the SurfaceData structure.
     
  20. liqid

    liqid

    Joined:
    Oct 4, 2016
    Posts:
    17
    Oh my bad, the example was badly chosen, I guess. Yes, you are right. In that case I wouldn't need it, but my actual shader does indeed need it, because it relies on gobal vector position data. That means, I have a object with a material using my shader and the shader does different things depending on where some completely different GameObject is in screen space. The actual global position of that GameObject is made available to the shader via a global vector. How would I transform some global position data from world space to screen space, using your better shaders asset, if the buildin function ComputeScreenPos() isn't available for HDRP?
     
  21. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    It is available on HDRP, it just has a different signature than on URP/BiRP, because Unity thought it'd be fun to make everyone's lives hell. So what you'd have to do is handle the HDRP case differently using #if _HDRP
     
  22. liqid

    liqid

    Joined:
    Oct 4, 2016
    Posts:
    17
    Oh, thanks a lot for the hint. So I looked at the HDRP version of ComputeScreenPos and saw that it now is
    ComputeScreenPos (float4 pos, float projectionSign)
    with
    o.xy = float2(o.x, o.y * projectionSign) + o.w;
    instead of the original
    o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w;
    .

    I'm still confused because in Built-In and URP the following code works as expected and I obtain from worldSpacePosition my screenPositon which is in this case also equivalent to your d.screenPos.
    Code (CSharp):
    1. float4 clipPos = mul(UNITY_MATRIX_VP, float4(d.worldSpacePosition, 1.0));
    2. float4 screenPos = ComputeScreenPos(clipPos );
    Considering the signature change in HDRP I would have guessed the following could would do the same in HDRP
    Code (CSharp):
    1. float4 clipPos = mul(UNITY_MATRIX_VP, float4(d.worldSpacePosition, 1.0));
    2. fixed4 screenPos = ComputeScreenPos(clipPos , _ProjectionParams.x);
    But sadly this is not the screenPos and because of that obviously differs from d.screenPos.

    I looked at your files and saw that you are doing
    output.screenPos = ComputeScreenPos(TransformWorldToHClip(positionRWS), _ProjectionParams.x);
    but afaik
    TransformWorldToHClip(worldPos)
    is equivalent to
    mul(UNITY_MATRIX_VP, float4(worldPos, 1.0))
    , and using this function instead yields the same results in my case.

    Could you maybe give me a hint what I'm doing wrong? Also, wouldn't it be beneficial for everyone if "ComputeScreenPos()" worked identically for all 3 Pipelines, and not just Builtin and URP? It just seems odd because everything else works flawlessly. Thanks so much for your help!
     
    atomicjoe likes this.
  23. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    my only thought is that it’s because world position is camera relative in HDRP.
     
  24. liqid

    liqid

    Joined:
    Oct 4, 2016
    Posts:
    17
    Oh, I didn't know that. Thanks you so much for that information! Now it finally works!

    In case somebody else is interested in how I fixed it:

    In the example above I just had to transform the actual non-camera-relative world position
    d.worldSpacePosition 
    to a camera-relative one using
    GetCameraRelativePositionWS(worldSpacePosition)

    Code (CSharp):
    1. float4 clipPos = mul(UNITY_MATRIX_VP, float4(GetCameraRelativePositionWS(d.worldSpacePosition), 1.0));
    2. fixed4 screenPos = ComputeScreenPos(clipPos , _ProjectionParams.x);
    If you do this, you get the same behaviour as in URP and Built-In RP.

    Thanks again for your help and sorry for bothering you this long!
     
    Last edited: Sep 24, 2021
    hopeful likes this.
  25. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    Not sure where to ask this question, here or on microsplat etc.

    I think I saw somewhere you only support LTS, however we're in need of having some things done on 2021.2 (which obviously breaks some things)

    If we purchase the Better Shaders asset, would we be able to dissect the various asset's that was made with Better Shaders and temporarliy make it work, untill actual version and support catch up to 2021.2? (considering we're not coders)

    Or, would it be best to be patient and wait for official support and updates on Better Shaders arrive for 2021.2?

    We're aiming for 2021.2 because we cant go without DLSS and raytracing improvements in HDRP 12
     
  26. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    I cannot guarantee what works and what is broken in 2021.2. HDRP shaders are extremely complex, undocumented, fundamentally unstable because of Unity's SRP design, and making it fully compatible with a new version takes me about a solid week of reverse engineering their changes. Further, there is no guarantee of when Unity will or won't change things, so if I was to do a version for a tech release, Unity might break it all the very next day. Unless you are shipping before 2021.3LTS, features like DLSS are not needed for developing your game, and trying to stay with the latest versions of Unity is likely to only cost you development time.
     
    hopeful likes this.
  27. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    Yeah we're not creating a game or shipping an app. We're creating a film and outputting using sequences and Recorder.
     
  28. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    why would that need diss? Why wouldn’t you just super sample the whole thing instead of using AI to reconstruct something similar?
     
  29. newguy123

    newguy123

    Joined:
    Aug 22, 2018
    Posts:
    1,248
    For one thing, we're not coders. After 2 years struggling with BAD AA in raytracing and TAA being absolutely useless in our use case, DLSS solved all our AA issues in raytracing.
     
  30. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    super sampling is just rendering at a higher resolution than you need and scaling it down, which is the best AA you can get.
     
  31. Slashbot64

    Slashbot64

    Joined:
    Jun 15, 2020
    Posts:
    322
    Is the Better Lit Shader included in this?
     
  32. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    No
     
  33. awardell

    awardell

    Joined:
    Feb 5, 2014
    Posts:
    71
    Should there be any problem using this with the standard pipeline in 2021.1?
     
  34. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    No, standard pipeline isn't under the rapid changes that the SRPs are..
     
    awardell likes this.
  35. mrabisch

    mrabisch

    Joined:
    Dec 13, 2019
    Posts:
    6
    Happy new year! I see tgere is a new version for better shader. How much is the upgrade fee for users that bought the old 2019 version?
     
  36. firstuser

    firstuser

    Joined:
    May 5, 2016
    Posts:
    147
    You should be able to see it once you go to the asset store page, if there is a discount it's shown automatically.
     
  37. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    $20
     
    mrabisch likes this.
  38. mrabisch

    mrabisch

    Joined:
    Dec 13, 2019
    Posts:
    6
    Thanks
     
  39. MarshallR

    MarshallR

    Joined:
    Nov 22, 2012
    Posts:
    4
    Hi. I just got BetterShaders 2021. I noticed that I can switch/change one or more layers in a stacked shader while the editor is running, and hitting the apply button will freeze the game while the shader recompiles, and then seems to proceed as normal after about 10-20 seconds. I was wondering if it's possible to hot swap layers in a stack this way in a standalone app, and as opposed to the editor. It would be really cool to dynamically reconfigure stacked shaders on the fly this way, but of course it may incur various performance penalties and so forth. There might be other ways to achieve the same effect, but I was just wondering what potential concerns might be had in doing this. Thanks for your time, I really appreciate it. Cheers!
     
  40. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    No, unity's shader compiler is not available at runtime.
     
  41. ShadowLogan31

    ShadowLogan31

    Joined:
    May 24, 2020
    Posts:
    4
    Hi, I plan to buy Better Shaders for a specific use case. Before buying it, I'd like to know if this shader I have listed below can be completely converted to Better Shader. Thanks for your time, and I hope you have a great day!

    Code (CSharp):
    1. Shader "Celestial/Earth"
    2. {
    3.     Properties
    4.     {
    5.         [Header(Flat Terrain)]
    6.         _ShoreLow("Shore Low", Color) = (0,0,0,1)
    7.         _ShoreHigh("Shore High", Color) = (0,0,0,1)
    8.         _FlatLowA("Flat Low A", Color) = (0,0,0,1)
    9.         _FlatHighA("Flat High A", Color) = (0,0,0,1)
    10.  
    11.         _FlatLowB("Flat Low B", Color) = (0,0,0,1)
    12.         _FlatHighB("Flat High B", Color) = (0,0,0,1)
    13.  
    14.         _FlatColBlend("Colour Blend", Range(0,3)) = 1.5
    15.         _FlatColBlendNoise("Blend Noise", Range(0,1)) = 0.3
    16.         _ShoreHeight("Shore Height", Range(0,0.2)) = 0.05
    17.         _ShoreBlend("Shore Blend", Range(0,0.2)) = 0.03
    18.         _MaxFlatHeight("Max Flat Height", Range(0,1)) = 0.5
    19.  
    20.         [Header(Steep Terrain)]
    21.         _SteepLow("Steep Colour Low", Color) = (0,0,0,1)
    22.         _SteepHigh("Steep Colour High", Color) = (0,0,0,1)
    23.         _SteepBands("Steep Bands", Range(1, 20)) = 8
    24.         _SteepBandStrength("Band Strength", Range(-1,1)) = 0.5
    25.  
    26.         [Header(Flat to Steep Transition)]
    27.         _SteepnessThreshold("Steep Threshold", Range(0,1)) = 0.5
    28.         _FlatToSteepBlend("Flat to Steep Blend", Range(0,0.3)) = 0.1
    29.         _FlatToSteepNoise("Flat to Steep Noise", Range(0,0.2)) = 0.1
    30.  
    31.         [Header(Snowy Poles)]
    32.         [Toggle()]
    33.       _UseSnowyPoles("Use Poles", float) = 0
    34.         _SnowCol("Snow Colour", Color) = (1,1,1,1)
    35.         _SnowLongitude("Snow Longitude", Range(0,1)) = 0.8
    36.         _SnowBlend("Snow Blend", Range(0, 0.2)) = 0.1
    37.         _SnowSpecular("Snow Specular", Range(0,1)) = 1
    38.         _SnowHighlight("Snow Highlight", Range(1,2)) = 1.2
    39.         _SnowNoiseA("Snow Noise A", Range(0,10)) = 5
    40.         _SnowNoiseB("Snow Noise B", Range(0,10)) = 4
    41.  
    42.         [Header(Noise)]
    43.         [NoScaleOffset] _NoiseTex ("Noise Texture", 2D) = "white" {}
    44.         _NoiseScale("Noise Scale", Float) = 1
    45.         _NoiseScale2("Noise Scale2", Float) = 1
    46.  
    47.         [Header(Other)]
    48.         _FresnelCol("Fresnel Colour", Color) = (1,1,1,1)
    49.         _FresnelStrengthNear("Fresnel Strength Min", float) = 2
    50.         _FresnelStrengthFar("Fresnel Strength Max", float) = 5
    51.         _FresnelPow("Fresnel Power", float) = 2
    52.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    53.         _Metallic ("Metallic", Range(0,1)) = 0.0
    54.  
    55.    
    56.  
    57.         _TestParams ("Test Params", Vector) = (0,0,0,0)
    58.    
    59.     }
    60.     SubShader
    61.     {
    62.         Tags { "RenderType"="Opaque" }
    63.         LOD 200
    64.  
    65.         CGPROGRAM
    66.  
    67.         // Physically based Standard lighting model, and enable shadows on all light types
    68.         #pragma surface surf Standard fullforwardshadows vertex:vert
    69.         #pragma target 3.5
    70.  
    71.         #include "../Includes/Triplanar.cginc"
    72.         #include "../Includes/Math.cginc"
    73.  
    74.         float4 _TestParams;
    75.         float4 _FresnelCol;
    76.         float _FresnelStrengthNear;
    77.         float _FresnelStrengthFar;
    78.         float _FresnelPow;
    79.         float bodyScale;
    80.  
    81.         struct Input
    82.         {
    83.             float2 uv_MainTex;
    84.             float3 worldPos;
    85.             float4 terrainData;
    86.             float3 vertPos;
    87.             float3 normal;
    88.             float4 tangent;
    89.             float fresnel;
    90.         };
    91.  
    92.         void vert (inout appdata_full v, out Input o)
    93.         {
    94.             UNITY_INITIALIZE_OUTPUT(Input, o);
    95.             o.vertPos = v.vertex;
    96.             o.normal = v.normal;
    97.             o.terrainData = v.texcoord;
    98.             o.tangent = v.tangent;
    99.  
    100.             // Fresnel (fade out when close to body)
    101.             float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    102.             float3 bodyWorldCentre = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
    103.             float camRadiiFromSurface = (length(bodyWorldCentre - _WorldSpaceCameraPos.xyz) - bodyScale) / bodyScale;
    104.             float fresnelT = smoothstep(0,1,camRadiiFromSurface);
    105.             float3 viewDir = normalize(worldPos - _WorldSpaceCameraPos.xyz);
    106.             float3 normWorld = normalize(mul(unity_ObjectToWorld, float4(v.normal,0)));
    107.             float fresStrength = lerp(_FresnelStrengthNear, _FresnelStrengthFar, fresnelT);
    108.             o.fresnel = saturate(fresStrength * pow(1 + dot(viewDir, normWorld), _FresnelPow));
    109.         }
    110.  
    111.         // Flat terrain:
    112.         float4 _ShoreLow;
    113.         float4 _ShoreHigh;
    114.  
    115.         float4 _FlatLowA;
    116.         float4 _FlatHighA;
    117.         float4 _FlatLowB;
    118.         float4 _FlatHighB;
    119.  
    120.         float _FlatColBlend;
    121.         float _FlatColBlendNoise;
    122.         float _ShoreHeight;
    123.         float _ShoreBlend;
    124.         float _MaxFlatHeight;
    125.  
    126.         // Steep terrain
    127.         float4 _SteepLow;
    128.         float4 _SteepHigh;
    129.         float _SteepBands;
    130.         float _SteepBandStrength;
    131.  
    132.         // Flat to steep transition
    133.         float _SteepnessThreshold;
    134.         float _FlatToSteepBlend;
    135.         float _FlatToSteepNoise;
    136.  
    137.         // Snowy poles
    138.         float _UseSnowyPoles;
    139.         float3 _SnowCol;
    140.         float _SnowLongitude;
    141.         float _SnowBlend;
    142.         float _SnowSpecular;
    143.         float _SnowHighlight;
    144.         float _SnowNoiseA;
    145.         float _SnowNoiseB;
    146.  
    147.         // Other:
    148.         float _Glossiness;
    149.         float _Metallic;
    150.  
    151.         sampler2D _NoiseTex;
    152.         sampler2D _SnowNormal;
    153.         float _NoiseScale;
    154.         float _NoiseScale2;
    155.    
    156.  
    157.         // Height data:
    158.         float2 heightMinMax;
    159.         float oceanLevel;
    160.  
    161.  
    162.  
    163.         fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten)
    164.         {
    165.             fixed4 c;
    166.             c.rgb = s.Albedo * 0.8;
    167.             c.a = s.Alpha;
    168.             return c;
    169.         }
    170.  
    171.         void surf (Input IN, inout SurfaceOutputStandard o)
    172.         {
    173.        
    174.             // Calculate steepness: 0 where totally flat, 1 at max steepness
    175.             float3 sphereNormal = normalize(IN.vertPos);
    176.             float steepness = 1 - dot (sphereNormal, IN.normal);
    177.             steepness = remap01(steepness, 0, 0.65);
    178.  
    179.             // Calculate heights
    180.             float terrainHeight = length(IN.vertPos);
    181.             float shoreHeight = lerp(heightMinMax.x, 1, oceanLevel);
    182.             float aboveShoreHeight01 = remap01(terrainHeight, shoreHeight, heightMinMax.y);
    183.             float flatHeight01 = remap01(aboveShoreHeight01, 0, _MaxFlatHeight);
    184.  
    185.             // Sample noise texture at two different scales
    186.             float4 texNoise = triplanar(IN.vertPos, IN.normal, _NoiseScale, _NoiseTex);
    187.             float4 texNoise2 = triplanar(IN.vertPos, IN.normal, _NoiseScale2, _NoiseTex);
    188.  
    189.             // Flat terrain colour A and B
    190.             float flatColBlendWeight = Blend(0, _FlatColBlend, (flatHeight01-.5) + (texNoise.b - 0.5) * _FlatColBlendNoise);
    191.             float3 flatTerrainColA = lerp(_FlatLowA, _FlatHighA, flatColBlendWeight);
    192.             flatTerrainColA = lerp(flatTerrainColA, (_FlatLowA + _FlatHighA) / 2, texNoise.a);
    193.             float3 flatTerrainColB = lerp(_FlatLowB, _FlatHighB, flatColBlendWeight);
    194.             flatTerrainColB = lerp(flatTerrainColB, (_FlatLowB + _FlatHighB) / 2, texNoise.a);
    195.  
    196.             // Biome
    197.             float biomeWeight = Blend(_TestParams.x, _TestParams.y,IN.terrainData.x);
    198.             biomeWeight = Blend(0, _TestParams.z, IN.vertPos.x + IN.terrainData.x * _TestParams.x + IN.terrainData.y * _TestParams.y);
    199.             float3 flatTerrainCol = lerp(flatTerrainColA, flatTerrainColB, biomeWeight);
    200.  
    201.             // Shore
    202.             float shoreBlendWeight = 1-Blend(_ShoreHeight, _ShoreBlend, flatHeight01);
    203.             float4 shoreCol = lerp(_ShoreLow, _ShoreHigh, remap01(aboveShoreHeight01, 0, _ShoreHeight));
    204.             shoreCol = lerp(shoreCol, (_ShoreLow + _ShoreHigh) / 2, texNoise.g);
    205.             flatTerrainCol = lerp(flatTerrainCol, shoreCol, shoreBlendWeight);
    206.  
    207.             // Steep terrain colour
    208.             float3 sphereTangent = normalize(float3(-sphereNormal.z, 0, sphereNormal.x));
    209.             float3 normalTangent = normalize(IN.normal - sphereNormal * dot(IN.normal, sphereNormal));
    210.             float banding = dot(sphereTangent, normalTangent) * .5 + .5;
    211.             banding = (int)(banding * (_SteepBands + 1)) / _SteepBands;
    212.             banding = (abs(banding - 0.5) * 2 - 0.5) * _SteepBandStrength;
    213.             float3 steepTerrainCol = lerp(_SteepLow, _SteepHigh, aboveShoreHeight01 + banding);
    214.            
    215.             // Flat to steep colour transition
    216.             float flatBlendNoise = (texNoise2.r - 0.5) * _FlatToSteepNoise;
    217.             float flatStrength = 1 - Blend(_SteepnessThreshold + flatBlendNoise, _FlatToSteepBlend, steepness);
    218.             float flatHeightFalloff = 1 - Blend(_MaxFlatHeight + flatBlendNoise, _FlatToSteepBlend, aboveShoreHeight01);
    219.             flatStrength *= flatHeightFalloff;
    220.            
    221.             // Snowy poles
    222.             float3 snowCol = 0;
    223.             float snowWeight = 0;
    224.             float snowLineNoise = IN.terrainData.y * _SnowNoiseA * 0.01 + (texNoise.b-0.5) * _SnowNoiseB * 0.01;
    225.             snowWeight = Blend(_SnowLongitude, _SnowBlend, abs(IN.vertPos.y + snowLineNoise)) * _UseSnowyPoles;
    226.             float snowSpeckle = 1 - texNoise2.g * 0.5 * 0.1;
    227.             snowCol = _SnowCol * lerp (1, _SnowHighlight, aboveShoreHeight01 + banding) * snowSpeckle;
    228.  
    229.             // Set surface colour
    230.             float3 compositeCol = lerp(steepTerrainCol, flatTerrainCol, flatStrength);
    231.             compositeCol = lerp(compositeCol, snowCol, snowWeight);
    232.             compositeCol = lerp(compositeCol, _FresnelCol, IN.fresnel);
    233.             o.Albedo = compositeCol;
    234.  
    235.             // Glossiness
    236.             float glossiness = dot(o.Albedo, 1) / 3 * _Glossiness;
    237.             glossiness = max(glossiness, snowWeight * _SnowSpecular);
    238.             o.Smoothness = glossiness;
    239.             o.Metallic = _Metallic;
    240.         }
    241.         ENDCG
    242.     }
    243.     FallBack "Diffuse"
    244. }
    245.  
     
  42. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    It's a surface shader without any unusual bits, so as far as I see it can be easily converted into the Better Shaders format. :)
     
  43. ShadowLogan31

    ShadowLogan31

    Joined:
    May 24, 2020
    Posts:
    4
    In Jason Booth's tutorial video, anything with IN.worldPos was changed to d.WorldSpacePos, what do I do in the case of places where my shader has IN.vertPos or IN.normal?
     
  44. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    829
    Can't recall off hand, sorry! Which actually reminds me of a question I had about the "automagical structures" approach (by which I mean the quoted concept):
    I didn't see it in the documentation so I was wondering - would it be possible to add a full list of autodetected names into the Better Shaders Google document? You can find them by looking at included files, but having a list copied there could be awesome, if you have the time!
     
  45. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    The fully documented shader lists them all, so if you create that to start with, it will have the full structure listed with all of them there..

    Yeah, almost anything in a surface shader can be done in better shaders, except for some extra funky pass semantics which they allowed.
     
    bac9-flcl likes this.
  46. Eltharis

    Eltharis

    Joined:
    Aug 30, 2018
    Posts:
    17
    Hi @jbooth. Just quick question - is URP deferred mode working at this point in Better Shaders? It's available in Unity 2021, gives a lot more lights to work with.
    If not, is it possible that you implement it sometime soon? I can't work in forward rendering mode in URP and switching to built-in now would be a nightmare ;/. And I need to use these shaders, it's for SGT (but not only that, I see I'd prefer to use your shaders for my stuff too). Yeah, SRP life.
     
  47. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Yeah, shipped with Better Shaders 2021..
     
    Eltharis likes this.
  48. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    This thread is now effectively closed. Support for my products will no longer be provided through Unity's forums. Discord Only.
     
    Last edited: Mar 17, 2022
  49. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Just like that? Without explanation?
     
  50. Mauri

    Mauri

    Joined:
    Dec 9, 2010
    Posts:
    2,664
    Not an owner of any of his products, but I wonder why as well. A simple "Support will be handled via Discord only from now on" (should that be the plan for the immediate future) would've been enough, but let's see... maybe he'll add this info later on?!

    Considering that Jason is usually very vocal about anything that Unity f***s up (e.g. SRP, shaders) and often criticizes them for their lack of transparency in e.g. Asset Store-related stuff, this feels kinda ironic...

    EDIT: Yeah, like I thought...
     
    Last edited: Mar 1, 2022
    hopeful and atomicjoe like this.