gpujs / gpu.js

GPU Accelerated JavaScript
https://gpu.rocks
MIT License
15.1k stars 652 forks source link

Exception passing 3d image from texture.toArray() as kernel arg #661

Open markebowles opened 3 years ago

markebowles commented 3 years ago

What is wrong?

Passing a 3d image ([480][640][4]) generated by texture.toArray() as an argument to another kernel generates an exception.

The HTML script block is:

window.onload = () => {
        const gpu = new GPU({ mode: "gpu" });
        const canvas1 = document.getElementById("canvas1");
        const ctx1 = canvas1.getContext("webgl2", { alpha: true, premultipliedAlpha: false });
        const canvas2 = document.getElementById("canvas2");
        const ctx2 = canvas2.getContext("webgl2", { alpha: true, premultipliedAlpha: false });

        // create and return a texture of blue pixels in canvas1
        load = gpu.createKernel(
            function () {
                return ([0, 0, 1, 1])
            })
            .setPipeline(true).setImmutable(true)
            .setOutput([canvas1.width, canvas1.height])
            .setCanvas(canvas1)
            .setContext(ctx1);

        // load an image into canvas2
        insert = gpu.createKernel(
            function (img) {
                const pixel = img[this.thread.y][this.thread.x];
                this.color(pixel[0], pixel[1], pixel[2], pixel[3])
            })
            .setOutput([canvas2.width, canvas2.height])
            .setGraphical(true)
            .setCanvas(canvas2)
            .setContext(ctx2);

        const blueTexture = load();
        const image = blueTexture.toArray();
        console.log(`image width: ${image[0].length}, height: ${image.length}, depth: ${image[0][0].length}`)
        insert(image);
    }

The exception is:

Uncaught Error: argument not found
    at r.lookupFunctionArgumentBitRatio (gpu-browser.min.js:14)
    at WebGL2FunctionNode.L [as lookupFunctionArgumentBitRatio] (gpu-browser.min.js:14)
    at WebGL2FunctionNode.astMemberExpression (gpu-browser.min.js:14)
    at WebGL2FunctionNode.astGeneric (gpu-browser.min.js:14)
    at WebGL2FunctionNode.astCallExpression (gpu-browser.min.js:14)
    at WebGL2FunctionNode.astGeneric (gpu-browser.min.js:14)
    at WebGL2FunctionNode.astExpressionStatement (gpu-browser.min.js:14)
    at WebGL2FunctionNode.astGeneric (gpu-browser.min.js:14)
    at WebGL2FunctionNode.astFunction (gpu-browser.min.js:14)
    at WebGL2FunctionNode.astFunctionExpression (gpu-browser.min.js:14)

Where does it happen?

Chrome browser with "latest" gpu.js (https://cdn.jsdelivr.net/npm/gpu.js@latest/dist/gpu-browser.min.js) on mac

How do we replicate the issue?

Jsfiddle: https://jsfiddle.net/t9Ljfevx/

How important is this (1-5)?

Seems like it should be a relatively common operation.

Expected behavior (i.e. solution)

The receiving kernel should have processed the array-from-texture successfully.

Other Comments

The application has a pipeline of image processing on the user camera on a laptop or phone, in a browser app. The pipeline starts with the HTML Video node connected to the camera, and ends with a canvas on the web page. We also wish to display the result of an intermediate step in the pipeline in a second canvas -- this requires extracting the image from the pipeline midway and writing it into a kernel attached to the second canvas.

This is my first gpu.js application, but I'm a decades-experienced software engineer in other genres. So, please insert typical noobie apologies by reference :-). Also, please let me know if I'm doing this the "hard way" somehow.