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
    Can you send me anything, preferably a demo scene, such that I can reproduce the issue and analyze what is happening?
     
  2. Katarak

    Katarak

    Joined:
    Feb 19, 2013
    Posts:
    13
    Hi There,

    Your system is great, but I'm having a little of a hard time with certain things.
    Using the Platformer Demo with the FadeOutLOS script, I make walls and such disapear. But if there are any decals, they stay. Is there a way to
    A. Disable a projector in runtime? (how would one go about to find the exact projector with a raycast?)
    B. Disable the group maybe?
    C. Change the material to a transparent material just like they do? and change it back to the previous one?

    I tried disabling the renderer of the wall, but your Inactive Renderer check I guess is only processed once and not a runtime?
    Would it be possible seperate all the decals in the scene into multiple decals systems? I guess you lose quite a bit on performance there.

    My current solution is seperate all the decals into seperate groups. I seperate the buildings in my scene in a similar manner so not the whole building disapears when I use the LOS system. I will see how that turns out.

    Please let me know if you feel there is a better way to achieve this.
    Thank you.
     
  3. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    All the runtime changes have to be made in the same way as the bullet demos. Otherwise, your changes can't be applied and stay invisible.

    Groups have no effect at runtime. They only exist to group projectors in the editor.

    You can change the material like that:
    Code (csharp):
    1. yourDecals.CurrentMaterial = newMaterial;
    2. yourDecals.ApplyMaterialToMeshRenderers ();
    But this will modify the material for all the projectors of this decals instance.

    I am not entirely sure what you would like to achieve. Can you describe it with an actual use case? Like that it will be less abstract for me to understand what your requirements are and it allows me to give you a more precise answer.
     
  4. MassoftGames

    MassoftGames

    Joined:
    May 2, 2013
    Posts:
    41
    I was waiting this.I will use this to bullet damage system.
    perfect project...
     
  5. ensiferum888

    ensiferum888

    Joined:
    May 11, 2013
    Posts:
    317
    This looks like such a great tool!!! I'm wondering if it could be used for procedural "roads"? What I do in my game as of now is instanciate a prefab that has a dirtroad material on it, and when I move my mouse, I keep two vertices at the original position and move the two others to my mouse position so you can see the road as you build it. The problem is I cannot do this over hills the terrain needs to be flat.

    Would it be possible to "project" roads on my terrain using this tool? More importantly would it be possible to do it at run time?

    Thank you, and regardless of your answer it looks like a fantastic tool!
     
  6. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Unfortunately this is not possible. Each projector is just a rectangle. You would at least need a trapeze which simply doesn't work at the moment and it is also not planned for the near future.
     
  7. Formica

    Formica

    Joined:
    Jun 12, 2013
    Posts:
    37
    Reading 31 pages is bit too much so i'll just ask: am i able to use a texture atlas for my decals? It would help my quite a bit with my draw calls.
     
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Yes. That is one of the central parts of the Decal System. There is a bunch of videos explaining the functionality:
    http://www.youtube.com/watch?v=C87xkHj8jHM&list=PLBD9CA3140ECF817A

    And as the Decal System is freely available, you may just try it out on your own :)
     
  9. Natoncy

    Natoncy

    Joined:
    Sep 28, 2012
    Posts:
    6
    First of all, I want to say this an awsome Tool and it will help my Project a lot.
    I wanted to use the Decals as Bulletholes: I made a Prefab with a Decal Projector and let it instantiate when a Bullet hits a Collider.
    So far it works perfect, but I need to Update every Projector manually in the Inspector. So how do I do that from Script?
     
  10. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    There is a bunch of example scripts for bullets. Please check them out and have a look at how it may be done at runtime.

    Hope this helps.
     
  11. Natoncy

    Natoncy

    Joined:
    Sep 28, 2012
    Posts:
    6
    I have seen the examples, but I only need to Update an existing Projector and not creating a new one.
     
  12. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The "Update" button is not available at runtime, outside of the Unity editor, because it is too slow. You have to implement that functionality on your own. This is what happens in the examples.
     
  13. Natoncy

    Natoncy

    Joined:
    Sep 28, 2012
    Posts:
    6
    Ok, I took the BulletExampleJS Script and changed things there, and now it works perfect. ;)

    Thank you!
     
  14. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Awesome!
     
  15. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Decal System (Pro) 1.4 is now under review. You may already have a look at the release notes.
     
  16. CallHimX

    CallHimX

    Joined:
    Jun 16, 2013
    Posts:
    7
    Hey there,

    is there any way to cast dynamic shadows on that decals?
    Sorry I'm new at Unity in case that is a crazy dump question. :p
     
  17. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    What?!!!. :D
    It's a new tool?
    Free or not?
    What the difference with this one?
     
  18. Dantus

    Dantus

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

    I am not aware of a dynamic shadow solution for transparent meshes that works in general.
     
  19. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Beside the Decal System, there will be a paid Pro version. If you have a look at the release notes, you will see the feature delta. The Decal System gets a few more features plus several improvements and bug fixes, while the Decal System Pro has certainly many relevant advanced features.
    Don't hesitate to ask more specific questions.
     
  20. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,649
    Thx for the replay..

    Edit :
    Information here.
    What about the price?
     
    Last edited: Aug 12, 2013
  21. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Decal System Pro will cost 95$.
     
  22. ThomasJohn

    ThomasJohn

    Joined:
    Feb 10, 2013
    Posts:
    4
    Hello

    first thanks for this beautiful piece of software.
    Second :), I have a Decals object inside of a prefab. In this Decals object, I have a Decals Mesh Renderer and a Projector. When I instanciate that prefab, I need to update the projector of the Decals inside of that new prefab instance. How can I do that ?
    Also, I'm a bit new to unity so I might not understand everything but I still have one draw call for all the prefabs I instantiated on the scene. And when I change the material of the Decals of an instance of a prefab, it adds 1 draw call but doesn't show that Decals when I press the play button (I updated projectors, etc...)

    What would be the best approach, knowing that I will have the same material for every instance of that prefab ? keep it this way and update the projectors, one by one or create a Decals, with a Decals Mesh Renderer and a Projector at runtime ? I would really be able to just have to update the projector for each prefab instance... :)

    thanks for your time !

    tom.
     
  23. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    @ThomasJohn, welcome to the forum!

    Having multiple prefab instances is not the actual idea behind the Decal System. The concept of the decal projectors was introduced to achieve automatic batching within one Decals instance which is at the end visualized through the Decals Mesh Renderer.

    Did you check the Demos that come with the Decal System? There is a bunch of runtime examples that illustrate the way you should create and update decals.
    Updating one projector at runtime can be achieved by deleting the projector from the DecalsMesh and creating it again, including the addition of the meshes, ... .

    Hope this helps.
     
  24. ThomasJohn

    ThomasJohn

    Joined:
    Feb 10, 2013
    Posts:
    4
    hey
    thanks a lot for this prompt answer.

    My idea is to show a hex grid (made of several Decals objects with a Projector displaying a single hex texture) on a terrain using your decal system. I don't want to use unity's build in projectors as they are very expensive on mobile devices. But what I also would like to do is to be able to change the opacity of each projected decal in order to animate them separately (I imagine through the material's properties) The problem if I use a single Decals object with multiple Projectors is that if I change the alpha property of my material, I imagine all the decals are gonna be impacted, and not just the one I want.

    I checked your examples with the colored bullets and I see that you're using vertex colors, it's ok that way for a one time change but not for an animated change of colors as I don't want to update every vertices each frame.

    I'm gonna try destroying and recreating a projector.

    thanks again
     
  25. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Exactly for that kind of scenario, I have implemented several optimizations for the upcoming Decal System Pro. It is going to be possible to change the vertex color per decal projector. Internally you can optionally use caching of the vertex color array, such that it is not necessary to create arrays each time. When you only update the vertex colors, it will be possible to only update that part in the mesh. That is a huge improvement over the previous solution. In fact you could do exactly that on your own with some additional work.
    Alternatively you may use decal projectors for the parts that are not animated and Unity's projectors for animations. That is only feasible if you don't have too many animated projectors.

    From my point of view, those are the most practical approaches. Updating a decal projector at runtime in each frame (by removing it an recalculating it again) is usually too expensive.
     
  26. MassoftGames

    MassoftGames

    Joined:
    May 2, 2013
    Posts:
    41
    I can't do bullet holes with this. How we can use as game object?
     
  27. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    What do you mean exactly? Did you try the examples?
     
  28. MassoftGames

    MassoftGames

    Joined:
    May 2, 2013
    Posts:
    41
    So how can I create decal on runtime?For example; bullet holes or other game effect.
     
  29. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Did you try e.g. the Bullet Simple scene? You have to left click or press the crtl key to shoot. This will create a bullet hole. Keep in mind that this is just an example implementation and needs to be adjusted for any specific project.
     
  30. cician

    cician

    Joined:
    Dec 10, 2012
    Posts:
    233
    Hi, we're using this decal system for our game and it's great so far.

    Here's a solution for shadows with alpha blending. It's a hack, but works for us.

    The concept is that problems with shadows on transparent objects don't actually apply to decals because they are rendered immediately on top of solid geometry which DO write to Z buffer.
    In fact this is what decal:blend is there for and the end result equals to a simple multipass technique (think terrain splats).

    I wrote the shader for our needs before trying the Decal System. The artist used it initially by covering meshes with hand crafted decal geometry. With the Decal System the end result is the same, but automatized.

    Feel free to take and adapt to your needs. Public domain.
    I have another version with bumped specular. Parallax should work as well.
    NB: in Unity 4.2.0 remove fullforwardshadows since it has bug (or beg Unity guys to fix it).

    Code (csharp):
    1. // Shader for decals using overlay geometry. It's full of hacks.
    2.  
    3. Shader "Akari/Decal/Diffuse" {
    4.     Properties {
    5.         _Color ("Main Color", Color) = (1,1,1,1)
    6.         _MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
    7.     }
    8.     SubShader {
    9.         // Render in last of non transparent queues to minimize possibility
    10.         // of popping, but not in transparent queue because Unity automatically
    11.         // disables shadows.
    12.         Tags {"Queue"="AlphaTest+49" "RenderType"="AlphaTest"  }
    13.        
    14.         // Actually a cheap shader.
    15.         LOD 200
    16.        
    17.         // Don't write to depth buffer, actually implicit for transparent shaders.
    18.         ZWrite Off
    19.        
    20.         // Add an offset so you can place decal geometry in exactly the same position
    21.         // as underlying opaque one and the decal will render on top.
    22.         // Also should prevent flickering with low depth precision if decal is too close.
    23.         Offset -1,-1
    24.        
    25.         CGPROGRAM
    26.             // Shader renders in forward mode, otherwise the specular from underlying
    27.             // surfaces doesn't get completely masked, dunno what's exactly going on
    28.             // in deferred.
    29.             // fullforwardshadows and dualforward are optional
    30.             #pragma surface surf Lambert fullforwardshadows dualforward decal:blend exclude_path:prepass
    31.  
    32.             sampler2D _MainTex;
    33.             fixed4 _Color;
    34.  
    35.             struct Input {
    36.                 float2 uv_MainTex;
    37.             };
    38.  
    39.             void surf (Input IN, inout SurfaceOutput o) {
    40.                 half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    41.                 o.Albedo = c.rgb;
    42.                 o.Alpha = c.a;
    43.             }
    44.         ENDCG
    45.        
    46.         // add the shadow collector pass but NOT the shadow caster
    47.         UsePass "VertexLit/SHADOWCOLLECTOR"
    48.     }
    49.    
    50.     // if semething goes wrong fall back to transparent diffuse or Transparent/VertexLit
    51.     FallBack "Transparent/Diffuse"
    52. }
    53.  
     
  31. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    @cician: Thank you very much for sharing the shader! I have planned to experiment in that direction as well. I already have something that somehow works, but it is quite complex and not as generic as your solution. I'll definitely give it a try!

    Thanks again for the contribution!
     
  32. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Decal System 1.4 is now available!

    One of the many new features is Normals Smoothing:

     
  33. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Beside the free version, there is now also Decal System Pro. Those videos illustrate the main features which are only available in the paid version.

    Vertex Colors




    Texture Atlas Asset




    Affect Details

     
  34. ThomasJohn

    ThomasJohn

    Joined:
    Feb 10, 2013
    Posts:
    4
    hi again

    would it be difficult to add a function to the DS_Decals script that would allow us to update all projectors inside of it ? or something similar... the idea is to be able to update every projector a Decals object I placed on the scene within Unity has, through a script.

    Also, in your pro version, when updating the vertex colors of a projector in a Decals object, I guess all the vertices data of every projector contained in that specific Decals object have to be re-uploaded to the memory ? in this case, is it better to actually have +-10 more drawcalls (by using separate Decals object for each projector and only modifying the color through the material property) or re-upload all the data to memory each frame as I would like to animate the color to have smooth transition ?

    thanks !
     
  35. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    DS_Decals is the wrong place for that. You need to have a look at the example scenes, including to code to get an idea about how you may achieve that.

    It is only necessary to re-upload the vertex colors. But you are right, that needs to be done for all the decal projectors of that decals instance.
    I can't say if it would make sense to use one or the other approach. You have to test it, because that heavily depends on the project and target platforms.
    And there are so many ways to achieve that. If you have a certain amount of decal projectors don't aren't changed, they can belong to a certain decals instance. Further you may have one decals instance for all the animated decal projectors, or use one decals instance for each of them and use a separate material for each of them. Those are topics you have to try out!
     
  36. ThomasJohn

    ThomasJohn

    Joined:
    Feb 10, 2013
    Posts:
    4
    It seems that if I want to update decals meshes with a DS_Decals object, I need a DecalsMesh object to pass to the function UpdateDecalsMeshes. But I can't get a DecalsMesh object from anywhere (or I can't find a way, without having to create myself the projectors and the DecalsMesh by code)
    And this seems to me to be the only solution when looking at the example scripts.

    How does the "Update All Projectors" button works ?

    For the rest, I'm gonna test a couple of things, but I'm almost sure I'm gonna go for the several Decals instances.

    Thanks again for your prompt reply !
     
  37. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The point of the DecalsMesh is that you have to create it at runtime. That is where all the heavy work happens. That's where the slow computations are made to make it fast from then on.

    The "Update All Projectors" button is not supposed to be used at runtime, because it is far too slow. That's also the reason why you don't get the possibility to call it in anyway.
    Internally it gets all the meshes with
    Code (csharp):
    1. Object.FindObjectsOfType (typeof (MeshRenderer);
    The SkinnedMeshRenderers and Terrains are found in the same way. Then it computes the intersection of each projector that is updated with the bounds of the meshes/skinned meshes and something like that for terrains as well (can't remember right now).

    If I would provide that functionality, people would use it and would start to complain because of the speed. It works quite well in the Unity Editor, because I can assume that it is running on at least a half decent machine. Further people usually update only one projector in the editor. I can't make that assumption at runtime.
    From a practical point of view, you HAVE to implement that functionality for your specific project and the way you have set up your models/colliders/... .

    I am aware, that is not what you want to hear, but it is the reality.
     
  38. huxley

    huxley

    Joined:
    Apr 27, 2009
    Posts:
    334
    Hey Dantus,

    we've encountered a strange bug using the decal system. We have three projectors setup and cleared as the user selects different decals from a runtime menu system. This issue that we're having is that 3 decal Mesh Renderers are being created at runtime. We can't determine why this is happening, but it's causing the decals to overlap, rather than disappear and update individually.

    Code (csharp):
    1.  
    2.     // Use this for initialization
    3.     void OnEnable()
    4.     {
    5.         foreach(EffectiveCar c in DataReference.User.Cars) {
    6.             if(c.CarID == carType) {
    7.                 m_EffectiveCar = m_EffectiveCar ?? c;
    8.                 break;
    9.             }
    10.         }
    11.        
    12.         m_Decals = GetComponentInChildren<DS_Decals>();
    13.         if(m_Decals == null) {
    14.             Debug.LogWarning("Cartype \""+carType+"\" does not have a DS_Decals script");
    15.         } else {
    16.             m_DecalsMesh = new DecalsMesh(m_Decals);
    17.             m_DecalsMeshCutter = new DecalsMeshCutter();
    18.             m_projectors = new List<WrappedDecalProjector>();
    19.            
    20.             // Remove the old decals mesh renderer
    21.             DestroyImmediate(GetComponentInChildren<DS_DecalsMeshRenderer>());
    22.         }
    23.        
    24.        
    25.         DataReference.User.OnChange += UpdateAppearance;
    26.         UpdateAppearance();
    27.     }
    28.    
    29.     // Update is called once per frame
    30.     void OnDisable()
    31.     {
    32.         DataReference.User.OnChange -= UpdateAppearance;
    33.     }
    34.    
    35.     public void UpdateAppearance()
    36.     {
    37.         bool inGarage = Application.loadedLevelName == "Garage";
    38.        
    39.        
    40.         // HACK: Decals are not scaled appropriately unless the car is scaled to 1,1,1
    41.         if(m_Decals != null  transform.localScale == new Vector3(1f,1f,1f)) {
    42.             ResetUVs();
    43.             SetUV("Hood", inGarage ? m_EffectiveCar.PreviewHoodUV : m_EffectiveCar.CurrentHoodUV);
    44.             SetUV("Side", inGarage ? m_EffectiveCar.PreviewBodyUV : m_EffectiveCar.CurrentBodyUV);
    45.         }
    46.        
    47.     }
    48.    
    49.     private void ResetUVs() {
    50.         // Remove the old decal projectors
    51.         foreach(WrappedDecalProjector projector in m_projectors) {
    52.             m_DecalsMesh.RemoveProjector(projector);
    53.         }
    54.         m_projectors.Clear();
    55.         m_Decals.UpdateDecalsMeshes(m_DecalsMesh);
    56.     }
    57.    
    58.     // Sets the UV to the specified index for every projector containing the passed string in its name
    59.     private void SetUV(string str, int index) {
    60.         // Create new decal projectors
    61.         foreach(DS_DecalProjector dp in GetComponentsInChildren<DS_DecalProjector>(true)) {
    62.             if(!dp.name.Contains(str)) {
    63.                 continue;
    64.             }
    65.            
    66.             dp.uv1RectangleIndex = index;
    67.             dp.uv2RectangleIndex = index;
    68.            
    69.             WrappedDecalProjector projector = new WrappedDecalProjector(dp);
    70.             m_DecalsMesh.AddProjector(projector);
    71.             m_projectors.Add(projector);
    72.        
    73.             // Add the mesh data to the decals mesh, cut, offset it, and display it
    74.             MeshFilter meshFilter = this.transform.GetComponentInChildren<MeshFilter>();
    75.             Matrix4x4 worldToMeshMatrix = this.transform.worldToLocalMatrix;
    76.             Matrix4x4 meshToWorldMatrix = this.transform.localToWorldMatrix;
    77.             m_DecalsMesh.Add(meshFilter.mesh, worldToMeshMatrix, meshToWorldMatrix);
    78.             m_DecalsMeshCutter.CutDecalsPlanes(m_DecalsMesh);
    79.             m_DecalsMesh.OffsetActiveProjectorVertices();
    80.             m_Decals.UpdateDecalsMeshes(m_DecalsMesh);
    81.             m_Decals.OptimizeDecalsMeshes();
    82.         }
    83.     }
    84.  
     
    Last edited: Aug 19, 2013
  39. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    There are two things I suddenly see that are not optimal.

    First line 20 where you destroy the decals mesh renderer. You should never do that manually, as it needs to be handled by the Decal System. Maybe you introduced that because you had too many renderers. As soon as you call UpdateDecalsMeshes, all the unneeded renderers will be removed or more of them are created, depending on what is needed.

    If you make several changes on your DecalsMesh, you shouldn't call UpdateDecalsMeshes after each change, just like OptimizeDecalsMeshes. Get rid of lines 54, 79 and 80. Instead after line 43, call the update and optimize methods.

    The second one is more a performance/cosmetic one, while the first one is usually not a good idea.
     
  40. huxley

    huxley

    Joined:
    Apr 27, 2009
    Posts:
    334
    Thanks for the quick response. Your edits cleared up the issues that we were having with the duplicate mesh renderers. Thanks a bunch!
     
  41. KyleHatch85

    KyleHatch85

    Joined:
    Dec 13, 2011
    Posts:
    99
    hello. I've been experimenting with your decal system. It's very impressive.

    My question if to do with tessellation, we create a custom mesh which is tessellated. When trying to put a decal over the mesh, i receive an error (attached in a screenshot), is it possible to put the decals over a tessellated area?
     

    Attached Files:

  42. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Yes, you can place decals over tessellated areas. Usually you need to offset the decals due to intersections as the decals themselves are mostly not tessellated.
    But there is certainly something wrong. Can you provide me a unitypackage with a reproduction of this bug?
     
  43. KyleHatch85

    KyleHatch85

    Joined:
    Dec 13, 2011
    Posts:
    99
    Go into the examples folder and run _SimpleTessellation. i've made some edits to include two decals, both currently on the simple no tessellated cube. move one of them across to the tessellated cube and you get the error.

    Make sure your running Unity in DX11 mode.
     

    Attached Files:

  44. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Thanks a lot for reporting the issue. It turned out to be unrelated to DX11. It was caused by the TextMesh objects. The issue is now resolved and will be in the next version.

    Here is the update you can use meanwhile:
    https://dl.dropboxusercontent.com/s...XhyOy7WLi1hUKHaSStH4aLcFZ6VyEWq30kLsm7gA&dl=1

    Let me know if that solved the issue.
     
  45. MassoftGames

    MassoftGames

    Joined:
    May 2, 2013
    Posts:
    41
    I developed your bullet hole algorithm but in this code how can I change the decal texture to ground name? For example metal,wood,concrete. I have been working on function NextUVRectangleIndex and choosed min and max limit of UVRectangle index but doesn't work or I couldn't. I need your help.

    PHP:
             // The prefab which contains the DS_Decals script with already set material and
            // uv rectangles.
        
    var decalsPrefab GameObject;
            
    // The reference to the instantiated prefab's DS_Decals instance.
        
    private var m_Decals DS_Decals;
        private var 
    m_WorldToDecalsMatrix Matrix4x4;
            
    // All the projectors that were created at runtime.
        
    private var m_DecalProjectors : List.<DecalProjector> = List.<DecalProjector> ();
            
    // Intermediate mesh data. Mesh data is added to that one for a specific projector
            // in order to perform the cutting.
        
    private var m_DecalsMesh DecalsMesh;
        private var 
    m_DecalsMeshCutter DecalsMeshCutter;
            
    // The raycast hits a collider at a certain position. This value indicated how far we need to
            // go back from that hit point along the ray of the raycast to place the new decal projector. Set
            // this value to 0.0f to see why this is needed.
        
    var decalProjectorOffset float 0.5;
            
    // The size of new decal projectors.
        
    var decalScale Vector3 Vector3 (0.22.00.2);
        var 
    cullingAngle float 90.0;
        var 
    meshOffset float 0.001;
            
    // We iterate through all the defined uv rectangles. This one indices which index we are using at
            // the moment.
        
    private var m_UVRectangleIndex int 0;
        private var 
    DecalStyle:String="";
        private var 
    DecalMaxIndex:int=0;
            
    // Move on to the next uv rectangle index.
        
    private function NextUVRectangleIndex () {

        if (
    DecalStyle=="Concrete"){
            
    m_UVRectangleIndex m_UVRectangleIndex 1;
            if (
    m_UVRectangleIndex >= m_Decals.uvRectangles.Length-15) {
                
    m_UVRectangleIndex 0;
            }
        }
        if (
    DecalStyle=="Metal"){
            
    m_UVRectangleIndex m_UVRectangleIndex 1;
            if (
    m_UVRectangleIndex >= m_Decals.uvRectangles.Length-7) {
                
    m_UVRectangleIndex 10;
            }
        }
        
        }
        
        function 
    Start () {
                
    // Instantiate the prefab and get its decals instance.
            
    var l_Instance UnityEngine.Object.Instantiate (decalsPrefab);
            
    m_Decals l_Instance.GetComponentInChildren.<DS_Decals> ();
            if (
    m_Decals == null) {
                
    Debug.LogError ("The 'decalsPrefab' does not contain a 'DS_Decals' instance!");
            } else {
                    
    // Create the decals mesh (intermediate mesh data) for our decals instance.
                    // Further we need a decals mesh cutter instance and the world to decals matrix.
                
    m_DecalsMesh = new DecalsMesh (m_Decals);
                
    m_DecalsMeshCutter = new DecalsMeshCutter ();
                
    m_WorldToDecalsMatrix m_Decals.CachedTransform.worldToLocalMatrix;
            }
        }


    function 
    Update(){

    Debug.Log(m_UVRectangleIndex);
    if( 
    Input.GetButton("Fire1")){    
                var 
    l_Ray Camera.main.ScreenPointToRay (Vector3(Screen.width/2,Screen.height/2));
                var 
    l_RaycastHit RaycastHit;
                if (
    Physics.Raycast (l_Rayl_RaycastHitMathf.Infinity)) {
                    if (
    l_RaycastHit.transform.name=="Metal"){
                        
    DecalStyle="Metal";
                        
    m_UVRectangleIndex=10;
                    }
                    if (
    l_RaycastHit.transform.name=="Concrete"){
                    
    DecalStyle="Concrete";
                    
    m_UVRectangleIndex=0;
                    }
                    
    //m_UVRectangleIndex = m_UVRectangleIndex + 1;
                        // Collider hit.
                    
                        // Make sure there are not too many projectors.
                    
    if (m_DecalProjectors.Count >= 10) {
                    
                            
    // If there are more than 50 projectors, we remove the first one from
                            // our list and certainly from the decals mesh (the intermediate mesh
                            // format). All the mesh data that belongs to this projector will
                            // be removed.
                        
    var l_DecalProjectorForRemoval m_DecalProjectors [0];
                        
    m_DecalProjectors.RemoveAt (0);
                        
    m_DecalsMesh.RemoveProjector (l_DecalProjectorForRemoval);
                    }
                    
                        
    // Calculate the position and rotation for the new decal projector.
                    
    var l_ProjectorPosition l_RaycastHit.point - (decalProjectorOffset l_Ray.direction.normalized);
                    var 
    l_ForwardDirection Camera.main.transform.up;
                    var 
    l_UpDirection = - Camera.main.transform.forward;
                    var 
    l_ProjectorRotation Quaternion.LookRotation (l_ForwardDirectionl_UpDirection);
                    var 
    DenemeRotation Quaternion.FromToRotation(Vector3.upl_RaycastHit.normal);
                    
                        
    // Randomize the rotation.
                    
    var l_RandomRotation Quaternion.Euler (0.0fRandom.Range (0.0f360.0f), 0.0f);
                    
    l_ProjectorRotation l_ProjectorRotation l_RandomRotation;
                    
                    var 
    l_TerrainCollider TerrainCollider l_RaycastHit.collider as TerrainCollider;
                    if (
    l_TerrainCollider != null) {

                    } else {
                        
                            
    // We hit a collider. Next we have to find the mesh that belongs to the collider.
                            // That step depends on how you set up your mesh filters and collider relative to
                            // each other in the game objects. It is important to have a consistent way in order
                            // to have a simpler implementation.
                        
                        
    var l_MeshCollider l_RaycastHit.collider.GetComponent.<MeshCollider> ();
                        var 
    l_MeshFilter l_RaycastHit.collider.GetComponent.<MeshFilter> ();
                        
                        if (
    l_MeshCollider != null || l_MeshFilter != null) {
                            var 
    l_Mesh Mesh null;
                            if (
    l_MeshCollider != null) {
                            
                                    
    // Mesh collider was hit. Just use the mesh data from that one.
                                
    l_Mesh l_MeshCollider.sharedMesh;
                            } else if (
    l_MeshFilter != null) {
                            
                                    
    // Otherwise take the data from the shared mesh.
                                
    l_Mesh l_MeshFilter.sharedMesh;
                            }
                            
                            if (
    l_Mesh != null) {
                            
                                    
    // Create the decal projector.
                                
    var l_DecalProjector DecalProjector (l_ProjectorPositionDenemeRotationdecalScalecullingAnglemeshOffsetm_UVRectangleIndexm_UVRectangleIndex);
                                
                                    
    // Add the projector to our list and the decals mesh, such that both are
                                    // synchronized. All the mesh data that is now added to the decals mesh
                                    // will belong to this projector.
                                
    m_DecalProjectors.Add (l_DecalProjector);
                                
    m_DecalsMesh.AddProjector (l_DecalProjector);
                                
                                    
    // Get the required matrices.
                                
    var l_WorldToMeshMatrix l_RaycastHit.collider.renderer.transform.worldToLocalMatrix;
                                var 
    l_MeshToWorldMatrix l_RaycastHit.collider.renderer.transform.localToWorldMatrix;
                                
                                    
    // Add the mesh data to the decals mesh, cut and offset it before we pass it
                                    // to the decals instance to be displayed.
                                
    m_DecalsMesh.Add (l_Meshl_WorldToMeshMatrixl_MeshToWorldMatrix);                        
                                
    m_DecalsMeshCutter.CutDecalsPlanes (m_DecalsMesh);
                                
    m_DecalsMesh.OffsetActiveProjectorVertices ();
                                
    m_Decals.UpdateDecalsMeshes (m_DecalsMesh);
                                
                                
    NextUVRectangleIndex ();
                            }
                        }
                    }
                }

        }
        
    }
    //update end 
     
  46. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    @datneto, I won't have time today to check it. You can expect to get an answer by tomorrow.
     
  47. MassoftGames

    MassoftGames

    Joined:
    May 2, 2013
    Posts:
    41
    Ok,but my problem not difficult and urgency for you.
     
  48. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I wouldn't use m_UVRectangleIndex anymore. Instead make one for the metal and one for the concrete. Now just apply the logic that exists for one to both of them consequently.
     
  49. ShoyukenX

    ShoyukenX

    Joined:
    May 11, 2013
    Posts:
    6
    I like your decal system. Previously I have tried the free version and I love it.
    Now I would like to know what are the advantages of the Pro version.
    I know that the features are Vertex Colors, Texture Atlas Assets, and Affect Detail, but what exactly can I do with those features that I cannot accomplish with the free version? I mean, are the features in the pro version worth investing? Is it more optimized for mobile devices and other advantages?
     
  50. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    With the Decal System Pro you get especially workflow improvements and a few optimizations.

    Vertex Colors
    The vertex colors allow you to give each projector another color. This gives you the possibility to have a lot of variations with fewer materials or smaller textures. E.g. lets assume you have placed some decal projectors which use different uv rectangles. If you find out that you need a different color touch for some projectors, it is necessary to extend or modify the texture atlas, which is quite time consuming. With vertex colors, it becomes a no brainer. You can do the same with the transparency per projector.
    If your environment uses vertex colors you can use them to shade your projector such that you get a smoother look for your decals. You even get the possibility to mix the underlying vertex colors with the vertex color you have set for your projector.
    At runtime you can use all that and you get an optimization in the case that you only update the vertex colors. In the case that you don't add or remove projectors, you can e.g. fade in/out or change the color with a minimal performance impact. Internally there is some caching going on to minimize or if possible to eliminate memory allocations at runtime. The performance hit was barely measurable in the test scene which comes with the Pro version. I haven't tested the performance on mobiles yet.
    Another thing I should mention is that vertex colors don't add additional draw calls.

    Texture Atlas Assets
    Easily exchange of texture atlas between DS_Decals using Texture Atlas Assets. If you every wanted to change the texture atlas for several existing decals, you will understand how useful this can be.

    Affect Details
    If you have a heap of rocks with some plants and you want to add moss but only to the rocks, this can be quite tedious. Without the Decal System Pro, you need to place the plants a special layer that is not affected by the moss projector. This can easily lead to a mess with the layers, because they can be used for many different things. With the details, you can simply specify which meshes - in this example the plants - should not be affected. You could alternatively specify that only the rocks should be affected which would produce the same result.

    Terrain Density
    If you place a big projector on a terrain it will produce a huge amount of vertices. With the terrain density feature you can lower this count with the tradeoff that it doesn't match the terrain perfectly anymore.

    Further Runtime Improvements
    If you have a short bitmap animation you would like to show, like a paint ball splash it is very computationally expensive without the Decal System Pro, because the whole projector needs to be recalculated. In the Pro version only the uv/2 can be recalculated and updated in an optimized way with internal caching to minimize or if possible to eliminate memory allocations. This is technically comparable to the runtime update of vertex colors. You can even mix them! If a player shoots a paint ball somewhere, you can playback the uv animation on impact to visualize how the color slowly flows and during that you could already fade it out using vertex colors.
    With Texture Atlas Assets uv rectangles for such animations can be initialized automatically as long as the individual images are correctly distributed in your texture atlas.

    That pretty much sums it up. Most features were requested by several studios. They were introduced to bring practical benefits.

    Hope this helps. Let me know if you have more questions.


    Edit: And the Decal System Playlist was extended with some explanation videos of the Decal System Pro features:
    http://www.youtube.com/watch?v=C87xkHj8jHM&list=PLBD9CA3140ECF817A
     
    Last edited: Aug 22, 2013