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

Feature Request URP + ShaderGraph final color node?

Discussion in 'Universal Render Pipeline' started by funkyCoty, Mar 9, 2022.

  1. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    719
    I was thinking of putting together an asset for a custom fog gradient. It's something I'm using in a personal project already, in my custom urp shader setup. But, I figured for a distributed version people would appreciate having ShaderGraph support to, so I've been digging into it.

    What I need for this to happen is something like this:
    • output -> my custom 'final color modifier' code -> final color

    upload_2022-3-8_21-53-48.png

    Is this feature available and I'm just missing it? Or did the shadergraph team drop the ball here? Seems like such an obvious and very easy to add feature.
     
    Last edited: Mar 10, 2022
    kripto289, customphase and JesOb like this.
  2. iamvideep

    iamvideep

    Joined:
    Oct 27, 2017
    Posts:
    118
    You can always write a custom pass (Scriptable render pass) and queue it after the post-process event. I doubt if they are going to add this functionality to the shader as it does not follow the graphics-pipeline...
     
  3. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    719
    You misunderstand what I'm asking for. This method would avoid a post process pass. It's "post processing" the material itself, not the kind of post process you're referring to where you draw a quad over the screen with a post process shader. This requires no pipeline reworking. It literally is just "ok after the lighting pass, here's another node, do what you want with the final color"
     
    kripto289 likes this.
  4. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    719
    For an example of what I mean, read the docs on Surface Shader's "Final Color Modifier"


     
  5. svenneve

    svenneve

    Joined:
    May 14, 2013
    Posts:
    79
    You would need to rebuild the shading your self, not sure this is possible with SG.
    It is possible with Amplify though (which I would recommend over the sad joke that SG is anyday.)
     
  6. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    719
    I know it's not possible right now, I'm requesting that it is supported as soon as possible. It seems like a very trivial thing to add, and it was a feature of the builtin pipeline's surface shaders.
     
    JesOb likes this.
  7. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    719
  8. BOXOPHOBIC

    BOXOPHOBIC

    Joined:
    Jul 17, 2015
    Posts:
    506
    This would be awesome, but given the fact that basic features were not added in years to SG, I dought it will happen.

    Amplify has the template system and you can create a new port for final color and how to blend that with you own additional post color.
    I never tried it, but I would say it is possible and should be relatively easy to add.
     
  9. BoaNeo

    BoaNeo

    Joined:
    Feb 21, 2013
    Posts:
    56
    Was this ever added (Can't find it, so I guess not?)... Seems like a silly omission and not having it makes so many things really hard if not impossible to do. But I guess that just speaks to my pet peeve that "visual programming" sucks, because it only ever gets you half way there :) ...
     
  10. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    719
    lol imagine unity giving us meaningful updates on literally anything
     
  11. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I second this. I've been asking for this for years. As-is, if you need to make final alterations to the color of the final output, you can only use an unlit graph. So to do this with lighting, you'd have to replicate all the lighting yourself in the graph. This is an important feature to enable things like custom fogging that attenuates everything, including emission, etc.
     
  12. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    267
    You can define a custom subtarget for shadergraph and then freely modify includes and passes in the generated shader file.
    https://forum.unity.com/threads/adding-custom-passes-to-shadergraph-via-custom-subtarget.1446595/

    (It would be dramatically less hacky if some of the methods were not internal)
     
  13. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I hadn't seen that, and still don't as I currently have to be on 2021 (URP/Shadergraph 12.1.12). In what version is that available?

    But yeah, it would be WAY simpler if there were just a "final color" (and "final Z"?) node. We simply don't have full control over our shaders until we have this.
     
  14. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    719
    Another nice solution would be to just have an in/out PBR node, so we could use 'unlit' nodes more easily.
     
    JesOb, Brady and ElliotB like this.
  15. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    267
    It isn't really 'available' in that you need to embed the package and expose the internals, but you could do that in 2021 also

    The 'final color' would just be an unlit shader. I agree with above a PBR node would be lovely, but I think it's never going to happen
     
  16. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Yes, basically what I'm describing is having an intermediary lighting/PBR node that has a final output that feeds into an actual terminus that just accepts the final color, just like an unlit shader graph does. I don't really understand why the only approach taken is for all the lighting to be done in at the very end of the graph so that you can't do anything with the final output.
     
  17. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    267
    In the meantime though, if your modification is minor -
    https://github.com/Unity-Technologi.../ShaderGraph/Includes/PBRForwardPass.hlsl#L72

    The fragment shader for the pbr pass is defined here and inserted into the generated shader through an include added by the Lit SubTarget.

    You could make your own SubTarget, change the pragma to use a different name for the fragment shader, so you can use your own custom function instead. In your function you could wrap the call to frag and intercept the output. It's far from your ideal solution but it might be useful
     
    Brady likes this.
  18. Kabinet13

    Kabinet13

    Joined:
    Jun 13, 2019
    Posts:
    100
    You could use a custom function node and just call UniversalFragmentPBR (Function is called something like that) directly, get the output color, and do whatever you want with it afterwards in an unlit graph. Until Unity adds custom lighting nodes, which is on the roadmap (and likely coming with SG2), we have to use a bit of shader code for the task unfortunately.
     
    ElliotB likes this.
  19. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I didn't know about this. I had searched for something like this, but for some silly reason "PBR" wasn't on the list of key search terms I thought of looking for, so I never found it. I haven't tried messing with it yet, but this looks to be exactly what I was looking for--a node to handle the lighting calculations, but that outputs the results for further processing rather than being the terminal node.
     
  20. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    So I tried a custom function node with the following:
    Code (CSharp):
    1. void PBR_float(float3 positionWS, half3 normalWS, half3 normalTS, half3 viewDirectionWS, half3 bakedGI, half3 albedo,
    2.         half metallic, half3 specular, half smoothness, half occlusion, half3 emission, half alpha, half clearCoatMask, half clearCoatSmoothness, out float3 Color)
    3.     {
    4.     #if defined(SHADERGRAPH_PREVIEW)
    5.         Color = float3(1, 1, 1);
    6.     #else
    7.         InputData inputData;
    8.         inputData.positionWS = positionWS;
    9.         inputData.normalWS = NormalizeNormalPerPixel(normalWS);
    10.         inputData.viewDirectionWS = SafeNormalize(-viewDirectionWS);
    11.         inputData.shadowCoord = half4(0, 0, 0, 0);
    12.         inputData.fogCoord = 0;
    13.         inputData.vertexLighting = half3(0, 0, 0);
    14.         inputData.normalizedScreenSpaceUV = half2(0, 0);
    15.         inputData.shadowMask = half4(0, 0, 0, 0);
    16.         inputData.bakedGI = bakedGI;
    17.        
    18.         SurfaceData surfData;
    19.         surfData.albedo = albedo;
    20.         surfData.specular = specular;
    21.         surfData.metallic = metallic;
    22.         surfData.smoothness = smoothness;
    23.         surfData.normalTS = normalTS;
    24.         surfData.emission = emission;
    25.         surfData.occlusion = occlusion;
    26.         surfData.alpha = alpha;
    27.         surfData.clearCoatMask = clearCoatMask;
    28.         surfData.clearCoatSmoothness = clearCoatSmoothness;
    29.        
    30.         Color = UniversalFragmentPBR(inputData, surfData);
    31.     #endif
    32.     }
    But I get weird results. The shadergraph preview output is all black no matter what (unless I set emission color to something above black, so it seems emission is the only bit that's working). And the actual object in the scene that uses it is all black with random flickering white pixels. Super weird.

    If I bypass this node and route all my other inputs directly to the output fragment node, it renders correctly (as correctly as you'd expect without lighting information). That is, textured, colored, not all black, etc.

    Does anyone have an example lit node they can share so I can compare?
     
  21. ElliotB

    ElliotB

    Joined:
    Aug 11, 2013
    Posts:
    267
    Are you using a lit or unlit shadergraph? The unlit one (which you want, so you can directly write color) wont have keyword defines to enable lighting, so you'll need to add the various keywords as custom properties to the graph yourself
     
  22. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Unlit. That might be the issue. Unfortunately, I can't find how to add those, nor am I sure which ones I need to add.
     
  23. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Wait, I now see where you can add keywords (same as where you add inputs). Now I just need a clue as to the keywords I'll need.
     
  24. Kabinet13

    Kabinet13

    Joined:
    Jun 13, 2019
    Posts:
    100
    They should all be in the Lit shader source, it should be in the URP folder somewhere under packages.
     
  25. fleity

    fleity

    Joined:
    Oct 13, 2015
    Posts:
    337
    Custom node is a really hacky and limited way to set this up if you ask me (I used this often before too ^^)
    If you use and Unlit target you need to define the lighting keywords yourself which might be annoying and you won't get any debugging support in the rendering debugger. If you use the Lit Target and set everything to black and only input into emission you get those things but it feels really hacky - in a bad way - and only the shader compiler fixes your problems.
    The best solution imo is to write another shadergraph target which incluldes your fog modification directly into the forward pass (this is much more work too though).
     
    Brady likes this.