Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Lightning fast, quality occlusion: Simple SSAO

Discussion in 'Assets and Asset Store' started by arkano22, Feb 28, 2016.

  1. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    The occlusion function he uses is exactly the same as I do. The Alchemy engine guys wrote a paper on it that you can see here: http://graphics.cs.williams.edu/papers/AlchemyHPG11/, which contains the exact same formula I came up with in my article. They did it in 2011 and I did in 2010, one year before. So I assume they took my formula, which I arrived at empirically, and imbued it with physical meaning. Actually I was surprised to find it had a physical meaning at all.:p

    The guy in that thread is also right about Unity adding the ambient term to the gbuffer, but I solved that issue by grabbing the buffer in its previous state (while it has only direct lighting) and then subtracting it from the final lighting buffer to get an ambient only buffer.

    So SimpleSSAO, SSAO Pro and that thread's AO use the same occlusion formula. The difference resides on the sampling pattern. As I said before, i´m using a interleaved sampling/pseudo-separable kernel hybrid. No idea what OmniAO uses.

    Also, no idea on the new Unity AO. I´ve yet to check it out.

    Recently I read up a very interesting idea on extending SSAO and I´m toying with it. It involves sampling more than one depth layer (ala depth peeling, but faster) to generate some sort of camera-space "voxelization" of the scene. This solves two of the biggest problems of SSAO: no occlusion from hidden surfaces, and haloing.

    Anyway, what Nvidia is doing (proper realtime world-space voxelization) is better is most aspects. But you need a nuclear-powered GPU to run it. :cool:
     
    Last edited: May 26, 2016
  2. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,994
    SSSAO
    Screen Shot 2016-05-25 at 10.25.47 PM.png
    Unity cinematic AO
    Screen Shot 2016-05-25 at 10.14.12 PM.png
    mac gpu profiler still broken in 5.4 so can't benchmark them accurately but fps in sssao is 10% slower than conematic
     
  3. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    783
    Alchemy AO was used in Vicarious Visions game engine (also called Alchemy) for commercial games several years before this paper was published. Sincerely I think that if they took your formula they would have mentioned it in their paper references.

    That said, no doubt your formula is great!
     
  4. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Damn! I though I had actually invented something :D. Anyway, when I wrote that article I was really excited about the results and intended everyone to benefit from them so I would be really proud if they had taken it and developed it further, whether they mentioned it or not.

    cheers!
     
  5. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,994
    @arkano22, SSSAO doesn't do a thing when I set the landscape to
    Code (CSharp):
    1. Shader "Diffuse With Shadows"
    2. {
    3.     Properties
    4.     {
    5.         [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         Pass
    10.         {
    11.             Tags {"LightMode"="ForwardBase"}
    12.             CGPROGRAM
    13.             #pragma vertex vert
    14.             #pragma fragment frag
    15.             #include "UnityCG.cginc"
    16.             #include "Lighting.cginc"
    17.  
    18.             // compile shader into multiple variants, with and without shadows
    19.             // (we don't care about any lightmaps yet, so skip these variants)
    20.             #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
    21.             // shadow helper functions and macros
    22.             #include "AutoLight.cginc"
    23.  
    24.             struct v2f
    25.             {
    26.                 float2 uv : TEXCOORD0;
    27.                 SHADOW_COORDS(1) // put shadows data into TEXCOORD1
    28.                 nointerpolation fixed3 diff : COLOR0;
    29.                 nointerpolation fixed3 ambient : COLOR1;
    30.                 float4 pos : SV_POSITION;
    31.             };
    32.             v2f vert (appdata_base v)
    33.             {
    34.                 v2f o;
    35.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    36.                 o.uv = v.texcoord;
    37.                 half3 worldNormal = UnityObjectToWorldNormal(v.normal);
    38.                 half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
    39.                 o.diff = nl * _LightColor0.rgb;
    40.                 o.ambient = ShadeSH9(half4(worldNormal,1));
    41.                 // compute shadows data
    42.                 TRANSFER_SHADOW(o)
    43.                 return o;
    44.             }
    45.  
    46.             sampler2D _MainTex;
    47.  
    48.             fixed4 frag (v2f i) : SV_Target
    49.             {
    50.                 fixed4 col = tex2D(_MainTex, i.uv);
    51.                 // compute shadow attenuation (1.0 = fully lit, 0.0 = fully shadowed)
    52.                 fixed shadow = SHADOW_ATTENUATION(i);
    53.                 // darken light's illumination with shadow, keep ambient intact
    54.                 fixed3 lighting = i.diff * shadow + i.ambient;
    55.                 col.rgb *= lighting;
    56.                 return col;
    57.             }
    58.             ENDCG
    59.         }
    60.  
    61.         // shadow casting support
    62.         UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
    63.     }
    64. }
     
  6. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Hi Laurent,

    You forgot to tell Unity that your shader is supposed to be opaque, so that shader replacement works with it and it is rendered in the normals/depth buffer. Just add " Tags { "RenderType"="Opaque" }" right after "SubShader {".
     
  7. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,994
    Just added, still no sssao on those objects. Anything else maybe?
     
  8. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Are you using the deferred render path, in "integrate" mode? if that's the case, your shader is forward-only so it won´t show up in the gbuffer, and "integrate" will not be able to pick it up.

    Change SSSAO to deferred/multiply or forward/multiply, or use something else than multi_compile_fwdbase in your shader. As it is, your shader can only receive lighting from one light, and will always be rendered using the forward path, not deferred.
     
  9. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,994
    I patched that shader together and didn't realize that it's fwd only, and yes I had defered on and now that rendermode is set to fwd and multiply it's all nice.
    How would I make this shader defered friendly? The doc, it hurts my brain.
     
  10. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Just use the "Deferred" light mode:
    http://docs.unity3d.com/Manual/SL-PassTags.html

    However, your might need to do additional changes to the shader to get it to work, as it seems to be tailored specifically for forward mode.

    Edit: specifically, it is computing lighting in the vertex shader. That is just not how deferred works.
     
  11. zugsoft

    zugsoft

    Joined:
    Apr 23, 2014
    Posts:
    453
    Hello,
    On Android a simple scene crash, and the application is closed.

    GpuProgram creation error: empty shader string
    W/Unity (28994):
    W/Unity (28994): (Filename: ./Runtime/GfxDevice/GpuProgram.cpp Line: 845)
     
  12. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Make sure your target device supports at least 8 MRTs. This limitation will be removed when the Unity 5.4 version is released (thanks to texture arrays support).

    cheers!
     
  13. zugsoft

    zugsoft

    Joined:
    Apr 23, 2014
    Posts:
    453
    Unity5.4 is available lol
    But for the moment I only try with the last 5.1 and last 5.3

    I will try with 5.4.
    ssao pro works with 5.1 and Android, why?
     
  14. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    I meant when I release the SSSAO version updated to take advantage of Unity 5.4's texture arrays, which will be in a couple weeks. SSAO Pro works probably because they are using random sampling, which is slower but does not need MRT. I´m using interleaved sampling, which does need MRT at the moment.

    cheers!
     
    laurentlavigne likes this.
  15. layola

    layola

    Joined:
    Aug 6, 2013
    Posts:
    94
    current version 1.2 still very slowly test in android .
    when will update your next version and road map?
     
  16. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,994
    1.3?
     
  17. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Hi Layola,

    Unless you're maxing out sample count and using color bleeding, it should run fine in high-end mobile devices. Keep in mind that SSAO is a very demanding effect, so it should be used sparingly in mobile devices, if at all.

    Anyway, I´m waiting for Unity to fix bug in texture array support before releasing a new version, which should be slightly faster on mobile.
     
    laurentlavigne likes this.
  18. layola

    layola

    Joined:
    Aug 6, 2013
    Posts:
    94
    what 's "the high-end mobile devices"
    how about qualcomm 810?
    it's only 10 or up FPS only!
    current we have no 820 devices.
     
  19. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Hi layola,

    The CPU makes no difference at all in regards to SSAO. What's important is the device's GPU. Make sure your sample count is low, your radius is relatively low, and color bleeding is deactivated. I´m getting 25-30 fps in a fairly complex scene with this settings in a Galaxy S4, which isn´t exactly high-end nowadays:

    - Sample count 2
    - Radius 0.05
    - Color bleeding intensity 0

    cheers!
     
  20. craig_cerceo

    craig_cerceo

    Joined:
    Apr 3, 2012
    Posts:
    3
    Hi @arkano22, I purchased Simple SSAO out of interest in how it would perform on iOS. I've setup a test scene which is empty with the exception of some UI to display FPS, a camera, and the Simple SSAO script. My test scene is only recording ~8 FPS. Profiling the device CPU, I'm getting `Gfx.WaitForPresent` taking ~110ms. I'm using the default settings with the changes you mentioned above with your S4 test:

    I'm using an iPhone 6+, iOS 10.2, Unity 5.5.0f3, Simple SSAO 1.2. Are there any known issues with this setup? Or, can you share the settings you used to achieve the FPS in your mobile tests?
     
  21. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,994
    @arkano22 can you update SSSAO to 5.5, I'm getting all sorts of weird errors. Cheers.

    IndexOutOfRangeException: Array index is out of range.
    SSSAO.SimpleScreenSpaceAmbientOcclusion.OnPreRender () (at Assets/SSSAO/SimpleScreenSpaceAmbientOcclusion.cs:479)
     
    chiapet1021 likes this.
  22. ekergraphics

    ekergraphics

    Joined:
    Feb 22, 2017
    Posts:
    257
    I hope something is wrong with this. I bought it because Obi Rope was excellent, and I wanted to compare this to Amplify Occlusion. However, the results are very weird:

    • 2-4 million poly scene, Amplify Occlusion, medium sample count, 0.2 radius - around 10-14ms render thread
    • 2-4 million poly scene, Simple SSAO, medium quality, 0.2 radius - around 40-70ms render thread!!
    Perhap this plugin isn't optimized for forward rendered VR? Or is it because the editor also gets shaded (unlike with Amplify which I think only shades the game view)?

    I have to say though, using the debug views for both, the quality difference is staggering. Especially on high quality, Simple SSAO is mindblowingly good at shading objects compared to Amplify, which makes me even more sad now that I can't use it. :(
     
  23. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Hi Roberteker!

    We haven´t really tested SSSAO in VR. So while we cannot say for sure what might be the issue, 40 ms is surely not even remotely normal.

    We render the scene twice for depth and normals (using the usual DepthTextureMode.DepthNormals in the camera), after that the rest of the computation is bounded by resolution, not amount of polys in your scene. So the fact that your scene has such high poly count shouldn't´t make such impact, if any at all.

    Can you share a screenshot of your profiler in deep-profiling mode? (just to give us an idea of what might be happening there)

    Edit: got Amplify Occlusion, and benchmarked both (no VR).

    At comparable settings, theirs runs at 9.6 ms and ours at 10 ms in their own test scene. Seems that their radius is not in world space units like ours (so a radius of 0.2 is extremely small for Amplify). A radius of 1-2 is around the same as a radius of 0.2 for ours. Note that this was a regular scene, not VR.
     
    Last edited: Jun 17, 2017
  24. ekergraphics

    ekergraphics

    Joined:
    Feb 22, 2017
    Posts:
    257
    Oddly enough, I can't find SSSAO in the profiler, but here are two comparative images to the best of my ability:

    http://imgur.com/H9Aj89R
    http://imgur.com/ryzMk7r

    Even more weird, increasing the Amplify radius to 1 did not really increase its render time either, and now they look very similar (both are viewed using their own debug modes here, but again, switching to normal doesn't really change render times either for me at least).
     
  25. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Cannot see the second profiler image, the link seems broken.

    Changing the radius shouldn't really increase render times by an appreciable amount, in pretty much any SSAO algorithm (unless you set really huge radii). I was just pointing out that 0.2 was not a good radius setting for Amplify.
     
  26. ekergraphics

    ekergraphics

    Joined:
    Feb 22, 2017
    Posts:
    257
  27. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    The only difference I see is that you're telling Amplify to ignore per-pixel normals, and treat every surface as perfectly flat. This allows it to render the entire scene just once in forward rendering mode, while SSSAO will be rendering it twice (which, for 2 million polygons, can be quite some render time).


    Set Amplify per-pixel normals to "Camera" and see if that bridges the performance difference.
     
    Last edited: Jun 17, 2017
  28. ekergraphics

    ekergraphics

    Joined:
    Feb 22, 2017
    Posts:
    257
    It did not make any difference to Amplify performance for me.
     
  29. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Hi there,

    I did some more benchmarking, and switching from "None" to "Camera" normals in Amplify degrades performance by about 40% in my tests, and almost duplicates the amount of triangles rendered in all scenes i´ve tried (which is consistent with how the camera depth/normals buffer is generated in forward rendering: re-rendering the entire scene with a replacement shader, so this is entirely expected).

    Amplify, per-pixel normals to "None": 27.5 ms / frame (8 ms render thread)
    Amplify, per-pixel normals to "Camera": 40 ms / frame (22 ms render thread)
    SSSAO: 39.0 ms / frame (20 ms render thread)

    So at the same quality level, SSSAO is marginally faster for me. I don´t know how there can be such strange performance behavior for you, would it be possible for you to share your scene with me?

    Screenies (in the above order):
    AmplifyNone.png AmplifyCamera.png SSSAO.png
     
  30. ekergraphics

    ekergraphics

    Joined:
    Feb 22, 2017
    Posts:
    257
    Sorry, it's a confidential project for a client so I cannot share it. Also, it's built from converted CAD data, which does produce a bit unusually constructed geometry at times.

    But as your tests show, and after the tip about range you showed me, the results between SSSAO and Amplify are very similar, so it's not a big loss for me (nor any big monetary loss).
     
  31. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,511
    Interesting.

    This is setting I am using for Amplify on PC.

    upload_2017-7-17_13-38-45.png

    I am wondering about SimpleAO 's performance and quality compared to this kind of setting for Amplify. Using deferred. I would like to try this asset, but 2 things that I am unsure of :

    1. performance compared to amplify AO as above, at 1920x1080
    2. Will it run on the consoles?
     
  32. backwheelbates

    backwheelbates

    Joined:
    Jan 14, 2014
    Posts:
    225
    @arkano22 , thanks, Im really enjoying using this in my mobile game!

    Just a quick question on settings. I notice in some situations, I'm getting a moiré pattern when viewing large surfaces from certain angles. Is this something that you are familiar with? Do you have any recommendations to adjust this so its less apparent?

    Thanks again!!
     
  33. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Hi Eric!

    If you mean a stripped-like pattern, try increasing the depth tolerance of your blur pass. ("Blur depth threshold" variable)

    This is caused by the blur not realizing the surface is continuous when looking at it from a grazing angle, thus leaving parts of it unblurred and revealing the stippling pattern used by the initial SSAO pass.

    You can also try increasing the bottom end of the "radius range" a bit.
     
  34. backwheelbates

    backwheelbates

    Joined:
    Jan 14, 2014
    Posts:
    225
    Thanks for the quick reply @arkano22. With tweaking I could definitely reduce the patterning dramatically.

    I have one other issue, that I'm attempting to debug. Have you or anyone else had issues with getting this to work with the Metal API on ios? It's like the alpha from the render texture gets stuck, and ends up frozen over the frame. Like a double image. Some kind of image buffer looks to be not updating.

    I'm doing builds with and without various image effects, and I'm still in the process of pinpointing the issue. At any rate, let me know if any of this sounds familiar.

    Thanks again!!
     
  35. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Hi Eric,

    Haven't tried to build using Metal, but will try and get back to you. cheers!
     
  36. Uli_Okm

    Uli_Okm

    Joined:
    Jul 10, 2012
    Posts:
    94
    Hello @arkano22 do you still support Simple SSAO? I bought it recently and can't make it work. I am using custom shaders, unlit opaque, and the SSAO effect don't seem to affect my objects. Is there something that needs to be tweaked in shaders to make this compatible? Thanks

    [EDIT]
    Answering my own question, the basically any shader to be affected by SSAO post processing needs to have a shadow caster pass. This can be easily solved by adding a fallback to diffuse or vertexlit to your custom shaders
     
    Last edited: Jul 10, 2019
  37. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,663
    Hi there,

    As you discovered, for a shader to cast any occlusion it has to be opaque and a shadow caster. A similar question popped up in this thread a while ago.

    kind regards,