How to use AdvancedDynamicTexture with offscreenCanvas

Hello everyone,

I achieved some good results with offscreenCanvas so far and I am able to pass most information like pointer events between threads. Right now I try to include some 2d gui to the scene but this leads to a problem with my offscreenCanvas because I cannot call .getContext(“2d”).

import { AdvancedDynamicTexture } from '@babylonjs/gui/2D'
const adt = AdvancedDynamicTexture.CreateFullscreenUI("UI")

“Uncaught (in promise) DOMException: Failed to execute ‘getContext’ on ‘HTMLCanvasElement’: Cannot get context from a canvas that has transferred its control to offscreen.”

Any ideas how to solve this?

Best

I am not sure where this could happen as the advanceddynamictexture should work on an offscreencanvas.

are you using 4.2 ?

And could you share a small repro ?

I found the issue. In my webworker I define:

self.document = {
	addEventListener: function (event, fn, opt) {
		bindHandler('document', event, fn, opt)
	},
	createElement: function () {
		return { onwheel: true }
	},
	defaultView: self.window
}

So the canvasGenerator doesn’t know that the canvas is offscreen due to:

if (typeof document === "undefined") {
    return new OffscreenCanvas(width, height);
}

document is defined and the function continues.

But I have to use self.document and self.window to be able to control the camera with pointer events.

I managed it like this: Babylon in worker

1 Like

This is not solved unfortunately :smiley:

It is not working with …

if (typeof document === "undefined")

… in canvasGenerator. Can you adjust the way bjs determines if it is an offscreenCanvas? In my case document is defined and I am still using offscreenCanvas.

But if you specify all the object in JS Babylon can not detect it which is normal and expected which is kind of expected. I guess other functionalities would be not working

Could you not simply in your code undefined the document before the creation and then reassign it ?

Not pretty but it might do the job

Yes, it is working with:

const documentTmp = document
document = undefined
this.advancedTexture = AdvancedDynamicTexture.CreateFullscreenUI("UI")
document = documentTmp

Do you know how to fix labels in offscreen?

Cannot set property ‘font’ of undefined

Control._GetFontOffset = function (font) {
        if (Control._FontHeightSizes[font]) {
            return Control._FontHeightSizes[font];
        }
        var text = document.createElement("span");
        text.innerHTML = "Hg";
        text.style.font = font;

Unfortunately those requires dom to get their size.

You could maybe find all your sizes during dev and prepopulate the array manually in your worker ???

Can you please explain how to do that?

Basically on the main thread or even offline you run the function I pasted before. Then you take what is in _ FontHeightSizes and send this to the worker or hard code it in. So that the function uses the cache instead of trying to compute it. If that works I ll make a public function to prepopulate it.

Thanks for your advise, I will try that.

1 Like