graphicsluameshlove2d

Strange texture behavior on mesh in Love2D, Help needed to achieve the result I was expecting


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:


Solution

  • 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