Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020.2 has been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Horizon Based Ambient Occlusion - HBAO image effect

Discussion in 'Assets and Asset Store' started by jimmikaelkael, Feb 21, 2016.

  1. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    808
    A-ha, makes sense, thanks! Did all that, seems to be working.
    And, as far as I understand, this opens up the possibility to do stuff like this in pass 35 where color bleeding is applied:

    Code (csharp):
    1.  
    2. // 35: combine color bleeding HDR (additive blending)
    3. Pass {
    4.     Blend One One
    5.     CGPROGRAM
    6.  
    7.         #pragma vertex vert
    8.         #pragma fragment frag_blend
    9.  
    10.         half4 frag_blend(v2f i) : SV_Target
    11.         {
    12.             #if UNITY_SINGLE_PASS_STEREO
    13.             float2 uv = UnityStereoTransformScreenSpaceTex(i.uv2);
    14.             half3 rt3 = tex2D(_rt3Tex, uv);
    15.             #else
    16.             half3 rt3 = tex2D(_rt3Tex, i.uv2);
    17.             #endif
    18.  
    19.             half4 addedColorbleed = half4(1 - FetchOcclusion (i.uv2).rgb, 1.0);
    20.  
    21.             [... fun stuff with rt3 being used to partially cancel added result and so on]
    22.  
    23.             return addedColorbleed;
    24.         }
    25.  
    26.     ENDCG
    27. }
     
  2. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Exactly sir ;)

    EDIT: version 2.6 will have the changes I've shown in any case.
     
  3. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    808
    Thanks for all the help!

    Unfortunately, it looks like it's not possible to correct color bleeding at the point of blending, because the points sampled from deferred render targets at that step do not correspond to points in deferred render targets which were used to produce the bleeding. Most basic test would be place a red cube in the scene and to mask out any color bleeding on pixels where albedo is red - doing that would only remove the color bleeding on screen pixels containing that red cube:



    Since the artifact we're looking to resolve is pseudo-bloom/halos around emissive windows/displays/lights, I should probably look at a place where samples are collected in the first place, and revert all modifications made to color bleeding blending. I guess the proper place to attempt culling of undesirable splotches would be HBAO_frag.
     
  4. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    I see, this makes sense...
    In HBAO_frag _MainTex is CameraTarget.
     
  5. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    808
    Okay, found a way to remove color bleeding samples from emissive objects :)
    Those GIFs have saturation and intensity of color bleeding turned up too high here for the sake of visibility, but you get the idea. This is accomplished by calculating a simple "mask" factor from an emission sample and multiplying emission sample by it. No additional samples required, since color bleeding already samples emission.



    Mask calculation isn't very refined right now - I'd prefer a way to explicitly define a brightness level at which masking starts and a brightness level at which emission sample masking reaches 0. Got an idea for a clean formula accomplishing that?

    Given emission value X, limit start A and limit end B, what formula would make emission untouched when X < A, lerped from full to zero between A and B and zero beyond B? :)
     
    Last edited: Oct 16, 2017
    jimmikaelkael likes this.
  6. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Need to think a bit longer to this as I'm at work...

    Maybe scale the averaged emission in 0..1 range could help ?
    Code (csharp):
    1.  
    2. float mask = 1 - saturate((average - minBrightness) / (maxBrightness - minBrightness));
    3.  
     
    Last edited: Oct 16, 2017
  7. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    808
    Sounds like a good idea, all the test values seem to come out as expected and low-brightness areas are no longer touched by this fading. I've got one last very minor issue, not sure if it can be fixed - there is some delay or temporal artifact with this approach: when you move the camera, masking becomes slightly less efficient, as if brightness "leaks out" a bit around masked samples:

    Shouldn't be too noticeable with motion blur and bloom enabled, but curious about it's causes. :)
     
  8. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    hmmm, strange... And without deinterleaving ?
     
  9. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    808
    Yup, that gif was with 4x deinterleaving; disabling it removes this artifact, everything looks stable in motion. No big deal, I suppose. :)
     
  10. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Yeah, not much I can do for deinterleaving... I'm not surprised, by the way it's designed to work, that it exhibit such artifacts with color bleeding.
     
  11. buttmatrix

    buttmatrix

    Joined:
    Mar 23, 2015
    Posts:
    609
    very nice, somebody get this guy a beer +1
     
    jimmikaelkael likes this.
  12. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
  13. buttmatrix

    buttmatrix

    Joined:
    Mar 23, 2015
    Posts:
    609
    Just to be clear, by disabling deinterleaving and using dithering or random noise, the artifact in the gif no longer appears?
     
  14. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    808
    Alright, here are the changes nece
    Yup. Here are full changes you need to do for that fix (this set of changes modifies color bleeding in deferred mode when integrated version of HBAO is used with Before Reflections integration mode).

    HBAO.shader
    around line 69
    new variables

    Code (csharp):
    1. float _CBBrightnessMask;
    2. float _CBBrightnessMin;
    3. float _CBBrightnessMax;
    HBAO_frag.cginc
    around line 195
    color bleeding block

    Code (csharp):
    1. #if COLOR_BLEEDING_ON
    2.     float3 col = float3(0.0, 0.0, 0.0);
    3.  
    4.     UNITY_UNROLL
    5.     for (int s = 0; s < DIRECTIONS * STEPS; s += 2)
    6.     {
    7.         #if UNITY_SINGLE_PASS_STEREO
    8.             float2 uvForSample = UnityStereoScreenSpaceUVAdjust (float2(cbUVs[s].x, cbUVs[s].y * _MainTex_TexelSize.y * _MainTex_TexelSize.w), _MainTex_ST);
    9.         #else
    10.             float2 uvForSample = float2(cbUVs[s].x, cbUVs[s].y * _MainTex_TexelSize.y * _MainTex_TexelSize.w);
    11.         #endif // UNITY_SINGLE_PASS_STEREO
    12.  
    13.         float3 emission = tex2D (_MainTex, uvForSample).rgb;
    14.         float average = (emission.x + emission.y + emission.z) / 3;
    15.         float scaledAverage = saturate ((average - _CBBrightnessMin) / (_CBBrightnessMax - _CBBrightnessMin));
    16.         float maskMultiplier = lerp (1, 1 - scaledAverage, _CBBrightnessMask);
    17.  
    18.         col += emission * cbContribs[s] * maskMultiplier;
    19.     }
    20.  
    21.     col /= DIRECTIONS * STEPS;
    22.  
    23.     #if DEFERRED_SHADING_ON
    24.         #if UNITY_SINGLE_PASS_STEREO
    25.             float2 stereoUV = UnityStereoScreenSpaceUVAdjust (i.uv2, _MainTex_ST);
    26.             float3 albedo = tex2D (_CameraGBufferTexture0, stereoUV).rgb * 0.8 + 0.2;
    27.         #else
    28.             float3 albedo = tex2D(_CameraGBufferTexture0, i.uv2).rgb * 0.8 + 0.2;
    29.         #endif // UNITY_SINGLE_PASS_STEREO
    30.  
    31.         col = saturate (1 - lerp(dot (col, 0.333).xxx,col * _AlbedoMultiplier * albedo, _ColorBleedSaturation));
    32.     #else
    33.         col = saturate(1 - lerp(dot(col, 0.333).xxx, col, _ColorBleedSaturation));
    34.     #endif
    35. #else
    36.     float3 col = float3(EncodeFloatRG(saturate(P.z * (1.0 / _ProjectionParams.z))), 1.0);
    37. #endif
    HBAO_Core.cs
    around line 213
    extending color bleeding properties container

    Code (csharp):
    1.  
    2. [Serializable]
    3. public struct ColorBleedingSettings
    4. {
    5.     [Space(6)]
    6.     public bool enabled;
    7.  
    8.     [Tooltip("This value allows to control the saturation of the color bleeding.")]
    9.     [Space(10), Range(0, 4)]
    10.     public float saturation;
    11.  
    12.     [Tooltip("This value allows to scale the contribution of the color bleeding samples.")]
    13.     [Range(0, 32)]
    14.     public float albedoMultiplier;
    15.  
    16.     [Tooltip ("Use masking on emissive pixels")]
    17.     [Range (0, 1)]
    18.     public float brightnessMask;
    19.  
    20.     [Tooltip ("Brightness level where masking starts")]
    21.     [Range (0, 7)]
    22.     public float brightnessMin;
    23.  
    24.     [Tooltip ("Brightness level where masking ends")]
    25.     [Range (1, 8)]
    26.     public float brightnessMax;
    27.  
    28.     [SerializeField]
    29.     public static ColorBleedingSettings defaultSettings
    30.     {
    31.         get
    32.         {
    33.             return new ColorBleedingSettings
    34.             {
    35.                 enabled = false,
    36.                 saturation = 1f,
    37.                 albedoMultiplier = 4f,
    38.                 brightnessMask = 1f,
    39.                 brightnessMin = 0.8f,
    40.                 brightnessMax = 1.2f
    41.             };
    42.         }
    43.     }
    44. }
    HBAO_Core.cs
    around line 490
    adding new shader property identifiers

    Code (csharp):
    1. colorBleedBrightnessMask = Shader.PropertyToID ("_CBBrightnessMask");
    2. colorBleedBrightnessMin = Shader.PropertyToID ("_CBBrightnessMin");
    3. colorBleedBrightnessMax = Shader.PropertyToID ("_CBBrightnessMax");
    HBAO_Core.cs
    around line 650
    passing new properties to the shader

    Code (csharp):
    1. _hbaoMaterial.SetFloat(ShaderProperties.colorBleedBrightnessMask, colorBleedingSettings.brightnessMask);
    2. _hbaoMaterial.SetFloat(ShaderProperties.colorBleedBrightnessMin, colorBleedingSettings.brightnessMin);
    3. _hbaoMaterial.SetFloat(ShaderProperties.colorBleedBrightnessMax, colorBleedingSettings.brightnessMax);
     
    Last edited: Oct 16, 2017
    jimmikaelkael likes this.
  15. buttmatrix

    buttmatrix

    Joined:
    Mar 23, 2015
    Posts:
    609
    @jimmikaelkael do you plan to integrate these changes to HBAO for a public release? Otherwise I will begin modifying on my end.
     
  16. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Of course, I was already planning a fix for AO not cancelled by emissives on PBR lit AO. That would be criminal not to integrate it!
     
    buttmatrix likes this.
  17. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Changes are done in HBAO core and main shader code, it will allow to fix emissives for every integration stages ;)
     
  18. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    I don't think you need the final lerp. The scaled value is already bound to 0..1:
    Code (csharp):
    1.  
    2. float maskMultiplier = 1 - (scaledAverage * _CBBrightnessMask);
    3.  
    And we have to make sure _CBBrightnessMin < _CBBrightnessMax otherwise we could have a division by 0;
     
  19. Archviz3d

    Archviz3d

    Joined:
    Apr 4, 2016
    Posts:
    92
    Hi!! Im trying to make it work on my android device (samsung galaxy s7) but it doesnt work! Im using unity 2017.2f03 ! Although it works fine on my pc in play mode! Am i doing something wrong? Does HBAO support android? Thanks :)
     
  20. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    It used to work fine with Android but I have to admit I haven't checked it recently.
    However I couldn't recommend to use it on mobile, as most SSAO this is not the type of device where it shines...

    Will take a look at it on this week-end.
     
    Archviz3d likes this.
  21. Archviz3d

    Archviz3d

    Joined:
    Apr 4, 2016
    Posts:
    92
    Thanks!! :)
     
  22. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Tried it, when you force to graphic API to GLES2 it works fine. As soon as auto graphics API is ticked it then choose GLES3 but the shader fails to compile but this is not a HBAO fault: it complains about a missing sampler_CameraDepthTexture sampler.
    Related to: https://github.com/Unity-Technologies/PostProcessing/issues/268

    Not much I can do for now, it's up to Unity to fix this bug...
     
    Archviz3d likes this.
  23. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    HBAO v2.6 has been submitted for review, changelog is the following:
    • Fixed emission not cancelling AO in deferred occlusion
    • Added color bleeding emissive masking
    • Fixed VR Single Pass support in Unity 2017.2
     
  24. Archviz3d

    Archviz3d

    Joined:
    Apr 4, 2016
    Posts:
    92
    Hiii!!! Thanks for checking it out...i was getting crazy trying to figure out if i was doing something wrong!!! Hope they can fix it soon :-(
     
  25. Carpet_Head

    Carpet_Head

    Joined:
    Nov 27, 2014
    Posts:
    151
    Is there any chance you could update your trial package so we can evaluate the asset for vr in 2017.2?
     
  26. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Sorry for the late reply, I'll try to look at this on this week end but can't promise anything...
     
  27. SpaceShaman

    SpaceShaman

    Joined:
    Sep 29, 2016
    Posts:
    5
    Hey! Is there a simple way to exclude objects from AO contribution/reception via HBAO?
    Thanks!
     
  28. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    As with every SSAO plugin, HBAO is a screen space image effect and is geometry agnostic.
    One way to workaround this is to set a higher custom render queue to the material.
     
  29. docsavage

    docsavage

    Joined:
    Jun 20, 2014
    Posts:
    1,003
    Hi @jimmikaelkael,

    Just letting you know game in the last stages and still using HBAO. It's really helped make it look that much better. Great sytem!
     
  30. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    597
    Hi @jimmikaelkael ,
    I tried to apply your HBAO image effect to a VR camera (VRTK_SDKManager, SteamVR, Camera (eye)).
    But when it is turned on the AO effect itself looks like it is using another matrix to convert its calculations into clipspace.
    I tried both Multi Pass and Single Stereo Pass rendering. The camera is rendering in forward mode. Is there anything special to take care about before this will run in VR?

    Unity 2017.3.1p1
     
  31. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    It should work out of the box with VR especially with Multipass where there's nothing special. Single Pass has been tested with Oculus and Vive (I have to admit I'm never testing it with patch versions as they can bring a whole lot of problems).
    You mentionned Camera(eye), what does it means ? Anything special with this camera rig ?

    Please don't hesitate to post screenshots from your camera component, project hierarchy etc...
    You can also try the HBAO demo scene to see if it's correct.
     
  32. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    597
    Nothing that I would be aware of. The project uses VRTK and SteamVR.
    upload_2018-3-27_15-37-39.png

    HBAO itself is sitting in its default folder structure, all compiles nicely. Perhaps it is the patch version causing the trouble.
     
  33. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    I see a VRSimulatorCameraRig object. Are you testing with HMD or in Unity ?

    Would it possible to send me that project in PM (stripped from anything irrelevant if you want) ?
     
    Last edited: Mar 27, 2018
  34. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    597
    I am testing it with the Vive while running the game mode of the editor. I haven't tried a build so far. I am getting similar issues with the postprocessing stack (v1 and v2) AO ...

    Sadly I cannot send you the project.
     
  35. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Testing in Unity editor itself shouldn't be a problem...
    I will do a full re-test with Unity 2017.3 and SteamVR on this week end and report but I think something specific in your project is preventing it to work correctly. Maybe it's VRTK so I'll check that too.
     
  36. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    597
  37. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    I see, thx for the links.
    Initially, before you press Play in editor but go to the game view, do you see a correct AO ?
    Once you pressed Play, aren't there changes in the camera rig hierarchy ?
     
  38. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Sorry for the late feedback @Marco-Sperling
    Tested with Unity 2017.3.1f1, latest SteamVR using VRTK setups: everything is working correctly in both single/multi pass.
     
  39. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    597
    Thanks for testing and letting me know. Where did you place your HBAO script? On the same camera as I did in the screenshot above?
     
  40. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Exactly.
     
  41. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    597
  42. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    I'm sorry but there's no hostile code...
    The problem is that it's normally up to Unity to handle this in their UnityCG.cginc macros. HBAO already uses the proper macros for screen space transforms.
    If Unity fixes their macros as they have done with their PPS (https://github.com/Unity-Technologies/PostProcessing/commit/003f57a4fb956cc7d51dabc0c7ddc8964888c873, file xRLib.hlsl) then HBAO should work fine with adaptive quality.

    I will look at it in more details tonight and try to bring a workaround.
     
  43. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    597
    Sorry, that came off wrong. I meant the VRTK code - not yours. And "hostile" was the quickest association that came to my mind - offending, faulty... buggy... you an pick one :)
    But they all are directed towards the VRTK side.
     
  44. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    You don't have to be sorry, I perfectly understand and you are legitimate to say that even if it was for HBAO.
    As you have noticed this is not a HBAO nor VRTK fault but once again a limitation in Unity we need to workaround...

    I promise to investigate this and bring a proper solution quickly.
     
    Marco-Sperling likes this.
  45. MU-TH-UR

    MU-TH-UR

    Joined:
    Aug 16, 2016
    Posts:
    20
    Hi, do you have an updated demo to test Single Pass Stereo for VR? Right now it's double screen. Your trial package is HBAO_v2.3_Trial and it looks like 2.6 is the latest. Thanks!
     
  46. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    I don't have so much time currently to update the demo package, I'm sorry for that. Single Pass is supported but renderViewportScale (adaptive quality) still causes troubles. I'm still awaiting support from Unity on the V2 Post Processing Stack to understand what's the problem.
     
  47. MU-TH-UR

    MU-TH-UR

    Joined:
    Aug 16, 2016
    Posts:
    20
    I understand, thanks
     
  48. Candac59

    Candac59

    Joined:
    Sep 18, 2015
    Posts:
    106
    Hi,



    when I activate the ambient occlusion, the relief of the ground is visible through the vegetation (I use Vegetation Studio). Until then I understood that the problem is related to ambient occlusion and Post Processing Stack. I always had trouble (even before using HBAO) and even on a blank project. Even using more standard AO of unity and using HBAO now the problem is dreading. I did not find any trail ... Do you have an idea?

    image gif URL:
    https://www.noelshack.com/2018-22-2-1527555796-294e47b83f6d60683f18460922c51057.gif

    Sorry for the quality of the Gif, the problem is visible on the tree trunks (dark band at the base of the trunks)
     
  49. jimmikaelkael

    jimmikaelkael

    Joined:
    Apr 27, 2015
    Posts:
    623
    Could we see a good screenshot of vegetation with AO only debug view ?
    Also which shader foliage is using ?
    Are you using Forward rendering path or deferred ?

    Please try setting Per pixel normals on Reconstruct oin AO settings to see if it makes a difference.
     
  50. candycat

    candycat

    Joined:
    Jun 5, 2014
    Posts:
    29
    I found that the HBAO_Intergrated related shaders will break the alpha channel of the screen buffer. Our image effect does depand on the alpha channel to do fancy effects. I think you should add ColorMask RGB in ALL your final passes, like:

    Code (CSharp):
    1. // 34: combine integrated HDR (multiplicative blending)
    2.         Pass {
    3.             Blend DstColor Zero
    4.             ColorMask RGB // IMPORTANT
    5.             CGPROGRAM
    6.  
    7.                 #pragma vertex vert
    8.                 #pragma fragment frag_blend
    9.  
    10.                 #include "HBAO_Integrated.cginc"
    11.  
    12.             ENDCG
    13.         }
     
unityunity