[HTML5] Switch between Canvas and WebGL through code

Hello,

is it possible to define through Javascript code (or other means) whether the openfl project will run in webgl or canvas? We would like to offer a canvas mode to our users based on some soft factors like performance or user choice and I assume this should be possible without uploading a second build.

Any input is appreciated, thanks in advance.

We support this in our NPM builds, I forget if choice of the runtime renderer is exposed right now in the Haxelib version.

If you use cacheAsBitmap or bitmapData.draw to force software rendering, then you could certainly do it using a custom parameter. In your lime.embed, set parameters: { } as an object with your own values, such as parameters: { forceCanvas: "true" } then use loaderInfo.parameters.forceCanvas == "true"; to check at runtime

Any chance you would expose the setting in haxelib for us? Setting cacheAsBitmap = true; on each object sounds like some overkill that we would like to avoid for now. We tried a simple cacheAsBitmap = true; on our bottom Sprite, but the performance impact is too heavy and we lose all the advantage of performance boost that we see when we use -Dcanvas.

Thanks in advance

What about doing it once on your top sprite, or calling bitmapData.draw once per frame, with all your other content off-stage?

Hey,

thanks for your reply. I am not sure I understand that correctly, can you clarify? We tried cacheAsBitmap = true on the topmost Sprite (i.e. the Main Sprite) but we see 20 FPS then instead of the 60 FPS that we see in -Dcanvas. (Could be the same 20 FPS that we also see in WebGL without cacheAsBitmap = true).

How would bitmapData.draw on an empty stage help? Does it mean a single call to bitmapData.draw forces the whole scene to be rendered on the Canvas? What about all the textures that (I assume) have been created on the GPU to be rendered in WebGL, they would be useless overhead, no?

Thanks

It might actually be possible to force canvas at runtime by doing { hardware: "false" } or { renderer: "canvas" } in the options within the lime.embed call. I’m doing a refactor of Lime that may help make this simpler, but I think these options may be respected even outside of NPM

Hi,

thanks a lot for this suggestion, it works! This means we can now switch between Canvas and WebGL based on a code check, nice!

However we tried to instantiate Away3D now in the hope that the build contains all the neccessary compilations to run the 3D scene. But when the renderer is set to Canvas, Away3D will stay black. I assume this is because the WebGL handler is not passed to Away3D or never created in the Canvas renderer.

Any chance you could make Away3D render in WebGL, even when the rest of the OpenFL scene is rendered in Canvas? Maybe it’s just a small change while you are refactoring this anyway. Just to clarify, we don’t need Away3D in Canvas, we just want Away3D rendering to WebGL, even when the rest of the project is drawing to Canvas.

Thanks in advance

It may be possible to do that using -Ddom, we can layer a BitmapData (using bitmapData.draw for rendering with canvas) with a Stage3D layer (using a second WebGL canvas), but when targeting canvas, we do not use WebGL, so Stage3D is unsupported

An older version of Away3D (like Away3D 3, I think) that worked with the Flash 10 API (not Stage3D) might be able to work in canvas as well, though I think it could be slow

Okay just for my understanding, is it completely theoretically impossible to combine OpenFL -Dcanvas with Away3D rendering in WebGL or is it just not possible right now with the current OpenFL build? Sorry if that is a stupid question but I don’t have much experience with HTML5 rendering. If it would be possible to combine both renders in theory, then that is something we might look into and maybe add that support in Away3D.

Background: Our game performs much faster in Canvas (we assume due to heavy use of fonts) but we have an ingame view in 3D that needs to render in Away3D nontheless. Therefore we would like to have the menu rendering in Canvas but the ingame scene in WebGL / Away3D.

Thanks in advance

Use of bitmapData.draw creates a Canvas renderer on HTML5, and draws to a BitmapData (which is a canvas on HTML5). You can use this to combine the canvas renderer with other render types

1 Like