Search Unity

Slight modifications to standard shader

Discussion in 'Shaders' started by cpuRunningHot, Jan 25, 2020.

  1. cpuRunningHot

    cpuRunningHot

    Joined:
    May 5, 2018
    Posts:
    94
    Please forgive me if this is a trivial question. I have begun to dip my toes into writing shaders, and running into this one issue that perhaps there is an easy answer to.

    I would like to make sight modifications to the standard shader, but all of the examples and tutorials I could find generally show to "replace" things in the standard shader.

    One example of what I would like to do is to alter the overall lighting value in the standard shader, hopefully without having to re-implement the lighting calculations. Something like this

    float3 myLightingAfterShadows(...)
    {
    float3 value = standardLightingAfterShadows(...)

    // Modify value here

    return value;
    }

    so in the above example, if I forced value to 1.0, then everything would be unlit with no shadows ( again, overly simplistic, I'm sure I'd have to do it in a few different places )

    I realize that it will be more complex than this, with multi passes and all of that. The main point is that I would like to inherit the standard values and make slight modifications, rather than re-implement or copy/paste existing shader code.

    Is there a straight forward way of doing this? I'm guessing no ( since I could not find examples ), but I could be missing something obvious.

    Could someone point me towards a good example for doing this? I would be most grateful :D
     
    Radivarig likes this.
  2. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    399
  3. cpuRunningHot

    cpuRunningHot

    Joined:
    May 5, 2018
    Posts:
    94
    So I figured out how to achieve what I am looking to do. The problem with most of the examples is that the custom shaders lose much of the functionality of the original standard shader. A few examples are transparency, multi light shadows, secondary maps, etc. So what I was looking for was to have a fully functional clone of the standard shader, and then inject some custom tweaks. I will post more details as soon as I clean up my implementation, but here is the gist of it...

    - Find the source for the Unity Shaders
    - Copy these files to your custom folder and rename them
    - Standard.shader
    - UnityStandardCore.cginc
    - UnityStandardCoreForward.cginc
    - and probably UnityStandardCoreForwardSimple.cging ( I think it may be used for mobile, still investigating )
    - Rename the files ( e.g. Standard_Custom.shader, etc. )
    - rename the references to the cginc files ( e.g. #include "UnityStandardCore_Custom.cginc" )
    - rename the shader ( e.g. Shader "Custom/Standard_Custom" )

    Now, at this point, the new shader "Standard_Custom" will be a carbon copy of the original standard, with ALL of it's functionality intact.

    From this point, most of the action takes place in UnityStandardCore_Custom.cginc

    To make changes to the basic color/light shading, locate fragForwardBaseInternal () and here you can make changes/tweaks/additions to the basic shading and light attenuation, shadows ( for the main light only )

    Then if you want to make and changes to subsequent light/shadows, then locate fragForwardAddInternal() and make the tweaks in there.

    So, say you want to alter the shadows ( attenuation ) for all lights. Then you have to do it in two places...

    fragForwardBaseInternal()
    {
    ...
    UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld);
    // tweak atten here


    and in here...

    fragForwardAddInternal()
    {
    ...
    UNITY_LIGHT_ATTENUATION(atten, i, s.posWorld)
    // same tweak here

    Anyhoo, I still have to clean up my implementation, but I'm going to attempt to make a boiler-plate template for this and will be happy to share it. It's not elegant like inheriting from a C# class and overriding the desired virtual functions obviously, but with some massaging, it should be good enough :D

    To recap on my motivation for this... I want to create shaders that have all of the functionality of the original standard shader, just with some extra features. Every tutorial I have found for creating custom shaders ends up breaking some key features ( e.g. transparency, multi-light shadows, etc. ) and those features would all have to be re-implemented, and that opens up a clown car of potential bugs, etc. But taking this approach, we are guaranteed to have a carbon copy of the standard shader as our starting point, and then making some tweaks from there.
     
    jamespaterson likes this.
  4. cpuRunningHot

    cpuRunningHot

    Joined:
    May 5, 2018
    Posts:
    94
    Ok, here is my first draft at a boiler plate template for a carbon copy of the standard shader.

    The new files UnityStandardBRDF_ShaderTemplate.cginc contains a clone of BRDF3_Unity_PBS which can be modified ( currently modified to make everything red ) and LightAttenuationModifier_ShaderTemplate.cginc can be modified to change the shadows ( currently modified to make everything 25% darker). I'm not married to this style of injection and may change it as I flush out my custom shader. For the purposes of the shader I am working on, these are the only two places where I need modifications.

    Following this pattern, you can modify other aspects of the standard shader by injecting similar modifications. So just copy this template into a folder of it's own, inject the changes you want to make and you're good to go.

    A key point here is that you do not need to copy over every cginc file from the original, just the ones you intend on modifying. The rest of the #include statements will simply include the original files. When I first looked at doing this, it seemed like a daunting task, but when I realized that only a few files need modification, it didn't seem so bad. The key is to make the modifications cleanly so it doesn't turn into a bug hairy mess.

    For some context, I am working on a heavily stylized toon shader ( not like conventional toon shaders ) that needs to be able to go from full standard to full toon, and anywhere in between. And it needs to affect the shadow of all light sources ( the toon shaders that I have been previewing do not support more than one planar light properly ).
     

    Attached Files:

    Last edited: Feb 5, 2020
  5. chai

    chai

    Joined:
    Jun 3, 2009
    Posts:
    84
    Thank you kindly for the example mate, superb and very clean!