Search Unity

Make emmisve Bloom like standard shader

Discussion in 'Shaders' started by BinaryCats, Jun 21, 2019.

  1. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Hello,

    I am using post processing stack 2, and I have Bloom enabled. This gives emmisve objects a glow around them.

    I am trying to write a shader which with blooms the same way as the standard shader

    Here you can see the standard shader (left) and my shader (right) (objects have the same emmisve value)



    Code (CSharp):
    1. Shader "MyShader"
    2. {
    3.     Properties
    4.     {
    5.         [HDR]_Color0("Color 0", Color) = (0,0,0,0)
    6.     }
    7.  
    8.     SubShader
    9.     {
    10.         Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry+0" "IsEmissive" = "true"  }
    11.         Cull Back
    12.         CGPROGRAM
    13.         #pragma target 3.0
    14.         #pragma surface surf Standard keepalpha addshadow fullforwardshadows
    15.         struct Input
    16.         {
    17.             half filler;
    18.         };
    19.  
    20.         uniform float4 _Color0;
    21.  
    22.         void surf( Input i , inout SurfaceOutputStandard o )
    23.         {
    24.             float4 color3 = float4(1,1,1,1);
    25.             o.Albedo = color3.rgb;
    26.             o.Emission = _Color0.rgb;
    27.             o.Alpha = 1;
    28.         }
    29.  
    30.         ENDCG
    31.     }
    32.     Fallback "Diffuse"
    33. }
    34.  
    What do I need to do to get the same result as the standard shader?
     
  2. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Hello, Just an update to this issue.

    The above only happens in linear colour space, not gamma.

    I have reported a bug report to unity
     
  3. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    After some digging the following is how the standard shader seems to set the emission
    Code (csharp):
    1.    half3 emissiveColor = UNITY_BRDF_PBS (s.diffColor, s.specColor, s.oneMinusReflectivity, s.smoothness, s.normalWorld, -s.eyeVec, gi.light, gi.indirect).rgb;
    2.  
    3.     #ifdef _EMISSION
    4.         emissiveColor += Emission (i.tex.xy);
    5.     #endif
    6.  
    7.     #ifndef UNITY_HDR_ON
    8.         emissiveColor.rgb = exp2(-emissiveColor.rgb);
    9.     #endif
    https://github.com/TwoTailsGames/Un...lob/master/CGIncludes/UnityStandardCore.cginc

    However I am unsure how to implement this in my shader (I'm not a shader guy sorry). Where is the "s" declared? How do I get it in my shader?

    If anybody can provide any assistance it would be most appreciated
     
  4. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    "s" is the output struct from a Surface shader, such as
    SurfaceOutputStandard
    , when you're assigning all those o.Albedo, o.Normal, etc.. properties in the surface shader surf function.

    But I believe that part isn't important anyways for the emission unless you want to perfectly replicate unity's lighting model in your shader, otherwise all that's important is for you to take your current lighting/shading calculation and add it to your emission and have this last part:

    Code (CSharp):
    1. #ifndef UNITY_HDR_ON
    2.     emissiveColor.rgb = exp2(-emissiveColor.rgb);
    3. #endif

    If that still doesn't fix the result, then you can do a search for BRDF1_Unity_PBS in UnityStandardBRDF.cginc to see all the calculations on those inputs Unity is doing.
     
    Last edited: Jun 30, 2019
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    That same shader code is used by the surface shader already. If you look at the generated shader code from your surface shader you’ll find the same “exp2()” line. That’s not the problem.

    I think the problem stems from the Standard shader using a custom editor vs just using the [HDR] flag on the color property, but I don’t know for sure. There’s nothing obvious in the editor code for why they should produce different results.

    I would check with the frame debugger to see if the color values both shaders are receiving are the same, but I highly suspect they will not and the Standard shader is for some reason getting a much brighter color value.
     
    BinaryCats likes this.
  6. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
  7. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Thank you for the information, Its great to hear that my shader doesn't need to worry about that code because it does it already.

    Thanks for the advice of using framedebugger, I was searching for a way to see the shader varibles values. From that I discovered that the values where infact different! - Despite being the same in the color picker!


    After some digging, it does infact seem to be because of the [HDR] flag vs custom material editor!

    (editor code is more my thing, over shaders)
    Writing a custom GUI for my shader (/copying from the standsharderGUI) does infact solve this issue! and the outputted values are the same. I am still somewhat unsure as to Why though, i'll keep digging.

    Also, just to note, that unity has confirmed my bug report - so this does infact seem to be a bug

    --Update--

    I have found the cause of the issue, simply its the HDR tag on the color. If I have a custom editor replicating what the StandardShaderGUI does but my color field does not have the [HDR] tag, the emissive value color will be the same as the standard shader.

    If I add the [HDR] tag, the value is reduced.
     
    Last edited: Jun 30, 2019
    bgolus likes this.