[vtk-developers] Proposed fix for vtkOpenGLTexture

Patrick Bergeron pbergeron at spiria.com
Tue Feb 19 11:48:17 EST 2019


Hello. I sent a recent email stating I needed to pass arbitrary data to a shader, encoded in a texture of float format.


Unfortunately, my shader only received texels with values clamped between 0-1.  As you can imagine, this is a problem.


I have traced the problem down to vtkOpenGLTexture::Load() function.


What Load() does is :

- Checks number of inputs. If 1, normal texture. If 6, cubemap texture.  (OK)

- Gets the image scalars (aka pixels) and number of components (aka: channels)   (OK)


- Calls MapScalarsToColor if not depth map, or if colormpde is Map_Scalars, or if datatype is NOT unsigned char.  (UGH!)


- Resizes the input of the source exceeds GL's internal dimension capacity. (OK)

- Resamples the image if needed. (OK)


- Creates a 1-channel floating point depth image, if it's a depth texture, by calling CreateDepthFromRaw(). (OK)

  (or, if not a depth map)

- Creates a 3 or 4-channel cube map, or normal texturemap, by specifying the new converted data type of VTK_UNSIGNED_CHAR.



There is actually very little to do to support arbitrary float data: Simply avoid remapping to unsigned char if the data is float (unless there's intentional remapping by using such ColorMode), and pass the actual format down to CreateXXXFromRaw()



My proposed change is to not convert incoming float data to unsigned char, but rather, to leave float color data alone.


Edit:


Change this (eg: remove red line)


        if (this->IsDepthTexture != 1 &&
          (this->ColorMode == VTK_COLOR_MODE_MAP_SCALARS ||
           inscalars->GetDataType() != VTK_UNSIGNED_CHAR ))
        {
          dataPtr[i] = this->MapScalarsToColors (inscalars);
          bytesPerPixel = 4;
        }

to this:

        if (this->IsDepthTexture != 1 &&
          (this->ColorMode == VTK_COLOR_MODE_MAP_SCALARS))
        {
          dataPtr[i] = this->MapScalarsToColors (inscalars);
          bytesPerPixel = 4;
        }


and these:

          this->TextureObject->CreateCubeFromRaw(
            xsize, ysize, bytesPerPixel, VTK_UNSIGNED_CHAR, vtmp);

          this->TextureObject->Create2DFromRaw(
            xsize, ysize, bytesPerPixel, VTK_UNSIGNED_CHAR, resultData[0]);


to these:

          this->TextureObject->CreateCubeFromRaw(
            xsize, ysize, bytesPerPixel, dataType, vtmp);


          this->TextureObject->Create2DFromRaw(
            xsize, ysize, bytesPerPixel, dataType, resultData[0]);



And that's all there is to it.

Does anyone have any objection?  The only side effect I can imagine is that more texture memory is consumed iff the source image data is float and no remapping is desired. With recent GPU hardware, I'd be surprised if this was a problem.

In any case, with this change, we can effectively pass unclamped arbitrary floating-point data buffers to shaders to be used for advanced viz techniques.

Thanks
Patrick Bergeron




[cid:4ef6fc93-3360-44ea-8ddb-1187a837e507]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://vtk.org/pipermail/vtk-developers/attachments/20190219/80922f96/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pastedImage.png
Type: image/png
Size: 40581 bytes
Desc: pastedImage.png
URL: <https://vtk.org/pipermail/vtk-developers/attachments/20190219/80922f96/attachment-0001.png>


More information about the vtk-developers mailing list