We have a square plane with a texture on it. We want to be able to specify the shape of the image by defining the coordinates of its 4 corners.
Take the following images as examples of what we need.
With the following code, we have gotten really close to achieving what we need, but we still can’t figure out what we are doing wrong. If anybody can spot our mistake or give us some pointers on another solution, we would be more than happy.
//We do this in the fragment function of the shader
//(x1, y1)...(x4, y4) are the corrdinates of the four points, starting on the upper left corner and going clockwise.
float2 uv = UV;
UV.x += (x4 - x1) * uv.y - x4;
UV.x /= (x3 - x4 + uv.y * (x2 - x1 - x3 + x4));
UV.y += (y4 - y3) * uv.x - y4;
UV.y /= (y1 - y4 + uv.x * (y2 - y3 - y1 + y4));
What you’re after is not affine mapping. affine transformations keep parallel lines of the source space parallel in the transformed space. See Affine mapping. What you want is a perspective correct mapping which actually causes a non linear transformation.
the rasterizer of the gpu automatically does a perspecive correction based on the perspective distance. Note that this only works for faces which are actually a rectangle but are distorted due to perspective projection. If you want to draw a pure 2d shape you would need to use s,t,r,q texture coordinates. Have a look over here as well as the linked tutorial post from the question