[SOLVED] Converting a pc.Texture into a HTMLImageElement

I’m trying to output a Render Target to an HTML object and use it in the browser / transfer over the network.

pc.Texture#getSource() returns null (presumably because this didn’t come from an asset but was rendered)

None of the graphics device readPixels-type implementations are exposed or look like they are uniformly supported (e.g. by WebGPU)

Is there a good way to do this?

1 Like

Hi, first you need to pass the texture to the render target, and then read it.

1 Like

Hi DareDevil!

Yeah as you’ve seen Engine v1 only has WebGLTexture.read().

Engine v2.0 has replaced this with a more complete async implementation which is supported across WebGL and WebGPU.

Ah yeah - ok got it.
So, for completeness - if you’re using WebGL, this works:

// this isn't public API yet
let pixelData = await texture.read(0,0, width, height);
// this won't ever be public API but can work in typescript builds...
//let pixelData = await texture.impl.read(0,0, width, height);
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
let idata = new ImageData(new UInt8ClampedArray(data), width, height);
ctx.putImageData(idata, 0, 0);
let url = canvas.getDataURL();
let image = Image(width, height);
image.src = url;

Oh actually the function is called texture.downloadAsync(). This is what model-viewer used up until recently (on engine v1) to support png download.

If your PNG contains alpha you might want to consider using something else as safari might still destroy image by pre-multiplying (and then un-premultiplying) alpha during this process.

Looks like it’s called read() in Engine v2?

But it isn’t a public API yet (and hence I can’t access it in my typescript build)

1 Like

Yes, engine v2 has read() function that is cross-platform, but as you noticed, it’s not public yet as it only has support for a limited combination of input parameters.

But you should be able to call it regardless, even when not exposed?

Yep, I’ve implemented it as in the code above.

Thanks guys.

1 Like