以下代码有这样的结果:
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
我想知道如何得到这样的结果:
如果不使用 3D 库,您就无法在不实现透视的情况下获得真正的深度效果。问题是多边形是由 2D 三角形组成的,并且只能应用 2D 效果,例如剪切或缩放(作为整体)。纹理中的平行线始终是平行的,但底部图像的情况并非如此,因为它们会聚向消失点。
更多阅读请参阅纹理映射的透视正确性部分
更改纹理贴图的坐标可以通过向消失点剪切而不是缩放来在视觉上最小化一些伪影。
如果纹理中的线条是单独三角形的一部分,则它们不必平行,因此添加更多三角形可以使它们相互剪切,但代价是更多剪切。
对于不同样式的纹理,修改纹理坐标和使用更多三角形都可能会出现问题,因此您可能需要根据具体情况进行调整。
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
构建能够解决此问题的着色器的数学通常在谷歌上的许多线程中进行解释,并且有多种方法(标签:透视正确的纹理映射)。
如果您想构建自己的着色器或使用不同于 Love2D 的源着色器,请注意 Love2D 目前使用 GLSL v.1.20 并进行了一些细微的更改。
在论坛帖子中您可以获取完整的着色器文件,目前适用于 Love2D v.0.10.2。使用简单,代码注释正确。
https://www.love2d.org/forums/viewtopic.php?f=5&t=12483&start=120 由醉酒者发表 » 2017 年 4 月 26 日星期三上午 11:03
实现此效果的另一种方法。 将四边形的顶点排列为四边形上下之字形。
zigZagCount = 11
verticesCount = zigZagCount + 3
mesh = love.graphics.newMesh(verticesCount,"strip")
local meshImage = love.graphics.newImage("uv.png")
mesh:setTexture(meshImage)
halfWidth = 100
halfHeight = 100
function love.load()
updateMesh()
end
function love.draw()
love.graphics.setColor(1,1,1)
love.graphics.translate(halfWidth+20,halfWidth+20)
love.graphics.draw(mesh)
for i=1,verticesCount do
love.graphics.setColor(1,i/verticesCount,0)
local x,y = mesh:getVertex(i)
love.graphics.circle("fill",x,y,3)
end
end
function updateMesh()
local topScale = .5
local bottomScale = 1
local topX = -halfWidth*topScale
local bottomX = -halfWidth*bottomScale
local uIncrement = 1/zigZagCount
local widthPart = halfWidth*2/zigZagCount
local topXIncrement = widthPart*topScale
local bottomXIncrement = widthPart*bottomScale
local u = 0
local isTopPoint = true -- flip the zig zag with false
if isTopPoint then
mesh:setVertex(1,
topX,-halfHeight,u,0,.5
)
else
mesh:setVertex(1,
bottomX,-halfHeight,u,.5
)
end
isTopPoint = not isTopPoint
for i=2, verticesCount-1 do
if isTopPoint then
mesh:setVertex(i,
topX,-halfHeight,u,0
)
else
mesh:setVertex(i,
bottomX,halfHeight,u,1
)
end
topX = topX+topXIncrement
bottomX = bottomX+bottomXIncrement
u = u+uIncrement
isTopPoint = not isTopPoint
end
if isTopPoint then
mesh:setVertex(verticesCount,
topX-topXIncrement,-halfHeight,1,.5
)
else
mesh:setVertex(verticesCount,
bottomX-bottomXIncrement,halfHeight,1,1
)
end
end
Increase `zigZagCount` for higher accuracy.
This might have some use-cases. Didn't end up using it but here ya'll go.