Search Unity

  1. Unity 2019.1 beta is now available.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We're looking for insight from anyone who has experience with game testing to help us better Unity. Take our survey here. If chosen to participate you'll be entered into a sweepstake to win an Amazon gift card.
    Dismiss Notice
  4. On February 28th the Feedback website will shut down and be redirected to the Unity forums. See the full post for more information.
    Dismiss Notice
  5. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  6. Unity 2018.3 is now released.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Skinned Decals

Discussion in 'Assets and Asset Store' started by phosphorous_, Dec 13, 2018.

  1. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    Hey,

    we just released an editor extension called Skinned Decals on the asset store. It is a solution for mesh-based decals overlayed on any character (using one or multiple Skinned Mesh Renderers) during gameplay or in the editor. The characters do not need a collider, you add a decal by providing a ray where the decal is projected on to the character. The system uses the snapshot of the current pose to create the decal mesh.

    Summary:
    • Easy way to add decals such as bullet holes on your characters (add one component and one line of code).
    • Doesn't require any colliders on the character.
    • The decals follow animation exactly like the source skinned mesh.
    • Possible to use complex shaders with parallax, tessellation etc. to create depth for the decals (shaders and decal textures are included)
    • Multithreading is included as an option for runtime generation, performance depends on the underlying mesh complexity.
    Let me know what you think or ask if you have any questions!

    ASSET STORE LINK: http://u3d.as/1nCA


    MANUAL

    Creating decals in the editor:


    Runtime demo video:


    --

    Description from the Asset Store:

    You need a way to show effects on your character model such as damage, bullet holes, scratches, stains, dirt and more. Skinned Decals will allow you to add impressive decals to your characters during gameplay (and editor) with ease, just one line of code.

    The system does not require the skinned mesh to have any colliders, the decals are placed according the mesh data.

    The mesh based solution allows flexibility in shaders, for example it is possible to use Tesselation to enhance the depth of the effects. Skinned decals will also perfectly follow the animation of your model.

    Sample character, bullet hole decals and shaders are included!

    FEATURES

    - Run-time generation (with optional multithreading)
    - Does not require colliders
    - One line of code to add decal
    - Supports characters composed of many skinned meshes
    - Atlasing, draw many decal types with one draw call.
    - Option to add decals to character in the editor and save mesh for later use.
     
    Last edited: Jan 19, 2019
  2. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21


    Here is a side-by-side comparion with the decals on/off. There are 4 bullet holes here (combined in to one draw call). The character itself is composed of 6 skinned meshes.
     
  3. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    I have tested the package on older Unity versions and verified that it works on Unity 2017.1.0f3 and newer.
     
  4. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    Had some requests about support for earlier Unity versions, but the oldest supported version is 2017.1. This is due to using Mesh.GetVertices() and the other similar functions which were introduced in that version.

    The Asset Store package is also now updated to show the required version as 2017.1.0 or higher!
     
    blackbird likes this.
  5. christoph_r

    christoph_r

    Joined:
    May 20, 2013
    Posts:
    432
    Very interesting. How does it work? It seems to generate new skinned meshes?
     
    Ragoo likes this.
  6. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    Yes that is it.

    How it works is that it:
    1. takes a snapshot of the vertices in the characters skinned mesh,
    2. calculates which vertices are affected by the projected decal,
    3. adds those vertices in to a new skinned mesh (or existing one if previous decal has already created it) and calculates new uv's for the decal.
     
    EvilGremlin, Flurgle and christoph_r like this.
  7. christoph_r

    christoph_r

    Joined:
    May 20, 2013
    Posts:
    432
    Sounds good - how many micro(/mili?)seconds does it take, on average, to generate a decal for a skinned mesh with, say, 40k vertices? Do you have some numbers on additional memory usage? And do you have some ideas on how to handle LOD gracefully?
     
  8. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    I did some tests using a model with ~35k vertices (the Guard model from Adam character package).

    In this test on average (with 20 datapoints) I got ~120 decal vertices per millisecond. So for example if you have a decal that covers an area with ~4000 vertices it will take ~34 milliseconds to create the decal. Memory vice we are talking about few megabytes of mesh data. With multithreading enabled there won't be much visible impact from the computation, but you will be triggering garbage collection if you create a lot of decals with large meshes.

    For comparison using a model with ~6k vertices (Robot Kyle), with same decal and same amount of tests I got an average of 80 vertices / millisecond. The average decal was 400 vertices and took ~5ms to create.

    In both tests I used the same decal which has a size of 0.4 world units. With this system the amount of vertices within the decal area determines the overall performance, so characters with lower mesh density are recommended.
     
    EvilGremlin likes this.
  9. strongbox3d

    strongbox3d

    Joined:
    May 8, 2012
    Posts:
    606
  10. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    41
    This asset looks interesting. After trying a few other decal assets that have decent reviews and them failing all my requirements I am looking towards this one now.

    My use case is I have a skinned mesh character. I want to have some wounds in various places that I can toggle on/off during runtime. I don't want to create them at runtime. I can set them up before hand in the editor, but at runtime I need to be able to toggle them on/off. And not just the whole set of decals, I need to be able to enable/disable specific ones.

    For example.

    I will have a character that has a rash on part of his neck. And when you touch it with something in VR, that rash decal goes away and is replaced by a different lotion decal.

    Would this be possible with this asset?
     
  11. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    I haven't tested so cannot confirm it. If you have high-poly models and want to generate large decals during runtime I think it will be slow with mobile device. If you generate the decals in the editor and just enable the meshes during runtime it should be fine.
     
  12. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    Yes this is possible. You can generate the decals in the editor, save the resulting skinned meshes to the project and toggle them on/off or load when you need them.

    I created a video that shows how this works, I hope it helps to clear things out!

     
    EvilGremlin likes this.
  13. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    41
    Awesome thats perfect! Thanks! Ill write a review for you after I use it for a bit.
     
  14. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    41
    @phosphorous_

    Going well so far. A couple questions

    1. Is there a way to make it not hit the other side of the mesh when placing the decals?
    2. It seems like some of the shaders are deferred rendering only, can you quickly tell me which shaders are deferred only? I'm currently using forward rendering for AA in VR, I can switch to deferred but I'd rather not do it right now.
     
  15. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    Nice, I hope it works out for you!

    1. In the decal inspector there is "Normal clip" which you can set to 0 if you want the decal only be applied to vertices facing where the decal is projected.
    2. The shaders are written deferred rendering in mind, but I wrote this version of the Tesselated Parallax shader for example on how to do it.

    Code (CSharp):
    1. Shader "SkinnedDecals/Tessellated Parallax Forward" {
    2.     Properties {
    3.         _MainTex ("Albedo (RGB) Alpha (A)", 2D) = "white" {}
    4.         _Color ("Main Color (RGB) Alpha (A)", Color) = (1, 1, 1, 1)
    5.         _BumpMap ("Normals", 2D) = "bump" {}
    6.         _SpecularMap("Specular map", 2D) = "white" {}
    7.         _SpecularColor ("Specular Color", Color) = (1, 1, 1, 1)
    8.         _Shininess ("Shininess", Range(0,1)) = 0.5
    9.         _ParallaxMap ("Height", 2D) = "gray" {}
    10.         _Tess ("Tessellation", Range(1,32)) = 4
    11.         _Displacement ("Displacement", Range(0, 0.1)) = 0.01
    12.         _Parallax ("Parallax Amount", Range(0.005, 0.08)) = 0.02
    13.         _MinDistance ("Minimum Distance", Range(0, 50))= 10
    14.         _MaxDistance ("Max Distance", Range(0, 50))= 25
    15.  
    16.         _AlphaClip ("Alpha Clip", Range(0, 1))= 0.01
    17.     }
    18.     SubShader {
    19.         Tags { "RenderType"="Opaque" "Queue"="Geometry+5" }
    20.         Fog { Mode Off }
    21.         Offset -1, -1
    22.         LOD 600
    23.  
    24.         Blend One OneMinusSrcAlpha
    25.      
    26.         CGPROGRAM
    27.         #pragma surface surf StandardSpecular noshadow vertex:disp tessellate:tessDistance nolightmap alpha
    28.         #pragma target 4.6
    29.  
    30.         #include "Tessellation.cginc"
    31.  
    32.         sampler2D _MainTex;
    33.         sampler2D _BumpMap;
    34.         sampler2D _SpecularMap;
    35.         sampler2D _ParallaxMap;
    36.  
    37.         float4 _Color;
    38.         float4 _SpecularColor;
    39.  
    40.         half _Shininess;
    41.         float _Tess;
    42.         float _Displacement;
    43.         float _Parallax;
    44.         float _MinDistance, _MaxDistance;
    45.  
    46.         float _AlphaClip;
    47.  
    48.         struct appdata {
    49.                 float4 vertex : POSITION;
    50.                 float4 tangent : TANGENT;
    51.                 float3 normal : NORMAL;
    52.                 float2 texcoord : TEXCOORD0;
    53.             };
    54.                
    55.         float4 tessDistance (appdata v0, appdata v1, appdata v2) {
    56.             return UnityDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, _MinDistance, _MaxDistance, _Tess);
    57.         }
    58.  
    59.         void disp (inout appdata v)
    60.         {
    61.             float d = saturate(tex2Dlod(_ParallaxMap, float4(v.texcoord.xy,0,0)).r -0.515) * 2 * _Displacement;
    62.             v.vertex.xyz += v.normal * d;
    63.         }
    64.  
    65.         struct Input {
    66.             float2 uv_MainTex;
    67.             float3 viewDir;
    68.         };
    69.  
    70.         void surf (Input IN, inout SurfaceOutputStandardSpecular o) {
    71.             // Parallax
    72.             fixed2 uvs= IN.uv_MainTex;
    73.             fixed4 height = tex2D(_ParallaxMap, IN.uv_MainTex);
    74.             float clampedHeight = min(0.5, height.r);
    75.             float2 parallax = ParallaxOffset(clampedHeight, _Parallax, IN.viewDir);
    76.             uvs += parallax;
    77.  
    78.             // Albedo comes from a texture tinted by color
    79.             fixed4 c = tex2D (_MainTex, uvs);
    80.             o.Albedo = c.rgb * _Color.rgb;
    81.  
    82.             // Normals
    83.             o.Normal = UnpackNormal (tex2D (_BumpMap, uvs));
    84.  
    85.             // Specularity & Smoothness
    86.             fixed4 specMap = tex2D(_SpecularMap, uvs);
    87.             o.Specular = specMap.rgb * _SpecularColor.rgb;
    88.             o.Smoothness = specMap.a * _Shininess;
    89.  
    90.             // Alpha
    91.             o.Alpha = c.a * _Color.a;
    92.             clip(o.Alpha - _AlphaClip);
    93.         }
    94.  
    95.         ENDCG
    96.     }
    97.     FallBack "Diffuse"
    98. }
    99.  
    Changes in this shader compared to the original:
    • Removed pragmas "finalgbuffer:finalGBuffer", "exclude_path:forward" and "noforwardadd"
    • Added pragma "alpha"
    • Added "_AlphaClip" for clipping out areas where alpha is near zero.
     
    Last edited: Jan 16, 2019
  16. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    41
    @phosphorous_ dang awesome! That shader works great.

    I was having issues trying to use the deferred shaders. I load my assets using assetbundles and after loading, the decals looked like it was set to forward rendering somehow. Not sure if that's something with this asset, or something weird with how assetbundles work.

    But with the forward shader it works great even when loading from an assetbundle!

    Would you be able to provide all of the shaders in forward rendering mode? Shader code is a little beyond me at this point so I wouldn't feel comfortable editing them all.

    Thanks for the quick feedback!
     
  17. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    @Jribs great that it worked out!

    I will go through the shaders soon and convert them, also will update the package on the asset store with those added.
     
  18. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    New version with the forward rendering compatible shaders has been uploaded to asset store for review!
     
    EvilGremlin likes this.
  19. artilla

    artilla

    Joined:
    Jul 8, 2017
    Posts:
    3
    Hello, I have an error. please check it.
    I load Demo, add a decal in editor, and run but i get an error.

    NullReferenceException: Object reference not set to an instance of an object
    SkinnedDecals.SkinnedDecalBuilder.Initialize (SkinnedDecals.SkinnedDecalSystem ds) (at Assets/SkinnedDecal/Scripts/Core/SkinnedDecalBuilder.cs:48)
    SkinnedDecals.SkinnedDecalSystem.Initialize () (at Assets/SkinnedDecal/Scripts/Core/SkinnedDecalSystem.cs:81)
    SkinnedDecals.SkinnedDecalSystem.Awake () (at Assets/SkinnedDecal/Scripts/Core/SkinnedDecalSystem.cs:53)

    Unity version is 2018.3.5f1
     
  20. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    Hey, to get around this enable "Combine meshes of same decal type" on the Skinned Decal System -inspector when you create the decals in the editor OR disable "Find all child skinned meshes" and manually ensure that no editor decal meshes are on that list.

    Without "Combine meshes of same decal type" setting you might end up with empty decal meshes on the character, if the character is made of multiple skinned meshes and some parts do not have any decal vertices. This can cause this problem during runtime if you have "Find all child skinned meshes" enabled, because the decals you created in the editor are also skinned meshes and they will unnecessarily end up on that list.

    I will add a fix to the next version that will ensure that no empty meshes are created. The above advice regarding not using "find all child skinned meshes" still is recommended if you use both editor and runtime decals.
     
  21. tavovallejo

    tavovallejo

    Joined:
    Nov 22, 2014
    Posts:
    12
    Hi, would my character need to use a specific shader or can I use any? I'm using uber shaders.

    also; If I use smoothed tesselation on my character, would there be any visual glitch? I suppose it would be solved by using tesselation on the decals, with the same smoothing and camera distances configs.

    even without tesselation im interested, hope you dont remove this asset, out of no where like many others...
     
  22. phosphorous_

    phosphorous_

    Joined:
    Jul 25, 2016
    Posts:
    21
    @tavovallejo Thanks for your interest! You can use any shader, the system itself doesn't require any specific shader on the character.

    The decals do not take the characters GPU tessellation in to account and there will likely be glitches where the decal geometry appears to be under/over the characters skin if the characters tessellation causes a lot of displacement. This is because the decal system takes a snapshot of the characters skinned mesh on the CPU side and therefore will get the pre-tessellated geometry.

    The skinned decals tessellation feature is designed to give the decals themselves depth, so you can create effects like the image below. In this I have exaggerated the displacement from the default 0.015 to 0.075.