mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.81k stars 35.38k forks source link

Texture from region of canvas #25669

Open ikerr opened 1 year ago

ikerr commented 1 year ago

Description

It would be handy if THREE.Texture / THREE.CanvasTexture allowed you to create a texture from a subregion of a canvas (I'd imagine this would also be useful for images). I'm attempting to filter very large canvases using GLSL (with dimensions greater than MAX_TEXTURE_SIZE), so the canvases need to be tiled. I'd like to be able to create a set of THREE.CanvasTexture instances where each one references the same canvas, but a different subregion of that canvas.

Solution

This looks to be possible with WebGL 2 using pixelStorei with UNPACK_SKIP_ROWS and UNPACK_SKIP_PIXELS (see https://stackoverflow.com/questions/20930466/webgl-is-there-an-efficient-way-to-upload-only-part-of-an-image-canvas-as-a-tex).

Perhaps these could be additional properties on THREE.Texture: unpackSkipRows, unpackSkipPixels.

Alternatives

Currently I need to create a separate canvas for each "tile" texture.

Additional context

No response

Mugen87 commented 1 year ago

I'm okay with adding the suggested texture properties. The names seems also fine since they match nicely to Texture.unpackAlignment. Do you want to make a PR?

ikerr commented 1 year ago

@Mugen87 Do we need a fallback for WebGL 1? These properties require WebGL 2. If so, for WebGL 1, I think the renderer would need to create an internal canvas for the texture, draw the subregion to the canvas, and then upload the internal canvas to the GPU.

Mugen87 commented 1 year ago

I would not add a WebGL 1 fallback and just note in the documentation that both properties require WebGL 2. We will eventually stop WebGL 1 support in the future. Besides, certain new features like 3D textures, MRT or morphing colors already require WebGL 2.

makc commented 1 year ago

if your canvas is not dynamic, you can use getImageData() result with 3js Texture