Refraction texture limit per scene?


warning, pg contains 20 bathtubs off screen, you may experience a fps hit.

I am experiencing in chrome perceptible fps drops with multiple water meshes, each with its own refraction texture/settings and all sharing the same depthtex. The fps hit happens only once when the water mesh is in the view frustrum. Thereafter it goes away. It also does not manifest consistently, ie, there are runs when I don’t feel the drop and times where it is consistent every load.

question: is there a code limit to the number of refraction textures per scene? If not, is there a best practice for having multiple refraction RTTs ?

1 Like

ping @Evgeni_Popov

No, there’s no limit on the number of textures that can be generated in a RenderTargetTexture per frame (except the GPU memory limit).

I don’t reproduce the problem, even when switching to a view where all 20 thubs are visible at the same time:

The number of compiled effects before and after the switch stays the same (4), so the hiccups is not related to shader compilation.

If this doesn’t always happen, could it have something to do with what’s going on with your system (antivirus triggering, etc.)?

I have a distinct hit with 200 tubs:

This number is really outlier case. At 100 tubs, I don’t get 60fps anymore. Then again, this scene is simple. I’m getting the vibe that its one of those perf spikes that’s not easy to isolate/track down.

yh, it might be, certainly not antivirus, more likely tab switching or stuff that chrome does behind the scenes or graphics driver…pesky stuff

This time I do have some slow down, but it’s not a spike, it’s simply too much work for 60fps, so the frame rate is lower.

Note that all the refraction textures are rendered each frame, even if no tubs are visible! You may want to check the visibility of the tubs and populate scene.customRenderTargets for the visible tubs only.

Yes, this is exaggerated case (200 tubs is just crazy). I have an idea! Since seedborn is playable as guest, you can try it live! Just do a slow mouse click and drag around the starting island, especially around the sea. There should be a point where its jerky (somewhere southwards).

I did a performance snapshot in Chrome and got:

The green timeline is the GPU timeline.

It seems quite alike (even if it’s not in the same context):

I don’t know why the GPU would suddenly run continuously a whole 150ms at a specific point of time, and then continue normally…

Maybe there are some new visible parts of the scene that are using textures not used until that point that are only uploaded to the GPU at this moment, because the driver defered the upload?

To test this scenario, you could try to remove all textures from your scene and see if this fixes it.

The depth texture renderlist contains the terrain and a wooden dock southwards. So as you drag the wooden dock into the view frustrum, that’s where the spike consistently hits once then its gone. And the depthTex is responsible for the foam on the sea so the dock has foam.

There are actually 7 water meshes of different sizes in the scene, which means 7 refraction textures, 2 lights, csm, some color post, 1 ortho cam. But water is the primary bottleneck. With end-game mesh heavy savefiles (>1k), if the meshes do not interact with the water, I can get above >30fps all day in chrome. If they do interact, the fps stutters. Granted I haven’t optimized fully for perf yet, so there may still be some leeway.

I will disable the materials tomorrow and test. Time to hit the sack.
Thanks for the continued support!

I can confirm that its NOT related to textures. And I’m happy to say that I got a consistent repro, and its nothing to do with water!

Two spheres are loaded out of view. Drag the view around slowly while watching the fps, once the 2 spheres come into view, you should see the fps stutter. This only happens in chrome, not in ffox and across all versions from 4.2.1 to latest.

The problematic line is sphere1.receiveShadows = true;. There is no issue if the parent is also receiving shadows, or only the parent is receiving shadows. I do not know if this helps your other observed issues but since its browser specific, its prolly a lead.

It’s a problem with Angle in Chrome.

If you set the Angle setting to OpenGL, the stuttering disappears.

Here’s a PG that makes it easier to test, as you don’t need to move the camera yourself:

If you browse chrome://flags and do:

You will see you don’t have stuttering anymore (after restarting the browser).

Unfortunately, we can’t do anything about it…

1 Like

Was wondering why angle was shipped as default, so I did some perf collection on a mesh heavy scene (also cos I hadn’t done one in a while).


Turns out other than the minor gpu improvement, everything else is comparable. Angle is slightly better gpu perf at the expense of stuttering?

Looking at the numbers, I wonder if there is a different approach specific to rendering mesh heavy scenes we could use, hmm…

Actually, it’s not Angle vs OpenGL.

Angle is a framework that implements OpenGL ES for different OSs. You can configure Angle to use a specific graphics API, depending on the OS. On Windows, you can configure it to use Direct3D9, Direct3D11, Direct3D11on12 and OpenGL. In Chrome, the default setting is to use either Direct3D11 or Direct3D11on12 I think.

So, Chrome/Angle is really Chrome/Direct3D in your screenshot if you are using Windows. It’s Metal if you are using Safari => all major browsers (Chrome, Firefox, Safari) are using Angle.

You can try to report an issue about it in the Chromium bug tracker: Monorail - chromium - An open-source project to help move the web forward. - Monorail

1 Like

I didn’t read the fine print, so its Direct3D11 vs OpenGl. Got it, thks!

As of v116 chrome update this morning, the stutter is no longer apparent in the repro. I’m marking as solved. Thanks @Evgeni_Popov for all the help! I’m a happy dev today, woohoo!