Home Unity

Question about reducing draw calls in Unity

polycounter lvl 11
Offline / Send Message
Zodd polycounter lvl 11
Hi everyone.
I was hoping you guys can help me solve, or at least shed some light on the problem I'm having with reducing draw calls in unity.

Here's what I'm trying and what i did

-Made set of rock cliff meshes that can
-Have them share one shader to reduce the draw calls
-Made shader that blends 2 textures based on grayscale vertex paint

What wont work

-Each mesh that uses custom shader adds to the draw calls instead of batching


First the image
gS9ClsE.png




Now the problem occurred when I've noticed that the rock wall mesh was adding to draw calls every time it was placed in the scene
I've tried changing the shader to diffuse only, unlit, but nothing changed still every mesh called additional calls

Next tried reducing the amount of vertices (mesh had ~210) reduced to it to ~110 this fixed it, but i think I've read somewhere that this vertex limit
should be somewhere around 800-900, not 100verts ???

...Just noticed this when i was preparing to upload this image, in unity seems each of these "rock" meshes has 0.8k verts(that's 800 right ?),
while maya "claims" it has 105 ??

Ok so the above thing kinda "solved" the initial problem.

Also made a custom shader, now this is where the real problem lies because those 100 verts i can live with but thing that bothers me is that the shader in question is using 3 passes, ok so i assumed that that would be 3 draw calls for lets say 10 objects sharing it on screen, but nope, even with the reduced vertex count
( that works with basic "primitive" shaders ) with 3-pass shader i get
+3 draw calls each time i duplicate object on screen.


Here is the shader I've put together, the problem may very well lay in it because
it was Frankensteined from youtube tutorials since i have 0 experience in dealing with shaders.
Shader "2-Part Vertex Blend" {
     
    Properties
    {
       _Color("Color", Color) = ( 1,1,1)
       _Ambient("Ambient", Color) = (1,1,1)
       _Texture1("Texture 1", 2D) = ""
       _Texture2("Texture 2", 2D) = ""
    
    }
    
    SubShader
    {
                
        
        BindChannels
        {
            Bind "vertex", vertex
             Bind "texcoord", texcoord
            Bind "color", color
            Bind "normal", normal 
        }
        
        Pass
        {
            SetTexture[_Texture1]{Combine texture * primary}
    //        SetTexture[_Texture2]{Combine texture * one-primary} 
           }
        
        Pass
        {
             Blend one one
             SetTexture[_Texture2] {Combine texture * one-primary}
             SetTexture[_] {Combine previous * one-primary}
             
        }
        
        Pass
        {
            Blend DstColor SrcColor
                       
            Material
            {
                Ambient [_Ambient]
                Diffuse [_Color]
            }
            Lighting On
        }
        
       }

}

Replies

  • SanderDL
    Options
    Offline / Send Message
    SanderDL polycounter lvl 7
    I think your problem is that you are doing Dynamic Batching while you should be using Static Batching:

    http://docs.unity3d.com/Manual/DrawCallBatching.html

    If you read the criteria for Dynamic batching I think you will see why it isn't working for you.
  • Zodd
    Options
    Offline / Send Message
    Zodd polycounter lvl 11
    Yeah but isn't static batching available in unity pro only ? or have i misunderstood what they wrote in documentation ? <- I'm basing this on the fact that if i tick Static in the inspector window nothing happens ??

    However, after reading about batching again I've just noticed that multi-pass shaders break batching... i guess i missed it first couple of times :)

    Also, since this shader is written in (i think) shaderLab and requires 3 passes in order to work
    i suppose it should be written in CG in order to achieve the effect in one pass ??
    Any help/advice with that ? :poly122:
  • SanderDL
    Options
    Offline / Send Message
    SanderDL polycounter lvl 7
    Oh sorry you are right, it is a pro-only feature. I didn't realize they had this restriction for all platforms.

    You could use a shader that uses vertex colors to decide which textures to use. Or you could one big texture atlas for all your models.

    Still Dynamic batching is very limited and you will still hit restrictions quickly unless you have really low poly models or very simple shaders.
  • Farfarer
    Options
    Offline / Send Message
    Zodd wrote: »
    ...Just noticed this when i was preparing to upload this image, in unity seems each of these "rock" meshes has 0.8k verts(that's 800 right ?),
    while maya "claims" it has 105 ??
    Maya is telling you how many positional vertices the mesh has.

    In Unity (and every other game engine) the mesh must be split up into one vertex for every unique property. So a hard edge in shading, vertex colour, either of the UV channels or mesh tangents - all of these mean the vertex has to be duplicated.

    If your mesh was all one UV island with no seams in both UV maps, all one vertex colour, and all one smoothing group, and all had smoothed tangents, then it would have 105 vertices inside of Unity.

    This has some nice visual examples of how splits will increase the vertex count in the section "Welcome to Splitsville".



    For your purposes, though, there are scripts out there (MeshCombiner?) which sort of works like Static Batching. You give it some game objects and you tell it to combine them and it'll create one object out of them. You have to do this before building (whereas Static Batching happens automatically on build) but it should help.
  • Zodd
    Options
    Offline / Send Message
    Zodd polycounter lvl 11
    Hi guys, it's me again
    Managed to solve the batching problem, made shader in CGPROGRAM, the previous one was in shaderlab i believe... still very new :)
    Now i ran into a problem again, which is not a huge one but i wanted to ask if this problem is solvable, here's how i tried to make river.
    Made one vertically tileable texture that can be scrolled to simulate river flow, i went and found shader that scrolls texture, which is not mine i copied it of unity forums so all credit goes to the person behind it i just used it to check if my texturing is tileable vertically, will make my own because i found it to be very fun :)
    So here's where the problem starts.
    Because the shader uses "Transparent" tag and queue and i watched some tutorials about that :D it seems that the bottom plane is clipping the top planes (they use the same material) this is, from what i understood, problem with alpha sorting, and because the material is grayscale transparent ( cutout wouldnt be making these problems ) and they work fine with default diffuse, but soon as i apply shader with transparent properties it starts clipping.
    Here are the images of the problem.
    pPGIC0U.png

    It only clips from certain camera angles, these are the extreme angles that each show one of the "ripple" meshes being clipped by bottom mesh ( there is a square mesh underneath them )
    Now this is solvable i think, just by cutting those squiggly strips into the lower mesh would solve it because then nothing is above it.
    But can this be solved at all? i mean i can work around it this time but should i need to put some sort of ripples on top of it i would be in immediate trouble.
    Also i like it semi-transparent because it looks crystal-y :)
    Any help advice greatly appreciated, and many thanks for the advices so far.
  • Farfarer
    Options
    Offline / Send Message
    The only real way to sort this is to ensure that the one you want on topaws last.

    If it's isolated incidences like this, you could create a duplicate shader and give it a queue of Transparent+1, which will force to draw after all the other transparent things that have their queue set to
    Transparent.

    But then you wind up with problems when you have two of those together because they end up with alpha sorting issues between themselves...
  • warby
    Options
    Offline / Send Message
    warby polycounter lvl 18
    if you merge your meshes together in maya the polys/objects you selected LAST before combining them will draw on top because i believe transparent poyls draw in the order they show up in inside the file
  • Zodd
    Options
    Offline / Send Message
    Zodd polycounter lvl 11
    Makes perfect sense... I will definitely keep that in mind for now I've manage to mitigate the problem using shader and fiddling with draw order ( render queue ) so it shows up adequately, now the next order of business is getting it to show correctly when overlayed with particles ( explosions and fire ) but my guess is shader fiddling and render queues AGIAN :)

    On the other note, the amount of "behind the scenes" knowledge one has to have is huge, and it's not the knowledge you can get from your usual tutorials dug out on the web, I mean...
    - Vertex draw calls and the fact that soft/hard edge actually affects the number of them
    - The eternal mystery of transparency and its drawing order/sorting and whats showing up
    over/under what ( btw does that happen in other more "sophisticated" engines like Unreal ??)
    - And the latest drawing order of the polygons that make up the model

    To sum it up, this is some great in depth knowledge and thank you guys for sharing it ! :)
Sign In or Register to comment.