Skinned Decals

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.

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.

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!

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?

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.

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.

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.

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?

Click to expand...

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!

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.

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.

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.

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.

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...

@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.

I have got this tool work pretty well, my only issue is that it does not always create the decal, I am using a ray that hits colliders on the bones, this gives me a more accurate body impact results. However when I get a ray hit, I call the createdecal function passing in the ray origin and direction, I know I am getting a hit but the skinned decal system does not always place the decal, it adds the gameobject for the decal to the mesh, but does not add the decal... this seems to happen significantly on parts of the mesh that has a lot of animation motion like the head and the forearms, any help on this would be appreciated... Also I am calling the function multiple times per frame, if this a problem, i.e. multiple impact points, I seem to get upto 3 hits but actually had 20 hits that called the function.

I just read the post about the tessellation, that answered my multiple hit question, I will need to create a decal to represent multiple hits and average hits... easy enough thanks

I have got this tool work pretty well, my only issue is that it does not always create the decal, I am using a ray that hits colliders on the bones, this gives me a more accurate body impact results. However when I get a ray hit, I call the createdecal function passing in the ray origin and direction, I know I am getting a hit but the skinned decal system does not always place the decal, it adds the gameobject for the decal to the mesh, but does not add the decal... this seems to happen significantly on parts of the mesh that has a lot of animation motion like the head and the forearms, any help on this would be appreciated... Also I am calling the function multiple times per frame, if this a problem, i.e. multiple impact points, I seem to get upto 3 hits but actually had 20 hits that called the function.

I just read the post about the tessellation, that answered my multiple hit question, I will need to create a decal to represent multiple hits and average hits... easy enough thanks

Click to expand...

Hey, nice to hear it works out for you! About the the system not registering hits, I am wondering what is the time between those hits?

It seems to work as expected on your demo scene models. Here I added 2 "Slash02" decals, and neither showed up on the other side of the model.
However, on my model, it always shows through to the other side:

Hi, sorry I don't know much about coding and wanted to integrate this asset with Opsive Ultimate Character Controller. I know I have to call the CreateDecal function according to the manual but I am unsure how to do this exactly. The controller has an event system where you can execute scripts for example on a character taking damage. Alternatively I suppose I could insert it in the decal system logic of the controller but I am still confused about how to go about this. I tried looking at the demo scene but it seems all the scripting is in compiled code? Has anyone done this yet and could help me out?

Hi, sorry I don't know much about coding and wanted to integrate this asset with Opsive Ultimate Character Controller. I know I have to call the CreateDecal function according to the manual but I am unsure how to do this exactly. The controller has an event system where you can execute scripts for example on a character taking damage. Alternatively I suppose I could insert it in the decal system logic of the controller but I am still confused about how to go about this. I tried looking at the demo scene but it seems all the scripting is in compiled code? Has anyone done this yet and could help me out?

Click to expand...

Hey, unfortunately I am not familiar with Opsive controller, but this is how I would approach this:

Create a script that listens to Opsives OnHealthDamage-event.

Add a reference to the characters SkinnedDecalSystem to that same script.

Also add reference to the decal you want to use.

When OnHealthDamage-event is raised call CreateDecal using the parameters included in the event.

The vectors needed in CreateDecal are "origin" aka where the bullet came (the muzzle of the shooter) and "direction" aka the direction the bullet is flying. You should be able to calculate these based on the parameters included in the event.

So, the script itself seems to work, I think? But I've just noticed that the decal rendering as a whole seems borked for me somehow. So in just the demo scene, there is lots of odd clipping with the skinned decals going on that based on your YouTube videos doesn't seem normal. See here: https://imgur.com/a/wboujkh

Then in my own project, if I simply add any random model to a scene, then the Skinned Decal System and drag in one of the premade decals for editing in the editor and alt click on it, nothing shows up on the model. If I use the script you made in conjunction with one specific model (the Opsive character) I have in the scene at runtime, it works, but only on the head, the decal looks stretched and constantly disappears/reappears depending on camera position: https://imgur.com/a/oNnrcYm

So is this actually just a rendering issue now? What might be the reason? I've switched between forward and deferred rendering with no luck.

So, the script itself seems to work, I think? But I've just noticed that the decal rendering as a whole seems borked for me somehow. So in just the demo scene, there is lots of odd clipping with the skinned decals going on that based on your YouTube videos doesn't seem normal. See here: https://imgur.com/a/wboujkh

Then in my own project, if I simply add any random model to a scene, then the Skinned Decal System and drag in one of the premade decals for editing in the editor and alt click on it, nothing shows up on the model. If I use the script you made in conjunction with one specific model (the Opsive character) I have in the scene at runtime, it works, but only on the head, the decal looks stretched and constantly disappears/reappears depending on camera position: https://imgur.com/a/oNnrcYm

So is this actually just a rendering issue now? What might be the reason? I've switched between forward and deferred rendering with no luck.

Click to expand...

The clipping on the first gif looks as if the decals meshes are moving slightly out of sync with the character and then getting left under the characters skin, which I haven't seen before.

I noticed you are using a Mac with Metal as your graphics API, I read there are some shader incompatibilities with it. Could you try changing it to OpenGLCore at "Edit->Project Settings->Player->Other Settings", uncheck "Auto graphics API for mac" and drag OpenGLCore as the first option.

The second video looks like the shader is not rendering correctly, check the camera for forward/deferred in that one because that is how it looks when its the wrong shader for the mode.

As for the decal showing up only on one part of the mesh, that is likely because the character has multiple submeshes. This problem came up before and has a simple fix which is not yet updated on Asset Store:

So in just the demo scene, there is lots of odd clipping with the skinned decals going on that based on your YouTube videos doesn't seem normal. See here: https://imgur.com/a/wboujkh

Click to expand...

One more thing regarding this, you could try to change the shader to one that doesn't have tessellation, for example "SkinnedDecals/Parallax" or "SkinnedDecals/Specular" and see if that is causing the problem.

impressive. I am very new to shader especially to Tessellation. is this "Tessellation" make the depth effect on wound?
you have include bullet wound in this package. then if i need some other depth effect wound, how can i get those. for example if i need sword slice depth effect wound , do i need to build some specific map for Tessellation by myself?

impressive. I am very new to shader especially to Tessellation. is this "Tessellation" make the depth effect on wound?
you have include bullet wound in this package. then if i need some other depth effect wound, how can i get those. for example if i need sword slice depth effect wound , do i need to build some specific map for Tessellation by myself?

Click to expand...

Yeah, tessellation generates more polygons on the GPU to give the decals more detail and makes it possible for parts of the decal to portrude outwards. There is also Parallax effect included in the shaders that create a depth effect on the parts of the decal that are under the surface.

The textures you need are: Albedo map, Specular map, Normal map and Height map. In the manual under the title "Shaders" (page 7) there are specified the needed maps for each included shader.

The most important map for the depth effect is the Height map. Here is a important note from the manual regarding Tessellation shaders and how the height map needs to be setup:

Skinned Decals Manual said:

"Tessellation shaders supplied by this package only displace mesh to the direction of mesh normal with values that are above 0.5 (50% grey to white) in the height map. Parallax effect is applied only to values below 0.5 (50% grey to black) to create illusion of depth. This method makes sure that there won’t be any clipping geometry. It is extremely important that your height maps have their middle ground at 0.5 (50% grey) value."

Click to expand...

In otherwords, pixels on the height map that are on level with the surface should be at 0.5, values under that will have the parallax effect and values over that will be displaced outwards or portruding.

Included in the package are 4 bullet wounds, 2 slash wounds and 2 bullet armor hits.

So first off let me say that this looks like a great looking system and I'm definitely interested but I'm also a little shy about purchasing assets that don't get very good support and obviously forum support isn't great has anybody emailed them to see how that support is?

has anyone managed to get this working on skinned mesh renderers without bones?
Part of my model has separate skinned meshes (for the face) which do not have bones and so the system throws an error (at Assets/SkinnedDecal/Scripts/Core/SkinnedDecalBuilder.cs:75)

Oops...

"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.