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

[RELEASED] Decalicious – Deferred Decal System

Discussion in 'Assets and Asset Store' started by Daerst, Nov 21, 2016.

  1. T5Shared

    T5Shared

    Joined:
    Oct 19, 2018
    Posts:
    152
    Is this working in Unity 2020? Trying it in Unity 2020.3.11, and I am not seeing anything after upgrading from Unity 2018.
     
  2. Agoxandr

    Agoxandr

    Joined:
    Aug 16, 2014
    Posts:
    42
    You should switch to Ultimate decals Ultimate Decals (Deferred, Forward, URP) | Utilities Tools | Unity Asset Store. It works pretty well. I had to make a few changes to the way the clip is performed for deferred, but it works. You could also wait for URP 2021.
     
    T5Shared likes this.
  3. Daerst

    Daerst

    Joined:
    Jun 16, 2016
    Posts:
    275
    Be aware that Decalicious works with Deferred Shading and the Build-In / Legacy Render Pipeline only. 2020 should not be a problem.
     
    T5Shared likes this.
  4. T5Shared

    T5Shared

    Joined:
    Oct 19, 2018
    Posts:
    152
    Hi both, thanks for the replies! Daerst, that is good to know that it should work in 2020. We are using the built-in render pipeline, so that should not be the problem. I will have a second look then to find out what the probems are
     
  5. T5Shared

    T5Shared

    Joined:
    Oct 19, 2018
    Posts:
    152
    I just downloaded and imported the package from the Unity Asset Store into a fresh Unity 2020.3.11 project, and I can confirm that the example scene works perfectly, (Almost perfectly, because there is no floor in the last room, so I cannot get close to the final examples by walking there)

    So yeah, it works fine in Unity 2020, just not in our project. Which I should be able to fix
     
    Daerst likes this.
  6. T5Shared

    T5Shared

    Joined:
    Oct 19, 2018
    Posts:
    152
    Yup, it's all fixed and works fine in Unity 2020. Decals FTW!
     
    Daerst likes this.
  7. whidzee

    whidzee

    Joined:
    Nov 20, 2012
    Posts:
    161
    I'm looking to optimise my game and am looking everywhere for savings. I am running Unity 2018, standard renderer.
    looking in my profiler i am getting DecaliciousRenderer.OnPreRender() (0.46ms)
    Just wondering if 0.46ms is roughly what you all are getting with this? or if there was a way to trim this down somehow?
     
  8. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,145
    Hi,

    i am looking for a good decal system for Unity's Standard Pipeline...

    i am doing a Livery System for a racing game (similar to CarX Drift) and i need to be able to sort decals and also being able to somehow restrict the decals to a given car body... as i can see Decalicious does both of the these, i just want to be sure that i understand the features correctly and also the system hasn't been updated for a long time and the Roadmap shows some bugs !

    So would Decalicious do the job in our case and is any update coming soon ?
    Also also, can the system apply a color, metalness and smoothness per decal so we don't have to touch materials, like per instance override values ?
     
  9. Jmangles

    Jmangles

    Joined:
    Aug 1, 2015
    Posts:
    53
    Decals weren't showing in WebGL builds so I tested Windows builds and found no decals there either. Afterwards checked to see if the shaders were included in the "Always include" shader list and they are. Then I decided to check if it was an asset bundle issue so I set my Addressables run mode to use built asset bundles and finally I got the decals to break in-editor.

    The materials and shaders are all there I think? If I check out the decals in the scene view it shows the "Please select a Material with a Decalicious shader." message. If I select the exact same material from my project window and apply it to the decal component I can see the decal correctly.

    My assumption is that the bundled versions of the shaders don't have the same reference as the ones found in the Decal component when it uses Shader.Find.

    I fixed our issue by simply changing the "else" RenderMode in Decal.cs line 99 to Deferred rather than Invalid since I know for our project I can deal with the fallout of someone applying the wrong material type later in the worst case.

    Edit: To make it cleaner and keep the safeties I added a tag to the deferred and unlit shaders that I compare instead of the direct shader references.
     
    Last edited: Feb 1, 2022
  10. Jmangles

    Jmangles

    Joined:
    Aug 1, 2015
    Posts:
    53
    Noticed that this asset was taking up a good chunk of our CPU time in a scene with a lot of decals so I did a bunch of simple optimizations.

    In the Decal.cs and DecaliciousRenderer.cs files there's a lot of low-hanging fruit to reduce hashing calls such as caching the integer value of each shader property, especially for the heavy method SetLightProbeOnBlock. Just by doing this for every shader property in this system we were able to reduce frame times a good bit.
    private static readonly int unity_SHAr = Shader.PropertyToID("unity_SHAr");


    After that, the biggest optimization was fixing the redundant hashing call in the dictionary checks for AddDeferred and AddUnlit.
    Code (CSharp):
    1. if(dictionary.Contains(x))
    2.     dictionary[x].Whatever();
    Calls the dictionary hashing method twice while this only calls it once while doing the same thing.
    Code (CSharp):
    1. if(dictionary.TryGetValue(x, out Something value))
    2.     value.Whatever();
    These two things alone gave me over a full millisecond back on the CPU. There are more optimizations we did but they don't apply to your general case. By preventing things like Fade from being set at runtime without calling a SetFade method I was able to remove the OnWillRenderObject method entirely which saved a good chunk of time since the remaining slowdowns were all the hashing calls for TryGetValue and the HashSet.Contains calls. Instead of generating the dictionaries/hashsets every frame they're cached in Awake and then modified only when a change is detected. This breaks decals in the editor so I had to make it use your original code only when in edit mode.
     
    DwinTeimlon likes this.
  11. Zarkow

    Zarkow

    Joined:
    Jul 27, 2015
    Posts:
    92
    Would you have a first changeset for the adjustments made so others can do them too? Seeing as this asset has not gotten any updates in years now...
     
  12. Zarkow

    Zarkow

    Joined:
    Jul 27, 2015
    Posts:
    92
    Daerst >> Will support for skinned mesh renderers for 'Limited To' ever come?
     
  13. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    294
    I also did a bunch of optimizations. I guess @Jmangles talking about these functions in
    DecaliciousRenderer. I can't remember if I also changed the data structure of those containers, so included them in the code part.

    Code (CSharp):
    1.  
    2. protected Dictionary<int, Dictionary<Material, HashSet<Decal>>> _deferredDecals;
    3. protected Dictionary<int, Dictionary<Material, HashSet<Decal>>> _unlitDecals;
    4.  
    5. private void AddDeferred(Decal _decal)
    6. {
    7.      if (!_deferredDecals.TryGetValue(_decal.RenderOrder, out Dictionary<Material, HashSet<Decal>> list))
    8.         _deferredDecals.Add(_decal.RenderOrder, list = new Dictionary<Material, HashSet<Decal>>());
    9.  
    10.     if (!list.TryGetValue(_decal.Material, out HashSet<Decal> decals))
    11.          list.Add(_decal.Material, new HashSet<Decal> { _decal });
    12.      else
    13.          decals.Add(_decal);
    14. }
    15.  
    16. private void AddUnlit(Decal _decal)
    17. {
    18.     if (!_unlitDecals.TryGetValue(_decal.RenderOrder, out Dictionary<Material, HashSet<Decal>> list))
    19.         _unlitDecals.Add(_decal.RenderOrder, list = new Dictionary<Material, HashSet<Decal>>());
    20.  
    21.     if (!list.TryGetValue(_decal.Material, out HashSet<Decal> decals))
    22.         list.Add(_decal.Material, new HashSet<Decal> { _decal });
    23.     else
    24.         decals.Add(_decal);
    25. }
    26.  


    There is a bit more I have changed:
    decalEnum.Dispose()
    was never called after
    GetEnumerator()
    which actually causes a memory leak.

    I have replaced all the strings where shader properties are not cached:
    Code (CSharp):
    1.         private static readonly int MASK_MULTIPLIER = Shader.PropertyToID("_MaskMultiplier");
    2.         private static readonly int LIMIT_TO = Shader.PropertyToID("_LimitTo");
    3.         private static readonly int UNITY_SH_AR = Shader.PropertyToID("unity_SHAr");
    4.         private static readonly int UNITY_SH_AG = Shader.PropertyToID("unity_SHAg");
    5.         private static readonly int UNITY_SH_AB = Shader.PropertyToID("unity_SHAb");
    6.         private static readonly int UNITY_SH_BR = Shader.PropertyToID("unity_SHBr");
    7.         private static readonly int UNITY_SH_BG = Shader.PropertyToID("unity_SHBg");
    8.         private static readonly int UNITY_SH_BB = Shader.PropertyToID("unity_SHBb");
    9.         private static readonly int UNITY_SHC = Shader.PropertyToID("unity_SHC");
    10.  
    In regards to remove OnWillRenderObject in Decal.cs. This will only work if you are not dynamically changing any of the decals at runtime. Though you could add a static decal which could then be handled differently in the DecaliciousRenderer. Probably an optimization worth doing, as most of the decals in games are static anyway.
     
    Last edited: May 30, 2022
  14. SuperPoopsy

    SuperPoopsy

    Joined:
    Jan 20, 2020
    Posts:
    17
    @Jmangles and @DwinTeimlon Sorry for bothering you, but would you mind to compile a full comprehensive list of changes/optimizations you did for Decalicious for us less knowledgeable folks to implement?

    Something a little more specific, like "line X of Y script -> new code" in a organized list.

    It's probably just a matter of checking the diff between your files and the original ones, it shouldn't take too long.

    It's a shame the author seems to have abandoned it, I quite enjoy the asset and it's already pretty fast compared to others I've tried, but every little bit of performance improvement always helps.
     
  15. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    294
    I am just quite busy atm. If you can wait a few weeks, I can do this for sure.
     
  16. SuperPoopsy

    SuperPoopsy

    Joined:
    Jan 20, 2020
    Posts:
    17
    That's not a problem at all, thanks for contributing!
     
  17. Zorkind

    Zorkind

    Joined:
    May 4, 2015
    Posts:
    55
    I am so sorry for taking this long to answer this.

    Yes, exactly, Decalicious is 100% working in the base game.
     
  18. Zorkind

    Zorkind

    Joined:
    May 4, 2015
    Posts:
    55
    Thanks for this, it fixed my Assetbundle issue :D

    Such a simple solution ^^