Single object (single mesh) with many, many drawcalls

Greetings everyone,

i have been tinkering the past week in a scene trying to make my own decent torch prefab, with not too much of a performance drawback.

Now when i started looking closely at my statistics, i notice my draw calls in a quite simple scene are well… through the roof, to put it bluntly.

First i’ll include two screenshots

Screenshot of the main part of the scene and statistics

closeup of the main object (the building)

now…

I have been experimenting with single-objects, multi-materials in terms of modeling.
I managed to lay out 9 groups of vertices which have assigned their own material.

The material i have been using for every object in this scene (for testing purposes of this) is my newly finished triplanar mapping shader.
This shader uses both normals, colormaps and speculars through the colormap’s alpha channel.

When i am running my scene, the scene consisting of only 12 unique objects (which contain a material tag) of which three torches that consist of a main model, the lit up part of the torch (and a few emitters casting flame decals.)

However the scene counts over 340 draw-calls!

I already tried to use the “Draw Call minimizer” from the asset store, but it won’t do anything because it claims i am using unity’s default material… (i am not, not in a single part of the scene…) but that won’t work…

So i think i best start with this question:
Does someone know if every projection of my triplanar shader adds a whole drawcall per object/material used? (so in the case of one unique colormap and one unique normalmap per material, it uses 6 calls to cast?)

The shader combines the colormap in this way:

fixed4 c = tex2D(_MainTex, IN.worldPos.xz/scale);
fixed4 c1 = tex2D(_MainTex, IN.worldPos.xy/scale);
fixed4 c2 = tex2D(_MainTex, IN.worldPos.zy/scale);
half4 result = lerp(c, c1, projnormal.z);
result = lerp(result, c2, projnormal.x);

(got to that snippet using a snippet i found of someone’s not finished old triplanar shader using google.)

Also i was wondering if every particle casted through an ellipsoid particle emitter is rendered in a different draw call.

Does any of you maybe have one or more pointers on where to look further?

Thanks in advance!

This isn’t nessesarily going to fix your issue but why do you have 48 textures in use for that 1 building + the floor? That, to me, seems like an incredible number of textures, I’ve never before in a game seen 2 objects use this many textures.
It sounds like your model is made up of seperate pieces, with each piece having a different shader (custom?) applied, if all these use the same shader then it would be easier, and wiser, do group them/combine them in your 3d application into 1 single model and then apply them.
Do you have the object UVmapped too? If not then I highly suggest doing so, should massivly reduce the draw calls (especially from textures and models).

You also have 88 different shadows being cast, you could try baking your shadows too, 88 shadows seems rather extreme.

I can’t say doing this will 100% fix your draw call numbers, but at the very least combining your objects, uv mapping or simply using the same shader on objects with the same texture, should help a great deal.

I’ve been toying some more with disabling separate objects and came to some interesting conclusions.
Normally i have also SSAO and Bloom effects added to the camera, for easier comparison i disabled these effects.

This is when i am only using the playerobject and the building itself, only 29 drawcalls
All (dynamic) lights have been disabled too.

This is when enable the directional light i am using as sunlight and all elements of the torches, EXCEPT for their point light (using hard shadows each), immediately an increase of 78 draw calls! that’s huuuge!

And when i enable the rest, only disabling the floor, flashlight and image effects;

at 277 draw calls.

After disabling the seperate lightpoints and re=enabling them i have come to the following estimate:
Each dynamic light i add to this scene seems to add 60 to 70 drawcalls, is that normal behaviour?

looking at the mesh in the inspector i see the following details;
2848 Verts, 1649 Tris, 9 Submeshes, uv, uv2.

So… maybe for each of these submeshes, another drawcall is added per light, does that seem likely?
I am using only 8 unique materials throughout the whole scene, only one uses a different shader (the ‘burning’ part of the torch mesh is using Unity’s Self-Illumin/VertexLit shader.) all others use my custom triplanar shader.

by smartly disabling some smaller object’s shadow caster tags i managed to slightly decrease the draw call count to roughly 320.
Shadow caster count however still is at 64. which is less, but probably still too many.

I am already using Unity Pro (hence the dynamic shadows)
the dynamic shadows i use mainly to have a nice animation in the shadows that simulate the flickering of a torch.
Loading the torch in a seperate scene uses 29 drawcalls including the camera effects, ‘only’ 18 without them.

Also looking in how the flashlight causes more or less draw calls to be used, i am getting the impression that none of the pointlights calculations are being culled on surfaces already behind another collider.
This as for my flashlight the amount of drawcalls fluctuates if i shine it on a part of the model using more textures. But when i move the pointlights, the draw call amount rarely fluctuates, as if it’s always casting itself to ALL objects.

Does someone recognize some of these features? i had purposedly only been using hard shadows with low resolution maps, but that won’t help me beating down drawcalls by itself.

Disabling one of the torches’ lightpoints decreases the shadow caster count by about 20, i think that’s a number i should look into to improve.

From animation and illustration i remember compositing objects in a certain way could cut down render times enormously for raytrace rendering,
does someone know if (i.e.) I could composite the same model of my building solely for the purpose of compositing the shadow casting?
since i am under the impression the light renders an additional shadow for each submesh currently.

In the meantime i’ll try to get that to work… if anyone has tried this in the past, please let me know!