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:
We’d really like batching because we’ve got a bunch of grass models with the same materials (partially transparent for the record)
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?
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.
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.
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)
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.
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.”
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!
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.
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 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?