Rapezoidal shape to rectangular area texture map

I have a question. Thanks

In the picture on the left, I cut a trapezoidal shape (red area)

I want to compress it to the rectangular area (blue area) on the right. Is there any good texture mapping method to keep the texture unchanged

I think ofxHomography is what you need

I have this shader from long time ago it takes a quad from a texture and fill a shape in draw method (usually a rectangle)

draw() {
// fill shader variables (texture, quad, etc)
shader.begin()
drawrect(x,y,w,h)
shader.end()
}

the bilinear part I understand the math, the perspective method I have copied from somewhere in the web and don’t know exactly how this works. rsrsrsrs

//-----------------------------------------------------------------
#version 120

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

uniform float params[16];

// params[0] → faderPos (0.0 → 1.0)
// params[1] → faderMode (0 = fadeIn tex0 – 1 = mixer tex0 and tex1)
// params[2] → someParam (some param)
// params[15] → texelMode (0 = bilinear – 1 = perspective)

uniform sampler2DRect tex0;
uniform vec2 size0;
uniform float quad0[8];

uniform sampler2DRect tex1;
uniform vec2 size1;
uniform float quad1[8];

vec2 getPerspectiveVertex(vec2 p, float q[8]) {

float T = (q[4] - q[2]) * (q[5] - q[7]) - (q[4] - q[6]) * (q[5] - q[3]);

float G = ((q[4] - q[0]) * (q[5] - q[7]) - (q[4] - q[6]) * (q[5] - q[1])) / T;
float H = ((q[4] - q[2]) * (q[5] - q[1]) - (q[4] - q[0]) * (q[5] - q[3])) / T;

float A = G * (q[2] - q[0]);
float D = G * (q[3] - q[1]);
float B = H * (q[6] - q[0]);
float E = H * (q[7] - q[1]);

G -= 1.0;
H -= 1.0;

T = G * p.x + H * p.y + 1.0;
return vec2((A * p.x + B * p.y) / T + q[0], (D * p.x + E * p.y) / T + q[1]);

}

vec2 getBilinearVertex(vec2 p, float q[8]) {

vec2 vr, vs;

vr.x = (1.0 - p.x) * q[0] + p.x * q[2];
vr.y = (1.0 - p.x) * q[1] + p.x * q[3];
vs.x = (1.0 - p.x) * q[6] + p.x * q[4];
vs.y = (1.0 - p.x) * q[7] + p.x * q[5];

return vec2((1.0 - p.y) * vr.x + p.y * vs.x, (1.0 - p.y) * vr.y + p.y * vs.y);

}

void main(void) {

float faderPos  = params[0];
float faderMode = params[1];
float texelMode = params[15];

vec2 pos = gl_FragCoord.xy / resolution.xy;

vec4 srcA;
vec4 srcB = vec4(0.0,0.0,0.0,0.0);

if(texelMode == 1.0) {
	srcA = texture2DRect( tex0, getPerspectiveVertex(pos, quad0));
} else {
	srcA = texture2DRect( tex0, getBilinearVertex(pos, quad0));
}

if(faderMode != 0.0) {
	if(texelMode == 1.0) {
		srcB = texture2DRect( tex1, getPerspectiveVertex(pos, quad1));
	} else {
		srcB = texture2DRect( tex1, getBilinearVertex(pos, quad1));
	}
}

gl_FragColor = srcA * faderPos + srcB * (1.0 - faderPos);

}

another add-on that may help

I don’t understand what you want it to do, and what it’s doing differently. If you take a trapezoid shape, and map the color texture in it onto a rectangular shape, of course it will either need to stretch/warp the texture. What else would you like it to do?

1 Like

But you need to know what you mean by that. I don’t understand what you think you want.

One way to “not deform” the texture, would be to only take the texture from a rectangle. Otherwise, if you take more pixels from one side than another (i.e. a trapezoid), you’ve got to either not use some pixels (e.g. cropping the source to a rectangle), or you’ve got to map a different number of pixels in the source to the destination, because there are a different number, which is going to appear as “deformed”, because moving from a trapezoid to a rectangle is a deformation.

If you mean something else, you’re not using words that communicate what you mean. Only by knowing what you mean, could we translate that into an algorithm or code.

Would I be wrong to think that what you really want is a texture that is aligned with the image content, more like this?