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

no SSAO on surf LightingSimpleSpecular

Discussion in 'Shaders' started by daprato, Sep 22, 2019.

  1. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    Hi fabulous Unity people. Still learning shader... Don't want right now doing a whole cg shader in vert and frag to integrate all ambient color and shadows, etc... I like to play a little bit with surf. Here I'm trying to find a good base lighting but that can work with ambient, post-process, shadows without re-writing everything.

    The custom lighting example of Unity documentation, surf LightingSimpleSpecular work great with the SSR but not quite well with the SSAO. in fact it's "casting" SSAO onto other Standard rendering, but can't receive SSAO. Is there some zwrite or other tag to put in this shader ?




    Thx :)

    Code (CSharp):
    1. Shader "1_Lit_SimpleSecular" {
    2.     Properties{
    3.     _Color("Main Color", Color) = (1,1,1,1)
    4.     _MainTex("Texture", 2D) = "white" {}
    5.     _BumpMap("Bumpmap", 2D) = "bump" {}
    6.     }
    7.     SubShader{
    8.         Tags { "RenderType" = "Opaque" }
    9.         CGPROGRAM
    10.         #pragma surface surf SimpleSpecular
    11.  
    12.         half4 LightingSimpleSpecular(SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
    13.             half3 h = normalize(lightDir + viewDir);
    14.             half diff = max(0, dot(s.Normal, lightDir));
    15.             float nh = max(0, dot(s.Normal, h));
    16.             float spec = pow(nh, 48.0);
    17.             half4 c;
    18.             c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * atten;
    19.             c.a = s.Alpha;
    20.             return c;
    21.         }
    22.  
    23.         struct Input {
    24.             float2 uv_MainTex;
    25.         };
    26.  
    27.         float4 _Color;
    28.         sampler2D _MainTex;
    29.         sampler2D _BumpMap;
    30.  
    31.         void surf(Input IN, inout SurfaceOutput o) {
    32.             o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb * _Color;
    33.             o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
    34.         }
    35.         ENDCG
    36.     }
    37.         Fallback "Diffuse"
    38. }
     
  2. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    There's the camera depth-buffer and the "real" depth/normals buffer. I need more reading onto those 2 differents depth. Apparently having cutom shader writing into some depth is a matter of creating it's own rendertype and modifying the SSAO shader to understand it like...
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Unless you’re moving vertices around or using alpha testing and UVs that aren’t just the first UV set, there should be no need for a custom shadow caster pass or depth normal shaders. The fallback and RenderType should be enough. In fact, most people have the problem that they can’t get the SSAO to not apply to their shader. This makes me think your material has it’s queue overridden to a transparent queue, or maybe you’re using the deferred rendering pipeline which renders all non-Standard materials separately. Though for deferred I’d still expect the SSAO to be applied later.

    The fact your object is still affecting the AO on other objects means it is being rendered unto the appropriate textures.

    Use the Frame Debugger and look for when the SSAO is getting applied and when your object is being rendered.
     
  4. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    Thx bgolus, good idea indeed :)
    I'm trying to figured-out but I don't know what I'm saying about the mulit-rendering of Unit, haha. Hope this could help you helping me :p
    @0:00 = problem description
    @2:44 = frame debugger
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Definitely looks like something is going even more wonky than usual with the deferred / forward opaque mixing.

    Two questions for you:
    1. Is there a particular reason you’re using the deferred pipeline?
    2. Do you plan on using this, or similar shaders with custom lighting for most or all of your scene?
    If the answer is yes to both questions (I.E.: I want to use a lot of lights & all background objects are going to use this shader) then you have a problem. Any surface shader with a custom lighting function is rendered using the forward rendering path so you get none of the benefits of the deferred rendering path, only the downsides of higher memory & bandwidth usage, and forward rendered opaque objects have always been a little funky when mixed with deferred.

    Basically what Unity does is it renders the shadowcaster pass of the forward opaque shader into the gbuffer. This fills the albedo buffer (RT0, what you’re looking at in the video) with black, and the depth buffer, but nothing in the normals or specular buffers. This means any post process effects that use the depth buffer should show correctly, but anything that uses the normals or any other data will be wrong. What’s odd here is the default SSAO that Unity uses is Multi-Scale VO, which only uses the depth buffer, so that should be correct still. And it applies after your object has been rendered. But for some reason it doesn’t appear to render over your object still, and I’m not sure I understand why. But switching to using the forward rendering path instead of deferred for your project should fix everything.

    Otherwise if you really need the benefits of deferred’s multiple lights, and use a custom lighting model, you’ll need to modify Unity’s built in deferred shaders to either use the custom model, or allow you to specify which one to use by encoding it in one of the channels.
     
  6. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    Answer 1: no, just using the new default of Unity. Could be only in forward cause my rendering will not be demanding...

    Answer 2: All of my scene will use some forward special lighting shader, aka special ramp lighting or cheap fake SSS like. But the majority of the shaders, like maybe 75%, could be the same opaque one. So deferred could help there that's for sure reducing the drawcalls, especially for lighting.

    I planned to render low-res; around 800px * 600px and even less. Not much dynamic lighting, maybe 1 or 3 per frustums. Not much triangles, a pixelated 3d sidescroller you see. So if it's Forward Rendering it should be fine. Using also generally Lightmaps. But because things move around without casting shadow at every corners; getting some slight SSAO can help a lot :)

    Tried to set the rendering path to forward, reboot, and nothing, bug still there.

    FIXED:
    I just tested-out with the LTS 2018.4 and the latest 2020 and surf Custom Lighting are working great in SSAO. For me this SSAO weird bug happens maybe only with the 2019.2.5f1.

    I'm not yet in production for my little project, but I'll test-out the 2019.3 ish... Or start right now, even alpha, with the 2020 (by the way the "gradient" environment lighting on the 2020 seams to be broken,anyway...!).

    And finally, yes it could be deferred if I know my precise shaders desired that I'd like to pack in an ID buffer, modifying the deferred Unity lighting. But, I'm not 3d programmers so I can't code such things. I'm working at Ubisoft and familiar about the restriction of a Deferred rendering in term of shader diversity. For my little personal project, more cartoonish or we would say, more stylish, I'll work on some exotic Forward shaders and see if I turned completely on Rendering the whole scene in Forward or keeping Deferred for the 75% common opaque materials.

    Thx @bgolus
     
    bgolus likes this.
  7. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    FINALLY, maybe it's not buggy rather than been limited. Camera in Forward rendering renders well the SSAO onto my "surf custom lighting".

    But, I want SSR and SSAO, they can't live together apparently if you have some forward custom lighting, even if Unity called them "surf".

    I've set the camera to Deferred in the past because SSR demand to be in Deferred. But the "surf custom lighting" don't received SSAO.

    So...

    Setting-up camera to Forward, is that possible to get an SSR working ?
     
    Last edited: Sep 24, 2019
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Yes, and no.

    Unity's built in SSR, and most implementations of it, only support deferred. It is totally possible to do SSR with forward rendering, and there are probably some assets on the store that allow for that, but the main issues is SSR needs a camera normal texture and to work properly needs to have a custom forward shader on the object rather than purely as a post process.

    Generally speaking doing SSR in a forward renderer is much less efficient, hence why it's rare to find an example of it working with forward rendering.
     
    daprato likes this.
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Surface shader just mean Unity handles the more complicated parts of lighting "behind the scenes". The documentation explicitly calls out that custom lighting functions only work with forward rendering. This isn't a Unity thing, this is a the-whole-way-deferred-rendering-works-is-by-limiting-shading-to-a-single-lighting-model thing.
     
    daprato likes this.
  10. daprato

    daprato

    Joined:
    Sep 25, 2013
    Posts:
    31
    Haha. Super thx for the replies :) appreciated