Texture mapping on a polygon

Hello,

I am working on replacing the Visualization in our legacy application that earlier used OpenGL and trying to use VTK as a replacement.

When applying a texture to a polygon as shown below, the texture image does not appear as I am expecting and gets distorted as shown in the below image

Here is my VTK code

  ```
    // Step 1: Read Image Data
    vtkSmartPointer<vtkImageReader2Factory> readerFactory = vtkSmartPointer<vtkImageReader2Factory>::New();
    vtkSmartPointer<vtkImageReader2> imageReader = readerFactory->CreateImageReader2("D:\\Temp\\MyTestImage2.jpg");
    imageReader->SetFileName("D:\\Temp\\MyTestImage2.jpg");
    imageReader->Update();

    // Step 2: Convert Image Data to Image Mapper...
    m_imageMapper = vtkSmartPointer<vtkImageMapToColors>::New();
    m_imageMapper->SetInputConnection(imageReader->GetOutputPort());
    m_imageMapper->SetLookupTable(m_lookupTable);
    m_imageMapper->Update();

    // Step 3: Create Texture from image mapper....
    m_texture = vtkSmartPointer<vtkTexture>::New();
    m_texture->SetInputConnection(m_imageMapper->GetOutputPort());
    m_texture->RepeatOff();
    m_texture->InterpolateOn();

    // Step 4: Initialize Points
    m_points = vtkSmartPointer<vtkPoints>::New();
    m_points->InsertNextPoint( 0.0, 0.0, 0.0);
    m_points->InsertNextPoint(-0.5, 0.0, 0.0);
    m_points->InsertNextPoint(-2.0, -0.5, 0.0);
    m_points->InsertNextPoint(-1.0, -1.0, 0.0);

    unsigned int numPoints = 4;

    // Step 5: Create a polygon
    m_polygon = vtkSmartPointer<vtkPolygon>::New();
    m_polygon->GetPointIds()->SetNumberOfIds(numPoints);
    for (unsigned int i = 0; i < numPoints; i++)
    {
        m_polygon->GetPointIds()->SetId(i, i);
    }

    m_polygons = vtkSmartPointer<vtkCellArray>::New();
    m_polygons->InsertNextCell(m_polygon);

    m_polyData = vtkSmartPointer<vtkPolyData>::New();
    m_polyData->SetPoints(m_points);
    m_polyData->SetPolys(m_polygons);

    // Step 6: Add texture coordinates
    vtkSmartPointer<vtkFloatArray> textureCoordinates = vtkSmartPointer<vtkFloatArray>::New();
    textureCoordinates->SetNumberOfComponents(2);
    textureCoordinates->SetName("TextureCoordinates");
    textureCoordinates->InsertNextTuple2(0.0, 0.0);
    textureCoordinates->InsertNextTuple2(1.0, 0.0);
    textureCoordinates->InsertNextTuple2(1.0, 1.0);
    textureCoordinates->InsertNextTuple2(0.0, 1.0);
    m_polyData->GetPointData()->SetTCoords(textureCoordinates);

    // Step 7: Map Texture to Polygon
    m_polyDataMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    m_polyDataMapper->SetInputData(m_polyData);

    // Step 8: Render
    m_sector = vtkSmartPointer<vtkActor>::New();
    m_sector->SetMapper(m_polyDataMapper);
    m_sector->SetTexture(m_texture);
    m_sector->VisibilityOn();

    m_renderer1->AddActor(m_sector);

I am new to VTK and come from an OpenGL background.

I could be missing some VTK understanding on texture mapping and greatly appreciate
if you could help with some pointers to get the texture mapping right.

Thanks for your time.

Regards

Balaji

Looks like the colors are getting interpolated after being mapped which makes the result show the polygon’s underlying triangulation, you can identify this with the long edge joining (-2, -0.5) and (0, 0).

Can you try interpolating before mapping? Call m_polyDataMapper->SetInterpolateScalarsBeforeMapping(true);

Yes, you’re seeing the triangulation of your trapezoid, VTK automatically triangulates during rendering, unless the polydata is already triangulated.

So imagine that your texture is cut diagonally into two triangles. Each of those triangles is mapped to one of the triangles that make up the trapezoid.

Also note that for each triangle, the texture transformation is a linear transformation: the transformations applied to the texture are translation, rotation, shear, and scaling but there is no perspective (i.e. the width of the bands in your texture is constant, the width does not decrease towards the shorter end of the trapezoid).

My understanding is that if you texture map a quad in 2D, OpenGL will calculate the perspective automatically, but when texture mapping a triangle in 2D there is no perspective unless homogeneous texture coordinates are used.

As a follow-up, I found a page that does a good job of explaining the perspective transformation needed to properly apply a texture map a non-rectangular quad.

TLDR: for proper interpolation of quads, quad-specific shader code is needed, because you can’t get the right result by cutting the quad into triangles and then interpolating the triangles.

Thanks Jaswant and David for your replies.
The texture mapping remained as before with SetInterpolateScalarsBeforeMapping(true)

The blog post that David mentioned is also very helpful.
It has given me a better understanding on the underlying reason

I will explore further on this.