Anson Chan
Anson Chan

Reputation: 25

(Three.js) Bloom effect performance

It has 50-60fps, if there is no bloom effect.

renderer.render( scene, camera );

Then, just have 10fps after added bloom effect.

camera.layers.set( BLOOM_SCENE );
bloomComposer.render();
camera.layers.set( ENTIRE_SCENE );
finalComposer.render();   

How can i fix it? demo link is here https://codepen.io/anson-chan/pen/QXeKqm?editors=1010

Upvotes: 1

Views: 1443

Answers (1)

manthrax
manthrax

Reputation: 5036

There are a few different problems here.

You have a LARGE number of cubes in your scene. Each cube is a unique material and drawCall. To keep a scene fast, you want to keep the number of drawcalls around 500 or so, and the number of polygons at or below around 1.5 million. This is called being "draw call bound". There are some strategies for dealing with this... such as using hardware instancing and/or a library like THREE.BAS to do instancing of your cubes. These techniques can render LARGE numbers of objects with a single draw call, and may help you.

(https://github.com/zadvorsky/three.bas)

(http://three-bas-examples.surge.sh/examples/instanced_prefabs/)

Next up: your resize handler is always resizing to the bounds of the window.. not the size of the actual canvas. You are also NOT resizing the actual renderPasses in your code. Each pass that has a width/height parameter also needs to be resized, along with the effectsComposer itself, and presently always resizing to the size of the window.. not the size of the actual canvas area your are rendering.

Instead, try something like renderer.resize(renderer.domElement.width,renderer.domElement.height,false) Then control the canvas resizing via css rules, and then make sure your blurPass size is set, and the effectsComposer size is also set. The 'false' parameter on the resize method prevents THREE from setting the width/height of the canvas style, and allows you to control it explicitly. Otherwise, you can have problems of your size changing triggering additional resizes when THREE tries to change the CSS of the canvas to the new width/height you're passing. This problem is causing you to render a full window sized canvas and effects pass no matter what the display size it.

The next issue is that blur/bloom is an inherently costly operation.. since it requires scaling down the entire framebuffer a few times to generate the blurred/bloomed version of the effect. This is compounded by the sizing problem mentioned above ^

Next up... I don't know what hardware you are running on, but if it's a retina display.. your devicePixelRatio will be greater than 1, in which case it further compounds the display sizing problems, since on a retina display, a devicePixelRatio of 2 will cause the renderer to render 4x as much as a devicePixelRatio of 1. You may want to consider using 1 instead of whatever you get from window.devicePixelRatio.

All of these issues compound each other. GPU's can only do so much, so you have to be clever how you manage them and what kind of loads you place on them.

Hope this helps.

Upvotes: 2

Related Questions