Set content of Texture(Array) from canvas

I am implementing a custom 2D overlay by drawing my overlay into a canvas and then use this to populate a RawTexture2DArray. Because RawTexture2DArray only accepts an ArrayBufferView to populate the contents of texture, I tried populating my texture using CanvasRenderingContext2D.getImageData(). This actually works, however, I figured out that:

It looks like I need to prepare a PR that adds support for this kind of data source. While I looked through the code I was wondering:

  • Is there a particular reason why the regular Texture does not accept a canvas as image source: Texture | Babylon.js Documentation
  • I see that the Texture internally keeps a reference to the buffer if _doNotHandleContextLostis not set. Is it safe to omit this? Otherwise I have to grab the canvas buffer as well in order to populate this ref.

What do you think? Did I miss anything?

Best regards


Heya, you can pass a canvas to the DynamicTexture’s constructor to create a texture from the canvas. Here’s a super simple example. Note, you need to call update() on the texture whenever the canvas changes to keep it up to date. :slight_smile: Or is that option not working out for you for some reason? :thinking:

I see that DynamicTexture is actually meant for this usecase. However, I struggle making it a 2D texture array. In my application, as soon as I change the code to the DynamicTexture and call texture.is2DArray = true; right after the constructor, I only get a an error of

INVALID_OPERATION: bindTexture: textures can not be used with multiple targets. This happens in thinEngine.js:3717

when calling
this._gl.bindTexture(target, texture?._hardwareTexture?.underlyingResource ?? null);

I guess this is because for some reason, the texture is already used as a non array texture. Maybe I need to unbind it first before setting it to an array. You can test this by adding

texture.is2DArray = true

after line 34 of the mentioned playground. You will see that the mesh becomes black as the standard material doesnt support an array texture, but the error is raised already from the new line 35, even before any code from the material is called.

Oooh oops, I missed that part… I’m actually only familiar with the normal 2D textures (using sampler2D and texture2D). IDK maybe that PR would be needed after all then? Let’s see what the texture gurus think. :slight_smile:

Lets see if @Evgeni_Popov has a trick for it or we d need to update our API to support it.

I think the DynamicTexture class (and the low level implementation in the thin engine / webgpu engine) will need to be updated if we want to support 2D array / 3D textures.

The is2DArray (/ is3D / isCube) property is not meant to be set by the end user, it is set by the 2D array texture constructor at creation time. I think we should make it clear by making the setter protected instead of public => Here’s a PR that should do it:

1 Like

Yeah, settings this in order to make the target a 2D array texture felt awkward in the first place, however, because there was a getter, I concluded that in principle the functionality is there and this was the only way I could find to tell it that I want a 2D texture array. I’d be surprised by myself if this was working.