Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Decal System

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

  1. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    No, you don't have to create a texture atlas. For that special case, it is still needed that you have a uv rectangle, but you can just use the one that surrounds the whole textures. Like that you get exactly the wanted behaviour.
     
  2. hay78

    hay78

    Joined:
    Sep 25, 2011
    Posts:
    41
    I've been using this decal system for couple days, and i must say that it's amazing tool :D

    I've used a lot of decals on my 3d world, particularly the ground landscape. However something weird happened that all the meshes created by projectors connecting each other.

    Also i accidently hit the optimize scene or optimize button, but it was still alright for long time. Until this weird problem happened.

    Does anyone expereienced this and know how to solve this issue?
     
  3. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    That sounds like a graphics driver issue for me. The Decal System does nothing else than computing the meshes and indeed all projectors that belong to the same decals share the same mesh. When you optimize it, Unity's mesh optimization is applied. Though, a screenshot would help to make sure nothing else produces that wrong result.
    As a workaround for you: Modify one projector per decals instance and revert the change. That recomputes the mesh without optimizing it and thus the result should be correct again.
     
  4. Seith

    Seith

    Joined:
    Nov 3, 2012
    Posts:
    755
    Hey Dantus, thanks for your reply regarding decals on tessellated water; I haven't tried it yet, but I will.

    Now I have another question: Do you think it would be possible to add support for a parallax occlusion mapping shader to your system? It's just that sometimes, normal-mapping alone is not enough, and I can't seem to find any option for a POM shader for the decals...
     
  5. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I'll look into it. It's now on my TODO list for the Decal System. But as usual I can't promise anything.
     
  6. hay78

    hay78

    Joined:
    Sep 25, 2011
    Posts:
    41
    I fixed it by deleting all those troubled projectors, and splitting all those decals into more decals groups as suggested by my colleague programmer because unity only support 64k vertex per mesh.
     
  7. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Not sure why you encountered an issue because the Decal System was made to create more than one mesh if needed - theoretically :) . If you find some time, it would be awesome if you could describe how to reproduce the issue.
     
  8. hay78

    hay78

    Joined:
    Sep 25, 2011
    Posts:
    41
    I was creating lots of projectors in one decal, probably around hundreds of them and they are applied to 'non flat' ground, And all those projectors's mesh will be combine in one decal mesh renderer, and it has lots of tris count. So i assuming the problem happened because it reached that vertex limitation per mesh
     
  9. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The vertex count has no influence because the Decal System will create more than one mesh if needed. As this vertex limit is reached, it creates a new mesh for the ones that don't fit into the first mesh. What it really strange about it is that it only happens when you optimize it.
     
  10. JDHansen

    JDHansen

    Joined:
    Dec 16, 2012
    Posts:
    1
    First of all, thank you for this amazing plugin! I was hoping you might be able to shed some light on this. I'm working on a space combat game, and I want to instantiate a decal system to project a decal onto the spaceship's invisible "shield" when it gets hit. I can instantiate the prefab just fine, but nothing shows up unless I edit a value on the projector or "Update All Projectors." What is the best way to approach my problem?
     
  11. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Do you want to project it at runtime? In that case, you may have a look at the bullet example. I personally wouldn't instantiate a Decal System. Instead I would prepare a Decal System with all the correct setting. Then at runtime, just create the needed projectors in the way it is done in the bullet example.

    Hope this helps.
     
  12. dactilardesign

    dactilardesign

    Joined:
    Jun 9, 2009
    Posts:
    68
    Donation done!
     
  13. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Thanks a lot for the donation. Sorry for not being very responsive. I have got a flu.
     
  14. Sundersoft

    Sundersoft

    Joined:
    Sep 15, 2012
    Posts:
    4
    Here's a script that copies UV rectangles between DS_Decals and DS_SkinnedDecals components (I don't believe that it's possible to do this currently):

    To use it, create the file "Assets/Editor/copy_decal_rectangles.cs" and copy the code into it. It will create a "Decals" option under the "Edit" menu which contains the options to copy and paste rectangles. It will copy from/paste to the selected gameobject.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections.Generic;
    5. using Edelweiss.DecalSystem;
    6.  
    7. public class copy_decal_rectangles : ScriptableObject {
    8.  
    9.  
    10. [System.NonSerialized] static UVRectangle[] rects_1=null;
    11. [System.NonSerialized] static UVRectangle[] rects_2=null;
    12.  
    13. static UVRectangle[] clone(UVRectangle[] targ) {
    14.     if (targ==null) return new UVRectangle[0];
    15.     var res=new UVRectangle[targ.Length];
    16.     for (int x=0;x<targ.Length;++x) {
    17.         var c=targ[x];
    18.         var n=new UVRectangle();
    19.         n.name=c.name;
    20.         n.lowerLeftUV=c.lowerLeftUV;
    21.         n.upperRightUV=c.upperRightUV;
    22.         res[x]=n;
    23.     }
    24.     return res;
    25. }
    26.  
    27. [MenuItem ("Edit/Decals/Copy Decal Rectangles")]
    28. static void copy() {
    29.     var a=Selection.activeTransform;
    30.     UVRectangle[] t_rects_1=null;
    31.     UVRectangle[] t_rects_2=null;
    32.     //
    33.     {
    34.         var c=a.GetComponent<DS_Decals>();
    35.         if (c!=null) {
    36.             t_rects_1=c.uvRectangles;
    37.             t_rects_2=c.uv2Rectangles;
    38.         }
    39.     }
    40.     if (rects_1==null) {
    41.         var c=a.GetComponent<DS_SkinnedDecals>();
    42.         if (c!=null) {
    43.             t_rects_1=c.uvRectangles;
    44.             t_rects_2=c.uv2Rectangles;
    45.         }
    46.     }
    47.     //
    48.     rects_1=clone(t_rects_1);
    49.     rects_2=clone(t_rects_2);
    50. }
    51.  
    52. [MenuItem ("Edit/Decals/Paste Decal Rectangles")]
    53. static void paste() {
    54.     if (rects_1==null || rects_2==null) return;
    55.     var a=Selection.activeTransform;
    56.     {
    57.         var c=a.GetComponent<DS_Decals>();
    58.         if (c!=null) {
    59.             Undo.RegisterUndo(a, "Paste Decal Rectangles");
    60.             c.uvRectangles=clone(rects_1);
    61.             c.uv2Rectangles=clone(rects_2);
    62.             return;
    63.         }
    64.     }
    65.     {
    66.         var c=a.GetComponent<DS_SkinnedDecals>();
    67.         if (c!=null) {
    68.             Undo.RegisterUndo(a, "Paste Decal Rectangles");
    69.             c.uvRectangles=clone(rects_1);
    70.             c.uv2Rectangles=clone(rects_2);
    71.             return;
    72.         }
    73.     }
    74. }
    75.  
    76.  
    77. };
    78.  
     
  15. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You're right, that not yet possible.

    Thanks for sharing the script!
     
  16. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    245
    hello there. Im having an issue with Asset Store i believe. Im trying to download the package, then press import, trying to import and it gives me this error:


    Can it be because of the bad package file? I think its is, because in unity store the size is said to be 42,0 Mb, but downloaded unity package somehow is 40,0. Is there a way to download it without using Asset Store?
     
  17. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I got this message too from time to time, though not with the Decal System. You may try to delete the Decal System, close Unity, restart your pc. Then download and import it again. That always solved the issue for me so far.
    Hope this helps.
     
  18. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    245
    Thanks for the fast response and solution. I believe it was the Mono Develop that just wont let importer do anything with the existing dll. As soon as i closed it, everything imported fine.
     
  19. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    245
    Hello again. Im having an issue with skinned decals. Actually, it seems like they are working fine, but somehow they are constantly giving error that "Number of bind poses doesn't match number of bones in skinned mesh.". And it doesnt even come from any of the decalSystem components, but from EditorGUIUtility.cs. I tried searching it here on forums and answers, found out it happens because of multiple materials on the mesh. Also i tried to see the lengths of bindposes array and bones array, and they both have equal length. Does anyone know any solution on that?
     
  20. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The skinned decals are not yet production ready. First, the result they produce is not always as good as it should be. Though the issue you encountered is new and I guess that it is related to the updated Unity 4 mesh api. I added it to my todo list. If the error occurs and the decal has some visible errors, you may try to click the "Update All Projectors" button as a workaround.
     
  21. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    245
    Oh well. Gonna be waiting for updates then. Thanks!
    Also i forgot to tell, that im creating this via script. When i do it in editor, there is no such errors, somehow. Maybe its my script coded wrong?
     
  22. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    If it doesn't happen due to the editor scripts, it is likely a bug in your script. The error message sounds very much like the exceptions I added to the code to prevent invalid inputs.
     
  23. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    245
    I believe i found out whats the problem. Can it be because there is actually 2 same skinned objects at one place, one is ragdoll and one is usual animated mesh? So its projecting on both? If its so, then i need to somehow change the affected layers via script. Can it be done some way? Ive looked the API, and i didnt find such field in SkinnedDecalProjector.
    And also, cant i just instantiate already set up projectors, with some random changes and then update meshes? I tried this, but then i could find how to get to the decal's mesh, cause UpdateSkinnedDecalsMeshes requires a mesh as a parameter.
     
    Last edited: Feb 10, 2013
  24. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    It sounds as if you try to mix up the Decal System's editor functionality with your own scripts, which is a bad idea and I would be surprised if that worked.

    You can check the bullet example to get an idea how it looks if you use it for runtime functionality. For the skinned variant there are simple a few more arguments. For runtime purposes it is better to use the projectors made for runtime situations than the ones you create in the editor, you can also check how to use them in the bullet example.

    In general, either use the editor functionality without your own scripting in the scene view, or script something entirely on your own, but don't mix that.
     
  25. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    245
    Thanks for the answer!
    But i did almost everything like in the example. Except the fact that i dont have a prefab, im just instantiating editor created DS_SkinnedDecals with skinned decals mesh renderer in it as a child. I would appreciate if youll have a look at the code, if theres something wrong.
    Code (csharp):
    1. var go = Instantiate(blood_decals);
    2. go.transform.parent = col.gameObject.transform;
    3. m_Decals = go.GetComponentInChildren.<DS_SkinnedDecals> ();
    4. m_DecalsMesh = new SkinnedDecalsMesh (m_Decals);
    5. m_DecalsMeshCutter = new SkinnedDecalsMeshCutter ();
    6. var m_WorldToDecalsMatrix = m_Decals.CachedTransform.worldToLocalMatrix; //btw dont know why is here, cause its not used anywhere in code, as far as i see
    7. var l_Mesh: Mesh = col.transform.root.Find("smdimport").GetComponent(SkinnedMeshRenderer).sharedMesh; //smdimport is where the mesh is, col is a collision gameObject
    8. m_Bones = col.transform.root.Find("smdimport").GetComponent(SkinnedMeshRenderer).bones;
    9. var textureIndex = Random.Range(0,6);
    10. var projectorPosition = col.contacts[0].point+col.contacts[0].normal*0.2;
    11. var projectorRotation =  Quaternion.FromToRotation (Vector3.up, col.contacts[0].normal);
    12. var projectorScale = Vector3(Random.Range(0.20,0.5), 0.22, Random.Range(0.20,0.5));
    13. var projector = SkinnedDecalProjector (projectorPosition, projectorRotation, projectorScale, 180, 0.0003, textureIndex, textureIndex);
    14. var l_WorldToMeshMatrix: Matrix4x4 = col.transform.root.Find("smdimport").renderer.transform.worldToLocalMatrix;
    15. var l_MeshToWorldMatrix: Matrix4x4 = col.transform.root.Find("smdimport").renderer.transform.localToWorldMatrix;
    16. m_DecalsMesh.AddProjector (projector);  
    17. m_DecalsMesh.Add (l_Mesh, m_Bones, l_WorldToMeshMatrix, l_MeshToWorldMatrix);                  
    18. m_DecalsMeshCutter.CutDecalsPlanes (m_DecalsMesh);
    19. m_DecalsMesh.OffsetActiveProjectorVertices ();
    20. m_Decals.UpdateSkinnedDecalsMeshes (m_DecalsMesh);
    21.  
     
  26. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    @customphase at first the code looks valid. What is the exact error message you are getting?
     
  27. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    245


    EDITED.
    Just figured out that condition i had:
    is not working. And thus creating many of "blood_decals" results in an error. Dont know exactly why though. If i limit the creation to happen only once it gives no error.
     
    Last edited: Feb 10, 2013
  28. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Does the very first error message also look like that?
     
  29. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
     
  30. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Your code is currently made for one projector. I assumed you only needed one... If you have more than one projector, you have to use them as demonstrated in the bullet example.
     
  31. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    245
    Im sorry, ive looked at an example many times and i still cant unrestand alot. Why do the spheres have buletexampledynamicobjectJS script on all of them? Do i have to instantiate DS_SkinnedDecals for every moving bone of my ragdoll, or when i create DecalsProjectors they are binding to the bones themselves?
     
    Last edited: Feb 10, 2013
  32. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You have to work based on BulletExampleJS.
     
  33. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Hi Dantus,
    Sorry if my question was already asked, but i'm wondering if it's possible to used your system to doing something like that in run-time.
    I want to placed a sort of tag on my avatar from an atlas texture. Of course, the tag would be different (one by avatar), that mean i want to choose the uv coordinate of the atlas texture.Possible?

     
    Last edited: Feb 10, 2013
  34. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Yes, this is possible, with the restriction that the skinned decals are not yet production ready. Though it may work for your character.
     
  35. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    So, what your advice? Wait for the next update? It is not urgent.

    BTW, Thx this very fast response. ;)
     
  36. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The skinned decal update will take a while because it is a very tricky topic. I have the impression that your character's weight painting is quite simple, meaning most vertices are weight painted to exactly one bone. If that is the case, it should already work now even without an update. You can easily try it in the editor and see how well it works.
     
  37. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Ok. Thx a lot.
    BTW the previous picture is not my avatar (the Kyle Robot model from Unity Tech), but it's like this one. ;)
     
    Last edited: Feb 10, 2013
  38. SoP

    SoP

    Joined:
    Aug 6, 2012
    Posts:
    3
    Hi!

    There is an way to "Update All Projectors", by code? I'm trying to do as I seen at BulletExample.cs.

    Here is what im trying.

    Code (csharp):
    1.  
    2. auxCut.GetComponent<DS_Decals>().UpdateDecalsMeshes(new DecalsMesh (auxCut.GetComponent<DS_Decals>()));
    3.  
    Where auxCut is an Instantiated object with the DS_Decals Component.

    Thanks!
     
  39. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The "Update All Projectors" button just removes all projectors from the DecalsMesh and the adds one projector after another with all the required meshes and performs the cutting. You need to implement that on your own at runtime. If you keep track of all the projectors and the meshes you are adding to each of them, it should be possible to reconstruct everything and get the same behavior as the "Update All Projectors" button in the editor. But keep in mind that you have to add each projector to the DecalsMesh, add the corresponding meshes and perform the cutting.
    Hope this helps
     
  40. SoP

    SoP

    Joined:
    Aug 6, 2012
    Posts:
    3
    Well, I understood what you said but It's kinda difficult to do with my experience on unity and prormming.
    The thing is , on my project, when I instantiate the decal, the mesh that I wanted to appear, dont appear. But when I press "Update All Projectors" on the instatiated object, they appear. I just wanted to activate the "Update All Projectors" button by code, because I cant do this when the game is compiled, obviously.
     
  41. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    This button is obviously integrated into the editor code. As such it is not accessible at runtime. It uses some pretty slow functions and as such it is not generally usable at runtime. For that reason, the runtime code which uses the Decal System has to be carefully coded. I am aware that coding with the Decal System is not easy for non programmers, but unfortunately I can't take that burden away. The Decal System was made to be as flexible as possible while still using the available optimizations, such as atlasing, batching, ... . That's the reason why implementing scripts with it is complex and will always be.

    Edit: I am aware that this is not the answer you wanted to hear, but that is just the way it is.
     
  42. SoP

    SoP

    Joined:
    Aug 6, 2012
    Posts:
    3
    Umm ok i understood what you said! Well I'm gonna ask for some friends of me that programms alo to help me with this! Thank you anyway and congratulations for this excelent Asset :D
     
  43. FahmiHasan

    FahmiHasan

    Joined:
    Jan 9, 2013
    Posts:
    4
    Hello, first of all, thank you for this great effort on creating awesome stuff.
    Anyway, i've tried to download this package via Unity asset store but it always keep saying conection failed
    (maybe due to bad connection in my place). I wish you can give me directlink via PM to download it.
    kind regards,
     
  44. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    PM sent
     
  45. Ken-T

    Ken-T

    Joined:
    Jun 15, 2012
    Posts:
    19
    Hi

    I've recently started having a problem with my decals which are dynamically placed on terrain and meshes disappearing. I must have changed something because they were working great. Any suggestion on where to look, I have been lost for a couple of days.

    Thanks
     
  46. Ken-T

    Ken-T

    Joined:
    Jun 15, 2012
    Posts:
    19
    Hi

    To speed up Replays I've decided to try resetting the Scene to its start state rather than just reloading.

    I thought this:

    Code (csharp):
    1.     public void Reset (){
    2.         print ("Simple Reset");
    3.         while(m_DecalProjectors.Count > 0){
    4.             var l_DecalProjectorForRemoval = m_DecalProjectors [0];
    5.             m_DecalProjectors.RemoveAt (0);
    6.             m_DecalsMesh.RemoveProjector (l_DecalProjectorForRemoval);
    7.         }
    8.  
    9.     }
    10.  
    would work but I'm guesting I don't really understand how Decals work.

    What would you suggest.
     
  47. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    @Ken T: I modified your code (WARNING: Untested)

    Code (csharp):
    1. public void Reset () {
    2.     print ("Simple Reset");
    3.     while (m_DecalProjectors.Count > 0) {
    4.  
    5.             // Removing the last projector is faster.
    6.         var l_DecalProjectorForRemoval = m_DecalProjectors [m_DecalProjectors.Count - 1];
    7.         m_DecalProjectors.RemoveAt (m_DecalProjectors.Count - 1);
    8.         m_DecalsMesh.RemoveProjector (l_DecalProjectorForRemoval);
    9.     }
    10.        
    11.         // Update the actual mesh.
    12.     m_Decals.UpdateDecalsMeshes (m_DecalsMesh);
    13. }
    Not sure what you mean exactly in your first post. Do you place them in the editor, but now they are not anymore showing up?
     
  48. Ken-T

    Ken-T

    Joined:
    Jun 15, 2012
    Posts:
    19
    I using the SimpleDynamicDecal.cs script to place decals on objects upon a collision.

    For a long time it worked perfectly. Recently it has stopped working consistently,
    which is the hard part, it still works some of the time and I can't figure out what would
    cause inconsistent behavior.

    On collision the decal is generated and you see it, then a moment later it just disappears.

    Occasionally, when they disappear, they reappear when the viewing distance or angle
    changes. But not always.

    I'm very lost and not sure where to look, so any suggestions or even wild guesses would
    be appreciated!

    Thanks!
     
  49. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I see two possible reasons.
    Did you change the shader?
    It could also be a bounding box problem.

    Which version of Unity are you using?
     
  50. Ken-T

    Ken-T

    Joined:
    Jun 15, 2012
    Posts:
    19
    Thanks for the Reset Help

    But there is an issue when applying the same logic to skinned:

    Code (csharp):
    1.     public void Reset () {
    2.         print ("Skinned Reset");
    3.        
    4.         while (m_DecalProjectors.Count > 0) {
    5.             // Removing the last projector is faster.
    6.             var l_DecalProjectorForRemoval = m_DecalProjectors [m_DecalProjectors.Count - 1];
    7.             m_DecalProjectors.RemoveAt (m_DecalProjectors.Count - 1);
    8.             m_DecalsMesh.RemoveProjector (l_DecalProjectorForRemoval);
    9.         }
    10.         // Update the actual mesh.
    11.         m_Decals.UpdateSkinnedDecalsMeshes(m_DecalsMesh);
    12.     }
    13.  
    This works but the following sequence of error messages start being issued after:
    m_Decals.UpdateSkinnedDecalsMeshes(m_DecalsMesh);
    is executed.

    !IsFinite(outDistanceForSort)
    UnityEditor.DockArea:OnGUI()

    !IsFinite(outDistanceAlongView)
    UnityEditor.DockArea:OnGUI()

    !IsFinite(outDistanceForSort)

    !IsFinite(outDistanceAlongView)

    m_IsVertexBufferMapped


    When running on my Mac I see error messages on the iPhone it just crashes.
     
    Last edited: Mar 8, 2013