Jump to content

Watch out for gl.clear()!


FunFetched
 Share

Recommended Posts

Hello, everyone! I just wanted to pass along some very important information that I just discovered regarding optimization that has been completely overlooked in optimization articles that I've read, and can have a huge impact on your apps!

I have a game that pushes a pretty similar number of triangles and commands as the Sponza demo, but I wasn't enjoying anywhere near the same frame rate on slower systems. I fired up SpectorJS, cleaned up as much as I could in terms of draw calls and such, and wound up with a game that had fewer calls, fewer commands, and yet STILL ran a good deal slower than Sponza. However, there was one more metric that I had yet to take a close look at, and that was "clear()". I had 6 of them, while Sponza was using only 1.

My game is a first-person-shooter that uses an additional camera to draw UI components, and on a different layer, so game geometry doesn't interfere with it. The player's hands and weapons are also drawn in a different rendering group for the same reason. It turns out, however, that for every new layer and group, Babylon kicks off a gl.clear() (which makes sense), and on systems with poor fill rates, this can absolutely wipe you out.

In my case, the engine was clearing various buffers 6 times per frame, including multiple times per group/layer. Disabling Babylon's engine.prototype.clear() entirely made a world of difference in terms of FPS, though I do need at least 1 or 2 gl.clear() calls to accommodate my layering requirements. 6 is excessive and unnecessary, however, and I'm currently investigating ways to minimize that. Hopefully, I can do it all by simply modifying my code, but I suspect I might have to make some small engine modifications as well so I have greater control over when gl.clear() gets called, and just how many times.

Edit: Just discovered scene.autoClear and scene.autoClearDepthAndStencil. Setting both to false takes care of... well... one of them!

Link to comment
Share on other sites

This is a good catch!

would you be ok to add this to the otpimization articles?

https://github.com/BabylonJS/Documentation/blob/master/content/How_To/scene/Optimizing_your_scene.md

 

as you mentioned the clear is controlled by scene.autoClear. You also have the same at render target level with texture.autoClear

Link to comment
Share on other sites

17 minutes ago, Deltakosh said:

This is a good catch!

would you be ok to add this to the otpimization articles?

https://github.com/BabylonJS/Documentation/blob/master/content/How_To/scene/Optimizing_your_scene.md

 

as you mentioned the clear is controlled by scene.autoClear. You also have the same at render target level with texture.autoClear

Absolutely! I also discovered scene.setRenderingAutoClearDepthStencil() to control clearing for each RenderingGroup. However, I also found this:

			// Multi-cameras?
			if (this.activeCameras.length > 0) {
				for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
					if (cameraIndex > 0) {
						//this._engine.clear(null, false, true, true);
					}
					this._processSubCameras(this.activeCameras[cameraIndex]);
				}
			}

... this is tricky, as there are some edge cases where you might not want this. In my case, I have some UI rendering with an Ortho camera with a different layerMask. Since it's all rendered at Z=0, I don't need (or even want) the depth or stencil buffers cleared before it's rendered. As you can see, I've commented it out temporarily for the app I'm working on. It might be a good idea to add an autoClear option to BABYLON.Camera as well.

In any case, I'm now down to one gl.clear() in my game (width shadows disabled), and have gained a good 20FPS on my cheap little test Chromebook. :) 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...