4

The following code has this result:

enter image description here

local mesh = nil
local img = love.graphics.newImage("test_blue.png")

function love.load()
  mesh = love.graphics.newMesh(4, img, "fan")
  mesh:setVertices({
    {125, 100, 0, 0, 255, 255, 255, 255},  --Top Left
    {150, 100, 1, 0, 255, 255, 255, 255},  --Top Right
    {200, 400, 1, 1, 255, 255, 255, 255},  --Bottom Right
    {100, 400, 0, 1, 255, 255, 255, 255} --Bottom Left
  })
end

function love.draw()
  love.graphics.draw(mesh, 200, 0)
end

I'd like to know how I could get a result like this:

ryanpattison
  • 6,151
  • 1
  • 21
  • 28
buddy148
  • 167
  • 1
  • 1
  • 9
  • The bottom image has depth (a 3D effect) whereas Love is a 2D library. – ryanpattison Jul 26 '15 at 12:26
  • @rpattiso Depth? Really? I see only nice 2d polygon (or maybe skew) - i dont know Love2D but it looks like they are drawing trianglestrip and not trianglelist or indices are wrong or something like that... – Jan 'splite' K. Jul 26 '15 at 12:42
  • We're currently using "Triangle Fan" as our MeshDrawMode, It seems to be the closet result to what we're wanting. – buddy148 Jul 26 '15 at 12:51
  • 1
    In the bottom image the scaling of the textures width is a function of its distance. Notice in the top image the checkers in the left and right triangles never change size within their triangles? A shader could manipulate the coordinates of the texture, or you could modify the texture itself to simulate the depth effect, or just use a 3D library. – ryanpattison Jul 26 '15 at 13:11
  • @Jan'splite'Kondelík please see the link in my answer for why the bottom image is a 3d mapping with a z component. – ryanpattison Jul 26 '15 at 16:18
  • @rpattiso I am sorry, but i still dont see any reason why it have to be depth (i think question is about rogue vertice or wrong triangulation - but as i say, i know nothing about Love2D so i will not post any answer) - What i see is polygon from two triangles, with, lets say (left/right top/bottom = [x; y; u; v], uv is DirectX) `LT = [-5;10;0;0], RT = [5;10;1;0], LB = [-10;-10;0;1], RB = [10;-10;1,1]` -> `vertices_cw = {LT, RT, LB, LB, RT, RB}` (two triangles) --> `drawPrimitives(TriangleList, ...)` have to draw nice (not in perspective) pseudo-pyramid-without-top like in second image. – Jan 'splite' K. Jul 26 '15 at 17:22
  • 1
    @Jan'splite'Kondelík look at the vertical lines in the texture of the bottom image, they converge to a vanishing point. therefore this is not an orthographic projection since those lines are parallel in the texture. This is the problem of perspective correctness in texture mapping. If you write an answer in your language that uses orthographic projection, triangles, and 2d coordinates I can convert it to Love, but I say it is not possible, the vertical lines in the texture must remain parallel in an orthographic projection. – ryanpattison Jul 26 '15 at 23:29
  • @rpattiso omg, you are right and i was wrong... Now i see it... – Jan 'splite' K. Jul 27 '15 at 08:52

2 Answers2

0

Without using a 3D library you cannot get a true the depth effect without implementing perspective. The problem is that the polygon is made from 2D triangles and only 2D effects can be applied like shearing or scaling (as a whole). The parallel lines in the texture will always be parallel which is not the case for your bottom image since they converge toward a vanishing point.

For more reading see Perspective Correctness section of Texture Mapping

Changing the coordinate of the texture map can minimize some of the artifacts visually by clipping toward a vanishing point instead of scaling.

Lines in the texture do not have to be parallel if they are part of separate triangles and so adding more triangles allows them to shear toward one another at the cost of more clipping.

Both modifying texture coordinates and using more triangles can be problematic for different styles of texture so you may need to tune it on a case by case basis.

local mesh = nil
local img = love.graphics.newImage("test_blue.png")

function love.load()
  mesh = love.graphics.newMesh(5, img, "strip")
  local top_left  = {125, 100, .125, 0, 255, 255, 255, 255} 
  local top_right = {150, 100, .875, 0, 255, 255, 255, 255}
  local bot_right = {200, 400, 1, 1, 255, 255, 255, 255}
  local bot_left  = {100, 400, 0, 1, 255, 255, 255, 255}
  local bot_mid   = {150, 400, .5,1, 255, 255, 255, 255} 

  mesh:setVertices{
      bot_left, top_left, bot_mid, top_right, bot_right,
  }

end

function love.draw()
  love.graphics.draw(mesh, 200, 0)
end

enter image description here

ryanpattison
  • 6,151
  • 1
  • 21
  • 28
  • 1
    Thanks for the information, Looks like we're going to need to take a look at this issue from a different perspective... – buddy148 Jul 27 '15 at 00:10
0

Math to build shader able to fix this issue is commonly explained on google in many threads, and there are multiple approaches (tag: perspective correct texture mapping).

If you want to build your own shader or use shader from source different than Love2D, mind that Love2D currently uses GLSL v.1.20 with some minor changes.

There is forum thread where you can get completed shader file, currently for Love2D v.0.10.2. Simple use, code commented properly.

https://www.love2d.org/forums/viewtopic.php?f=5&t=12483&start=120 Post by drunken_munki » Wed Apr 26, 2017 11:03 am