vtkScalarToRGBA Performance

(Donny Zimmerman) #1

I am loading a 2000 x 2000 8bpp texture through the vtkScalarToRGBA filter. The first render takes between 15 to 20 seconds to render. The interaction performance is great after that first render finishes. I stepped through the code and this section in the vtkScalarToRGBA requestData function is what takes so long:

for (var idx = 0; idx < data.length; idx++) {
var x = data[idx];
model.lookupTable.getColor(x, rgba);
rgba[3] = model.piecewiseFunction.getValue(x);
rgbaArray[offset++] = 255 * rgba[0];
rgbaArray[offset++] = 255 * rgba[1];
rgbaArray[offset++] = 255 * rgba[2];
rgbaArray[offset++] = 255 * rgba[3];

This iteration happens 4,000,000 times (2000 x 2000 texture). I am not very proficient at javascript yet, but is there any way to use pointers to access the lookupTable and piecewiseFunction instead of the call to getColor() and getValue() respectively? Would pointer references speed this process up?

Any help is appreciated.

(Donny Zimmerman) #2

After digging a little further I discovered it has nothing to do with “pointers”. I forgot how much functionality that the ScalarToRGBA filter has. There are alot of calculations going on. I think I might replace my use of the ScalarToRGBA filter with some basic index lookup logic to manually create the imagedata.

(Sebastien Jourdain) #3

That filter was made to help someone to get transparency on some slice. All of that can be achieved by the GPU but it is not yet implemented.

(Donny Zimmerman) #4

Thanks Seb,
I can see where that filter would be needed, but it was overkill for my task. I was able to get the initial render time down to about 1 second with the following:

const buffer = new Uint8Array(canvas.width * canvas.height * 4);
const ibuffer = idata.data;

        /*the size of the image in bytes */
        const size = idata.width * idata.height;

        var index = 0;

        for (var i = 0; i < size; i += 1) {
            let ind = ibuffer[i];
            buffer[index++] = colors[ind].R;
            buffer[index++] = colors[ind].G;
            buffer[index++] = colors[ind].B;
            if (ind <= 20) {
                buffer[index++] = 0;
            else {
                buffer[index++] = 255;
(Donny Zimmerman) #5

Check out what I have so far using vtk.js. This library is so awesome and I see so many possibilities. Thanks for a the work you guys put into it. Might have to scroll down to bottom of screen and select “desktop view” if using mobile phone.


1 Like
(Sebastien Jourdain) #6

Thanks for sharing your work. That looks great.

I’m glad that you see some value and benefit in vtk.js.