gre/gl-react

[Feature Request] Uint8Array as a Texture

Lemon-King opened this issue ยท 6 comments

Hi I have a feature request,
I'm unable to utilize a Uint8Array as a source for a texture. Having this would be a flexible feature for some projects utilizing raw image data arrays both web and native.

For reference I'm using gl-react on react-native.

<Node
    width={nodeWidth}
    height={nodeHeight}
    shader={shaders.node}
    uniforms={{
        texture: { width: textureWidth, height: textureHeight: data: textureUint8Array },
    }}
    clear={null}
/>

Alrighty, after finally figuring this out and anyone like me poking around how to do this.

You'll want to use a library called NDArray and set it up as NDArray(Uint8Array, [width, height, 4]), assign it to a uniform that is referenced as a sampler2d in your shader code.

And for a few keywords for anyone googling this problem: putImageData, Uint8Array, imageData

Actually, gonna reopen this since it could use further documentation.

gre commented

๐Ÿ‘ btw i think it's [height,width,4] with NDArray, but well it depends how your data is aligned indeed.

It'd be great if there was an example showing how to use the Uint8Array to make a data texture, perhaps something to the effect of this tutorial? https://webglfundamentals.org/webgl/lessons/webgl-qna-how-to-get-audio-data-into-a-shader.html

@Lemon-King did you use ndarray node module for this?

I've tried to use ndarray(buffer, [width, height, 4]) as I also have a rgba array but I get a no loader found for value issue.

Edit: oh I am using reactjs also not native.

I had a Node with an OnDraw event which I used to capture the NDArray when there was a draw event.
From there I handled the NDArray like any other unclamped uint8array using some undocumented calls after a considerable amount of digging in the source.

This will return the NDArray from the node, from there you may have to flip it as it'll be in opengl uv space.

    <Node
        ref={"image_node"}
        width={100}
        height={100}
        shader={shaders.canvas}
        uniforms={uniforms}
        clear={null}
        onDraw={() => {
            let imageData: ndarray.Data<number> = this.refs.image_node.capture();
            // handle data as needed
        }}
    />