Search Unity

Decal System

Discussion in 'Assets and Asset Store' started by Dantus, Jun 29, 2012.

  1. miroac

    miroac

    Joined:
    Aug 9, 2012
    Posts:
    4
    Heya there.

    I'm trying to update the projections in real-time. I'm using the decal plug-in in conjunction with uScript as I'm not a programmer. But when I move a projector in real-time it doesn't update.

    It will update when I manually move the projector while the game is running it won't update. Is there some way to tell it to update after the projector has been moved?
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Welcome to the forums!

    Moving a projector has not impact on a decals instance. There are a some required steps in order to create runtime decals. So far all information about that can be found in the BulletExample scripts. I don't know how to bring that into uScript, because I have no experience with it. But since there is an existing script, you may ask that question in the uScript thread.
     
  3. PizzaGuy213

    PizzaGuy213

    Joined:
    Nov 23, 2010
    Posts:
    305
    Hi Dantus, Great tool!

    I am looking for an alternative to blobshadowprojectors for a mobile project. Would I be able to get some sort of shadowdecal following a dynamic object with your system?
     
  4. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    This is tricky but it may work. The optimal situation would be that only low poly objects are affected and not too many, such that you can cache the mesh data of the affected meshes. If that is all true, it MAY work, even on mobiles. I haven't tested it, so you have to do it. Keep in mind that the computations that are needed to calculate a decals mesh are quite expensive. And what you want to do is to compute that in every frame. Sure the computation becomes less expensive if there is not that much geometry in the meshes. But I can't promise anything.
    Let me know how it works or if you need help with the implementation.
     
  5. cerebrate

    cerebrate

    Joined:
    Jan 8, 2010
    Posts:
    261
    would it be possible to add a projection mode that allowed you to have the decal texture repeat over the decal? IE: specify a repeat x and repeat y value, and have the generated mesh's UV coordinates repeat? I would imagine this might change the mesh generation procedure though, as you'd have to add edges at the repeat boundaries.
     
  6. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I like this idea. Though, I don't know how this would make sense in an acual application. Can you explain me how you would use it?
     
  7. cerebrate

    cerebrate

    Joined:
    Jan 8, 2010
    Posts:
    261
    the main reason is say we have a large area that we want a decal on, but want it to be a repeating texture, on a terrain.
    Say a large area with cobblestone. Currently, with the terrain system, you can't have a 'sharp edge' on terrain textures. One could kind of fake this via multiple decals spread out over the area, and that would be best if they all were at the same x/y scale, just repeating rather than a single instance of the texture scaled. Obviously for more than a square shape, you'd need to break up the edges with smaller decals. Point is this could be done currently by just duplicating the decals and then lining up the edges, but it'd be simpler if the large repeating surface could just be done with one decal and a repeating UV set.

    edit: Thinking about this, a repeating decal would probably need secondary decals at the edges to smoothly transition the edges. This could obviously be done by duplicating the center decal, and then making the edge decals non-repeating in one of the directions (the one away from the center piece), or, as I said earlier, but multiple smaller edge decals.

    I suppose the use cases are kind of fringe, due to the hard edges that would result, but I could still see some applications
     
    Last edited: Aug 15, 2012
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    With a certain setup, you may already achieve that.
    • Don't use a texture atlas, but only the repeating texture.
    • Create just one uv rectangle which covers the whole (0,0)x(1,1) area (is initialized automatically like that as you create a uv rectangle)
    • Place the decal projector as needed.
    • Select the material in the inspector and adjust the tiling.

    You certainly loose a few advantages, but you get at least the result you are looking for.
     
  9. cerebrate

    cerebrate

    Joined:
    Jan 8, 2010
    Posts:
    261
    yes, one could do that. You'd lose out on the batching though.
     
  10. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You're unfortunately right. Implementing your idea would be very interesting, but I simply don't have the time to do it at the moment. But you can be sure that I'll keep this in mind, it is now on my todo list!
     
  11. Joe-12

    Joe-12

    Joined:
    Jul 31, 2011
    Posts:
    4
    Thanks so much for this product!! I donated as soon as I got it, and I don't regret it!!

    One thing though: I'm having a hard time figuring out how to implement the system by creating a separate decals object for each decal(bullet mark), so that I don't need to worry about the dynamic objects screwing up. I am able to instantiate the object, but it does not contain a decals mesh so I cannot seem to preform any of the calculations that you did in the demo script. All help would be appreciated!!
     
  12. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You basically need to move the functinality from Start () into Update () or more precisely into the code block where you can be sure that something was hit. I don't have the time to implement it at the moment, but feel free to post your code here, such that I ore someone else can check it.
     
  13. Joe-12

    Joe-12

    Joined:
    Jul 31, 2011
    Posts:
    4
    Thanks for the quick Response!! Heres the part where I generate the decal object:

    Notes: The info is a class that I created, containing data about specific tags. It looks like this:

    Here is the part where I generate the raycast:

    the first block of code( the one where I generated the decal object ) is in the GenerateGraphics(hit, ray); method.
     
  14. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Please use code tags, the code is a lot more readable like that.

    At the moment you are placing the decals instance in the way you should actually place the decal projectors. There is nothing bad about that, but don't forget to place the decal projector correctly. I would not use DS_DecalProjector at runtime, but DecalProjector directly, but that is not required. Have a look at the example scripts.
    You further haven't specified the decal projector for the decals mesh! Before you add the mesh to the decals mesh, it is necessary to tell the decals mesh for which projector this needs to happen. An exception should be thrown because of that. Haven't you got an error message?

    Call
    Code (csharp):
    1. m.AddProjector (p);
    before you add the mesh.
     
  15. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,242
    I just saw your package, and wanted to thank you for making it available for free: you're awesome, thanks :) Don't know if I'll need it sooner or later, but when it will happen I'll surely donate (and rate).
     
  16. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I am glad you like it :)
     
  17. Joe-12

    Joe-12

    Joined:
    Jul 31, 2011
    Posts:
    4
    I have been getting an error message, a null reference exception for the mesh. However, when I try to add the DecalProjector to the mesh, It says that I need to add a DecalProjector Base to the mesh, not a DS_DecalProjector. How do I convert them?
     
  18. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Ouch, you got me. That's the reason why you should use a DecalProjector object instead of a DS_DecalProjector ;) .

    You need to wrap DS_DecalProjector instances. You have to use the WrappedDecalProjector class for that.
    Code (csharp):
    1. WrappedDecalProjector wrappedProjector = new WrappedDecalProjector (p);
    2. m.AddProjector (wrappedProjector);
    Hope this helps and I haven't missed something again :)
     
  19. chadchat

    chadchat

    Joined:
    Apr 5, 2008
    Posts:
    154
    A long time coming. Great work.
     
  20. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Thank you!
     
  21. Bariel

    Bariel

    Joined:
    Mar 8, 2012
    Posts:
    34
    The package looks great but I'm guessing it doesn't work on Mac OSx as the runtime and editor are both Windows .DLL files -- would you be able to provide the full source so I can try and get it compiled on Mac?

    Many Thanks
     
  22. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It already works on Mac and you can use it for all platforms. The dlls are managed .net files and thus they are usable on any platform. Though I don't know if it works with Flash.
     
  23. Bariel

    Bariel

    Joined:
    Mar 8, 2012
    Posts:
    34
    Thanks for the information that's really great to know :)
     
  24. Xatoku

    Xatoku

    Joined:
    Feb 15, 2011
    Posts:
    11
    Really great tool. I definitely plan on donating when I get paid, although I do have a question. Is there a reason why we aren't allowed to edit the mesh renderer? Sorry if this has been asked before, I just want to turn off the cast shadows option.
     
  25. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    That's a good point! "Cast Shadow" and "Receive Shadow" should be in the Decals inspector. I am going to add them for the next version.
    The mesh renderers are not editable because it is less error prone if there is a central place where you can set the options and they are propagated to the required places. It is possible to have more than one mesh renderer per decals instance if there are too many vertices. Like that, it is not necessary to check all the mesh renderers if you want to change something, it can be done in the decals inspector view.
     
  26. Xatoku

    Xatoku

    Joined:
    Feb 15, 2011
    Posts:
    11
    Ahh, okay. I was thinking it was a problem with my configuration or something. Looking forward to the addition :). Thank you.
     
  27. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Decal System 1.2 is now under review. I expect it is available after Unite12. Check the release notes.
     
  28. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The Unity Asset Store team is amazing! Decal System 1.2 has already been accepted. It only took them a few hours.
     
  29. hoony

    hoony

    Joined:
    Aug 23, 2012
    Posts:
    5
    Hi there.
    Thanks for sharing this awesome product!

    I'm trying to update the projections using DS_Decal Projector in real-time.
    I just want to update DecalsMesh in script as like push the "Update Child Projectors" button in editor.
    But decalMesh.AddProjector method can't use a DS_DecalProjector argument. :(
    Is it possible to update DecalsMesh in runttime with a DS_DecalProjector component?
     
  30. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Welcome to the forums!

    You find the solution in this post. You have to use a WrappedDecalProjector.
     
    evilt0m likes this.
  31. hoony

    hoony

    Joined:
    Aug 23, 2012
    Posts:
    5
    Thanks for your help. :)
    I have another question.
    Can I set the Layers to affect specific mesh in script?
    I can see this dropbox option in DS_Decal Projector editor.
    but I can't find this method to set the layer mask in projector class.
    Is there any way to make it project onto only mesh that I set the layer?
     
  32. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Yes this is possible. Keep in mind that the editor scripts are not implemented in the same way as the runtime ones. The reason is that we need precise computations of which meshes are affected in the editor, while the runtime scripts have to be fast.
    You can use the layer mask as parameter when performing the raycast. Have a look at the raycast api documentation. It's the fourth parameter, which is left empty in the example scripts if I remember that correctly.
     
  33. MiraLotus

    MiraLotus

    Joined:
    Aug 28, 2012
    Posts:
    3
    GJ! really nice tool! can save many time to design game stage
    As Decal is mesh based, will there be a function can "freeze" projected mesh in editor mode?
    (the freezed mesh will no longer a Decal object, just like general mesh)
    it would be helpful! :)
     
  34. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Right now, I don't see why this would be useful in general. Can you explain this with a use case? How would this be useful for you?
     
  35. MiraLotus

    MiraLotus

    Joined:
    Aug 28, 2012
    Posts:
    3
    I think it will be cool...
     
  36. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I see :) . Nice idea! From my point of view there is already a more elegant way to do that.

    Have you seen this video: http://www.youtube.com/watch?v=Cyeh1aGGco8
    At first it may not be that obvious. If you create a prefab, it automatically generates a mesh asset file. You can use this mesh directly.

    Workflow idea:
    - Create a new scene for the modeling
    - Build the geometry (as in the first picture)
    - Place the decal projectors (as in the second picture)
    - Create a prefab out of the decals instance (as in the video)
    - Create a new game object
    -> Add a mesh filter and mesh renderer component
    -> Use the mesh that was created for the decal prefab
    -> Set the material (same one as for the decals)
    - Create a prefab with that new game object, such that you can easily use it outside of the modeling scene.
    Done.

    The advantage of it is, the geometry (the cubes in the picture) onto which you project the decals is not destroyed. It still exist in the modeling scene. If you decide to slightly modify it, you can do it and it will automatically update the mesh asset and as a consequence also the prefab which renders that mesh.

    Hope this help. Let me know if something is not understandable.

    This is a pretty cool use case for decal prefabs I never though about so far!
     
  37. yinono

    yinono

    Joined:
    Sep 15, 2010
    Posts:
    27
    I try to move the decal along my scene and have it recalculate it mesh etc.
    What should I do other then moving the projector? is there a code sample.

    P.S. This tool is great
     
    Last edited: Aug 29, 2012
  38. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You can update the mesh by pressing the "Update All Projectors" or "Update Child Projectors" button in the inspector. This recalculates the mesh for all or the child projectors.

    Let me know if this is what you are looking for, I am not entierly sure if I understood you correctly.
     
  39. MiraLotus

    MiraLotus

    Joined:
    Aug 28, 2012
    Posts:
    3
    Thx! it helps a lot :)
    real-time mesh generation is really useful
    I'll try more to find out what Decal System can achieve.
     
  40. I am da bawss

    I am da bawss

    Joined:
    Jun 2, 2011
    Posts:
    2,574
    This looks fantastic! Great stuff !!! Bookmarked.
     
  41. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Thanks!
     
  42. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It is really new for me and I am curious to see which other opportunities exist! :) Awesome!
     
  43. yinono

    yinono

    Joined:
    Sep 15, 2010
    Posts:
    27
    Doesn't Update All Projectors work only in editor mode?

    I try to move a decal (think about a target sign) over a specific meshes in my scene during the game according to input from the player. I know recalculating the decal mesh is costly but I think I can afford this, and normal projector gave poor visual results.
    Is there a way to do this?
     
  44. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It wasn't obvious for me that you meant the runtime behaviour. Did you check the BulletExample script? It performs those operations at runtime. If you want to move a projector, it means you need to place the projector, perform all the required computations and in the next frame, you have to remove the projector from the decals mesh, add it again, place it as required and perform all the operations again.

    Hope this helps. Let me know if something is not understandable.
     
  45. yinono

    yinono

    Joined:
    Sep 15, 2010
    Posts:
    27
    tried this and now I get "InvalidOperationException: The decals instance is already linked to another decals mesh."

    Here my code snippets:

    m_projectors is an array of already configured DS_DecalProjector;
    and m_decals is the Decals object in the scene.

    Initalization:
    Code (csharp):
    1.  
    2. m_decalMesh = new DecalsMesh(m_decals);
    3. m_decalsCutter = new DecalsMeshCutter();
    4.  
    5. m_wrappedProjectors = new WrappedDecalProjector[m_projectors.Length];
    6. for (int i = 0;i<m_projectors.Length;i++)
    7. {
    8.       m_wrappedProjectors[i] = new WrappedDecalProjector(m_projectors[i]);
    9.       m_decalMesh.AddProjector(m_wrappedProjectors[i]);
    10. }
    11.  
    12. Matrix4x4 worldToMeshMatrix = m_meshFilter.transform.worldToLocalMatrix;
    13. Matrix4x4 meshToWorldMatrix = m_meshFilter.transform.localToWorldMatrix;
    14. m_decalMesh.Add(m_meshFilter.sharedMesh, worldToMeshMatrix, meshToWorldMatrix);
    15.  
    then every frame I call
    Code (csharp):
    1.  
    2. for (int i = 0; i < m_fingers.Length; i++)
    3. {
    4.     m_projectors[i].transform.position = fingers[i].transform.position;
    5.     m_projectors[i].transform.rotation = fingers[i].transform.rotation;
    6.     m_projectors[i].transform.localScale = fingers[i].transform.localScale;
    7.  
    8.  
    9.     m_decalMesh.RemoveProjector(m_wrappedProjectors[i]);
    10.     m_decalMesh.AddProjector(m_wrappedProjectors[i]);
    11.  
    12.     m_decalsCutter.CutDecalsPlanes(m_decalMesh);
    13.     m_decalMesh.OffsetActiveProjectorVertices();
    14.     m_decals.UpdateDecalsMeshes(m_decalMesh);
    15. }
    16.  
    The exception is thrown on line 9.

    Thanks for all your help.
    Yinon
     
  46. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    @Yinon, it looks valid without having tested it. After a glance in my code, this should not happen, so I am going to have a closer look at it as soon as I find some time. Probably today or tomorrow.

    You forgot something in your second code part. At line 10, you need to insert lines 11-13 from the initialization code part. That mesh data is needed in the decals mesh, because otherwise there is nothing for that projector that can be cut and thus nothing will be visualized.
     
  47. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    @Yinon. My first glance was too fast :) . You are using the m_decalMesh not only for m_decals, but also for another instance. That is not allowed. This would require you to call m_decalMesh.ClearAll (); which obviously clears all the data. Make sure that you only use m_decalMesh for one particular decals instance or clean it up in between.
     
  48. yinono

    yinono

    Joined:
    Sep 15, 2010
    Posts:
    27
    Thanks, that solve that for me.

    For me creating dynamic decals or moving them looks a bit complicated, especially opposed to the editor which is super nice and easy. Maybe there is a way to make the process simpler? maybe create a utility class that does all this job for you in one or two method calls:
    One method that create a new decal to an existing decal system/mesh, and maybe another call that remove old decals?

    Anyway the system is great, and a real thank you for the support.
     
  49. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You are welcome!

    I though about such a utility class too. So far I got in touch with about 5-6 different use cases with runtime decals and I could not find a common base for them yet. It will take some more time and especially more use cases, such that I have a better impression how it is often used and hopefully I will find a useful basis that most of them have in common.
     
  50. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I was just asked to make a video about skinned decals and believe me, it is not the first time :) . The interesting part is the actual answer.