Textured quads not rendering as expected when vertices are skewed.

Started by TomToad, September 14, 2019, 14:13:46

Previous topic - Next topic

TomToad

I have a textured quad.  Using a checkerboard pattern here to better illustrate my problem.



When I move two vertices closer together to make a trapezoid, I expect the texture to be something like this



But instead, it ends up like this.



After researching a bit, I discover that it is the result of the fact the quad is actually rendered as 2 triangles, each one unaware of the 4th vertex.  No matter how I set the uv coordinates, I cannot get it to look the way I want.  Anyone have a solution?
------------------------------------------------
8 rabbits equals 1 rabbyte.

iWasAdam

it's actually correct, but not what you want.
The result you are having is called affine texture mapping - where triangles are rendered with no perspective texture correction.

what you are wanting is rendering with Linear Texturing on.

You need to look for something that turns affine mapping off!

Also you will need to specify what 3d rendering your are using DirectX, OpenGL or custom. as I am sure that the api's will be different.

P.S. if you are using shaders, then generally they are linear based and not affine. Hope this helps to point the way??

Coder Apprentice

Do you modify the quad's vertexes position in the 3D engine or import it as a trapezoid from a modeling app?

GrindalfGames

Surely you could do 2 triangles. the textures should then stay where they are meant to be right? surely then you could weld them together to create a makeshift quad and they should still react correctly?

TomToad

@iWasAdam:  I am using AGK2 which uses OpenGL.  I do not see any options for linear Texturing or affine texturing. The modeling siftware I am using (AC3D) has the same problem.  Uses OpenGL as well.

@grindalf:  The problem seems that it wants to render 2 triangles.  Whether I weld the triangles together (sharing 2 vertices, 4 altogether), or unweld them (each has 3 vertices, 6 total), it renders the same.  Here is the quad with the two triangles unwelded and moved slightly apart.  Compare it with the image in the OP and you will see it is the same.
------------------------------------------------
8 rabbits equals 1 rabbyte.

GrindalfGames

I can see it now and why its doing what its doing. Is it even possible to do what you want?
If you look at your original image of what you expect to happen and draw a straight line from vertex to vertex across the triangle line and you can see you have drawn a curve across the texture from one corner to the other.

RemiD

even with an unwelded rectangle made of 2 triangles 6 vertices, instead of a welded rectangle made of 2 triangle 4 vertices, if the UVs are the same, and the vertices positions are the same, and the texture is the same, and the filtereing is the same, it should look the same...

maybe try to create the same textured rectangle in Blitz3d, and see what happens...
but yeah, disabling all filtering, is the best way to debug your UVs...

TomToad

Well, I managed to get the results I wanted, but not exactly the way I wanted to do it.  By making the texture pixels itself into the trapezoid, and then mapping the uv to that, I am able to get the texture looking right.  Problem is, if I change my model at all, I will also need to change the texture to match.  Maybe I could write a shader that'll do it automatically for me, was planning on adding a shader anyway.

@RemiD:  renders the same in Blitz3D as well.
------------------------------------------------
8 rabbits equals 1 rabbyte.

Kryzon

The perspective-corrected mapping needs the quad to be rotated in 3D space (the vertices need to have different Z values) for it to work. You're just moving vertices along the screen plane, so you're always gonna get affine mapping.


Edit: I agree with the solution you thought of, draw a perfect quad on screen, and inside the shader do that warping, treating the quad as a little viewport. Unfilled pixels should get alpha zero to be transparent.