Search Unity

Easy Decal - Decals everywhere

Discussion in 'Assets and Asset Store' started by Sycoforge, Oct 28, 2014.

  1. akareactor

    akareactor

    Joined:
    Apr 6, 2015
    Posts:
    74
    I believe this is a limited solution. Do not wish to strictly rely on its hardness. If the pool cannot return an decal for his internal reasons - let it be so. In this case, I get more choice due to optimization.
     
  2. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    The instantiation injection has been designed for a replacement to Unity's internal Instantiation method, thus nulls are not supported. This is a design restriction. What you can do though, is to create your own ProjectAt() method which handles nulls.

    Please find below the source of how the Easy Decal plugin implemented those methods.

    Code (CSharp):
    1.         private static EasyDecal ProjectInternal(GameObject decalPrefab, GameObject parent, Vector3 position, Quaternion rotation, Vector3 scale)
    2.         {
    3.             EasyDecal decal = decalPrefab.GetComponent<EasyDecal>();
    4.  
    5.             if (decal == null)
    6.             {
    7.                 throw new Exception("The prefab you want to instantiate has no 'EasyDecal' script appended.");
    8.             }
    9.  
    10.             if (parent != null && !ContainsLayer(decal.Mask, parent.layer))
    11.             {
    12.                 return null;
    13.             }
    14.  
    15.             float yScale = decal.Technique == ProjectionTechnique.Plane ? 1f : scale.y;
    16.  
    17.             EasyDecal clone = null;
    18.  
    19.             if (Instantiation != null)
    20.             {
    21.                 // Insert your pool logic here
    22.                 clone = Instantiation(decalPrefab, parent, position, rotation);
    23.  
    24.                 if(clone == null)
    25.                 {
    26.                     Debug.LogError("The assigned instantiation method returned a null object.");
    27.                 }
    28.             }
    29.             else
    30.             {
    31.                 clone = ((GameObject)GameObject.Instantiate(decalPrefab, position, rotation)).GetComponent<EasyDecal>();
    32.             }
    33.  
    34.             clone.transform.localScale = new Vector3(scale.x, yScale, scale.z);
    35.             clone.Receiver = parent;
    36.             clone.LateBake();
    37.  
    38.  
    39.             if (parent != null)
    40.             {
    41.                 DecalReceiver decalReceiver = parent.GetComponent<DecalReceiver>();
    42.  
    43.                 if (decalReceiver != null)
    44.                 {
    45.                     clone.Distance = decalReceiver.fractionsum;
    46.                     decalReceiver.Receive(clone);
    47.                 }
    48.  
    49.                 clone.gameObject.transform.parent = parent.transform;
    50.             }
    51.  
    52.             return clone;
    53.         }
    Code (CSharp):
    1.         /// <summary>
    2.         /// Instantiates the prefab at the specified position facing in the specified normal direction and rotation as child of parent.
    3.         /// </summary>
    4.         /// <param name="decalPrefab">The decal prefab.</param>
    5.         /// <param name="receiver">The decal parent (parent).</param>
    6.         /// <param name="position">The decal's position.</param>
    7.         /// <param name="normal">The parent's surface normal.</param>
    8.         /// <param name="rotation">The rotation along the receivers normal axis.</param>
    9.         /// <param name="scale">The scale of the decal.</param>
    10.         /// <returns>The decal object or <c>null</c> if the projection criteria was not fulfilled.</returns>
    11.         public static EasyDecal ProjectAt(GameObject decalPrefab, GameObject receiver, Vector3 position, Vector3 normal, float rotation, Vector3 scale)
    12.         {
    13.             Quaternion quat = Quaternion.AngleAxis(rotation, normal) * Quaternion.FromToRotation(Vector3.up, normal);
    14.            
    15.             return ProjectInternal(decalPrefab, receiver, position, quat, scale);
    16.         }
     
  3. GfK

    GfK

    Joined:
    Aug 15, 2014
    Posts:
    107
    [UPDATE 24/9/2019] More testing reveals this issue affects only box decals. Also, I've narrowed it down to static batching. If I turn that off, everything seems to be working OK.


    [ORIGINAL POST]
    New bug, and it's a weird one. It seems to be to do with static meshes and I think we've had issues with them before so I'm thinking this bug is most likely related to that.

    Untitled.png

    Bear with me, this is a bit complicated.

    The white thing is just a cube primitive, static geometry.

    The radar building has four legs and a platform, which are all static. The radar on top is not static (it has a script which rotates it).

    I have a couple of bullethole decals (for variation), and a blastcrater decal. The problem affects all ED decals.

    OK...

    If I shoot at the radar (legs), decals spawn and render fine. If I then shoot at the white cube, decals are being spawned, but do not render. The decal is in the correct place, facing the right way, but has no geometry. They show as visible to the camera, but no vertices or faces.

    Likewise, if I shoot the white cube first, THEN shoot the radar building legs, decals do not render on the legs.

    It's as if whatever static geometry I shoot first, is the only static thing decals will then project to.

    But then, if I have TWO static unity cubes, decals will render to both if any one of them has been shot first, or to neither, if the radar unit was shot first.

    The exception to all of this, is the terrain. That's also static, but decals work fine on that, all the time.

    To summarise I think there's still some issue with projecting onto static geometry, and when a decal has been projected onto something that's static, decals then won't project onto anything else that's also static.
     
    Last edited: Sep 24, 2019
  4. anzerkree

    anzerkree

    Joined:
    Feb 16, 2017
    Posts:
    12
    *** SOLVED With deferred decal ***
    Hello Sycoforge
    Thanks for this great plugin.

    I have a problem when my scene is darker (without light)

    My decals seem to be fluorescent. As if there were texture emission.

    My material is "Easy Decal / ED Standard (Mettalic, Vertex Alpha)"

    How can we ensure that the brightness of the decals is affected by the ambients lights?
    How can we remove this emission light ?

    My config : Linear Color and Deffered Camera






    *** SOLVED With deferred decal ***
     
    Last edited: Sep 26, 2019
  5. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    Our office is currently under construction. Our reaction time is therefore very slow. All inquiries will be answered by 1 October at the latest. We ask for your understanding. Thank you!
     
  6. GfK

    GfK

    Joined:
    Aug 15, 2014
    Posts:
    107
    I think I'm having an epic brainfart today.

    Suppose I want to fire splodges of paint around, all different colours. How can I change the colour of each decal individually?

    I've tried setting DecalMaterial.Color directly, and also DecalMaterial.SetColor. Both seem to be setting the colour of the source material without creating an instance of it.

    [edit] Worked around it by manually instantiating the material on Awake(), but I shouldn't have to do that, right?
     
    Last edited: Sep 26, 2019
  7. ZolnierGames

    ZolnierGames

    Joined:
    Feb 19, 2018
    Posts:
    35
    Just bought this and I'm curious if there is any way to create a custom text decal so I could use it for something like putting a custom text string on the back of a jersey. Is this possible?
     
  8. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    Changing the material leads to an instance with disables the auto batching. When not working with thousands of decals, this is fine. You could also store color data in the decal's vertex data and then write a shader that reads the vertex colors. You can change the vertex color by hooking to the OnProjectionFinished event of the decal. However, this method increases the projection CPU time.
     
  9. BitAssembler

    BitAssembler

    Joined:
    Jul 13, 2017
    Posts:
    63
    Maybe this is possible when having the text in a texture. Letting the player/user change the text at runtime requires you to render text to textures.
     
  10. a-bottosso

    a-bottosso

    Joined:
    Nov 13, 2015
    Posts:
    11
    Hi @Sycoforge
    We are currently using the latest version of Easy Decal, in a LWRP context and using Box Decals.
    We're experimenting a weird behaviour: the Decals work fine only when baking is on; when is disabled, changing the decal from the Atlas in play mode results in a huge fps drop in the editor and in build (down to around 7 fps).
    From the profiler, we can see that this is caused by the EasyDecal update, but we are unable to go deeper.
    In our game we need to change decals at runtime.
    Can you please help us to shed some light on this?
    Thanks in advance,
    Alessio
     
  11. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    Hi Alessio,

    The Box projector needs a noticeable amount of CPU while projecting the decal. There some heavy algorithms involved to calculate the intersection of the decal's bounding box with world geometry. However, box (mesh decals in general) decals are the best choice for static decals. Once they are soft-baked they need only a very tiny amount of CPU time (0.1 ms for 50 decals) to manage fading and stuff. When placing them at design time they could also be hard-baked to produce no overhead at all.

    In your case, when you have to change the atlas index (actually a geometry change -> UVs), you have to perform the following operations on the decal:

    1. Call LateUnbake()
    2. Wait for next frame
    3. Change atlas index
    4. Call LateBake()
    Code (CSharp):
    1.             Decal.EasyDecal d;// Your decal instance
    2.             d.LateUnbake();
    3.  
    4.             yield return null;// Wait one frame
    5.  
    6.             d.AtlasRegionIndex = 2;// New atlas index
    7.             d.LateBake();
    Please let me know if that helped!
     
  12. a-bottosso

    a-bottosso

    Joined:
    Nov 13, 2015
    Posts:
    11
    Hi @Sycoforge,
    Thanks for your super-quick answer!
    Now it works like a charm in editor.
    Testing on Android results in a short fps drop when changing the decal of the Atlas. Do you suggest using another tecnique instead of the Box one?

    Many many thanks,
    Alessio
     
  13. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    This mainly depends on the receiver and the usage:

    Plane

    Performance affected by
    • Resolution property
    Best for
    • Simple surfaces
    • Convex surfaces
    Drawbacks
    • May creates unnecessary geometry on complex surfaces
    • Always needs colliders
    • Not necessarily fit the geometry of the receiver

    Box

    Performance affected by
    • World space size of the decal
    • Geometry complexity of the receiver
    Best for
    • Complex surfaces
    • Static decals placed at design time
    Drawbacks
    • May creates unnecessary geometry on flat surfaces
    • Performance is size-dependent
    Deferred/Screen Space
    In HDRP: It's recommended to use Unity's implementation.
    In LWRP/URP only "Easy Decal/SSD/Multiply" shader is supported

    Performance affected by
    • Screen space size of the decal
    Best for
    • Complex surfaces
    • transparent decals with the need for proper shadow receiving
    Drawbacks
    • Cannot be batched
    • Works only with deferred rendering path
    • Works only with a perspective camera
    • Projection constraint options are limited

    When you need dynamic decals with a lot of changes in geometry, I would recommend using the Screen Space technique. However, you are bound to a multiply-blend shader.
     
  14. a-bottosso

    a-bottosso

    Joined:
    Nov 13, 2015
    Posts:
    11
    @Sycoforge it's possible to have a shader for the screen space without blending?
    We need a simple basic shader that handles decals with transparency in screen space.
    Have you something to share with us?

    Thanks
    Alessio
     
  15. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    Currently, only an unlit screen space shader is defined for the non-deferred pipelines. We'll investigate if it's possible to inject our screen space functionality to LWRP. Maybe there's a simple way to do this. Keep your fingers crossed. We'll keep you posted.
     
  16. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    We can provide a first prototype for a lit screen space decal shader for LWRP/URP. Please send us a private message or email with your invoice number and we'll give you early access to the shader. Please keep in mind that this is an alpha version and should not be used to ship a product.
     
  17. BenRogWilhelmAirship

    BenRogWilhelmAirship

    Joined:
    Aug 16, 2019
    Posts:
    1
    Hey there! I recently bought your plugin online partially due to the promise of source code access. Unfortunately I haven't been able to get your website working - the "add unity invoice" panel doesn't work at all, hitting the "add" button does nothing, I've tried in both Chrome and Firefox - and I've tried contacting support but haven't gotten a reply after a week. I do actually need sourcecode access. Can I get this taken care of?
     
  18. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    Unfortunately, your mail somehow didn't make it into our mailbox. Apologies for that. I have sent you a PM containing all info to access the additional downloads.
     
  19. aunity91

    aunity91

    Joined:
    May 20, 2019
    Posts:
    2
    Does EasyDecal require HDRP to be enabled? And is it compatible with Android build?
     
  20. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    No. HDRP is not needed.
    Yes. It works on Android. :)

    HDRP
    Use mesh decals (box or plane projectors) or Unity's deferred decals.

    LWRP/URP
    Use mesh decals or screen space multiply or screen space lit shader (experimental)

    Standard
    All is possible.
     
  21. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    Easy Decal 2020.1 is available for download from our website and soon also in the UAS.

    New in experimental state: Screen Space Decals for LWRP/URP (Unity 2019.2 +)! Let us know how they perform in your project.
     
    ratking and JBR-games like this.
  22. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,478
  23. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    Thanks for the report. There was an access right issue on the web shop. It should all be back to normal.
     
  24. Sycoforge

    Sycoforge

    Joined:
    Oct 6, 2013
    Posts:
    638
    Easy Decal 2020.1

    Fixes

    • Fixed tangent issue when combining.
    • Fixed normal scale issue with box projector.
    • Fixed "Instantiate after save" issue.
    • Fixed wrong scale after prefab creation.

    Features
    • Unity 2019.3 and 2020.1 Support.
    • Moved shortcuts to accessible C# file for easy change.
    • Added experimental LWRP/URP screen space decal shader.
     
    Willbkool_FPCS likes this.
unityunity