Three.js: Multiple mirrors in a scene kills performance

Created on 1 Sep 2017  路  16Comments  路  Source: mrdoob/three.js

TL;DR: After v85, having more than a handful of mirrors in a scene seriously reduces rendering performance.

Copy of https://stackoverflow.com/questions/45990275/multiple-mirrors-in-a-three-js-scene-kills-performance:

Based on the mirror example, I have recreated a good old praxinoscope "movie projector", where a column of mirrors reflect a short sequence of images to create the illusion of movement.

In version 84, this works quite well.

Example using v84: https://codepen.io/Sphinxxxx/pen/eEbjba
enter image description here

In version 85 however, there were some changes to Mirror.js, and in later versions all the mirrors (8 mirrors in this case) make the praxinoscope really slow (low FPS).

Example using v87: https://codepen.io/Sphinxxxx/pen/vJvozR
enter image description here

I suspect the slow performance has to do with a lot of recursive calls and unneeded rendering starting with calls to a onBeforeRender() function from Mirror.js. Stacktrace:

enter image description here

If you look at the code, mirrors are created and added in the addMirrorAndImage() function. Is there a better way to add mirrors, or some other trick that will give the same performance as the older (pre v85) version?

All 16 comments

I'll look into this. Many thanks for the examples!

Okay... I think the issue is that, somehow, the older code didn't render when the mirror was facing away the camera.

Fixed! 7dc8fa56f5106b51248f30115c7e884a3f8f6c91

Thanks, but sadly it's still not close to the same performance as v84. For these eight mirrors, the dev version runs well, but if you increase the number of mirrors, things slow down fast.

For example, change FRAMES_X to 6 in the JS code - this gives us 24 mirrors (the animation won't make sense anymore, but that's irrelevant). v84 will still run smoothly, but dev slows to a crawl. Even at 16 mirrors (FRAMES_X = 4), dev is noticeably slower.

I'll look into it 馃挭

I think it's because when FRAMES_X = 4 the mirrors see each other, so it produces 1 level of recursivity, which r84 didn't do.

Can you modify your code so there are more mirrors but that they don't see each other?

The outer ring (orange) shouldn't reflect anything, so I don't think the mirrors can see each other no matter how many there are. Here is a sketch of the scene from above. The mirrors are blue, and what the camera sees is pink:

prax-sketch

And here is a fork that may make it easier to see how the mirrors are placed. I also added a little space between each mirror, to make sure there are no overlapping edges;

https://codepen.io/Sphinxxxx/pen/KvjLaB?editors=0010

Working on it.

I guess I needed a weekend "off".

https://codepen.io/anon/pen/brPRGz
https://codepen.io/Sphinxxxx/pen/KvjLaB?editors=0010

In your particular case (half of the mirrors looking away) the latest version should actually be ~2x faster than r84 馃槉

Looking really good, thanks a lot!

If I read the code correctly, the fix was to add a "levels of rendering recursion" parameter. Does that mean there's no way to detect whether two mirrors see each other, and thus actually need recursion?

Well... If two mirrors see each other the level of recursion would be infinite. We can't do infinite renders and stay at 60fps 馃槈

So, for the time being, I think the best option is to add a parameter for the user to adjust for their use case.

Sure, there needs to be a max level, but I was wondering if it was possible to detect that no recursion was necessary (like in this case). I was just asking out of curiosity though, having a parameter should work for most cases.

I bet there is a way to detect it, but I have to move to other things unfortunately. With your example I noticed texture.offset/texture.repeat are broken on dev 馃檨

Alright. #12063 fixed it.

Great! However, I haven't noticed anything wrong with the praxinoscope. Was that issue unrelated to how I use offset/repeat here?

No. It was only in dev. You can ignore it now 馃槉

Was this page helpful?
0 / 5 - 0 ratings