Search Unity

[RELEASED] Dynamic Decals

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

  1. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @bcv - That's to be expected, masking is powerful, but it's not cheap, doubly so on skinned meshes. On PC you can get away with a lot fairly comfortably, but on mobile it will hit you. If you know you only want your projections on a few surfaces, ie. floors, walls etc. you could mask them instead, and tell your decals to only draw on them. You could also try thinning the projection bounds of your decals so that masking isn't required.

    I might be able to get the cost of skinned meshes down by drawing the renderer directly, as long as your using version 5.5 or above (causes crash in 5.4). The system will require 5.5 for GPU instancing regardless. I'll see what I can do when I get back from work. Send me an email (support@LlockhamIndustries.com), I'll give you a copy to play with :).

    Eventually I'm going to try and incorporate an optional version of masking that's built on shader replacement and dummy materials, which will scale better, allowing masks to be batched etc. but that will be post 2.0.
     
  2. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Interested with this asset and I have been reading the rest of the forum. The only thing is the performance concern over using masks.

    Let's say if I have a character on the floor and I want to spawn some decals on the ground. Then I would either have to mask the player or ground in order for the system to work as expected. However, if both the player and the ground is complex enough, this will be costly as you have mentioned above. In any normal cases, masking the player will be heavy on drawing extra draw calls and tri counts, and the gound has its own costs such as fill rates for the masks + drawcalls.

    If I try to thin the decal projector bounds , it may just work, but there is chance that the character's foot or part of it will be covered with the decals so it isn't desirable.

    I am not saying the other type of decals such as mesh based method is perfect because it still needs to float on top of the ground, but it doesn't have the other overhead costs. In this case this system may just be on par with the mesh based system.

    So two things that I makes me hesitant to buy this asset.

    1. Above issue that I talked about. I need to test the asset to see how thin I can get the decal projector's bound to make the decals acceptable looking on the player's foot without using masks.

    2. Will this work on consoles?

    I know you may not have access to consoles to test it so it isn't fair for me to ask you to let me know if it works on consoles before hand, but I bought far too many assets in the past that I later found not working on consoles so I am cautious.

    I wonder.. if masks are just a rendertextures, if it would be possible to make use of render to multiple target feature from shader to write masks with single pass. So the idea is to use the custom shader for the actual geometry that wants to use masks to write to the mask rendertextures. Perhaps it could be faster than generating masks separately as it is now.

    I have not bought the asset yet and never used it so I can't tell , but just an idea.
     
  3. Mad_Fox

    Mad_Fox

    Joined:
    May 27, 2013
    Posts:
    49
    Hi! quick question here, whats is the simplest way to change a raypositioner Decal color in runtime? (if i change it in the editor (in runtime) it doesnt do anything in my players because it's already pooled and i dont have the pool reference, what if i dont want to pool this raypositioners? (there are just 4 of them, 1 for each player to mark the position (it's a highlight in the floor))
    Thanks!
     
  4. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @castor76 - Thanks for taking such an interest in the system.
    I think I may have over-dramatized mask performance hit, if your not developing for mobile, and only masks what you need to, they really are a non-factor. They are currently rendered into a custom renderTexture and use only 1 pass for all 4 layers with a custom shader.

    The only concern with skinned meshes was that they had to have there mesh baked out before they where drawn, which was an expensive operation on mobile. But as of 1.6 (will be uploading in a few days), masks will be rendered directly, so no baking and much better performance. This does require Unity 5.5 or greater though, Unity 5.4 crashes when trying to render skinned mesh renderers with a command buffer (Why I was baking it out previously).

    As for whether or not the system will work on consoles, you're correct, I don't have access to consoles to test on, but there's no reason the system should not work. So I have a proposition. Send me an Email (Support@LlockhamIndustries.com) and I'll give you a copy of the system to try out. Test it on the consoles you have access to, work with me to clear up any bugs or issues, and I'll give you a few codes, so you can keep the system with all future updates etc. :).

    @Mad_Fox - That's a really good point, the positioner maintains a reference to the projection, but it's not exposed. I'll expose it so it can be modified. Nice find! Expect it in 1.6, send me an email if you want an advanced copy, or add the following to positioner.cs at line 10 :).

    Code (csharp):
    1. /**
    2. * The instance of the projection that we are currently positioning. If you seek to modify the positioners current projection, modify this. Cannot be set, may be active or inactive.
    3. */
    4. public Projection Active
    5. {
    6.     get { return proj; }
    7. }
    Then just access the current projection via :
    Code (csharp):
    1. Projection myProjection = GetComponent<RayPositioner>().Active;
     
    Last edited: May 13, 2017
  5. Mad_Fox

    Mad_Fox

    Joined:
    May 27, 2013
    Posts:
    49
    Excellent! works perfect.
    Thanks for the quick response as always!
     
    DanielDickinson likes this.
  6. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Hi thanks for the offer.

    Saehoon@pixellore.com is the address

    I will gladly test it on consoles. What my concerns about the masks is that no matter which way it need to redraw the meshes of it masking so draw call and tri count will be double for the masked objects. It may be fine depends on the game but whe your game is pushing towards high end it can quickly take large performance hits. I am only talking from my educated guess so yeah i will work with you to see how they perform.
     
    DanielDickinson likes this.
  7. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @castor76 - Copy sent out. Your not wrong, which is why it's recommended you only draw the the masked objects you require. In most cases you can get away with just masking your characters.

    In any case, if you want decals that are generated and adjustable at run-time, it's still significantly faster than generating and updating mesh based decals.
     
  8. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Thanks. Maybe you should consider static decals that has some performance improvements too. It might be possible to reuse the existing system, but just generate decal polygon data once and reuse it to draw with compute instead of regenerating every time. When you make game, you always need both of them. Static and Dynamic.
     
    DanielDickinson likes this.
  9. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Adding mesh-based decals would allow me to support light-mapping. I think my current technique will be faster once GPU instancing hits though. I'll nail down instancing/atlassing etc. first, then give it a shot.
     
    castor76 likes this.
  10. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    after playing with the system, I have this idea where if you need to create decals on the ground and such and have the characters on top of the ground not have the decals drawn, then perhaps what I can do is to make the characters to draw after the decals has been drawn. This will make some specific case of not having to have to use the masks, increasing the performance.

    I was wondering... how and when does decals gets to be drawn to the gbuffer? Do you think changing render order of the character's shader can be used to draw the character after the decals has been drawn?
     
  11. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Very nice idea! You could either put your characters renderers on a higher sorting layer (Currently they're all on the default) or adjust your characters materials to render at around 2500 (decals are currently rendered from 2445 - 2485). Using your renderers sorting layers seems like the cleaner solution. Then you don't have to mess with your characters material/shader.

    Might build that into the system as an alternative option for the projection mask component.
     
  12. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Yeah. That is what I thought too, since decals tends to be drawn in some kind of order in the game, it makes sense to use renderer's sorting order to control this. It should work in some cases since the decals are.. well drawn almost on very top of the objects, they don't float around in the air so if the game has some specific camera angles , settings it may be possible to use draw order instead of masking. For example if the game is say top down game, you would almost be certain that the ground will be drawn first and then its decals, then characters , objects etc.. in fact this could solve most of the problem for a lots of cases.

    Oh and yeah , I forgot about the renderer sorting order. Haha. yeah that would be better. I think they work with 3d objects right? :D cool!

    I wonder if adding sorting layer + order option for the individual decal is possible? If it can batch per same layer + order , it should be very effective since we can mix the order of decal + characters , objects to have finer control.

    -- Edit --

    Just tried it with renderer sorting layer, but it didn't work as the decal's render order seems to override / have higher priority than setting the render order. Changing character's material render order does seem to work however.
     
    Last edited: May 14, 2017
    DanielDickinson likes this.
  13. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @castor76 - Sorting Layers only seem to work in true forward, which is a shame, would have been a much flexible solution. Material.renderQueue definitely seems to be the more robust solution.

    To anyone else who's interested, you can prevent any material from have projections drawn on them by setting their render queue to 3000. This solution works in forward, forced forward and deferred, though it should be noted, if your using deferred rendering, this will cause these materials to be drawn in the forward render loop.

    Still a really nice find, definitely a cheaper (essentially free), if a little less flexible, option to masking, if anyone's interested.
     
  14. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    It should work for deferred mode if you use range from 2600 or so?
     
  15. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @castor76 - Anything in the transparent queue will be forced to render in a forward render-loop after deferred has finished (and our decals have been rendered). Unity states that transparency is officially at 3000, but I know they also want to support queues like "transparency - 1" or "transparency - 100". How big of a buffer they gave to support this, I have no idea, I know it's after at least 2500 - 2550 though, as that is roughly where the Cutout queue ends. It definitely seems plausible, if 2600 is working for you, you should be good in all render-modes with it :).
     
  16. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Hi ,

    I have tried to make character render order after 2485 like 2488 but the decals still being drawn after the character.

    Strange...

    And you are right about being rendered in forward pass. It seems like it starts from 2500.

    Is there way to adjust decal's render order ? Just to test things around?

    I know you may have set it to what it is now to draw after the alpha test pass, but I just wonder..
     
  17. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    It's not that actual render order that is having the effect, it's the fact that the render order is considered "transparent". You could set it to any in the transparent queue and it would work. In deferred rendering, decals are rendered "Before Reflections" using a command buffer, so they are not actually at any set queue. In deferred rendering, any "transparent" objects aren't actually rendered in deferred, but rather in a mini forward render-loop after deferred has completed. Thus setting your character to render in the transparent queue also sets it to draw in the mini render-loop after deferred has finished and all of your decals have been drawn.

    In forward rendering & forced forward rendering they use the queue, and it's adjustable via the decals "priority" :).
     
  18. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Yeah, I see... so for deferred mode, I am pretty much out of luck using render order then. Unless I could change when decals being rendered but that is probably going to cause some other issue.

    Oh well, had to try!

    I will try and use thin decal volume on ground to see if that works out.
     
  19. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    I understand your reservations about drawing your character twice, but the mask shader is insanely cheap, if your just masking your characters out, it would likely take less than 0.1ms. With masking enabled in my demo scenes, I'm still getting 1400+ fps. That's with my character split into 10 different pieces. If your building on anything other than mobile you almost certainly won't notice a drop on fps. Even on mobile, with the new technique it would be negligible. It only really becomes a problem when you start trying to mask out thousands of objects. You should at least give it a try.
     
  20. Mad_Fox

    Mad_Fox

    Joined:
    May 27, 2013
    Posts:
    49
    Hi!, i'm having problems with ray positioners after i destroy an object or in scene changes, (pooled projections keep asking for the original gameobject) is there a way to not pool this few projections or maybe clean the projections pool after these objects are destroyed?

    This is the error: " NullReferenceException: Object reference not set to an instance of an object DynamicDecals.RemoveProjection (.Projection Projection) (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:664)"
    and this one:
    "MissingReferenceException: The object of type 'ProjectionMask' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object."

    Thanks!

    Edit: also i've updated to 1.6, and now if i dont use "force forward rendering" it throws me an error (before with 1.56 that's didnt happen).
    This is the error: "IndexOutOfRangeException: Array index is out of range.
    DynamicDecals.UpdateProjectionBuffer (UnityEngine.Camera Camera, .CameraData Data) (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:1079)"
     
    Last edited: May 16, 2017
  21. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @MadFox - Just sent you a new copy, should fix all of those bugs, nice finds! Uploading the fix for everyone else tonight :).
     
  22. bcv

    bcv

    Joined:
    Sep 1, 2012
    Posts:
    34
    Hello there, I'm the guy who was having issues with saturated decals.

    At that moment you mentioned that what was happening is that all of the decals that share the same priority are rendering their base passes at once, then all of their additive light passes at once, so all of the additive light is being blended together, and recommended to add meshRenderer.sortingOrder = Random.Range(1, 32767); to the Projection.cs file.

    That seemed to work well until today when I tried creating a new gameobject with a Decal script, this time I tried lowering the Transparency to about 0.05 (it was higher before), as soon as I did that the effect is showing up again, so transparency is affecting the final result.

    Do you have an idea of how can I patch this up ? Cheers.
     
  23. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @bcv - Unfortunately, there isn't a good slap and dash solution for this problem, fixing it properly requires precice control of the rendering order of our forward decals, which requires a minor restructure. It's coming in 2.0, which is approaching quickly. If you send me an email I'll send you an early copy, once it's ready.
     
  24. ZKTECH

    ZKTECH

    Joined:
    Dec 29, 2015
    Posts:
    2
    Hello
    I have 2 Error Warnings with the collision printer
    Setup : Empty scene and only one object with sphere collider, rigidbody and collision printer script...

    Error 1 :
    Culling group was not disposed. You have to call Dispose explicitly from the main thread. This will likely result in a crash.
    UnityEngine.CullingGroup:Finalize()

    Error 2 :
    IndexOutOfRangeException: Array index is out of range.
    DynamicDecals.UpdateProjectionBuffer (UnityEngine.Camera Camera, .CameraData Data) (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:1079)
    DynamicDecals.RenderProjections (UnityEngine.Camera Camera) (at Assets/Dynamic Decals/Components/Core/DynamicDecals.cs:867)
    UnityEngine.Camera.FireOnPreRender (UnityEngine.Camera cam) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/CameraBindings.gen.cs:719)
     
  25. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @ZKTECH - A few bugs slipped through the last release build, all caused by a flaw in the singleton structure. They've all been addresses and are waiting for approval by the asset store team (release 1.61). I've sent you a copy of the latest build, if you have any bugs persisting let me know asap. Thanks.

    If anyone else is experiencing similar bugs email me at Support@LlockhamIndustries.com an I'll send you the latest build early, it should be up in a few days.
     
  26. BongoMongo

    BongoMongo

    Joined:
    Dec 12, 2013
    Posts:
    7
    First of all, great plugin! Bought it last week and I see a lot of potential!
    We use it for VR and there are some things I noticed. First the draw calls in forward rendering go up like crazy but if I understood this correctly you are looking into gpu instancing which will hopefully bring the draw calls down. Second, I have a bug when Single Pass Rendering is selected as stereo rendering method: "Dimensions of color surface does not match dimensions of depth surface".
    You can reproduce this if you create an empty scene, put one of the example decals into the scene and select Single Pass Rendering. Then the console gets spammed with this error. Is there any fix for this in the near future?

    Cheers,
    André
     
  27. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
  28. Griffo

    Griffo

    Joined:
    Jul 5, 2011
    Posts:
    700
    DanielDickinson likes this.
  29. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @Griffo - Texture atlassing and sprite sheet based texture animation are both coming in 2.0 :).
     
    Griffo likes this.
  30. castor76

    castor76

    Joined:
    Dec 5, 2011
    Posts:
    2,517
    Hi Llockham

    you should also consider fixing some warnings for 5.6 :

    Assets/Dynamic Decals/Components/Core/DynamicDecals.cs(1072,32): warning CS0618: `UnityEngine.Camera.hdr' is obsolete: `use Camera.allowHDR instead.'

    there are few of these at the moment.
     
    DanielDickinson likes this.
  31. Griffo

    Griffo

    Joined:
    Jul 5, 2011
    Posts:
    700
  32. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @castor76 - Cheers will do, If I release another patch before 2.0 expect it inside, otherwise expect it in 2.0.
    @Griffo - Currently no, I've not tried it. Downloading it now, I'll give it a shot after I'm done with stereoscopic rendering.
     
    Griffo likes this.
  33. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Update -

    @BongoMongo - ETA on Single Pass Stereo Rendering is unfortunately unknown. I've exhausted just about every method I can think of to get it running and at this stage I firmly believe it to be a caused by a few bugs, given that it's still quite new, it does seem likely. I've talked to a few other developers and they're having similar issues as well. Sent a few messages to some devs / forums, posted a bug report. I'll keep you posted.

    @Griffo - Unity2017 appears, to my disbelief, to be working fine (Beta 6). The only issue I've encountered thus far is how it reads transparency from .psd (Photoshop files) (Possibly changed intended behavior, though definitely looks like a bug). But converting the .psd files to .png's resolves the issue. They've also made a lot of really nice changes, really cleaned up the frame debugger, definitely a fan.

    At this stage, I'm about a week out from getting 2.0 into the hands of testers, the only known bug is the SPSR. So I'll continue to try and fix that in the off time / as I get new information. I'll still have to rebuild my demo scenes before releasing 2.0, and I want to iterate based on feedback. If all goes well, it should be out within a month :).
     
    Griffo likes this.
  34. BongoMongo

    BongoMongo

    Joined:
    Dec 12, 2013
    Posts:
    7
  35. Griffo

    Griffo

    Joined:
    Jul 5, 2011
    Posts:
    700
    @Llockham-Industries

    Hi, I've gone ahead and purchased you asset and must say I like what I see.

    One problem I've come across the Dynamic Decals window is corrupt, even when expanding to full size, can't see the options to the right ..

    Screen Shot 2017-05-25 at 07.35.07.png
     
  36. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @Griffo - Thanks, appreciate it. Also nice find, what version of beta are you running? And does it occur when not docked? Not able to recreate it in 2017.1.0b6, might just be beta being beta.
     
  37. Griffo

    Griffo

    Joined:
    Jul 5, 2011
    Posts:
    700
    Same here 2017.1.0b6

    Does it docked and un-docked.

    iMac 5k
    macOS Sierra
    version 10.12.5
     
    DanielDickinson likes this.
  38. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @Griffo - I'll try grab hold if a mac to test on, could be the difference.. Cheers :).
     
    Griffo likes this.
  39. KITPUNK

    KITPUNK

    Joined:
    Nov 11, 2014
    Posts:
    13
    Unless I missed it, but is it possible to have a decal inherit the normal / height / occlusion map of an underlying material without having to make separate materials for each decal? For example, if I had a brick wall and put a graffiti decal on it, the graffiti decal would then have the brick normal to make it look coherent. If I moved that same decal to a metal door, then it would have the metal door normal, etc.

    Been looking for a decal system that has a solution to this without needing to make a separate material for each different surface decal with a specific normal added to each. Would be extremely helpful, especially if you're overlapping two different normal maps.
     
    DanielDickinson likes this.
  40. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @Giga_Steve - The system will automatically inherit normals & occlusion from underlying geometry.

    The caveat here is that you cannot inherit normals from other decals. So your brick wall/ metal door / mixed surface normals will automatically be inherited, but if you tried to layer decals normals on top of decal normals the decal on top would draw with inherited normals from the surface but not the decals beneath it, as they have not been written to the normal buffer.

    The other caveat, it does not inherit height.
     
    Last edited: May 26, 2017
    KITPUNK likes this.
  41. ptizza

    ptizza

    Joined:
    Jul 9, 2014
    Posts:
    2
    @Llockham-Industries
    hi, just wanted to ask you if the system works with the new 5.6 lightmapping (i.e. being masked out/ignored in a shadow area from mixed light) and with the static(lightmapped) objects in general? deferred or forward, doesn't really matter.
    Thanks!
     
    Last edited: May 27, 2017
  42. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @ptizza - The system doesn't support light-maps directly, but it definitely supports being used in conjunction with them. The system fully supports light-probes / proxy volumes as well as reflection-probes (Forward or Forced Forward, True Deferred relies on command buffers which still don't support them fully), so you can use the same probes you use to light your characters & dynamic objects to light your decals and add your reflections.

    I'm not seeing any problems with decals being masked out or ignored in shadows from mixed lights or any problems rendering onto static objects in general. I'll play with it some more tomorrow, see if I can get you some images. :)
     
    ptizza likes this.
  43. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Okay, few images demonstrating decals receiving light and reflection probe data. Probably went a little overboard on the GI, wanted to make it obvious..
    LightReflectionProbes1.png LightReflectionProbes2.png

    Not quite as nice as light-mapping, but you still get your nice GI and reflections, and the decals can still be moved and updated, faded, scaled etc. :).
     
  44. ptizza

    ptizza

    Joined:
    Jul 9, 2014
    Posts:
    2
    @Llockham-Industries
    Thanks a lot! Will definitely give it a try. Meanwhile, could you post the same screenshots with directional(shadowcaster) set to mixed? and/or point lights set to baked? and what happens if you set the floor to lightmap static (if it's not already)? Do the decals on the screenshot work as cutout or full 8bit alpha? Thanks again.
     
  45. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Image as requested, really should have at least 1 real-time directional light though, so you dynamic objects receive at least directional shadows. System supports 8-bit alpha, or cutout, I've faded the 2 at the bottom right to demonstrate. MixedBaked.png
     
  46. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    517
    DanielDickinson likes this.
  47. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    Thanks Kevin, there's 2 likely causes to decals not working on custom shaders.

    1. If your in deferred rendering, and the shader only supports forward rendering (Uno is built around sm2.0 so very likely), the shader will render in a mini forward rendering loop after deferred has finished and after your decals have drawn. To fix this, go into the dynamic decals window and enabled force forward rendering. This will force decals to draw at the end of the mini forward rendering loop, after all your other objects have been drawn.

    2. Make sure you shader is opaque or using cutout transparency, a lot of custom shaders arbitrarily render in the transparent queue, which will render on top of all your decals, and won't write to a depth buffer (usually), which is required to reconstruct decal position in shader.
     
    Last edited: Jun 1, 2017
  48. lazdnet

    lazdnet

    Joined:
    May 9, 2017
    Posts:
    2
    So I'm having an issue where the Parent: Surface option for the Collision Printer results in decals not appearing, but they appear fine with Parent: Default.

    I imported the entire package, added the Collision Printer to my bullet object using the same values from the Shooter demo's Projectile - Collision object, then added the Decal script to my decal and slotted it into the Collision Printer on the Bullet object.

    When Parent: Default is set, the decals appear as expected and look great, but with Parent: Surface, they don't spawn at all and don't appear in the Scene view or in the Hierarchy.

    It appears to work just fine in the Rain and Shooter demo scenes, but they're just not spawning for me in my scene. There are no errors in the console and I can't see how I might troubleshoot this. Any ideas?

    Edit: So I dug into CollisionPrinter.cs, and I found that line 116 was doing the following:

    Code (csharp):
    1.  
    2. Print(position, Quaternion.LookRotation(-normal, rot), surface, hit.collider.gameObject.layer);
    3.  
    The `surface` variable is actually the bullet object itself, not the impacted surface, so the decal is getting parented to the bullet itself, which is then immediately destroyed by my script, taking the decal with it. Changing the code to the following yields the desired effect:

    Code (csharp):
    1.  
    2. Print(position, Quaternion.LookRotation(-normal, rot), collision.collider.gameObject.transform, hit.collider.gameObject.layer);
    3.  
    That is, it's parenting the decal to the transform of the GameObject the bullet collided with. So that leads me to the following question:

    Why cast a ray at all? Why not just do:

    Code (csharp):
    1.  
    2. ContactPoint hit = collision.contacts[0];
    3. position = hit.point;
    4. normal = hit.normal;
    5. surface = hit.otherCollider.transform;
    6. // ... rotation code
    7. Print(position, Quaternion.LookRotation(-normal, rot), hit.otherCollider.transform, hit.otherCollider.gameObject.layer);
    8.  
    Or something similar?
     
    Last edited: Jun 2, 2017
    DanielDickinson likes this.
  49. lazdnet

    lazdnet

    Joined:
    May 9, 2017
    Posts:
    2
    So now that I have decals appearing nicely on objects, I'm wondering how to change the albedo color of the printed decal based on the color of the GameObject that has the Collision Printer on it. I've written my own collision printer, and I can use GetComponent<MeshRenderer>().material.color within its PrintCollision() method to access the color of the GameObject, but how to I change the color of the decal that I print?
     
    DanielDickinson likes this.
  50. DanielDickinson

    DanielDickinson

    Joined:
    Aug 4, 2013
    Posts:
    278
    @lazdnet - Nice find! & solution! The additional ray-cast is used to get more accurate positions on collisions. Without it, you'll find that your decals float above or below the surface they hit. Usually this isn't a problem, but when working with smaller decals, that inaccuracy can cause decal volumes to fall short of the surface there projecting onto and not appear.
    I'll add a check to prevent self collisions.

    If you want to change the color of the decal your printing, you could either change it after print, or modify the prefab your printing on before print. The former is probably the cleaner solution. You'll have to play around with the print method within the printer base class to do this. You could modify it to takes the color of the material as an optional parameter, and then when the color provided is not Color.clear (your default), change the albedo color of the decal being printed. Then your custom printer / collision printer could call that method instead of the original print method, with the color from the surface material as a parameter.

    You seem pretty capable, but if you need a bit of help getting it working, shoot me an email at support@LlockhamIndustries.com, I'll send you some usable code :).