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. reptilebeats

    reptilebeats

    Joined:
    Apr 28, 2012
    Posts:
    272
    should of mentioned i only want to blend the outer edges not the whole texture
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You have the possibility to work with the target vertex color or to specify a mask. You would need to create a new shader that takes those into account and then draw the decal texture(s) using that additional data. I am aware of some projects in which the Decal System is used like that.
    But the decal is not blended with the target's diffuse channel, it is still just drawn over it.

    You might create a shader that blends the diffuse channels. This is not as scalable from a workflow point of view, as a new material needs to be created for each decal/target texture combination.

    Let me know if I understood your question correctly.
     
  3. reptilebeats

    reptilebeats

    Joined:
    Apr 28, 2012
    Posts:
    272
    yh i can make a shader that uses masks and vertex colors and a few others but im no expert in creating shaders, i'll have to do some further research into creating my own shaders, theres some good examples out there that might lead me to what im after.

    heres a video on the sort of effect i was looking at doing, probably a bit overkill though.
     
  4. reptilebeats

    reptilebeats

    Joined:
    Apr 28, 2012
    Posts:
    272
    hey i was just wandering if there was a text option, im currently creating it by hand but it would be nice to know if there was one or if one is planned
     
  5. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I missed your previous post. Let me get to that first:
    Theoretically it is possible to achieve that kind of effect, but that kind of shader isn't included in the Decal System.

    Text as such is not supported, but as fonts are stored in textures, you may used them. But again, it doesn't come out of the box, but you should be able to handle it on your own.
     
  6. reptilebeats

    reptilebeats

    Joined:
    Apr 28, 2012
    Posts:
    272
    yh for now i have my desired font as a texture and then spend a little time making the atlas in unity.
     
  7. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Hi there,

    Just a quick question. Is this system faster (In terms of performance) compared with standard projectors? I'm just looking for some performance improvement using projectors capabilities.
    And using it for Skinned mesh renderers it will keep giving that one draw call?(For instance using it to create blood splatters over a character.)
    Thanks a lot!
     
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    As a rule of thumb, if the projection is updated in every frame, the standard projector should be used. If the projection is just computed once and then stays, decals are most likely faster.

    In general the performance depends certainly on the platform, cpu, ... and on the number of vertices in the affected meshes. E.g. it is possible to use the Decal System for shadows for a walking character, if the shadow is only casts onto a mesh with very few vertices and they may e.g. be cached internally. But if you have a huge environment with high poly floors, it is usually not a good idea to use the Decal System for the shadows.
    If you want to use it for foot steps, the Decal System is usually the faster solution, because the computation is made once and from then on you just render a usual mesh.

    Let me know if you have more specific questions.
     
  9. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Thanks Dantus,

    Just one example, to keep things clear, is this suitable for making Blood splatters over moving characters? It is aimed to be used on PC. I need to make a wound of some kind over the characters. I've tried with projectors, but as soon as you have more than a dozen, the performance goes down. I've tried the classical planes, but over a skinned mesh moving and changing his shape they don't fit at all. So i only have two options, create a shader with 6 detail textures each fitting one character area, for instance, one for the head, one for the chest and one for each arm and leg. And setting the right texture in the shader through code, or your system, if it can do that reasonably faster.

    I can destroy them after some time and only allow 2 or three per character too, but all depends on how fast it is.

    Thanks again!
     
  10. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The Decal System can perform projections onto skinned characters. The effect you want to achieve should be possible. Keep in mind that if you are dealing with skinned meshes, it may require quite some fine tuning to get accurate results. Further at the moment there is no built-in support for shape key changes, because Unity doesn't provide an api for it. Though if you have Unity Pro and are a coder with a little experience in shader programming there might be a workaround depending on the amount of time you have.
     
  11. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Ok, thanks Dantus! Very helpful!
     
  12. nyaroshchuk

    nyaroshchuk

    Joined:
    Nov 26, 2014
    Posts:
    2
    Is source code supplied with Decal System Pro is full?
    We have a policy in our company that we can't use unity assets without full source. If it's full, then your asset will be a perfect fit for us.
     
  13. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Yes, the Decal System Pro contains the full source code.
     
  14. nyaroshchuk

    nyaroshchuk

    Joined:
    Nov 26, 2014
    Posts:
    2
    Thanks, that's exactly what we need.
     
  15. Alex-Some

    Alex-Some

    Joined:
    Oct 30, 2013
    Posts:
    15
    I have an exception with latest version.
    When i click ScaleZ on Projector:
    Code (CSharp):
    1. IndexOutOfRangeException: Array index is out of range.
    2. Edelweiss.DecalSystemEditor.GenericDecalProjectorMode`3[D,P,G].ReconstructProjectorRatioScaleZ (.P a_Projector)
    3. Edelweiss.DecalSystemEditor.GenericDecalProjectorMode`3[D,P,G].ReconstructProjectorRatioGUI (.P a_Projector)
    4. Edelweiss.DecalSystemEditor.DecalProjectorProjectorMode.CustomInspectorGUI ()
    5. Edelweiss.DecalSystemEditor.GenericDecalProjectorMode`3[D,P,G].InspectorGUI ()
    6. Edelweiss.DecalSystemEditor.GenericDecalsEditor`3[D,P,G].OnInspectorGUI ()
    7. UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor editor, Int32 editorIndex, Boolean forceDirty, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect, Boolean eyeDropperDirty) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1131)
    8. UnityEditor.DockArea:OnGUI()
    9.  
    Unity 5.0.0b13
     
  16. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Thanks for reporting!

    I tried to reproduce it with Unity 5.0.0b16, but didn't get any error message when I scaled the projector along the z axis. Could you give me a step by step explanation, such that I can reproduce the issue?
     
  17. CY_ts

    CY_ts

    Joined:
    Dec 22, 2014
    Posts:
    1
    Does the latest version support Unity5 beta?
     
  18. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    There is no official port yet. This will happen after the Unity 5 release.
    I just gave it a try and the API Updater can handle it properly. I was able to run all the test scenes and use the editor tools without any issue. If there are Unity 5 specific issues, I will certainly resolve them already now,
     
    gurayg and CY_ts like this.
  19. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    Is this built to spawn decals programmatically? I would be using this for blood splatter, and ideally I'd like to be able to cast a ray and spawn a random decal from a sheet on the object the ray collides with.
     
  20. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Yes, this is possible. You need to implement it on your own, because you need to get the mesh, based on the hit target object, which is not possible in general. To give you an impression, here is the code for the bullet example script that comes with the Decal System:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using Edelweiss.DecalSystem;
    5.  
    6. namespace Edelweiss.DecalSystem.Example {
    7.  
    8.    public class BulletExample : MonoBehaviour {
    9.      
    10.        // The prefab with the ready to use DS_Decals. The material and uv rectangles are set up.
    11.      [SerializeField] private DS_Decals m_DecalsPrefab = null;
    12.      
    13.        // The reference to the instantiated prefab's DS_Decals instance.
    14.      private DS_Decals m_DecalsInstance;
    15.      private Matrix4x4 m_WorldToDecalsMatrix;
    16.  
    17.        // We keep track of the projectors that we are creating at runtime. If we have more than
    18.        // the maximum number of projectors, we remove the oldest ones.
    19.      private List <DecalProjector> m_DecalProjectors = new List <DecalProjector> ();
    20.      [SerializeField] private int m_MaximumNumberOfProjectors = 50;
    21.  
    22.        // We need a decals mesh and a cutter to create the decal projectors at runtime.
    23.      private DecalsMesh m_DecalsMesh;
    24.      private DecalsMeshCutter m_DecalsMeshCutter;
    25.      
    26.        // The size, culling angle and mesh offset for the decal projectors for the bullets we are about to
    27.        // create at runtime.
    28.      [SerializeField] private Vector3 m_DecalProjectorScale = new Vector3 (0.2f, 2.0f, 0.2f);
    29.      [SerializeField] private float m_CullingAngle = 80.0f;
    30.      [SerializeField] private float m_MeshOffset = 0.0f;
    31.      
    32.        // We iterate through all the defined uv rectangles. This one inicates which index we are using at
    33.        // the moment.
    34.      private int m_UVRectangleIndex = 0;
    35.      
    36.        // Move on to the next uv rectangle index. We call this method after each projection. In practice
    37.        // you certainly don't do that, but pick an appropriate one depending on the surface that was hit.
    38.      private void NextUVRectangleIndex () {
    39.        m_UVRectangleIndex = m_UVRectangleIndex + 1;
    40.        if (m_UVRectangleIndex >= m_DecalsInstance.CurrentUvRectangles.Length) {
    41.          m_UVRectangleIndex = 0;
    42.        }
    43.      }
    44.      
    45.      private void Start () {
    46.        
    47.          // Instantiate the prefab and get its decals instance.
    48.        m_DecalsInstance = Instantiate (m_DecalsPrefab) as DS_Decals;
    49.        
    50.        if (m_DecalsInstance == null) {
    51.          Debug.LogError ("The decals prefab does not contain a DS_Decals instance!");
    52.        } else {
    53.  
    54.            // Create the decals mesh and the cutter that are needed to compute the projections.
    55.            // We also cache the world to decals matrix.
    56.          m_DecalsMesh = new DecalsMesh (m_DecalsInstance);
    57.          m_DecalsMeshCutter = new DecalsMeshCutter ();
    58.          m_WorldToDecalsMatrix = m_DecalsInstance.CachedTransform.worldToLocalMatrix;
    59.        }
    60.      }
    61.      
    62.      private void Update () {
    63.  
    64.        if (Input.GetKeyDown (KeyCode.C)) {
    65.          
    66.            // Remove all projectors.
    67.          while (m_DecalProjectors.Count > 0) {
    68.            m_DecalsMesh.ClearAll ();
    69.            m_DecalProjectors.Clear ();
    70.  
    71.              // Clearing of the decals mesh means we need to initialize it again.
    72.            m_DecalsMesh.Initialize (m_DecalsInstance);
    73.          }
    74.          m_DecalsInstance.UpdateDecalsMeshes (m_DecalsMesh);
    75.        }
    76.  
    77.        if (Input.GetButtonDown ("Fire1")) {
    78.          Ray l_Ray = Camera.main.ViewportPointToRay (new Vector3 (0.5f, 0.5f, 0.0f));
    79.          RaycastHit l_RaycastHit;
    80.          if (Physics.Raycast (l_Ray, out l_RaycastHit, Mathf.Infinity)) {
    81.            
    82.              // Collider hit.
    83.            
    84.              // Make sure there are not too many projectors.
    85.            if (m_DecalProjectors.Count >= m_MaximumNumberOfProjectors) {
    86.  
    87.                // If there are more than the maximum number of projectors, we delete
    88.                // the oldest one.
    89.              DecalProjector l_DecalProjector = m_DecalProjectors [0];
    90.              m_DecalProjectors.RemoveAt (0);
    91.              m_DecalsMesh.RemoveProjector (l_DecalProjector);
    92.            }
    93.  
    94.              // Calculate the position and rotation for the new decal projector.
    95.            Vector3 l_ProjectorPosition = l_RaycastHit.point;
    96.            Quaternion l_ProjectorRotation = ProjectorRotationUtility.ProjectorRotation (l_Ray.direction);
    97.  
    98.              // Randomize the rotation.
    99.            Quaternion l_RandomRotation = Quaternion.Euler (0.0f, Random.Range (0.0f, 360.0f), 0.0f);
    100.            l_ProjectorRotation = l_ProjectorRotation * l_RandomRotation;
    101.  
    102.            TerrainCollider l_TerrainCollider = l_RaycastHit.collider as TerrainCollider;
    103.            if (l_TerrainCollider != null) {
    104.              
    105.                // Terrain collider hit.
    106.              
    107.              Terrain l_Terrain = l_TerrainCollider.GetComponent <Terrain> ();
    108.              if (l_Terrain != null) {
    109.                
    110.                  // Create the decal projector with all the required information.
    111.                DecalProjector l_DecalProjector = new DecalProjector (l_ProjectorPosition, l_ProjectorRotation, m_DecalProjectorScale, m_CullingAngle, m_MeshOffset, m_UVRectangleIndex, m_UVRectangleIndex);
    112.                
    113.                  // Add the projector to our list and the decals mesh, such that both are
    114.                  // synchronized. All the mesh data that is now added to the decals mesh
    115.                  // will belong to this projector.
    116.                m_DecalProjectors.Add (l_DecalProjector);
    117.                m_DecalsMesh.AddProjector (l_DecalProjector);
    118.                
    119.                  // The terrain data has to be converted to the decals instance's space.
    120.                Matrix4x4 l_TerrainToDecalsMatrix = m_WorldToDecalsMatrix * Matrix4x4.TRS (l_Terrain.transform.position, Quaternion.identity, Vector3.one);
    121.                
    122.                  // Pass the terrain data with the corresponding conversion to the decals mesh.
    123.                m_DecalsMesh.Add (l_Terrain, l_TerrainToDecalsMatrix);
    124.                
    125.                  // Cut and offset the decals mesh.
    126.                m_DecalsMeshCutter.CutDecalsPlanes (m_DecalsMesh);
    127.                m_DecalsMesh.OffsetActiveProjectorVertices ();
    128.                
    129.                  // The changes are only present in the decals mesh at the moment. We have
    130.                  // to pass them to the decals instance to visualize them.
    131.                m_DecalsInstance.UpdateDecalsMeshes (m_DecalsMesh);
    132.                
    133.                  // For the next hit, use a new uv rectangle. Usually, you would select the uv rectangle
    134.                  // based on the surface you have hit.
    135.                NextUVRectangleIndex ();
    136.              } else {
    137.                Debug.LogError ("Terrain is null!");
    138.              }
    139.              
    140.            } else {
    141.              
    142.                // We hit a collider. Next we have to find the mesh that belongs to the collider.
    143.                // That step depends on how you set up your mesh filters and collider relative to
    144.                // each other in the game objects. It is important to have a consistent way in order
    145.                // to have a simpler implementation.
    146.              
    147.              MeshCollider l_MeshCollider = l_RaycastHit.collider.GetComponent <MeshCollider> ();
    148.              MeshFilter l_MeshFilter = l_RaycastHit.collider.GetComponent <MeshFilter> ();
    149.              
    150.              if (l_MeshCollider != null || l_MeshFilter != null) {
    151.                Mesh l_Mesh = null;
    152.                if (l_MeshCollider != null) {
    153.                  
    154.                    // Mesh collider was hit. Just use the mesh data from that one.
    155.                  l_Mesh = l_MeshCollider.sharedMesh;
    156.                } else if (l_MeshFilter != null) {
    157.                  
    158.                    // Otherwise take the data from the shared mesh.
    159.                  l_Mesh = l_MeshFilter.sharedMesh;
    160.                }
    161.                
    162.                if (l_Mesh != null) {
    163.                  
    164.                    // Create the decal projector.
    165.                  DecalProjector l_DecalProjector = new DecalProjector (l_ProjectorPosition, l_ProjectorRotation, m_DecalProjectorScale, m_CullingAngle, m_MeshOffset, m_UVRectangleIndex, m_UVRectangleIndex);
    166.                  
    167.                    // Add the projector to our list and the decals mesh, such that both are
    168.                    // synchronized. All the mesh data that is now added to the decals mesh
    169.                    // will belong to this projector.
    170.                  m_DecalProjectors.Add (l_DecalProjector);
    171.                  m_DecalsMesh.AddProjector (l_DecalProjector);
    172.                  
    173.                    // Get the required matrices.
    174.                  Matrix4x4 l_WorldToMeshMatrix = l_RaycastHit.collider.renderer.transform.worldToLocalMatrix;
    175.                  Matrix4x4 l_MeshToWorldMatrix = l_RaycastHit.collider.renderer.transform.localToWorldMatrix;
    176.                  
    177.                    // Add the mesh data to the decals mesh, cut and offset it.
    178.                  m_DecalsMesh.Add (l_Mesh, l_WorldToMeshMatrix, l_MeshToWorldMatrix);            
    179.                  m_DecalsMeshCutter.CutDecalsPlanes (m_DecalsMesh);
    180.                  m_DecalsMesh.OffsetActiveProjectorVertices ();
    181.  
    182.                    // The changes are only present in the decals mesh at the moment. We have
    183.                    // to pass them to the decals instance to visualize them.
    184.                  m_DecalsInstance.UpdateDecalsMeshes (m_DecalsMesh);
    185.                  
    186.                    // For the next hit, use a new uv rectangle. Usually, you would select the uv rectangle
    187.                    // based on the surface you have hit.
    188.                  NextUVRectangleIndex ();
    189.                }
    190.              }
    191.            }
    192.          }
    193.        }
    194.      }
    195.    }
    196. }
     
  21. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    Excellent, thank you! Merry christmas :)
     
  22. sama-van

    sama-van

    Joined:
    Jun 2, 2009
    Posts:
    1,734
    I am using the Unity's projector to simulate light into the level, but too expensive on drawcall.
    Wondering if your project system also include a projection mode with the shader on Mulitply and additive/

    EDIT : FInally just bought it.
    1 - It seems to do what I was looking for but I didn't found any multiply or Additive shader in the Decal/ list...
    Tried to assigned one from the default Unity lib but some z-fight on the ground and other asset...

    2 - Any function to refresh all DecalMesh in Runtimes?
    Is that something to do with the ”UpdateDecalMeshes"?
    But I do not success to list all the DecalMeshes in rutime, it doesn't seems to be the right class o_O....?
    Even this doesn't work?
    Code (csharp):
    1. foreach(DS_DecalProjector decal in FindObjectsOfType(typeof(DS_DecalProjector)) as DS_DecalProjector )    
    2. {      
    3. decal.GetDecals ().InitializeDecalsMeshRenderers ();        
    4. }
    Thank you... :)
     
    Last edited: Jan 9, 2015
  23. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You can use any shader you want for the Decal System. To avoid the z-fighting, you usually need to add one line to the shader "Offset -1, -1". If you have trouble with the shader, just post it here and I will do my best to help.

    Unity's built-in shaders are available here:
    http://unity3d.com/unity/download/archive

    You may consider to use this script: http://forum.unity3d.com/threads/decal-system.141792/page-11#post-1247584
    If you want to code it on your own, here is a quick explanation. In order to update a decal projector at runtime, there is a bunch of steps you need to strictly follow. There is a bunch of bullet examples that illustrate the overall process. In those examples, a raycast is used to find the mesh and mesh renderer that needs to be affected by the Decal System. In your case, it is not necessary to perform the raycast, but instead you need a list with all the mesh renderers onto which the projection needs to take place.

    Your approach to use the Decal System for lighting is a relatively exotic use case. Keep in mind that updating the decal projector is a relatively expensive step.
     
  24. sama-van

    sama-van

    Joined:
    Jun 2, 2009
    Posts:
    1,734
    I wrote a level editor for a game then the only thing I was hoping for is one the level loaded, it just update once for all every decal assets in runtime.

    Could be super cool to have a Decal.InitializerAll() for this kind of process to go over the Bullet tutorial :)
    Even if it does slowdown the game, it's mainly during the level Loading process, then the player won't really see what is going on.

    Gonna try your advice and see ^_^ Thanks!
     
  25. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    That sounds good.

    You can use the RuntimeDecalsUpdater for that.

    There is no such magic function as InitializerAll (), because it would far too expensive for the general usage.
     
  26. sama-van

    sama-van

    Joined:
    Jun 2, 2009
    Posts:
    1,734
    Should I just do this ?
    Code (csharp):
    1. foreach(DS_Decals decal in FindObjectsOfType(typeof(DS_Decals)) as DS_Decals [])  
    2. {
    3.         decal.gameObject.AddComponent<RuntimeDecalsUpdater>();    
    4. }
    Or is there an extra step?
    The script has to be dropped on the parent with the component DS_Decals, right?
    For now it doesn't seem to refresh anything :(
    What about the Affected MeshFilters variable, should it be the list of all the Mesh filter in the scene?

    Thank by advance, >_>....
     
  27. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    There is an extra step. You are right that the affected mesh filters need to be set. You find the updated script here which allows you to set them on your own.
    Afterward, you can call UpdateAllProjectors ().

    Hope this helps.

    Code (csharp):
    1. //
    2. // Author:
    3. //  Andreas Suter (andy@edelweissinteractive.com)
    4. //
    5. // Copyright (C) 2013-2014 Edelweiss Interactive (http://www.edelweissinteractive.com)
    6. //
    7.  
    8. using UnityEngine;
    9. using System.Collections;
    10. using System.Collections.Generic;
    11. using Edelweiss.DecalSystem;
    12.  
    13. namespace Edelweiss.DecalSystem.Example {
    14.  
    15.    public class RuntimeDecalsUpdater : MonoBehaviour {
    16.    
    17.      private bool m_IsInitialized = false;
    18.      private DS_Decals m_Decals;
    19.      private List <DS_DecalProjector> m_UsedDecalProjectors = new List <DS_DecalProjector> ();
    20.      private List <WrappedDecalProjector> m_UsedWrappedDecalProjectors = new List <WrappedDecalProjector> ();
    21.      
    22.      [SerializeField] private List <MeshFilter> m_AffectedMeshFilters = new List <MeshFilter> ();
    23.      public List <MeshFilter> AffectedMeshFilters {
    24.        get {
    25.          return (m_AffectedMeshFilters);
    26.        }
    27.      }
    28.    
    29.      private DecalsMesh m_DecalsMesh;
    30.      private DecalsMeshCutter m_DecalsMeshCutter;
    31.    
    32.      private void InitializeIfNeeded () {
    33.        if (!m_IsInitialized) {
    34.          m_IsInitialized = true;
    35.        
    36.          m_Decals = GetComponent <DS_Decals> ();
    37.          m_DecalsMesh = new DecalsMesh (m_Decals);
    38.          m_DecalsMeshCutter = new DecalsMeshCutter ();
    39.          
    40.          UpdateAllProjectors ();
    41.        }
    42.      }
    43.    
    44.      private void Awake () {
    45.        InitializeIfNeeded ();
    46.      }
    47.    
    48.      public void RemoveProjector (DS_DecalProjector a_Projector) {
    49.        InitializeIfNeeded ();
    50.      
    51.        RemoveProjectorInternal (a_Projector);
    52.        m_Decals.UpdateDecalsMeshes (m_DecalsMesh);
    53.      }
    54.    
    55.      private void RemoveProjectorInternal (DS_DecalProjector a_Projector) {
    56.        if (m_UsedDecalProjectors.Contains (a_Projector)) {
    57.          int l_Index = m_UsedDecalProjectors.IndexOf (a_Projector);
    58.          WrappedDecalProjector l_WrappedDecalProjector = m_UsedWrappedDecalProjectors [l_Index];
    59.          m_DecalsMesh.RemoveProjector (l_WrappedDecalProjector);
    60.          m_UsedDecalProjectors.RemoveAt (l_Index);
    61.          m_UsedWrappedDecalProjectors.RemoveAt (l_Index);
    62.        }
    63.      }
    64.    
    65.      public void UpdateProjector (DS_DecalProjector a_Projector) {
    66.        InitializeIfNeeded ();
    67.      
    68.        RemoveProjectorInternal (a_Projector);
    69.    
    70.        WrappedDecalProjector l_WrappedDecalProjector = new WrappedDecalProjector (a_Projector);
    71.        m_UsedDecalProjectors.Add (a_Projector);
    72.        m_UsedWrappedDecalProjectors.Add (l_WrappedDecalProjector);
    73.    
    74.        m_DecalsMesh.AddProjector (l_WrappedDecalProjector);
    75.        
    76.        foreach (MeshFilter l_MeshFilter in m_AffectedMeshFilters) {
    77.          Mesh l_Mesh = l_MeshFilter.sharedMesh;
    78.          Transform l_Transform = l_MeshFilter.transform;
    79.          Matrix4x4 l_WorldToMesh = l_Transform.worldToLocalMatrix;
    80.          Matrix4x4 l_MeshToWorld = l_Transform.localToWorldMatrix;
    81.          m_DecalsMesh.Add (l_Mesh, l_WorldToMesh, l_MeshToWorld);
    82.        }
    83.        
    84.        m_DecalsMeshCutter.CutDecalsPlanes (m_DecalsMesh);
    85.        m_DecalsMesh.OffsetActiveProjectorVertices ();
    86.        m_Decals.UpdateDecalsMeshes (m_DecalsMesh);
    87.      }
    88.      
    89.      public void UpdateAllProjectors () {
    90.        DS_DecalProjector[] l_DecalProjectors = GetComponentsInChildren <DS_DecalProjector> ();
    91.        foreach (DS_DecalProjector l_Projector in l_DecalProjectors) {
    92.          UpdateProjector (l_Projector);
    93.        }
    94.      }
    95.    }
    96. }
     
  28. sama-van

    sama-van

    Joined:
    Jun 2, 2009
    Posts:
    1,734
    Thank you so much! It works a charm ^___^!!!....
    You should add this one in the package from the store! :)
     
  29. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I wasn't sure whether it is a good idea to add it, but you convinced me.
     
    sama-van likes this.
  30. TimRamsay

    TimRamsay

    Joined:
    Jun 25, 2013
    Posts:
    2
    When I try to modify my decals vertex colors at run time with DecalsInstance.UpdateVertexColors(DecalsMesh) I am getting:
    Looking at the source of GenericDecals.cs I was wondering if in this code:

    Code (CSharp):
    1.            
    2.             int l_PreservedVertexCount = 0;
    3.             foreach (Color[] l_VertexColors in a_DecalsMesh.PreservedVertexColorArrays) {
    4.                 l_PreservedVertexCount = l_VertexColors.Length;
    5.             }
    6.             if (l_PreservedVertexCount != a_DecalsMesh.VertexColors.Count) {
    7.                 throw (new InvalidOperationException ("The preserved vertex color count doesn't match the one from the decals mesh. Avoid changes on the decals mesh which affect the number of vertices, after it was used to update the decals instance as preserving arrays are used."));
    8.             }
    9.  
    This line:
    Code (CSharp):
    1.  
    2. l_PreservedVertexCount = l_VertexColors.Length;
    3.  
    is supposed to be:
    Code (CSharp):
    1.  
    2. l_PreservedVertexCount += l_VertexColors.Length;
    3.  
    If not I may need help in figuring out what I am doing wrong.
     
  31. TimRamsay

    TimRamsay

    Joined:
    Jun 25, 2013
    Posts:
    2
    Looks like this was caused by me calling:
    m_DecalsMesh.RemoveProjector(decalProjector);

    Fix was to call this right after:
    m_DecalsInstance.UpdateDecalsMeshes(m_DecalsMesh);

    Hope this helps someone else :)
     
  32. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    I am glad you figured it out on your own. In general, it shouldn't be required to have a look at the source code of the Decal System and even more important, it should never be needed to modify code in it. If something can not be done using the available API, it needs to be fixed in the Decal System. And if someone finds a bug, it is certainly my job to resolve it as well.
    Don't hesitate to get in touch with me, either in this forum or via email.
     
  33. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,898
    hi there,

    working on the lux 2.0 shaders for unity 5 and dynamic snow accumulation a came across the problem of adding more and more details to the final result: how to add skidmarks? how to add any other kind of local detail?
    the answer – of course – was adding decals.
    so during the last 2 days i have been looking into adding decals to the lux snow shader in order to create much more lively environments.
    and as i wanted the decals to blend smoothly with the base surface (using alpha blending) without having to use forward rendering – while the camera would use the new deferred rendering pass – i worked on a "deferred decal snow shader" that supports alpha blending while still being rendered using the deferred rendering pass.
    so finally i came up with a (cg only) shader that does all this: it uses alpha blending (giving you nicely fading borders) while still being rendered using the deferred pipeline.

    finally i have tested it using dantus’ outstanding decal framework – and it works just fine!
    with a bit more of investigation i will probably not even have to use some hacky "alpha blending in deferred" but can simply use "alpha testing" and still get absolutely smoothly fading decals due to dantus’ superior framework (which lets you "steal" uvs from the underlaying geometry).

    snow decals are fully dynamically and react to all changes you make to the values of "snow amount" or "snow melting".

    more about the lux 2.0 snow shader for unity 5 can be found here:
    http://forum.unity3d.com/threads/lux-snow-shader-for-unity-5-beta-22.294821

    and this it what you might archive using dantus’ decal framework + lux 2.0 snow shaders in unity 5:

    LuxDeferredSnowDecals_anim.gif

    lars
     
    hopeful likes this.
  34. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Hey Lars,

    Thanks a lot for your post, it is always great to hear how assets are used by others and especially to see the actual results of it! Well done!
     
  35. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,898
    hi danuts,

    thanks a lot! and as a video will most likely give you a much better idea about snow decals, here we go.
    all this would not be fancy at all – if it was not deferred only ;-)

     
  36. erana79

    erana79

    Joined:
    Jun 26, 2013
    Posts:
    61
    Hi Dantus!

    We are working on a mobile game and were looking into using Decal System to put some snow on objects here and there.
    All the objects in the environment are low-poly, static, non-moving objects so the decals will be static as well. We basically need the decals to add some more details on bigger meshes and across mesh-combinations.
    I read that decal projectors are not that good for mobile performance.

    Is Decal System a good solution for our project? How is it performance-wise? Are you able to use decals as meshes (with no decal shader) or is it all projection shaders?

    thanks in advance!
     
  37. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The Decal System generates a new mesh for which you can use any material you want. The expensive part of the Decal System is always the calculation of the mesh. As you don't intend to compute the mesh at runtime, the performance is identical to that of any other mesh. That means it depends mostly on the amount of vertices and on the used material.

    Let me know if you have further questions.
     
  38. erana79

    erana79

    Joined:
    Jun 26, 2013
    Posts:
    61
    Thanks for the quick reply, Dantus!
    I used the free version before and - as far as i remember - it did some kind of projection within the decal-object's bounds. (as seen on the tutorial video on the first page). Does that mean you create a mesh from the decal at runtime based on the mesh that the decal projection "hits"?

    Do i need do keep something in mind when using Decal System with the static meshes? Like marking the decal object as static?
     
  39. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    If you use the Decal System in the editor, the mesh is generated in the editor and at runtime no further calculations are needed.
    There are no further restrictions if all the work is done in the editor. Just mark the Decal System as static if it should be like that.
     
  40. reptilebeats

    reptilebeats

    Joined:
    Apr 28, 2012
    Posts:
    272
    hi just wandering if we were going to see an update after unity 5 is officially released
     
  41. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Absolutely yes, there will be an update for Unity 5.
     
  42. reptilebeats

    reptilebeats

    Joined:
    Apr 28, 2012
    Posts:
    272
    awsome
     
  43. Luca Belluccini

    Luca Belluccini

    Joined:
    Apr 9, 2013
    Posts:
    1
    Hello,
    is there a way to test the decal system?

    My main use would be at runtime and I plan to use custom shaders on them.
    Is it possible?

    The final object, obtained after a runtime addition of a decal, is a mesh?
     
  44. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The Decal System can be used at runtime and it can be used in combination with any custom shader. Of course, as the Decal System produced a mesh the is exactly identical to the mesh onto which it is projected, this need to be considered in the custom shader (usually using Offset -1, -1).

    PS I am going to send you a pm.
     
  45. NTDC-DEV

    NTDC-DEV

    Joined:
    Jul 22, 2010
    Posts:
    593
    Dantus,

    I've been trying to find a solution to the ever-ending problem of stacking decals over decals...

    I noticed a couple of weird behavior that I'm hopping you can help me out with. Here's the setup:
    - TextureAtlas with a number of decals UVs preset
    - A decal containing 5 projectors, 1 projector is a background color, 4 other projectors are foreground details
    - Everything is projecting onto a simple diffuse textured 3d object, nothing special about that object.
    - Shader used on the material is Decal/Transparent Diffuse

    So, I place the background projector onto the 3d object. Everything is fine. Then I place the 4 other projectors, each with a different UV from the atlas, onto the background projector. All projectors are on the same level. Here's what I noticed;

    Problem: Some but not all, of the foreground projectors appear to be projecting before the background projector, thus are occluded (completely invisible) by it when I click on "Update All Projectors". Issue is compounded when I click on "Optimize Scene", as it calls "Update All Projectors", breaking the foreground.

    1) Clicking on "Update Child Projectors" on the foreground projectors makes them appear correctly over the background. Moving the projectors makes them appear as well.
    2) MeshOffSet does nothing to fix "Update All Projectors" occluding the foreground. (Background offset being 0.001, foreground is 0.005)
    3) Project After Offset = true does nothing to fix "Update All Projectors" occluding the foreground.
    4) Affect Other Decals = true does nothing to fix "Update All Projectors" occluding the foreground.
    5) When placing the foreground projector into a projector group and pressing "Update All Projectors", everything works. However, when the background project is then placed into a projector group and then removed, "Update All Projectors" no longer works as intended.
    6) There is no noticeable z-fighting when moving the camera, it really appears as if the background is occluding foreground, it being completely invisible.

    I suspect that something is off with "Update All Projectors". Seeing that updating the child projectors individually fixes the problem, shouldn't there be an order in which the projectors update?
    Ex; first level projectors update first, then their children.

    Thank you.
     
    Last edited: Feb 24, 2015
  46. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Thanks for the clear explanation. The reason for this issue is very simple. This kind of use case was not considered in the design, because when the Decal System was implemented, there was no way to sort game objects in the hierarchy. Even though, stacking was considered, I couldn't find a simple enough solution.
    I just added this on my TODO list as a high priority and let you know when I have something.

    As a quick explanation for the effects you are seeing, here is what is going on under the hood:
    All the decal projectors are combined into one mesh (if possible). That order is in general random (and that's what I am trying to change as soon as possible). If you now edit any projector, the mesh data of this projector is removed from the internal lists and is added at the end. The mesh is passed like that to Unity and more or less like that to the graphics card which draws the triangles exactly in that order, that's why the last edited projector is always on top.
    If you use "Update All Projectors", the order becomes random again.
     
    NTDC-DEV likes this.
  47. kurylo3d

    kurylo3d

    Joined:
    Nov 7, 2009
    Posts:
    1,123
    Sorry if this was asked already, but does this work with unity 5 and unity 5s baked GI? And I guess part of that question is can i use standard shaders on the decals so i can play with metallic properties and such.

    Oh and another question.. does your system automatically create texture atlases depending on many individual decal textures being brought in.. or do u have to first create your own atlas manually and then slice it up within unity to tell it where each decal is located on the atlas? Or both? I seem to have seen a video of yours that does the 2nd way.
     
    Last edited: Feb 24, 2015
  48. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The Decal System works in Unity 5, though the automatic updater is needed at the moment. I am currently upgrading the Decal System to work with all the new features from Unity 5. This means especially to support uv3 and uv4.
    My plan is to have a custom standard shader for the Decal System, which automatically handles the z-fighting that is inherent to decals.

    Right now, it is the second way.
     
    punk likes this.
  49. kurylo3d

    kurylo3d

    Joined:
    Nov 7, 2009
    Posts:
    1,123
    Thanks for the reply. Do your meshes, that are created from your product, static batch as well?
     
  50. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Yes, you can use static batching for them as for any other mesh.