Nicolas
Nicolas

Reputation: 2281

Update uniforms or get data from fragment shader after image processing

I do some image processing in the fragment shader (thresholding) and I would like to access the result from JavaScript. Then I can save out the modified image using regular JavaScript.

I pass the original texture to be segmented to fragment shader as a uniform, then I do the thresholding. It renders properly on screen. Now I want to access the thresholded image in order to save it out.

I am not even sure that makes sense given the fact that fragment shader runs over pixels rendered of the screen.

I understand most of the constraints and I am wondering in general if there is a good technique to perform some heavy image processing in the fragment shaders and be able to get the processing results out of the shaders somehow.

One other use case I have in mind: flood filling from the mouse cursor, etc.

Javascript is too slow for me and maybe web workers could help but I was hoping to leverage the GPU to do my image processing.

(I am currently using THREEJS + custom shaders - probably not relevant but FYI)

Best, Nicolas

Upvotes: 0

Views: 179

Answers (1)

Kirill Dmitrenko
Kirill Dmitrenko

Reputation: 3649

There're two ways to solve your problem (if I understood the problem correctly). So, let's say we have a canvas. We render our processed image to that canvas. Now we can save the image as a JPEG or PNG blob:

canvas.toBlob(
    (blob) => {
        /* do something with the blob, i.e. send it to a server */
    },
    'image/jpeg',
    0.95
);

Or as data URL:

const imageAsDataUrl = canvas.toDataURL('image/png');

Also, if for some reason you want access to actual values of pixels of the image, you can read them via WebGL call (assuming, that gl is the context):

const pixels = new Uint8Array(4 * canvas.width * canvas.height);
gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

Upvotes: 1

Related Questions