Search Unity

Weird artifacts on Android build

Discussion in 'Shaders' started by vincespeed, Nov 27, 2016.

  1. vincespeed

    vincespeed

    Joined:
    Mar 8, 2014
    Posts:
    70
    Hello guys. I am working on a system which should spam at the start of a scene a number of billboard trees. As a starting point I used the Aily's turboforest example, simplifying the whole thing for mobile performance.
    The system does the following: generates quads on my terrain, in random positions, and then applies to each quad a billboard. It works flawlessy on Editor, but when I run it on my Galaxy S3, it is like quads are higly distorted. Here's the relevant code and the shader (i removed alpha blending on purpose to make the artifacts clearer).I hope someone can help me because I am really freaking out on this
    Code (CSharp):
    1. void BuildMesh()
    2.     {
    3.  
    4.         if(tfQuad.quads.Count==0) return;
    5.  
    6.         Vector3[] verts=new Vector3[tfQuad.quads.Count*4]; // all trees (in mesh) vertices
    7.         Vector2[] uvs=new Vector2[tfQuad.quads.Count*4]; // trees uvs
    8.         Vector2[] uvs2=new Vector2[tfQuad.quads.Count*4]; // uvs2 store tre type, one of 4 trees texture shift
    9.         Vector3[] normals=new Vector3[tfQuad.quads.Count*4]; // normals store each tree position in mesh (billboards no need normals ;)
    10.        
    11.         int[] indices=new int[tfQuad.quads.Count*4]; // quads in mesh
    12.  
    13.         // need to calculate min and max bounds manualy, for correct AABB Unity calc
    14.         Vector3 min=tfQuad.quads[0].pos;
    15.         Vector3 max=min;
    16.        
    17.         Vector2 typeShift=new Vector2(0,0); // shift current on texture (tree type, one of 4)
    18.  
    19.         for(int i=0;i<tfQuad.quads.Count;i++) // fill arrays
    20.         {
    21.            
    22.             tfQuad q=tfQuad.quads[i];
    23.  
    24.             // AABB calc
    25.  
    26.             min.x=Mathf.Min(min.x,q.pos.x);
    27.             min.y=Mathf.Min(min.y,q.pos.y);
    28.             min.z=Mathf.Min(min.z,q.pos.z);
    29.            
    30.             max.x=Mathf.Max(max.x,q.pos.x);
    31.             max.y=Mathf.Max(max.y,q.pos.y);
    32.             max.z=Mathf.Max(max.z,q.pos.z);
    33.  
    34.  
    35.             int ii=i*4;
    36.  
    37.             // vertices of tree
    38.             verts[ii]=qv0*q.scale;
    39.             verts[ii+1]=qv1*q.scale;
    40.             verts[ii+2]=qv2*q.scale;
    41.             verts[ii+3]=qv3*q.scale;
    42.            
    43.             // randomize shading
    44.             float tint=1.0f-eachTreeShadingRandomize+(Random.value*eachTreeShadingRandomize*2);
    45.             verts[ii].z=tint;
    46.             verts[ii+1].z=tint;
    47.             verts[ii+2].z=tint;
    48.             verts[ii+3].z=tint;
    49.            
    50.             // base tree uvs (first frame of this tree)
    51.             uvs[ii]=uv0;
    52.             uvs[ii+1]=uv1;
    53.             uvs[ii+2]=uv2;
    54.             uvs[ii+3]=uv3;
    55.  
    56.             indices[ii]=ii;
    57.             indices[ii+1]=ii+1;
    58.             indices[ii+2]=ii+2;
    59.             indices[ii+3]=ii+3;
    60.  
    61.             // push tree up from groung on it height
    62.             q.pos.y+=-qv0.y*q.scale;
    63.  
    64.             // write tree position to it normals (for shader)
    65.             normals[ii]=q.pos;
    66.             normals[ii+1]=q.pos;
    67.             normals[ii+2]=q.pos;
    68.             normals[ii+3]=q.pos;
    69.  
    70.             // calc and write tree type
    71.             typeShift.x=0;
    72.             typeShift.y=0;
    73.            
    74.  
    75.            
    76.             uvs2[ii]=uv0 ;
    77.             uvs2[ii+1]=uv1 ;
    78.             uvs2[ii+2]=uv2 ;
    79.             uvs2[ii+3]=uv3 ;
    80.            
    81.         }
    82.  
    83.         // creating mesh
    84.         GameObject trees=new GameObject();
    85.         MeshFilter mf=trees.AddComponent<MeshFilter>();
    86.        
    87.         mf.sharedMesh=new Mesh();
    88.        
    89.         mf.sharedMesh.vertices=verts;
    90.        
    91.         mf.sharedMesh.normals=normals;
    92.         mf.sharedMesh.uv=uvs;
    93.         mf.sharedMesh.uv2=uvs2;
    94.         mf.sharedMesh.SetIndices(indices,MeshTopology.Quads,0);
    95.  
    96.         mf.sharedMesh.bounds = new Bounds(center: (min + max) / 2, size: max - min); // alexzzzz fix
    97.  
    98.         MeshRenderer mr=trees.AddComponent<MeshRenderer>();
    99.         mr.sharedMaterial=treeMaterial;
    100.  
    101.     }
    And this is the shader:
    Code (CSharp):
    1. Shader "Custom/TurboForest"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Base (RGB)", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.       Tags {"Queue"="Transparent" "IgnoreProjector"="True"}
    10.       LOD 20
    11.       Pass
    12.       {  
    13.        
    14.         CGPROGRAM
    15.         #pragma vertex vert
    16.         #pragma fragment frag
    17.         #pragma exclude_renderers xbox360
    18.        
    19.         uniform sampler2D _MainTex;      
    20.         fixed4 _LightColor0;
    21.        
    22.         struct vertexInput
    23.         {
    24.             float4 vertex : POSITION;
    25.             float4 tex : TEXCOORD0;
    26.            
    27.             float4 pos : NORMAL;
    28.         };
    29.         struct vertexOutput
    30.         {
    31.             float4 pos : SV_POSITION;
    32.             float4 tex : TEXCOORD0;
    33.             float tint: TEXCOORD2;
    34.         };
    35.         vertexOutput vert(vertexInput input)
    36.         {
    37.             vertexOutput output;
    38.             UNITY_INITIALIZE_OUTPUT(vertexOutput,output);
    39.        
    40.           output.pos = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, float4(input.pos.x, input.pos.y, input.pos.z, 1.0))- float4(input.vertex.x,- input.vertex.y, 0.0, 0.0));
    41.        
    42.             output.tex = input.tex;
    43.  
    44.            
    45.  
    46.  
    47.             return output;
    48.         }
    49.  
    50.         float4 frag(vertexOutput input) : COLOR
    51.         {
    52.            
    53.  
    54.  
    55.  
    56.  
    57.                         return tex2D(_MainTex, float2(input.tex.xy));  
    58.  
    59.         }
    60.         ENDCG
    61.  
    62.         }
    63.  
    64.        
    65.    
    66.     }
    67.    
    68. }
    I really cannot understand what is wrong with the android build.
     

    Attached Files:

  2. IronMathbook

    IronMathbook

    Joined:
    Apr 12, 2014
    Posts:
    60
    I can't really help you but I would suspect that the script is the problem
    I would play around with the code commented with
    // alexzzzz fix , // push tree up from groung on it height or even // vertices of tree
    and see if that changes anything
     
  3. vincespeed

    vincespeed

    Joined:
    Mar 8, 2014
    Posts:
    70
    The creator of the code has been so kind to give the solution to this matter. It seems Android can't draw quads. I've googled about every possible issue, but nowhere this is mentioned. You were anyway on the right path thinking that the problem is somewhere in the c# code!
    Thank you for replying
     
  4. recon0303

    recon0303

    Joined:
    Apr 20, 2014
    Posts:
    1,634
    what did you do to fix this, we have a issue, like this as well.
     
  5. vincespeed

    vincespeed

    Joined:
    Mar 8, 2014
    Posts:
    70
    To
    You have to assign "normals" data to vertex and vice versa. A swap indeed. :)
     
  6. recon0303

    recon0303

    Joined:
    Apr 20, 2014
    Posts:
    1,634
    Thanks.