# How can I optimize the volume rendering code based on the webGL: max\_texture\_size of the web-browser so that it can render image in any web browser?

**URL:** https://discourse.vtk.org/t/how-can-i-optimize-the-volume-rendering-code-based-on-the-webgl-max-texture-size-of-the-web-browser-so-that-it-can-render-image-in-any-web-browser/8938
**Category:** Web
**Created:** [July 12, 2022, 3:53pm UTC](https://discourse.vtk.org/t/how-can-i-optimize-the-volume-rendering-code-based-on-the-webgl-max-texture-size-of-the-web-browser-so-that-it-can-render-image-in-any-web-browser/8938 "2022-07-12T15:53:56Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Yuvi-416](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yuvi-416/32/3864_2.png) [@Yuvi-416](https://discourse.vtk.org/u/Yuvi-416)
#### Post date: [July 12, 2022, 3:53pm UTC](https://discourse.vtk.org/t/how-can-i-optimize-the-volume-rendering-code-based-on-the-webgl-max-texture-size-of-the-web-browser-so-that-it-can-render-image-in-any-web-browser/8938/1 "2022-07-12T15:53:56Z")

</div>

Hello everyone,  
I am trying to render a volumetric (volume dimensions: [5861, 3429, 27]) image into desktop Google Chrome using the volume rendering method (vtkVolumeMapper), but I am encountering the following webGL error:

```auto
WebGL: INVALID_VALUE: texImage3D: width, height or depth out of range
e.create3DFromRaw @ vtk.js:2
e.create3DFilterableFromRaw @ vtk.js:2
e.buildBufferObjects @ vtk.js:2
e.updateBufferObjects @ vtk.js:2
e.renderPieceStart @ vtk.js:2
e.renderPiece @ vtk.js:2
e.volumePass @ vtk.js:2
e.apply @ vtk.js:2
e.traverse @ vtk.js:2
GK.e.traverseVolumePass @ vtk.js:2
e.traverse @ vtk.js:2
e.traverse @ vtk.js:2
KL.e.traverse @ vtk.js:2
e.traverseAllPasses @ vtk.js:2
c @ vtk.js:2
Vm.e.render @ vtk.js:2
Vm.e.initialize @ vtk.js:2
volume_rendering @ index_render_options.js:495
(anonymous) @ index_render_options.js:1572
Promise.then (async)
vol_processFile @ index_render_options.js:1564
(anonymous) @ (index):1158
dispatch @ jquery-3.6.0.min.js:2
v.handle @ jquery-3.6.0.min.js:2

```

I looked into the problem to understand more, and I found that the texture I’m trying to render is larger than the GPU can handle, which is why I’m getting this error.  
Therefore, I checked the webGL properties of the desktop chrome and found the below info:

```auto
Textures:
Max Texture Size:	16384
Max Cube Map Texture Size:	16384
Max Combined Texture Image Units:	64
Max Anisotropy:	16
Max 3D Texture Size:	2048
Max Array Texture Layers:	2048
Max Texture LOD Bias:	15

```

When I try to render same image in my laptop with exactly same code on chrome which has below max texture support it render without a problem:

```auto
Textures:
Max Texture Size:	32768
Max Cube Map Texture Size:	32768
Max Combined Texture Image Units:	64
Max Anisotropy:	16
Max 3D Texture Size:	16384
Max Array Texture Layers:	2048
Max Texture LOD Bias:	15

```

I noticed that the texture size restriction was the cause of the error I was experiencing in desktop Chrome. I now want to take some action to optimize the volume rendering code and render it on both devices without running into texture limitation issues. How can I achieve it?

Any suggestion would be appreciated.

I am getting this error when I run volume rendering code, but I don´t get these errors for isosurface plot.  
Thank you!

---

<div class="post-metadata">

### Author: ![Forrest](https://discourse.vtk.org/user_avatar/discourse.vtk.org/forrest/32/300_2.png) [@Forrest](https://discourse.vtk.org/u/Forrest)
#### Post date: [July 12, 2022, 9:47pm UTC](https://discourse.vtk.org/t/how-can-i-optimize-the-volume-rendering-code-based-on-the-webgl-max-texture-size-of-the-web-browser-so-that-it-can-render-image-in-any-web-browser/8938/2 "2022-07-12T21:47:25Z")

</div>

You can consider downsampling your volume. You would get a more manageable data size at the cost of dataset resolution. I’m not sure what you can do to try to optimize the volume rendering code, so downsampling would be my first approach.

---

<div class="post-metadata">

### Author: ![Yuvi-416](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yuvi-416/32/3864_2.png) [@Yuvi-416](https://discourse.vtk.org/u/Yuvi-416)
#### Post date: [July 13, 2022, 1:39pm UTC](https://discourse.vtk.org/t/how-can-i-optimize-the-volume-rendering-code-based-on-the-webgl-max-texture-size-of-the-web-browser-so-that-it-can-render-image-in-any-web-browser/8938/3 "2022-07-13T13:39:42Z")

</div>

Hi,  
Thanks for the reply.  
I tried to downsample the volume by applying vtkImageReslice but it does not seems to work:

```auto
           down_sample = vtk.Imaging.Core.vtkImageReslice.newInstance();
            Interpolator = vtk.Imaging.Core.vtkImageInterpolator.newInstance();
            down_sample.setInputData(volume_imageData[i]);
            const ss = 0.5;
            down_sample.setOutputSpacing(ss, ss, ss);
            const imageResampled = down_sample.getOutputData();
            console.log('imageResampled', imageResampled)

```

I am getting error in imageResampled as: Uncaught (in promise) TypeError: Cannot read properties of null (reading ‘0’)

Can you provide me an example of performing down-sample? And also can you explain why I am getting GPU max\_3D\_texture\_size error in volume rendering but not in surface rendering?  
Thank you.

---

<div class="post-metadata">

### Author: ![Forrest](https://discourse.vtk.org/user_avatar/discourse.vtk.org/forrest/32/300_2.png) [@Forrest](https://discourse.vtk.org/u/Forrest)
#### Post date: [July 13, 2022, 6:31pm UTC](https://discourse.vtk.org/t/how-can-i-optimize-the-volume-rendering-code-based-on-the-webgl-max-texture-size-of-the-web-browser-so-that-it-can-render-image-in-any-web-browser/8938/4 "2022-07-13T18:31:11Z")

</div>

Can you provide the full stacktrace of your error?

The entire volume gets loaded into a texture, whereas surface rendering is geometry. Hence the memory differences.

---

<div class="post-metadata">

### Author: ![Yuvi-416](https://discourse.vtk.org/user_avatar/discourse.vtk.org/yuvi-416/32/3864_2.png) [@Yuvi-416](https://discourse.vtk.org/u/Yuvi-416)
#### Post date: [July 14, 2022, 10:19am UTC](https://discourse.vtk.org/t/how-can-i-optimize-the-volume-rendering-code-based-on-the-webgl-max-texture-size-of-the-web-browser-so-that-it-can-render-image-in-any-web-browser/8938/5 "2022-07-14T10:19:04Z")

</div>

Hi,  
Here you go.

```auto
for (i = 0; i < volume_imageData.length; i++){

            volume_vtk = vtk.Rendering.Core.vtkVolume.newInstance();
            volumeMapper = vtk.Rendering.Core.vtkVolumeMapper.newInstance();
            volumeProperty = vtk.Rendering.Core.vtkVolumeProperty.newInstance();
            ofun = vtk.Common.DataModel.vtkPiecewiseFunction.newInstance();
            ctfun = vtk.Rendering.Core.vtkColorTransferFunction.newInstance();

            // Load the Input
            dataRange = volume_imageData[i].getPointData().getScalars().getRange();
            dimensions = volume_imageData[i].getDimensions()
            console.log('volume dimensions', dimensions)
            const spacing = volume_imageData[i].getSpacing()
            console.log('volume spacing', spacing)

            ///////////
            down_sample = vtk.Imaging.Core.vtkImageReslice.newInstance();
            //Interpolator = vtk.Imaging.Core.vtkImageInterpolator.newInstance();
            down_sample.setInputData(volume_imageData[i]);

            const ss = 0.5;
            down_sample.setOutputSpacing(ss, ss, ss);
            // down_sample.setInterpolationModeToCubic();
           imageResampled = down_sample.getOutputData();
           console.log('resampp', imageResampled)
            //console.log(down_sample.getOutputExtent())
            // console.log('down_sample', down_sample)
            /////////////////

            // Calculating Pixel range
            ii_0 = parseInt(dataRange[0])
            ii_mid = parseInt(dataRange[1] / 2)
            ii_1 = parseInt(dataRange[1])

            // Define PieceWise transfer function
            ofun.removeAllPoints();
            ofun.addPoint(ii_0, 0.0);
            // ofun.addPoint((ii_0[0] + ii_1[1]) * 0.5, 0.5);
            console.log(ofun);
            ofun.addPoint(ii_1, 1.0);

            // #####################################################################
            min = ii_0;
            console.log(min);
            max = ii_1;
            console.log(max);
            temp = 0

            for (t = min; t <= max; t++){
                    newVal = parseInt(((t-min)/(max-min)) * 255);
                    if (newVal != temp) {
                        // console.log(t);
                        rgb = searchvalue(newVal, mycolor);
                         //print(i, r, g, b)
                        // console.log(rgb[0]);
                        ctfun.addRGBPoint(t, rgb[0], rgb[1], rgb[2])
                        // console.log(temp);
                        temp = temp + 1
                    }
            }

            // Define Volume Property
            volumeProperty.setRGBTransferFunction(0, ctfun);
            volumeProperty.setScalarOpacity(0, ofun);
            volumeProperty.setShade(true); // Increase the lights
            volumeProperty.setInterpolationTypeToLinear();
            volumeProperty.setAmbient(0.7);
            volumeProperty.setDiffuse(0.7);
            volumeProperty.setSpecular(0.3);
            volumeProperty.setSpecularPower(30.0); // setSpecularPower(1.0, 1.0, 1.0);
            volumeProperty.setOpacityMode(0, 20);
            volumeProperty.setIndependentComponents(true);
            volumeProperty.setUseGradientOpacity(0, true); // Helps to make image translucent
            volumeProperty.setGradientOpacityMinimumValue(0, 3.5);
            volumeProperty.setGradientOpacityMinimumOpacity(0, 0.0);
            volumeProperty.setGradientOpacityMaximumValue(0, 20);
            volumeProperty.setGradientOpacityMaximumOpacity(0, 1.0);

            volumeMapper.setInputData(volume_imageData[i]);
            // volumeMapper.setSampleDistance(0.4);
            volumeMapper.setMaximumSamplesPerRay(4000)

            // Define vtkVolume
            volume_vtk.setMapper(volumeMapper);
            volume_vtk.setProperty(volumeProperty);

            renderer.addActor(volume_vtk);

            volume_opacity_val[i] = volumeProperty
            volume_sample_Distance[i] = volumeMapper
            volume_visibility_control[i] = volume_vtk
            console.log(volume_visibility_control[i])
      }

```

Error:  
It gives me below error on **imageResampled = down\_sample.getOutputData()** :  
Uncaught (in promise) TypeError: Cannot read properties of null (reading ‘0’)

I also would like to ask you one more question regarding a addRGBPoint transfer function. Currently, I am passing the color points from the matplotlib library to addRGBPoint and it works but it does have all color which i want and the color are also not so dynamic. So do you know any other library which i can use to pass color points into it as i know volume render plot depends on the pixel intensity not a solid like in isosurface. Before I tried to pass VTK color but i didn’t get succeed and I also didn’t find any example.
