Multi-texture OBJ texture blending issue

Hi, I’m trying to load an OBJ file with more than one texture, using VTK 9.1.0 in Python. This post shows the basic idea and there is some further discussion here.

The following code shows the essential steps. Given a polydata object, an actor and a mapper, (vtkPolyData, vtkPolyDataMapper and vtkActor respectively), query the polydata field data to get the material names, then for each material load the appropriate texture file, link the texture to the material’s texture coordinates and set the texture on the actor's vtkProperty.

matNames = polydata.GetFieldData().GetAbstractArray('MaterialNames')
for n in range(matNames.GetNumberOfValues()):
    matName = matNames.GetValue(n)
    textureFilename = materials[matName]   

    tReader = vtk.vtkJPEGReader()
    tReader.SetFileName(textureFilename)

    texture = vtk.vtkTexture()
    texture.SetInputConnection(tReader.GetOutputPort())

    blendingMode = (
        vtk.vtkTexture.VTK_TEXTURE_BLENDING_MODE_REPLACE if n == 0 else vtk.vtkTexture.VTK_TEXTURE_BLENDING_MODE_ADD
    )
    texture.SetBlendingMode(blendingMode)
    texture.SetWrap(vtk.vtkTexture.ClampToBorder)

    tName = f'texture{n:01}'
    mapper.MapDataArrayToMultiTextureAttribute(
        tName,
        matName,
        vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS)

    actor.GetProperty().SetTexture(tName, texture);

This code works as expected as long as there are only two or fewer texture files. Once there are three or more the textures do not blend as expected, with the textures rendered earlier in the render process getting more and more saturated.

The following minimal OBJ example is a cube with a different material for each face:

mtllib cube.mtl
v -50.00 -50.00 50.00
v -50.00 50.00 50.00
v 50.00 -50.00 50.00
v 50.00 50.00 50.00
v 50.00 -50.00 -50.00
v 50.00 50.00 -50.00
v -50.00 -50.00 -50.00
v -50.00 50.00 -50.00

usemtl material_0
vt 1.00 1.00
vt 0.00 1.00
vt 0.00 0.00
vt 1.00 0.00
f 4/1 2/2 1/3
f 3/4 4/1 1/3

usemtl material_1
vt 1.00 1.00
vt 0.00 1.00
vt 0.00 0.00
vt 1.00 0.00
f 8/5 6/6 5/7
f 7/8 8/5 5/7

usemtl material_2
vt 1.00 1.00
vt 0.00 1.00
vt 0.00 0.00
vt 1.00 0.00
f 6/9 4/10 3/11
f 5/12 6/9 3/11

usemtl material_3
vt 1.00 1.00
vt 0.00 1.00
vt 0.00 0.00
vt 1.00 0.00
f 2/13 8/14 7/15
f 1/16 2/13 7/15

usemtl material_4
vt 1.00 1.00
vt 0.00 1.00
vt 0.00 0.00
vt 1.00 0.00
f 6/17 8/18 2/19
f 4/20 6/17 2/19

usemtl material_5
vt 1.00 1.00
vt 0.00 1.00
vt 0.00 0.00
vt 1.00 0.00
f 3/21 1/22 7/23
f 5/24 3/21 7/23

When the above Python code is used to map the same image to each face and render the cube, this is the result:

Only one face (the face assigned material_5) maps the texture correctly; the other five are more or less washed-out. (The expected outcome is a cube with the same image on each face.) If instead only two materials are used, the cube renders as expected.

Can anyone spot any errors in my approach, or is this likely to be a bug in VTK? Any help would be appreciated. I have a full working example if anyone would like to try it out, but cannot upload here as I am a new user :slight_smile:

Update

If the texture image is converted to PNG format with alpha channel (and loaded using a vtkPNGReader) the above issues disappear and the puppy image appears correctly on each face of the cube. Although this isn’t a viable workaround for the many scans with JPG texture images, it may point to the solution as having something to do with alpha transparency.

Looks like an actual issue, please open it on gitlab: https://gitlab.kitware.com/vtk/vtk/-/issues

FYI @ken-martin @Timothee_Chabat

Thanks @mwestphal . Issue created: https://gitlab.kitware.com/vtk/vtk/-/issues/18474.