Search Unity

[RELEASED] Dynamic Decals

Discussion in 'Assets and Asset Store' started by DanielDickinson, Jan 12, 2017.

  1. amasinton

    amasinton

    Joined:
    Aug 12, 2006
    Posts:
    138
    Bought it and am just dipping my toe in the water, so to speak. It's a great system!

    Another question: Is it possible to tile the projected decals? I'm trying to abuse this system as a kind of triplanar shader (because I'm lazy and don't want to UV map the building interiors in my environment).
     
    DanielDickinson likes this.
  2. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Currently tiling is not supported, that said, if you can find a genuine use-case for tiling it shouldn't be too much trouble to add.

    Also, please UV Map your building interiors! The system is optimized, but using decals to paint every surface of your level will never be as performant as simply UV mapping your buildings.

    Gave me a good laugh though, probably the most creative use of decals yet :D.
     
    amasinton likes this.
  3. kavast

    kavast

    Joined:
    Nov 10, 2013
    Posts:
    6
    First thought upon importing: this could use a namespace. Had a couple of naming conflicts.

    Second one: normal decals don't affect gradient ambient light. Possible to fix?
     
  4. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    What were the naming conflicts? I was specifically trying to avoid a namespace to keep it accessible to people with less scripting knowledge.

    By normal decals are you referring to the normal decal type? or just decals in general? The normal decal type only writes to the normal buffer by design, otherwise it should write to the ambient buffer as you would expect. Is this what you where referring to by "affect gradient ambient light"?
     
  5. kavast

    kavast

    Joined:
    Nov 10, 2013
    Posts:
    6
    PlayerController in the demo scenes (probably other common names in there too) and Mask (UnityEngine.UI.Mask being called as Mask in the Unity UI Extensions project). I don't mind having to fix these things, I think beginners are exactly the ones who would have difficulty with errors like this.

    Yes. My Ambient Source is set to Gradient so normals can be seen when there's no other light. But this trick doesn't work with the normal-only type decal.



    Full & Normal with direct light (top) and ambient only (bottom).

    The expectation is to have the bottom right resemble the top right. Perhaps it's not possible.
     
    DanielDickinson and Martin_H like this.
  6. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Theres definitely no reason all the demo-scene components can't be in an internal namespace and have less generic names, users don't need to script with them. And the mask component can certainly be renamed to projection mask. "Mask" is definitely quite vague. Expect these changes in 1.3.

    Edit - Changes made as of 1.3

    As for the normal decal type, using solely ambient light, I'd honestly never tried, I'll see if I can get it working.

    thanks for the feedback! solid stuff! :)
     
    Last edited: Feb 7, 2017
  7. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Okay, So the ambient is calculated in the shader per object and submitted to the ambient buffer, not at the end of the deferred pipeline like lighting is. So writing to the normal buffer will not affect how an object is lit by ambient light, only how normal lighting, shadows, and reflections affect it. It might be possible to instead modify the ambient buffer directly, however this seems really really counter-intuitive. Deferred rendering comes at a rendering cost. If your using many lights it more than makes up for itself, but if your not, your essentially writing to the albedo, normal and spec-smooth buffers for no reason.

    I think a better approach for an unlit project would be to use forward rendering, and then have a decal type that accepts a normal and an ambient gradient, and blends in the shades of the gradient based on the normal. I could probably just read the ambient directly from Unity so it would essentially be the normal decal type your using now, but designed to work in unlit scenes in forward rendering.

    If this genuinely sounds like a feature you or others would make use of, I'd be happy to have a crack at implementing it after 1.3. I can't promise it will work out, I would have to find a way to account for the influence the ambient has already had on the scene before blending over it, but I'm more than happy to try.

    And please note, this could only work in Unlit Scenes.
     
  8. Deleted User

    Deleted User

    Guest

    Hi! I am experiencing issues with the dynamic decals and fullscreen effects. For the SSAO it looks like when the decal is active, its writing to the depthbuffer incorrectly.
     
  9. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Decals don't write to the depth-buffer at all. They rely heavily on them, but none of the projection shaders actually write to it. The system does modify the Camera.DepthTextureMode however. In forward rendering it needs DepthTextureMode.DepthNormals, and you can set the DepthTextureMode it will switch back to when using deferred in the options menu. Perhaps this is the issue? Which SSAO asset are you using? Can you send me some images demonstrating the issue?
     
    Last edited: Feb 6, 2017
  10. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Version 1.3 has been submitted for approval. Huge shout out to HakJak for all of the feedback, a large chunk of this update is as a result of it. Notable mentions to Nuverian, Khavaz, Gamers2000 & Micheal too!

    The update -
    Multiple Pools have now been implemented and the limit is now tied to Unity's Quality Settings. I present to you, the new Dynamic Decals menu, the first pass at least -



    The new pooling interface occupies the top half, and the remnants of the old settings are below. Pools can be added, renamed, moved and deleted, and the limit for each set, per quality level. To change which Quality level your setting the limits for, you can use the tabs at the top of the menu. I've included a Total for convenience and the whole menu has complete Undo/Redo support, as you would expect. The default pool cannot be deleted or renamed, but the limits can still be modified.

    So how do you use these pools? The printer has been modified to print into a specifiable pool -



    You'll also notice a Prevent Overlap menu. Here you can specify pools to check against when printing, as well as an overlap "strength". Doing so, will prevent printers from printing if there is already a projection in the pool present.
    The overlap strength defines how strict the overlap must be to prevent a print. A value of 0 will prevent a print if any overlap occurs, a value of 0.5 only if significant overlap occurs and a value of 1 will only prevent a print if the decal would be in the exact same position.

    So say we had blood decals printed over the environment. If you go to print a new blood decal, and there is already blood present, there is no sense printing another decal over it. You can use prevent overlap to check against the blood pool to see if blood is already present, and prevent a print if it is.

    If you don't want to use the in-built printers, all of this functionality is still available to you via scripting. Instead of using a static pool class, you now get a pool via name, or grab the default pool using -
    Code (csharp):
    1. ProjectionPool myPool = DynamicDecals.GetPool("Blood");
    2. or
    3. ProjectionPool defaultPool = ProjectionPool.Default;
    You can then request, fade and return decals as you would have before.
    You can also use -
    Code (csharp):
    1.  bool intersecting = myPool.CheckIntersecting(Point, IntersectionStrength);
    to check if a point is intersecting any projections within a pool.

    And if your not interested in using the in-built pools, the pools aren't initialized until they're required, so they have zero performance impact if you choose not to use them.

    You'll also notice the rendering path and Default DepthTextureMode options are gone. Both are now completely automated, and don't need to be specified. If your cameras had a DepthTextureMode set, and it doesn't conflict with the system, it will no longer be modified. And if it needs to be modified, it'll be cached, and before saving it'll be restored to what it was before the system interfered using this guy. So the system shouldn't ever permanently modify your scenes camera settings.

    System warnings regarding the scene clipping planes becoming unruly have been modified, to better indicate how to resolve the issue and fixes have been implement for Unity 5.5 & the beta versions of 5.6.

    I've also gone through all the demo scene components and renamed them to prevent naming conflicts in the future, and the mask component (which admittedly was quite vague) is now the Projection Mask component. Less of a ring to it, but much more practical.

    Thanks again for the support and feedback! None of this would be possible without your input.
     
    Last edited: Feb 7, 2017
    nuverian and amasinton like this.
  11. Deleted User

    Deleted User

    Guest

    Hi! Thanks for the quick reply and the new update looks cool! It happends when I use the new Unity SSAO (https://bitbucket.org/Unity-Technologies/cinematic-image-effects)
     
    DanielDickinson likes this.
  12. PatrickKa

    PatrickKa

    Joined:
    Apr 30, 2014
    Posts:
    245
    So I found two issues:
    - The decals are flickering a bit when looking around
    - I cannot assign Layers based on the Unity Layering System.

    The last one is actually very annoying because I have been working on my project for a very long time already and I do not want to go through hundreds of prefabs, scenes to add your Layering component. Instead I just would like an option that allows me to choose a LayerMask like Unity does. In my case I only want to draw on the Default layer.
     
  13. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    - Monkzoren
    Grabbed the asset, checking it out now, by chance does 1.3 solve the issue? and are you using forward or deferred rendering?

    - PatrickKa
    1. Is the decal flickering in edit mode only? Try zooming in with the mouse wheel, does this fix resolve the issue?
    2. The masking layers are intentionally kept separate from Unity's physics layers, I'm sorry this is an inconvenience but there are a few good reasons for this.

    1. performance, it would take 8 masking buffers to cover all 32 possible layers, and to draw everything into a masking buffer is just a waste of cpu and gpu performance, we should only be drawing what really needs to be masked, and into a single buffer.
    2. Physics layers and Projection masking layers rarely share the same layering needs and requirements, in your case it seems you got lucky, but in most cases it seems unlikely. And in really large projects, you'll be trying to make the best use of your 31 physics layers, you don't want to have to share them with projection layers.

    As an alternative, you can just mask the objects in the layer you need, and in your decals specify to only draw to that layer, as opposed to masking everything you don't need (which seems like a lot more in your case) and telling decals to ignore them. Ideally you always want to use as few masks as possible.

    If your feeling creative, you could always write a quick editor script to iterate through all objects in a scene and add a mask to any with a renderer component in a specific layer. In fact, I might do that, sounds like a useful feature. :)

    Edit - Scene View Decal Flickering fixed as of 1.4
     
    Last edited: Apr 21, 2017
  14. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    - Monkzoren
    I've had a look at the asset, And I'm experiencing no issues with it. I'm actually quite impressed with it. A SSAO that lets you work off g-buffers! It should be common sense, but a lot of SSAO solutions still don't have this feature, I whole -heartedly suggest it to everybody.

    Now on to how to get it to work. If your working in deferred rendering, pick g-buffers as your Occlusion Source, they're already there, free and far more precise than the depth/depth normals gathered from shader replacement. If your working in forward rendering, pick DepthNormals as your Occlusion source, my systems requires depth and normals via shader replacement to work, so will force any camera to use depthNormals (In forward rendering only).

    Ignore the rest if your using Deferred rendering.
    Now, if you are in forward rendering, you may see some flickering in the editor when using this system (this will occur with or without my package when using depthNormals), but your in game view will be fine. My system suffers from the same problem, and I'm going to explain why it occurs, and how to fix it.

    Previously you where using Depth, instead of DepthNormals, the SSAO systems runs with it by default. By switching to DepthNormals, your switching from a 24bit depth buffer down to a 16bit depth buffer with 16bit normals packed in.
    So your losing a lot of precision by making the switch, but in game, it doesn't matter, because you don't need that much precision. The problem occurs in the scene view, Unity sets the scene cameras clipping planes really far apart, so you can see and select objects really far away, makes sense. The thing is, the depth buffer is stored as a decimal between these clipping planes, so as they get really far apart, we need more & more precision to render things correctly. 24 bits is usually, but not always, enough, but 16 bits falls really short. This is what causes the flickering/banding in the scene view.

    My package has a solution to this problem, called editor depth locking. Which will lock the clipping planes of the editor camera to reasonable values, you can find it in the settings menu. It should be noted, that to lock the clipping planes will disable scrolling with the mouse-wheel as well as focusing objects (Both adjust the clipping planes), so only use it when you need to.
    Alternatively, you can just scroll in with the mousewheel (which will move the editor far clipping plane closer), then navigate out with rightclick + s.

    Hope this helps, Dan.
     
    Last edited: Feb 8, 2017
  15. PatrickKa

    PatrickKa

    Joined:
    Apr 30, 2014
    Posts:
    245
    Flickering might have been the wrong word for it but if you place a decal to a flat ground and you slowly move the cam around it changes positions a bit. It looks a bit like big pixels moving around or scan lines.

    If you set it to 2D view and you move around it looks like a parallax effect even. It is a bit annoying because I would expect it to stay exactly the same way it used to be.

    You can see the issue here: http://imgur.com/DbHkTf9

    I did this in Edit Mode but it also happens in Play Mode and becomes very obvious when moving the camera around.

    As for the layers it is really annoying. I also would disagree that layers are only used for the physics engine.

    Edit: I sent you a link to a video in your inbox to illustrate the problem better.
     
    Last edited: Feb 8, 2017
  16. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Theirs 2 separate issues here. Video helps a lot, your definitely using forward rendering. The simple solution to both issues is to use deferred rendering, you'll get higher precision depth and normals which will fix both issues.

    The banding your experiencing in editor is caused by the scene camera clipping planes being set to far apart, which reduces the accuracy of the depth-buffer to the point that it rounds up or down to "bands". This only happens in the editor and can be solved by using editor depth locking, which can be found in the settings.

    The pixelation your experiencing in player is caused by low precision normals, again rounding up or down. Deferred rendering uses a special type of render-texture to achieve 20 bit normal accuracy, which give nice smooth results, while in forward, where stuck with 16 bits packed in with a 16 bit depth buffer.

    We can get away with this for low resolution devices like mobiles, but for PC's I would recommend using the system with deferred shading, if your able.

    The actual solution I'll need to implement will essentially be a custom DepthTextureMode that renders out high precision Depth & Normals into 2 separate buffers, as opposed to trying to pack it in one. This will solve both issues at once and it'll be needed to make the system usable with VR so I'll need to do it eventually, I can probably move it forward on my list of things to do.

    Thanks for the video, really helped clear things up. :)

    Edit - All precision issues fixed as of 1.4.
     
    Last edited: Apr 21, 2017
  17. PatrickKa

    PatrickKa

    Joined:
    Apr 30, 2014
    Posts:
    245
    I cannot switch to Deferred Rendering because my project is way too big to change stuff like that now.

    I think this is an issue that really should be adressed.
     
    Nimred and DanielDickinson like this.
  18. ColtonKadlecik_VitruviusVR

    ColtonKadlecik_VitruviusVR

    Joined:
    Nov 27, 2015
    Posts:
    197
    Hey Dan,

    Will definitely purchase this asset for our VR game when this is completed!

    Cheers,
    Colton
     
    DanielDickinson likes this.
  19. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    That's fair, I'll move dual-buffer Depth-Normals into the next patch. It's a pretty significant chunk of work though, so it'll likely take a few weeks. I'll keep you guys updated.
     
  20. kavast

    kavast

    Joined:
    Nov 10, 2013
    Posts:
    6
    Some issues with 1.3:
    • ProjectionPool.Default is returning null if there are no decals in the scene when starting.
    • The settings window has dark text on a dark background with the light editor skin.
    • The culling based removal doesn't seem to work at all (possibly not limited to 1.3, hadn't tried before).

    Yeah, thought it might be problematic. Regarding the feature you proposed, doesn't sound useful to me. To be clear, my project is not unlit, just not everything is reached by actual lights. Even then ambient occlusion makes holes and such visible, so it's not a huge issue. I might see if I can apply ambient light in a different way, though.
     
    DanielDickinson likes this.
  21. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Thanks for the bug reports / feedback! Would have been ages before I found these, appreciate it :).

    I just submitted 1.3.1 for approval, fixes all the bugs you found.
    - ProjectionPool.Default will now properly initialize on get.
    - Updating Pools is now performed before resetting Culling in Deferred Rendering (Fixes culling based removal).
    - The Dynamic Decals GUI has been modified to work with the personal skin.
    - An Emission Intensity Slider (Allows Decals to emit light past standard values for HDR) has been added to the decal component.
    - The core printer component is no longer abstract, and can be used like other printers. This is useful in situations in which your using a custom method to determine decal placement, sphere-casts for example. Instead of providing a ray, or waiting for collision, you simply provide a position and rotation whenever you wish to print.

    Shutout to Micheal for the last two.
    Still working towards 1.4 but it's going to take some time, a hot-fix seemed appropriate.
     
    Last edited: Feb 12, 2017
    ZJP likes this.
  22. Nimred

    Nimred

    Joined:
    Nov 1, 2014
    Posts:
    46
    Quite happy with Dynamic Decals so far, it's very easy to setup and it works on everything I want. Here's an example in my space game - I had to use two decals per printer: one as a persistent burn mark, the other to glow red hot and dissipate quickly.

    https://gfycat.com/QueasyCleverAuk

     
    Last edited: Feb 11, 2017
    DanielDickinson likes this.
  23. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Nice work, looks awesome!

    Cool use of decals, gives me a few ideas. Also just really cool to see the system getting used, thanks for posting :).

    If you wanted to use one decal, you could build a custom printer that prints a prefab instead of a projection, and print a decal prefab with a component attached that modifies it, fading the orange emission out over time, leaving the burn mark. You wouldn't get the shrinking glow though.
     
    Last edited: Feb 11, 2017
  24. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Show we a demo. (and add it in the pack) :D
     
    DanielDickinson likes this.
  25. Nimred

    Nimred

    Joined:
    Nov 1, 2014
    Posts:
    46
    That's a good idea, I didn't think of it. If the glowing decal was staying for long, then it would be worth doing as you say to improve performance. But since it goes away within a couple of seconds I think it's fine as it is :)
     
    DanielDickinson likes this.
  26. Blacklight

    Blacklight

    Joined:
    Dec 6, 2009
    Posts:
    1,241
    I bought the asset today, and I have a minor concern when spawning decals at runtime:

    I'm getting this error message whenever the first decal is spawned:
    Code (csharp):
    1. Destroying GameObjects immediately is not permitted during physics trigger/contact, animation event callbacks or OnValidate. You must use Destroy instead.
    2. UnityEngine.Object:DestroyImmediate(Object)
    3. DynamicDecals:Initialize() (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:805)
    4. DynamicDecals:AddProjection(Projection) (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:528)
    5. Projection:Register() (at Assets/Dynamic Decals/Components/Core/Projection.cs:331)
    6. Projection:OnEnable() (at Assets/Dynamic Decals/Components/Core/Projection.cs:310)
    7. UnityEngine.GameObject:AddComponent()
    8. PoolItem:Reset(ProjectionType) (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:1669)
    9. ProjectionPool:Request(ProjectionType) (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:1508)
    10. ProjectionPool:RequestCopy(Projection) (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:1544)
    11. Printer:PrintProjection(Projection, Vector3, Quaternion, Transform) (at Assets/Dynamic Decals/Components/Core/Printer.cs:161)
    12. Printer:Print(Vector3, Quaternion, Transform) (at Assets/Dynamic Decals/Components/Core/Printer.cs:140)
    13. RayPrinter:PrintOnRay(Ray, Single, Vector3) (at Assets/Dynamic Decals/Components/Printers/RayPrinter.cs:22)
    14. EnemyAI:ApplyDMG(Int32) (at Assets/GameAssets/Scripts/EnemyAI.cs:327)
    15. UnityEngine.GameObject:SendMessage(String, Object, SendMessageOptions)
    16. BulletScript:OnTriggerEnter(Collider) (at Assets/GameAssets/Scripts/BulletScript.cs:41)
    The cube your DynamicDecals.cs script creates in the Initialize() function is not destroyed.

    I trying to use it for a blood splatter effect when enemies are shot. It seems to have something to do with the projectiles I'm using being triggers.

    The error doesn't effect gameplay (except for the cube) and I tried replacing the line (in the Initialize() of DynamicDecals.cs):
    Code (csharp):
    1.  GameObject.DestroyImmediate(gameObject);
    with
    Code (csharp):
    1.  GameObject.Destroy(gameObject);
    and it seems to fix the issue at runtime but results in spawning cubes in whilst interacting with decals in the editor.

    I'm using 5.4.3f1 Personal.
     
    DanielDickinson likes this.
  27. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Points for having the clearest and most concise bug report I have, and may possibly ever receive, and thanks for finding it!

    Could you try replacing the line with -
    Code (csharp):
    1. if (Application.isPlaying) GameObject.Destroy(gameObject);
    2. else GameObject.DestroyImmediate(gameObject);
    I'm using that everywhere else to cleanup materials, missed it here. Solves the issue on my end, though I'd feel better knowing it works on your end and in your situation as-well.:)
     
  28. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Also, reducing my work hours down from 5-6 days a week to 3 days a week so I can spend more time developing Dynamic Decals. It's getting enough attention, and there's so much I still want to add, and you guys are so helpful, seems the least I can do is match your enthusiasm and support with my own. They've told me they can make it happen within the next few weeks, so expect more frequent updates and more content in the future. :)
     
    Last edited: Feb 12, 2017
    Martin_H and chelnok like this.
  29. Blacklight

    Blacklight

    Joined:
    Dec 6, 2009
    Posts:
    1,241
    No worries, I've had a bit of experience on both sides of customer service.
    The most annoying thing about this is that when I reopened Unity to apply the fix, the original code just started working again. Applied the change anyway, hopefully the change with prevent anything happening in future.

    Thanks for the help!
     
    Martin_H and DanielDickinson like this.
  30. praesidenter

    praesidenter

    Joined:
    Mar 5, 2016
    Posts:
    36
    Thinking about picking this up, I have been looking for a solid and easy to use PBR-decal solution for a long time. Looks very promising but I need to know how the decals behave when you bake lighting? Do they receive GI just fine or will I get some problems there? Sorry if this is a stupid question but I didn't find any information on that.
     
    Last edited: Feb 12, 2017
    DanielDickinson likes this.
  31. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    @Llockham-Industries, hi! Its look very sexy! Can I ask some questions?
    1. What about batching and draw call optimization?
    2. What techs used for masks in deferred render (I use some modification for G-Buffers, and it very important to me)?
     
    DanielDickinson likes this.
  32. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    - praesidenter - Unfortunately the system does not work with GI, nor with baked lightmaps. The Decal position &UV's are calculated in shader in real-time. Without this information before-hand we cannot bake lightmaps, definitely not a stupid question. The only current solution to getting Light-mapping or GI in decals is to use static mesh based decals, which have other disadvantages.

    - mf_andreich -
    1. - Screen-space decals cannot be batched by Unity by normal means, as they are reliant on the LocalToWorldMatrix of each individual decal, among other things, to project correctly. They can be instanced on the GPU to reduce draw-calls and set-pass calls, and this is definitely planned with atlassing, but there's a that I'd like to implement before-hand.
    2. - Dynamic Decals uses a custom buffer built for masking, it doesn't do anything you wouldn't expect to the g-buffers. I know a lot of people use the alpha of the normal buffer, for example, and you can continue to do so with this system.
     
  33. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    Do you think about "bake" all needed data into mesh UVs (box if I right understand your system) instead use local2world? For example in this case you can union your decals into one mesh and draw them in one dc. Just as idea. If you need more details, I can explain, because I thinking about similar system, but not try implement it yet.
     
    DanielDickinson likes this.
  34. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    As in have a custom cube mesh with the orientation baked into the mesh normals/tangents of the cube? I would still need the lossless scale and translation of the cube in it's new object space to construct a version of the unity_WorldToObject matrix. And I need this matrix to convert the position generated from the depth buffer back to object-space (Required for generating decal UV's). I could pass it in, but that would break batching.
     
  35. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    How many data in floats you need?
     
  36. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    16 floats, 4x4 matrix.
     
  37. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    Actually you have 16 floats. Its four UV channels (which can be float4 in shader and Vector4 in C#).
    In shader you can get it from appdata_full (or your custom struct with right semantics), in C# use GetUV/SetUV methods.
     
    DanielDickinson likes this.
  38. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    I think I get what your saying, If I wrote the matrix into the 4 UV channels of the mesh, (Vector2, 2 floats each) & the normal and tangents (Vector4 & Vector3, 7 floats), I could read these values and reconstruct the matrix in shader. That gives me 15, I might be able to get away with 15, or even 12, I'll give it a shot, thanks for the idea :).
     
  39. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    No problem!
     
    DanielDickinson likes this.
  40. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    DanielDickinson likes this.
  41. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
  42. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    No, I really plan implement something similar to your system, and I work with shaders and meshes from early 4 unity versions (actually I remember that count of UV channels growing from 2 to 4 channels, and in this time I see this methods) =)
     
    DanielDickinson likes this.
  43. kavast

    kavast

    Joined:
    Nov 10, 2013
    Posts:
    6
    I have custom deferred lights that use disabled cameras to render shadow maps. The way cameras are automatically added in Dynamic Decals results in this:



    I added a check into the primary cull and render methods to prevent this, but perhaps there should be a feature to restrict the system to specific cameras more elegantly.
     
  44. gamers2000

    gamers2000

    Joined:
    Jan 13, 2017
    Posts:
    5
    Is this just for the decals (i.e. projections) or for the masks as well? Right now we have relatively few projections but many masks, and the amount of draw calls for the masks is hitting the profiler pretty hard.
     
  45. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Khavas - Did not consider Camera.RenderWithShader! An edge case if I ever saw one, nice find! I'll disable the system on disabled cameras. And I agree, would be handy to be able to selectively prevent cameras from rendering masks & projections. Added to my to-do list :).

    gamers2000 - Masks are injected into the rendering pipeline after normal rendering but before decal rendering using CommandBuffers. I'm almost certain Unity batches command-buffers automatically, and the shader does support batching, so they should be batched already using Unity's Dynamic batching, but only on small mesh's that share mask properties.
    I'm using MaterialPropertyBlocks which might break batching though, I'm not sure if Unity will group identical blocks. I'll run some tests, if it breaks batching, well there are only 16 different mask materials possible, so I could just cache them as they are required and use them instead, at the expense of a minuscule bit of memory. In short, if masks aren't currently being batched, they definitely should be, also added to my to-do list :).

    In the interim, what are you trying to achieve with masking, and how are you currently going about it? You can go about masking in a few different ways, it's important to take an approach that uses as few masks as possible.
    Definitely avoid assigning every object in your scene to a mask layer.
     
  46. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    CommandBuffers dont use batching. Its "low level" api, which expect that you prepare all data "as needed" and dont do any additional things with it - just call SetPass and draw.
    I think you need think about different way for masking... I cant help with ideas, because I dont know how you do itright now)... but heree some points:
    You can use additional hided renderers with the same mesh and settings, and use additional vertex stream for bake mask into uvs or color of mesh. After it you can render them with replaced shader (it must batch geometry in the same way as normal render).
     
    chelnok and DanielDickinson like this.
  47. gamers2000

    gamers2000

    Joined:
    Jan 13, 2017
    Posts:
    5
    I wonder if it's more effective to use GPU instancing, rather than depending on Unity's static/dynamic batching.

    We're trying to show decals on structural elements, but not show up on items that can move to prevent the decal from temporarily showing up on the player, for example. Unfortunately the structural elements can be created and destroyed by the player at runtime, so they can't be baked into one large mesh or marked as static.
     
    DanielDickinson likes this.
  48. NeonTanto

    NeonTanto

    Joined:
    Jun 19, 2013
    Posts:
    156
    Instancing work only on renderers which share the same mesh.
     
    DanielDickinson likes this.
  49. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @mf_andreich - So in regards to combining projection meshes, even with the world2object matric cached into the mesh, decals themselves cannot be combined into a single mesh, as it would break overlapping projection bounds. i.e. where the projection bounds of two decals overlap then it will only render the projection closest to the camera. Essentially the bounds of the projections would occlude each other. I might need a diagram to explain this better. But instancing is still my best bet there.

    As with masks, I would like to avoid shader replacement because I really don't think people need to mask more than a few objects. Generally speaking, if your using hundreds of masks, your masking inefficiently, I can't think of a use-case where this would actually be required.

    Here though, baking the data into the meshes seems like a cool idea, and I might even be able to batch geometry manually and asynchronously if I'm a little lenient with the culling. Right now though I think this is like trying to swat a fly with nuclear arms. Until I see a use-case which genuinely requires hundreds of masks this will probably be low-priority.

    gamers2000 - So why not just mask the player? and tell your decals not to draw on the player layer, you don't have to mask any of your environment, it would take 1 mask per skinned mesh (Masking works on skinned meshes) and be cheap as chips. Is there a reason you need to mask the environment?
     
    Last edited: Feb 13, 2017
  50. gamers2000

    gamers2000

    Joined:
    Jan 13, 2017
    Posts:
    5
    We have multiple items in the game that can move that we want to avoid projecting on (sorry, should have been clearer on that). If anything, it's possible to have more items that we don't want to project on than items that we do.

    Most of the meshes that we DO want to project on are multiples of the same thing (think floor tiles, or kit walls).

    md_andreich - good point, I forgot dynamic batching could work with different meshes. Still, in our case we have many instances of the same mesh, so instancing would still be a huge win for us.