## Distort texture towards vanishing point (affine mesh?)

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Skeiks
Citizen
Posts: 51
Joined: Wed Jan 28, 2015 1:51 pm

### Distort texture towards vanishing point (affine mesh?)

Earlier today I saw this post https://www.love2d.org/forums/viewtopic ... 84#p199220 and I thought the effect Jasoco created looked really cool. I'm making a simple game about dodging bombs right now and after seeing this I want to implement a kind of 2.5d ground in my game. I thought it would be pretty simple but it's turning out to be a huge headache for me.

Mainly, I want the ground to vanish towards the background, like a sheet of paper. Pretty much a plane tilted 30* from the camera. There won't be any objects on screen other than the ground, the player, flowers, bushes and bombs, so I should be able to just fake the 3d effect pretty easily if I can just make the ground distort correctly.

Something like this is what I want, the "correct" one.

My first idea was to write a fragment shader to do this for me, but that didn't work at all.

My next idea was to draw the texture of the ground to a mesh, and have that mesh be in a trapezoid shape. That kind of worked, but gave me the affine distortion shown above. I read that adding more vertexes should fix the issue, or at least correct it somewhat, but it looked like that no matter how many horizontal vertexes I added to the mesh.

Could anyone point me in the right direction for this? Messing with things like this is a bit of uncharted territory for me so I'm not even sure what to google haha. Thank you!
Davidobot
Party member
Posts: 1212
Joined: Sat Mar 31, 2012 5:18 am
Location: Cambridge, UK
Contact:

### Re: Distort texture towards vanishing point (affine mesh?)

Here's the code for the updated textured quad library by xXxMoNkEyMaNxXx.
Check the original thread for usage: viewtopic.php?f=5&t=12483

Code: Select all

--By xXxMoNkEyMaNxXx
--[[Complete API----  This was made to be a module, PLEASE USE IT AS A MODULE

.cw=false
-Counter clockwise vertex order starting at top left.

.cw=true
-Clockwise vertex order starting at top left.

-loadup==true sets pixel effect to polygon texturer,
*NOTE: preload(false) must be done to draw blank polygons after textured ones.

.setRepeat(origin,size):
-Makes the image repeat every 'size' starting at 'origin'.
-The default is origin={0,0},size={1,1}.

-if 'image' is nil, the function will prepare to make it blank.

.quad(v1,v2,v3,v4) - draws a polygon with no image.

.fast(image,v1,v2,v3,v4) - draws a polygon with 'image' on it.
-Must include an image.

Info:
Vertices are in the form {x,y}.
Vertices go clockwise from the top left.

v1---v2
| img |
v4---v3
--]]

extern Image img;
extern vec2 v1;
extern vec2 v2;
extern vec2 v3;
extern vec2 v4;

extern vec2 p0;
extern vec2 rep;

vec2 one=vec2(1.0,1.0);

number c(vec2 v1,vec2 v2)
{
return v1.x*v2.y-v2.x*v1.y;
}
number intersect(vec2 v1,vec2 d1,vec2 v2,vec2 d2)
{
//v1+d1*
return c(v2-v1,d2)/c(d1,d2);
}
{
return vec4(over.rgb*over.a+base.rgb*(1-over.a),over.a+base.a*(1-over.a));
}
vec4 effect(vec4 colour,Image UNUSED1,vec2 UNUSED2,vec2 inverted)
{
vec2 p=vec2(inverted.x,inverted.y);

vec2 A1=normalize(v2-v1);
vec2 A2=normalize(v3-v4);

vec2 B1=normalize(v2-v3);
vec2 B2=normalize(v1-v4);

number Bdiv=c(B1,B2);

vec2 uv;

if(eq0.x && eq0.y){
//Both edges are parallel, therefore the shape is a parallelogram (Isometric)
number dis=dot(p-v1,A1);

//cos theta
number ct=dot(A1,B1);

//Closest point on v1->A1 to p
vec2 pA=v1+A1*dis;

//uv
number r=length(p-pA)/sqrt(1-ct*ct);
uv=vec2(1-r/length(v2-v3),(dis+r*ct)/length(v2-v1));
}else if(eq0.x){
//One Vanishing point occurs in numerically set scenarios in 3D, and is a feature of 2.5D

//Horizon is A1 (=A2) from B
vec2 Vp=v3+B1*c(v4-v3,B2)/Bdiv;

//Some point in the distance that diagonals go to
vec2 D=Vp+A1*intersect(Vp,A1,v4,normalize(v2-v4));

//uv
number u=intersect(v1,A1,Vp,normalize(p-Vp));
number v=intersect(v1,A1,D,normalize(p-D))-u;

number len=length(v2-v1);
uv=vec2(len-v,u)/len;//Reversed components to match up with other one
}else if(eq0.y){
//If the other edge is the parallel one
vec2 D=Vp+B1*intersect(Vp,B1,v4,normalize(v2-v4));
number u=intersect(v3,B1,Vp,normalize(p-Vp));
number len=length(v2-v3);
uv=vec2(u,len-intersect(v3,B1,D,normalize(p-D))+u)/len;
}else{
//Else, two vanishing points

//*intersect(v1,A1,v4,A2)
//*intersect(v3,B1,v4,B2)

//Vanishing points
vec2 B=v3+B1*c(v4-v3,B2)/Bdiv;

//Horizon
vec2 H=normalize(A-B);

//Pixel
uv=vec2(intersect(v4,-H,A,normalize(p-A))/intersect(v4,-H,v2,-A1),intersect(v4,H,B,normalize(p-B))/intersect(v4,H,v2,-B1));
}
}
]]
local gl_send=glsl.send
local q=love.graphics.polygon
-- local lgr = love.graphics
gl_send(glsl,"p0",{0,0})
gl_send(glsl,"rep",{1,1})

module(...)
cw=true--clockwise
setEffect(glsl)
else
setEffect()
end
end
function setRepeat(origin,size)
gl_send(glsl,"p0",origin)
gl_send(glsl,"rep",size)
end
function fast(img,v1,v2,v3,v4)
gl_send(glsl,"img",img)
gl_send(glsl,"v1",v2)
gl_send(glsl,"v2",v3)
gl_send(glsl,"v3",v4)
gl_send(glsl,"v4",v1)
q("fill",v1[1],v1[2],v2[1],v2[2],v3[1],v3[2],v4[1],v4[2])
end
if img and v4 then
setEffect(glsl)
gl_send(glsl,"img",img)
if cw then
gl_send(glsl,"v1",v2)
gl_send(glsl,"v2",v3)
gl_send(glsl,"v3",v4)
gl_send(glsl,"v4",v1)
else
gl_send(glsl,"v1",v2)
gl_send(glsl,"v2",v1)
gl_send(glsl,"v3",v4)
gl_send(glsl,"v4",v3)
end
else
setEffect()
end
-- lgr.setBlendMode("premultiplied")
if v4 then
q("fill",v1[1],v1[2],v2[1],v2[2],v3[1],v3[2],v4[1],v4[2])
else--img acts as a vertex
q("fill",img[1],img[2],v1[1],v1[2],v2[1],v2[2],v3[1],v3[2])
end
-- lgr.setBlendMode("alpha")
setEffect()
end
My projects: Raycaster, love.js v11.3 port
My library: LovelyMoon
Skeiks
Citizen
Posts: 51
Joined: Wed Jan 28, 2015 1:51 pm

### Re: Distort texture towards vanishing point (affine mesh?)

Thank you, that library worked great!

The effect still isn't perfect, and since I'm "faking it" I still have some work to do. But I have the distortion I needed

### Who is online

Users browsing this forum: Bing [Bot], davidkonsumer and 21 guests