PDA

View Full Version : Squeeze rectangle texture to a triangle



l00p1n6
04-18-2016, 09:57 AM
I know how to stretch the texture by using UV coordinates, but I am trying to do the opposite:
I am trying to find a way to squeeze a rectangular texture to a triangle object:

2256

Like in the image, move corner points 1 and 2 to the center and leave corner points 3 and 4 intact.

Is there some simple method of doing that?
Thank you!

GClements
04-18-2016, 01:20 PM
Is there some simple method of doing that?
To do what you want requires a custom texture-mapping formula in the fragment shader. Specifically, if the lower corners (labelled 3 and 4 in the diagram) have texture coordinates (0,1) and (1,1), and the apex corner has texture coordinates (0,0), then you can use e.g.


uniform sampler2d tex;
in vec2 texcoord;
...
vec2 uv = vec2(texcoord.s / texcoord.t, texcoord.t);
vec4 color = texture(tex, uv);


Note that the generated S coordinate is undefined at T=0, although that situation will only arise if the apex is exactly in the centre of a pixel. If that turns out to be an issue, add a very small positive constant to the divisor (or to the apex' T coordinate).

With a projective mapping, both the S and T coordinates are divided by the interpolated Q coordinate (which is usually 1, but may be an affine function when performing texture projection, i.e. when using 4D texture coordinates). It isn't possible to divide only the S coordinate, hence this can't be implemented using fixed-function texture mapping (i.e. glEnable(GL_TEXTURE_2D)); you have to use a shader.

A similar approach can be used to map a rectangular portion of a texture to a trapezoid, although you may need to use the third coordinate (P) for the divisor if you don't want it to converge at T=0.

l00p1n6
04-19-2016, 04:25 AM
It doesn't work :(

Please observe the triangle without your code:
2258

and compare it with the changes from your code:
2260

l00p1n6
04-19-2016, 05:31 AM
I devised the correct formula:


vec2 uv = vec2((texcoord.s - texcoord.t / 2.0) / (1 - texcoord.t), texcoord.t);

This produces the following image:

2261

Thank you GClements!

GClements
04-19-2016, 10:42 AM
It doesn't work :(
You wouldn't know, as you didn't try it.



Please observe the triangle without your code:
2258

Your texture coordinates are wrong. The apex corner has texture coordinates of (0.5,0) or (0.5,1) (probably the latter, as you're dividing by 1-T). I was quite explicit about this:


Specifically, if the lower corners (labelled 3 and 4 in the diagram) have texture coordinates (0,1) and (1,1), and the apex corner has texture coordinates (0,0), then you can use e.g.