Search Unity

[Solved] Blue flickering meshes when vertex painted

Discussion in 'Scripting' started by stickadtroja, Nov 11, 2015.

  1. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    i have a bunch of procedurally generated meshes that i want to color in different colors using the vertex colors.
    but for some reason they show as blue, and it flickers back and forth to the correct vertex color if i move around the camera.

    to the left is the correct but uncolored meshes. to the right is the meshes with vertex colors. its only the dark blue that is wrong, the subtle red, blue and pink is the intended color.

    the code for painting them goes like this;
    Code (CSharp):
    1. Mesh newRoomObjectMesh = newRoomObject.GetComponent<MeshFilter>().mesh;
    2.                 Vector3[] newRoomObjectVertices = newRoomObjectMesh.vertices;
    3.                 Color[] colors = new Color[newRoomObjectVertices.Length];
    4.                 for(int k = 0; k < newRoomObjectVertices.Length; k++)
    5.                 {
    6.                     colors[k] = newColor;
    7.                 }
    8.  
    9.                 newRoomObjectMesh.colors = colors;
    what am i missing?
    the only clue to me is that the small squares that sits on the bigger meshes, gets correctly colored with simular code. but those meshes are prefabs and not generated. is there a component i have forgot to add to the generetad meshes perhaps?
     
  2. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    anybody got an idea?
     
  3. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    I cant see anyrhing wrong with that piece of code. Sounds a bit like conflicting polygons though I cant see the telltale tearing effect in your shots. Are you sure there is no duplicate geometry there fighting over the same space? I dont recognize the shader, there could be an issue there too.
     
  4. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    im pretty sure there is no dublicate geometry. i also tested with unitys particle shader, the only one that supports vertex colours and i get the same result.

    i isolated the problem a little bit.


    i set all the vertex colours to differents amounts of red. in the upper picture, they display correctly, in the lower they are wrong. they flicker back and forth depending on camera angle and distance. interesting is that eventhough they turn incorrectly blue, they still have the same brightness. so if the intended vertex colour is 0.5,0,0 it ends up being 0,0,0.5.
    super weird.

    the difference between the pictures is that the upper have only meshes that comes straight from the prefabs.
    the lower has meshes generated from scratch.
    this is how;
    Code (CSharp):
    1. public Room (string inName, string inType, GameObject inRoomArea)
    2.     {  
    3.         roomName = inName;
    4.         roomType = inType;
    5.  
    6.         roomArea = new GameObject ();
    7.         roomArea.transform.position = new Vector3 (0.0f, 0.0f, 0.0f);
    8.         roomArea.transform.rotation = Quaternion.identity;
    9.  
    10.         roomArea.AddComponent<MeshFilter> ();
    11.  
    12.         Mesh newMesh = roomArea.GetComponent<MeshFilter>().mesh;
    13.  
    14.         if (inRoomArea.GetComponent<MeshFilter> () != null)
    15.         {
    16.             Mesh inMesh = inRoomArea.GetComponent<MeshFilter> ().sharedMesh;
    17.  
    18.             Vector3[] newMeshVertices = new Vector3[inMesh.vertices.Length];
    19.             Vector3[] newMeshNormals = new Vector3[inMesh.normals.Length];
    20.  
    21.             for(int i = 0; i < inMesh.vertices.Length; i++)
    22.             {
    23.                 newMeshVertices[i] = inRoomArea.transform.rotation * inMesh.vertices[i];
    24.                 newMeshNormals[i] = inRoomArea.transform.rotation * inMesh.normals[i];
    25.             }
    26.             newMesh.vertices = newMeshVertices;
    27.             newMesh.normals = newMeshNormals;
    28.             newMesh.triangles = inMesh.triangles;
    29.  
    30.         }
    31.  
    32.         roomArea.AddComponent<MeshCollider> ();
    33.         MeshCollider newCollider = roomArea.GetComponent<MeshCollider> ();
    34.  
    35.         newCollider.sharedMesh = newMesh;
    36.  
    37.     }
    so it basically copies the mesh in gameobject inRoomArea. it also rotates the vertices and normals to put them in local space.
    i copy all the components except meshrenderer, but that one i add later, when i instantiate the meshes.

    i think it has to be there the problem is. the question is what? does anybody have a lot of experience with procedurally generated meshes with vertex colors?
     
  5. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    It's been a while now, figured this out?
    I have been doing a lot of vertex color work on meshes myself and have never experienced what you describe here.
    In the code snippet you posted last there is no code regarding vertex colors.
    What kind of shader are you using?
     
  6. pixpusher2

    pixpusher2

    Joined:
    Oct 30, 2013
    Posts:
    121
    Shader flickers back and forth depending on camera view angle? Sounds like it Unity's dynamic batching kicking in.
    Go File > Build Settings > Player Settings and disable Dynamic Batching under the Other Settings column and see if it still flickers.
     
  7. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    thank you so much pixpusher2 that was it! disabled dynamic batching and got no flickering anymore! should i put "solved" in the thread title or something?
    thermalfusion: i put it on hold since i didnt find any solution. the code snippet was to show the part where i made the procedurall meshes, the only ones with the flickering. im using a custom made shader, got it from somewhere, its only vertex colours and diffuse map. thanks for all the replies, would never done it by myself.

    so, what is dynamic batching, and do i need it for anything?
     
  8. Tzan

    Tzan

    Joined:
    Apr 5, 2009
    Posts:
    736
    This is a vertex shader that works with the new StandardShader system.
    I used his previous version and it works great. This new version I havent tried yet, but now works in Deffered.
    You should try this.
    http://forum.unity3d.com/threads/standard-shader-with-vertex-colors.316529/

    Inside the package file you'll download is a sample scene.
    I just imported his package and I'll probably just leave it in my project, it doesnt take up too much space


    Dynamic Batching:
    When you make a bunch of GameObjects that use the same Material and the Mesh is not too big, <300 verts. then DynamicBatching will kick in when the frame renders.
    It combines many of the meshes into one draw call. Its something you want working if you have a frame rate problem caused by too many drawcalls.
     
    Last edited: Nov 19, 2015
  9. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    but if dynamic batching is causing this blue flickering, is there another way to batch the meshes?
    ill check out that shader of yours, thanks! although to me it seems the shader isnt the problem, as you can see none of the small bright boxes in the above screenshot is blue, and they use the same shader.
     
  10. Tzan

    Tzan

    Joined:
    Apr 5, 2009
    Posts:
    736
    After you assign triangles add this line:

    newMesh.RecalculateNormals();

    Making my own meshes never works right without this.
    http://docs.unity3d.com/ScriptReference/Mesh.RecalculateNormals.html


    Once you have all your meshes created you can merge them yourself.
    http://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html

    This is my stripped down combiner code, it takes meshes and returns the result.

    Code (csharp):
    1.  
    2. // CombineMeshParts(): same as above but: no GO, no naming, no collider is set,
    3.   // should work for Terrain parts and Landscape parts
    4.   public static Mesh CombineMeshParts(List<Mesh> meshList)
    5.   {
    6.   if (meshList.Count == 0)
    7.   return null;
    8.  
    9.   CombineInstance[] combine = new CombineInstance[meshList.Count];
    10.  
    11.   for (int i = 0; i < meshList.Count; i++)
    12.   {
    13.   if (meshList[i] == null)
    14.   {
    15.   Debug.Log("A mesh is NULL in MeshTools.CombineMeshParts()--------------");
    16.   continue;
    17.   }
    18.  
    19.   combine[i].mesh = meshList[i];
    20.   }
    21.   tempMesh = new Mesh();  //  1/26/12
    22.  
    23.   tempMesh.CombineMeshes(combine, true, false);
    24.  
    25.  
    26.   return tempMesh;
    27.   }
    28.  
    29.  

    I like the auto batcher, its never caused problems for me.

    Sorry I was a bit late getting back.
    I had work thurs/friday and of course I had to play StarCraft all day Saturday :)
     
    Last edited: Nov 22, 2015
  11. stickadtroja

    stickadtroja

    Joined:
    Oct 25, 2015
    Posts:
    33
    ok thanks i try it out later when i need batching