[RELEASED] Dynamic Decals

Introduction:
Dynamic Decals is the decal solution built from the ground up to be fast, easy to use and flexible. Perfect for bullet holes, blood effects, projected UI elements and just about anything else you can think of!

No more fiddling with quads to avoid z-fighting, or re-projecting / recalculating decal meshes every time you want to move a decal. Just drop a projection renderer onto an empty gameObject and setup your projection. You can save it as a prefab and spawn it like any other gameObject, as well as move, rotate and scale it at run-time without issue. It’s that easy.

On top of this, I’ve built a fast fully featured and flexible pooling system, a layered masking system and some “Printers” & “Positioners” to help users with no programming experience use the system.





Demo
https://www.youtube.com/watch?v=M-FXwdYdk0w
New Version 2.0 Features

  • GPU instancing with per-instance properties and atlassing.
  • Animated projections.
  • Additive & Multiplicative projections.
  • Masking via Unity layers.

Key Features

  • Print and manipulate decals at run-time.
  • Project decals onto skinned meshes.
  • Overlap and order decals.
  • Clean, simple editor integration.
  • Run-time Printers & Positioners.
  • Omni-directional Projections.
  • Mobile & VR support
  • Support for Deferred & Forward rendering paths & all shader models.
  • Full source code included.
  • Zero setup required.

Links
Website
Script Reference
Asset Store

Change Log
1.1

  • Removed close to all memory allocations within the core system.
  • Various optimizations, focused on main CPU thread
  • Added Normal and Roughness Decal types

1.2

  • Inverted decal support
  • Default DepthTextureMode
  • Various Shader optimizations
  • Pooling optimizations & fixes
  • Normal map fixes

1.3

  • Multiple pools
  • Pool Quality Settings
  • Overlap prevention
  • Automated redundant settings
  • Renamed components to prevent naming conflicts
  • Improved warnings
  • Fixes for 5.5 & beta 5.6

1.4

  • Particle printer
  • Automated DepthTextureMode
  • High precision forward projections
  • Fixes for 5.6 final release
  • VR support

1.5

  • Projection blockers
  • Forced forward rendering
  • Layer based surface detection for printers
  • Renamed “Pulse” to “Omni-Decal”

1.6

  • Tag based surface detection for printers
  • Various optimizations
  • Various bug fixes

2.0

  • GPU instancing
  • Per-instance properties
  • Texture atlases
  • Animated projections
  • Additive projections
  • Multiplicative projections
  • Masking by Unity layers
  • Nine-sprite projections
  • Print projections with behaviors attached
  • Omni-Directional decals now support all projection types
  • Brand new demo scenes
  • Extensive optimizations
15 Likes

Very happy someone finally published a commercial deferred decal solution.

Can it project roughness and normal maps as well?

1 Like

It can, It writes to all 4 deferred buffers (Albedo, Spec/Smooth, Normal and Ambient/Emission) and, in the PBR lighting mode (Default) will work just like the standard shader. It supports both metallic and specular workflows as well.

As of now it cannot project exclusively to just normal or just roughness, but it would be easy to add if theirs demand for it. Though such features could only work in Deferred shading, not Forward.

Edit - As of 1.1 It can project exclusively to normal or roughness. (Deferred Only)

1 Like

I’ve been working on a custom deferred decal solution to explicitly paint spec/smooth onto our trees to simulate wetness. This package seems to be further ahead and I’d like to use it as my new baseline.
Does this support texture atlasses? I prefer baking all our decals onto large atlasses for grouping and performance reasons.

1 Like

Currently no, but it would be pretty trivial to modify the shaders and the decal component to support them, as well as a custom pass to output exclusively to spec/smooth. If you need a hand I’d be happy to help. It seems I’ll likely be adding support for roughness maps anyway.

First of all, why has that poor llama a razorblade stuck in his throat? =(

I’ve already bought another solution, so I’ll not buy another one super soon (although it looks like your solution has a lot more features currently). But I would be interested to see how your solution holds up with massive numbers of decals. Like let’s say 5000 decal instaces of at least 10 different decal textures on screen. Demo videos of different usecases or an .exe for download would be very interesting for potential buyers too I’m sure.

2 Likes

Hell yes!!! I’m so happy right now I could kiss you on the mouth :smile:

Thank you for developing this. I’ll definitely be buying today!

1 Like

I second that. A video that shows how to set things up would be appreciated too, as well as some performance tests / numbers.

I personally would be interested how I would set up “footprint decals” and “blood decals” on arbitrary geometry, not just flat surfaces and what type of geometry might cause the decal system to give a hard time. I’ve also animated objects (doors) where decals need to move with the door when it gets opened (think of blood spray on door). Is it as simple as moving the decal into the door hierarchy?

The description mentions it features a pooling system. Is this referring to pooling of decal GameObject’s? If that’s the case, can I also choose not to use it, but use my existing GameObject pooling solution instead?

Can I use custom shaders / non-pbr materials for decal rendering?

I was reading the script documentation a bit, but most/some classes have rather generic descriptions only. It would be really useful to have an actual description for them, that describe what a particular class is doing, what problems it tries to solve and for what things it could be used.

2 Likes

+Martin H - The razor blade is an ode to how the name came to be. LLockham = Llama + Occam’s razor. Honestly surprised you noticed it.

A demo seems like a great idea. I’ll try get one up today.

+HakJak - Thanks for the support, means more than you could know.

+Peter77 - There is no setup required. If you want a decal, all you need to do is create an empty gameObject and add a decal component to it. The system will detect which rendering path your using and do everything behind the scenes for you.

It’s also perfect for footprint and blood decals. The performance of a decal is independent of surface complexity, you could project onto a surface with 1M verts of complexity and get the same performance as a flat plane.

Your more than welcome to use your own pooling system, though the in-built printers use the in-built pooling system. But you could easily build your own printers.

Think of decals as any other kind of GameObject. If you want to move rotate or scale them, simply do so, there are no tricks to it. If you want decals to move with a surface, parent them to that surface. If you want to create or duplicate them, instantiate them from a prefab like any other GameObject.

For Blood, an approach you could take, use the collision printer attached to “blood droplets” that spawn whenever a character is hit. Those droplets would then print blood decals wherever they land.

For Footprints, you have a few options. You could use the ray-collision printer on each foot to check when the foot comes close to the ground and print, or you could use a ray printer timed with animation events. The later would probably be more reliable.

Again though, you could easily custom build your own way of placing decals, the printers and pooling system included are more a convenience items so artists can use the system.

4 Likes

Alright, Uploaded a demo video (See start of thread) and have done some final bench-marking on my machine.

The system can run 5000 decals on screen with 10 materials as requested, but unfortunately not at an acceptable rate. It held around 30 - 40 fps on my PC (4 years old, mid range, which is what you would expect most gamers to have). With a game piled on that 5000 decals won’t be ship-able. As a hard limit I wouldn’t go over 1500 decals on a PC release and for mobiles, to be safe, I’d keep it around 250 - 500. Keep in mind though, this is on-screen at any one time. The system has full culling support, as well as ways to fade and remove temporary decals.

I’ll continue to optimize as I continue development, but as it currently stands, I still think the system is well worth the asking price.

I’d also really like to experiment with GPU instancing and atlassing. All projections already share the same mesh, and roughly 6 different shaders. So in theory we could draw tens of thousands of decals in a single draw call, and the entire system in a few. If this is possible it will still be a few months away though, so please don’t purchase the product if your not happy with it in it’s current state.

and thanks for the feedback guys, really constructive.

1 Like

That doesn’t sound too bad, what GPU model do you have? Thanks a lot for testing and making that video! For the kind of visuals I want there isn’t too much I can do to avoid the crazy numbers of decals. Also many of them will be on screen at the same time and there’s no occlusion culling because it’s an RTS style perspective.

I believe I’m running a Radeon R9 270x… But it’s of little consequence, the system is currently bound by the main CPU thread, not the render thread/s (Submits Draw-calls) or the GPU. Right now the onus is simply on me to find creative ways to optimize updating command buffers & such, then I can think about optimizing for the GPU.

Out of curiosity, what is your use-case? What exactly are you trying to achieve that requires 5000 decals on screen at once?

1 Like

I’ll send you a PM.

2 Likes

Just bought this and totally worth the price! Already production ready from the tests I’ve done so far. Super high quality and superb results. I’ve been waiting for a deferred decal solution for a long time and will be putting this baby to good use ASAP!

I’ll leave a review once I get my hands dirtier with it and implement it in my project. Great job man!!

2 Likes

Glad you like it! Keep me updated. if theirs ever a situation where you think to yourself, “Man, I wish it could do ___” or “Damn, I wish it did ____ like this.”. Let me know. chances are I can make it happen. The more use-cases the better!

2 Likes

As I didn’t see it on the asset store page: No link to a forum thread is usually a red flag for me, especially with technical and more complex assets. It’s a good indicator of what level of support to expect, a way to ask questions before buying and finding out about potential caveats.
I assume for skinned meshes you’d have to position decals based on bone transforms and not have to get them close to joints?

I’ll get a forum link on the asset store page asap, thanks for the tip!

And your correct, painting decals onto skinned meshes does so in world space volumes, so decals would not deform with the mesh as they are not baked to the mesh itself. Depending on the decal and how you approach applying them, this could cause some unfitting results. If your working with rigid characters like robots you would be fine, and if your working with normal characters you could probably still get away with small bloodstains or other details, if your clever about it. But placing a detailed tattoo across joints (Shoulder, Elbow, Knee) is definitely not recommended, and beyond the scope of a screen-space solution.

1 Like

Version 1.1 has just been submitted for approval. Most of the changes are behind the scenes, removing sources of memory allocation and optimizing, though I did add Roughness and Normal decal types.
The system now allocates zero memory on a frame by basis and very little anywhere else. You can’t avoid allocating memory when your creating or instantiating new projection instances, so printers will always allocate a little when they print new decals. But the core of the system shouldn’t ever allocate any after initialization.

I’ve also managed to reduce the impact on the main thread pretty significantly. where it used to take 25+ms to manage 5000 decals it now takes 17-18 ms. The render threads are still sitting down at about 10 ms as well.

The roughness and normal decal types are decals that project to only a single buffer/buffer channel. This does limit there use to Deferred Rendering. In Forward rendering they will simply be ignored.

The Roughness decal allows you to project only to the alpha of the spec-smooth buffer (Roughness/Smoothness). The most common use-case for this type of decal would be “Wetness” decals, where the decal would make the surface appear shinny-er and smoother as water hits it.

The Normal decal allows you to project only to the normal buffer, ignoring the albedo, gloss and ambient buffers. The most common use-case for these would be adding cracks, rivet holes etc. to a surface. This is useful when the base mesh is far too large to have fine details baked into its normal map, or if it uses tiling materials as it’s base and you need to break up the tiling with details to make it less obvious.

To those of you have bought it so far, thanks for the support! Enjoy!

4 Likes

Thanks for adding the normal and roughness decals. That is a great feature!

1 Like

Hey Dan,

Is there a reason why the DeferredDepthTextureMode is set to None?

I was having issues using this asset with SSAO Pro, and I tracked it down to the UpdateDeferred method setting it to DepthTextureMode.None.

Changing it to DepthTextureMode.DepthNormals fixed it, but a wise philosopher said not to change anything unless you understood what the old code did :slight_smile:

2 Likes