Batch.DrawInstanced on WebGL build in Chrome occasionally takes 14 seconds per frame

Our game runs at greater than 60 fps (usually greater than 100 fps) in the editor, on iOS, and for desktop. However when we build for WebGL we have substantial performance problems. In particular, we’re getting some super long frames on occasion:

That’s a 14 second frame! We’ve tried all combinations of enabling and disabling SRP, dynamic batching, and instancing. This screen shot was taken with SRP off, dynamic batching off, and instancing on for all materials. None of those seem to eliminate this problem. Normally the game runs around 60 fps in the browser otherwise.

The only thing that has been marginally successful is programmatically creating instances of all of our materials in the scene at runtime. Something like this:

        var renderers = feature.model.GetComponentsInChildren<Renderer>();
        foreach (var renderer in renderers) {
            renderer.material.SetFloat("_RelX", relative.x);
            renderer.material.SetFloat("_RelZ", relative.z);
        }

I’m assuming that because SetFloat creates a new instance of the materials, we’re forcing Unity to not be able to batch. However, there are two problems with this:

  1. We’d really like batching because we’ve got a bunch of grass models with the same materials (partially transparent for the record)
  2. With this fix we tend to get long periods of time where we run between 10-30 fps

Any thoughts at all? I’m not even really sure where to begin, but surely 14 seconds for a single function call means that something is broken here, no?

Unity Version 2019.4.2f1 by the way

1 Like

Another long frame:


Compared to a normal frame (the frame before the long one):

This happened while rotating the camera. Without moving the camera these long frames don’t happen.

2 Likes

Experiencing a similar issue where we’re generating a 3d dungeon from a tileset. The initial scene load causes several multi-second-long spikes of rendering opaque geometry (Batch.DrawInstanced is often upwards of 1000ms) and gets better after a while, but looking around will cause subsequent spikes as the instances come into the camera frustum.

2 Likes

I’m having a similar issue with several big frametime spikes in our game.
It runs fine otherwise, but at the beginning of the game there are several of these massive spikes that make the game stutter really hard.
After playing a while the stutters become less.

This is only a problem in WebGL, android and pc don’t have these problems for us.

1 Like

I’m also having the same problem when using terrain and instanced trees. Seems like when instanced objects get drawn for the first time there is a huge multi-second spike on Batch.DrawInstanced. (Only on WebGL)

2 Likes

Is that in 2020.2? I haven’t tried that version yet.

Yea, happens on 2020.2 as well as 2021.1b2

Hm, that’s very unfortunate. Has anyone filed a bug report for this yet?

We have seen really slow spikes like this on performance before. Investigation led to this ANGLE (== Chrome and Firefox common) issue: https://bugs.chromium.org/p/chromium/issues/detail?id=1072132#c17 .

You can try to debug if that is the case for you by running a Chrome or Firefox profiler over the slow path, and see where it hangs for several seconds. If the hang happens in glLinkProgram, then it strongly suggests that this problem is the cause. If the hang is somewhere else, then it suggests a different root cause.

2 Likes

Hi @jukka_j ,

I was reading through the issues on bugs.chromium.org and it looks like I have the same problem as described in the following:

https://bugs.chromium.org/p/angleproject/issues/detail?id=3682

If I understand correctly, a fix has been found for 3682 and commited on 9 Dec 2020. Is there a chance to find out if this fix should’ve already been shipped to browsers?

Also, in the issue you posted on Friday, there was a new comment by the devs that was probably addressed to you:

“Note, we’d still like to investigate this further. While we can probably instrument the browser or use an extension to grab all of the vertex and fragment shader sources, if Unity could easily provide those, that would help.”

Update:

I just managed to solve my “major hiccups while scrolling for the first time” problem by adding

#pragma instancing_options forcemaxcount:64

to my shader. After doing that my scrolling hiccups were completely gone while still benefiting from the GPU instancing performance boost. My average fps jumped from 25 (Built-In Renderer without GPU instancing) to 70 (Universal Renderpipline with GPU instancing and SRP batcher). That’s terrific!

1 Like

There is unfortunately no way to figure out which ANGLE version any given browser is using, except to ask Google directly.

I have noticed the comment, but have not been able to act on it, other things have been pressing on top to finish that investigation. Sorry about that.

1 Like

No problem, thanks for the update and good luck with that topic, seems like a difficult one.

I’m finding myself in the exact same situation. I am using Unity 2020.2.
No issues with the standalone windows build, but the WebGL build is unplayable sadly.

I believe I am having the same issue…

how did you find out that would help?

I don’t remember anymore, to be honest. It somehow made sense that I had too many objects to batch and then I tried out some instancing_options of which forcemaxcount appeared to be the closest to my problems. But it was more of a random lucky find. Did it help you too?

1 Like

Ok thanks and yeah it helped me too!

1 Like

Is this going to get fixed anytime soon? It’s making it so my game has way more drawcalls than necessary when on WebGL

Currently focused on making smooth experiences for WebGL and this is handicapping us so, oh, very so, so badly.