Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. 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

Screen-space outline effect for Unity (FREE)

Discussion in 'Assets and Asset Store' started by Arvtesh, Feb 27, 2020.

  1. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    169
    Yup, I figured things out, just in the spirit of bug report ;)
     
  2. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Hey @TobySch, I've made several changed to URP rendering (develop branch) in order to resolve the Single Pass Instanced issue. It works for me now (using XR Mock HMD Loader). The next release will include this and several other improvements. Just in case it is still relevant for you.
     
  3. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Hello everyone! A new release of the library has just been published (v0.8.2). It focuses on URP-related fixes and improvements. Details below:

    Added
    • Added URP-specific shader versions.
    • Added URP layer-based outline rendering (#9).
    • Added support for Single Pass Instanced XR rendering for built-in and URP (#13).
    Fixed
    • Fixed URP outlines rendering issue in Unity 2020.2 (#21).
     
  4. ghegi

    ghegi

    Joined:
    Jun 3, 2018
    Posts:
    28


    Hello, I spent decades looking for the perfect outline effect and I found yours and thought it was perfect until I saw this. Im a newb at this (sorry for that and my dumb questions) so, how do I remove the overlapping outlines? I would like for it not to overlap when it is being obstructed by 3D models, I appreciate you doing this god's work!! Thanks in advance!!
     
  5. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Hello @ghegi, try setting depth testing flag in outline settings.
     
  6. ghegi

    ghegi

    Joined:
    Jun 3, 2018
    Posts:
    28


    Hello, thanks for the quick reply but whenever I set the setting to depth testing, this happens to the layers affected by it in the game mode while in the editor mode, they look fine (except it still overlaps, the same as when there is no render flags). :// Any idea why it does this?
     
  7. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Which render pipeline do you use? What is Unity version?
     
  8. ghegi

    ghegi

    Joined:
    Jun 3, 2018
    Posts:
    28
    URP on 2019.4.14f1. ://
     
  9. Teea

    Teea

    Joined:
    Feb 11, 2016
    Posts:
    2
    Hi @Arvtesh keep up the good work, your asset is amazing.
    I'm experiencing same issue as @ghegi when trying to use depth testing. Depth Texture in URP Asset is enabled.
    I'm also using URP but on 2020.1.12f1.

    Also I have a suggestion if you don't mind:
    Could you please add an option to filter objects by rendering layer rather than only object LayerMask?
    I wanted to extend your settings and settings drawers classes myself, but some of it is internal so I have to copy original files or modify your asset source to do it.

    Also @ghegi is it 3D Among Us remake you are working on? :D
     
  10. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    @ghegi, @Teea, there is a bug in outline package, which produces such effect when both depth testing and MSAA are enabled. If you set UniversalRenderPipelineAsset->Quality->Anti Aliasing to Disabled, the outlines would work as expected. I'm working on the fix (no ETA yet).

    @Teea, yes, I can add possibility to select object by rendering layer. May I ask you to create a github issue for this feature request?
     
    Last edited: Nov 13, 2020
  11. Teea

    Teea

    Joined:
    Feb 11, 2016
    Posts:
    2
    @Arvtesh thank you, I'll try. Indeed I have FXAA enabled.

    I opened a ticket on github with feature request.

    Btw, how can I use two different Outline Settings for two layers in URP? I read from your changelog that this should be possible and editor interface kind of implies it, but no matter how I try - I can't make it to work. I ended up adding additional Outline Renderer Feature and configuring it separately for another layer, but this approach feels wrong.
     
  12. ghegi

    ghegi

    Joined:
    Jun 3, 2018
    Posts:
    28
    yeah, it's my first attempt at a 3d game and thought an outline would look good :D
     
  13. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    @Teea there are 2 ways you can filter objects for outline:
    1. Using OutlineLayerCollection you can setup multiple outline settings for different groups of game objects. This approach requires explicit selection of game objects (via adding them to a collection).
    2. Using Unity layers to implicitly select all game objects with the layer. Currently this requires one feature per outline settings, so your solution is the only possible atm.
    It’s worth mentioning that you can use both described methods with one feature.

    Hope this helps!
     
  14. ghegi

    ghegi

    Joined:
    Jun 3, 2018
    Posts:
    28
    @Arvtesh, hello. I'm back again. It worked! But it lags a lot on mobile. I have tried my game on mobile without the outline and it works fine without lag but when I enable the outlines, it suffers extreme lag. ://
     
  15. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    It’s a screen space effect, so it might be heavy for some mobiles. What you might try is making outline width smaller, thicker outlines require much more processing.
     
  16. Flying_Banana

    Flying_Banana

    Joined:
    Jun 19, 2019
    Posts:
    18
    Thank you for sharing your package, this looks like an amazing asset!

    I'm developing a 3D tilemap package and I want to replicate the built-in Unity outline for selected objects. I tried OutlineBehaviour without depth testing (red), with depth testing (yellow) and OutlineEffect (on camera) with object merging (blue):

    Screen Shot 2020-11-14 at 17.46.58.png

    These work pretty well, but aren't exactly what Unity has (orange):

    Screen Shot 2020-11-14 at 17.47.45.png
    It looks like Unity is grouping all individual selected objects in a single layer, then doing a depth testing within that layer only. Is there a way to achieve this with this package?

    Also, I have trouble getting OutlineEffect to render in the editor on a specific camera. It works fine in play mode, and OutlineBehaviour works fine in editor, so it might be some setting problems on my part...or is this intended behaviour? In the screenshot above, you can see that the blue outline is missing. In the camera, I only observe the command buffers for the first four cubes (red and yellow). I have the following setup:

    Screen Shot 2020-11-14 at 18.00.00.png

    Finally, it seems that in the scene, if I disable an outlined game object then re-enable it, the outline won't come back immediately unless I select some other game object. I tried ticking Update Renderers and calling UpdateRenderers() from a custom script from OnEnable(), but the outline won't update in the editor...

    Thanks again for sharing this great asset! :) I'm reading the code to see how you implemented it, but it would be amazing if you would shed some light on those issues!
     
    Last edited: Nov 15, 2020
  17. Flying_Banana

    Flying_Banana

    Joined:
    Jun 19, 2019
    Posts:
    18
    Outline.gif

    Here's a GIF on the outline update issue in the editor. Notice the outline only came back after I clicked on a different game object (edit: the clicked game object must also have OutlineBehaviour attached, or its parent has the script attached for this to work, otherwise outline still won't get updated). This is happening for me in Unity 2020.1f9 in built-in pipeline, by the way.
     
    Last edited: Nov 15, 2020
  18. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Hello @Flying_Banana, thank you for such a detailed feedback.

    First of all, I never put much efforts into adapting the outlines for editor. I'll look into OutlineEffect not being rendered in editor, this might be ab easy fix.

    The depth testing issue a bit harder. I'm afraid this is not something I can hotfix. I'll keep it in mind for future versions.

    I'll look into update issue as well.

    Edit: The OutlineEffect does not work in edit mode because it doesn't have ExecuteInEditMode attribute. I added the attribute and did a quick fix to OutlineBehaviour to correctly render outline after enabling. You can find the fixes in develop branch.
     
    Last edited: Nov 15, 2020
  19. Flying_Banana

    Flying_Banana

    Joined:
    Jun 19, 2019
    Posts:
    18
    Thanks for the quick response! Happy to say the fixes worked quite well, it's really satisfying to go through the code to find that the code doesn't break after undo and hot reload. This is a huge plus for editor tools. I went through countless hours getting those to work with my own package!

    I'm now attaching the
    OutlineEffect
    on the scene view camera, and manually adding/removing selected objects from it.

    A few suggestions:

    While it's possible to inspect and assign an
    OutlineLayerCollection
    from the inspector, this isn't possible via code (
    OutlineEffect.OutlineLayers
    is a readonly property that has a type of
    IList<OutlineLayer>
    ). This means I can't toggle the merge objects option from code without downcasting. I suggest exposing the property as public API, since
    OutlineLayerCollection
    class is already public.

    Should
    _mergeLayerObjects
    be a property of each
    OutlineLayer
    , instead of
    OutlineLayerCollection
    ? If I'm attaching to the scene view camera for outline rendering, then it might cause a potential conflict with some other package that is also attaching to the same camera.

    In the same line of thought, maybe
    RenderEvent
    should also be configured per layer? This will probably require a new dictionary in the the class that stores the mapping (as opposed to directly storing this in the layers. This ensures any changes to it will trigger an update to the appropriate command buffers).

    OutlineEffect.Update()
    isn't called as frequently as the camera is rendering in the scene. Similar to before your
    OutlineBehaviour
    fix, the outline isn't updated immediately after adding/removing an object from the outline layer under special circumstances. E.g. I called
    RemoveGameObject
    after
    Undo.undoRedoPerformed
    callback, but outline isn't updated. I fixed this by replacing the update call with the following:

    Code (CSharp):
    1.  
    2.     // Added.
    3.     private void OnPreRender() {
    4.       FillCommandBuffer();
    5.     }
    6.  
    7.     // Removed.
    8.     private void Update() {
    9.       FillCommandBuffer();
    10.     }
    11.  
    Here's a little demo of what it looks like!

    outline demo.gif
     
    Last edited: Nov 16, 2020
  20. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Thank you valuable suggestions, @Flying_Banana! The only thing I'm unsure is the RenderEvent change: why would someone wand to setup it per-layer? This change would also require using multiple command buffers instead of one. This is doable, I just cannot see a real case when this might be needed.

    As always, you can find the latest code in develop branch.
     
  21. Flying_Banana

    Flying_Banana

    Joined:
    Jun 19, 2019
    Posts:
    18
    This isn't a big issue for now, but imagine that multiple packages want to render outlines at different RenderEvents in the scene view camera. This would then create a conflict!

    Another probably more straightforward fix is to allow multiple OutlineEffect components per camera. I haven't fully went through the code to know whether that would introduce its own problems, but that way each package would only modify its own instance.

    Thanks for taking a look at the issues! I'll take a look later - your code is very structured and nice to read!
     
  22. Peter-Dijkstra

    Peter-Dijkstra

    Joined:
    Feb 15, 2013
    Posts:
    4
    Hi! First of all: loving how easy this is to set up.

    It seems that the lines do not get rendered at objects with my (unlit) Shader Graph (I'm using URP) shaders though. Anything I need to do to fix that? :)
     
    herrkjeldsen_unity likes this.
  23. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Hello @Peter-Dijkstra, URP outlines currently are only applied to objects having shader tag UniversalForward.
     
  24. JCorfer

    JCorfer

    Joined:
    Apr 22, 2016
    Posts:
    14
    Hi @Arvtesh

    Thanks for your asset. I've spent a lot of time searching a good solution to outline effect and I tried your solution. But unfortunately I'm getting the same probleme: the outline effect is totally bad performance with high resolutions, like tablet devices.

    I've tested your solution from Editor setting resolution to 2500x3500 and the FPS that I get is about 15 (in your test scene to Outline.URP)

    In this thread I ask about this cuestion https://forum.unity.com/threads/is-...outline-to-mobile-and-tablet-devices.1026778/

    Definetly, I'm starting to think I have to discard the outline effect from my project, with the artistic cost that this suposses :(.

    Do you think that this has any solution?

    Thanks!
     
  25. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Hello @JCorfer. The performance was never a goal for this outline implementation. That said, I used it on mobiles and it was good enough for real-time applications with right settings.

    There are several things to keep in mind though:
    • As with any post-processing effect, performance drops with resolution increased, especially on mobiles.
    • Outline width can easily be show stopper. Decrease it and you will definitely see better FPS.
    • Avoid using many outlines with different settings (like the sample scene does). In most real cases you only need one outline.
    • If the above mentioned does not fix performance issues you have, there are non screen-space based outline implementations out there.
    Hope this helps!
     
    JCorfer likes this.
  26. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    I'm pleased to announce that a new version of the library has been released (v0.8.3).

    Essential changes:

    Added
    • Added possibility to set custom shader tags for URP outlines.
    • Added support for filtering URP outline renderers by rendering layer mask (#22).
    Fixed
    • Fixed URP outlines rendering issue when both depth-testing and MSAA are enabled (#23).
    • Fixed OutlineBehaviour not working in edit mode after disabling and enabling it again.
    Changed
    • OutlineEffect now works in edit-mode.
    • OutlineEffect now exposes OutlineLayerCollection instead of IList.
    • OutlineEffect now uses OnPreRender to update its command buffer.
    • Moved MergeLayerObjects flag to OutlineLayer from OutlineLayerCollection.
    • Multiple OutlineEffect component instances can now be added to a camera.
     
  27. jrmgx

    jrmgx

    Joined:
    Oct 21, 2016
    Posts:
    39
    First of all, you're the best!
    I've been looking for a working outline shader or similar effect for the last two days (and thus testing many of them) and yours is the only one that works in my (specific?) case.

    Still, I have a question, I use your code to outline a Skinned Sprite Mesh, and the outline sticks to the limit of the mesh and not the sprite that it contains
    see image:

    We can see that there is a small offset between the character and the outline (the outline here follows the actual bounds of the mesh).

    In the OutlineLayerCollection config part, I really though that setting RenderFlags to "Enable Alpha Testing" will do the trick, but I guess I may have misunderstood something?

    Let me know if you have a solution for me :)
    Have a great day
     
  28. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    Hello @jrmgx, it seems you do everything correctly. If it doesn’t work, it’s a bug. Could you tell me which outline package you use? And what is the name of your skinned mesh shader?
     
  29. jrmgx

    jrmgx

    Joined:
    Oct 21, 2016
    Posts:
    39
  30. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
    @jrmgx, URP version of the library doesn't have full support of sprite outlines at the moment. It's not a bug, it's just not implemented yet. I'm going to add the support in the upcoming version. Thank you for the report.
     
  31. jrmgx

    jrmgx

    Joined:
    Oct 21, 2016
    Posts:
    39
    You're welcome!
    Where can I subscribe to know when it will be added?
    Great job anyway, very useful
     
  32. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    77
unityunity