Ok, hopefully this comment will be more useful than the one above.
This uses the setRectZ shader from above to automatically set the z of each point to equal the y coordinate of the baseline of each rect, so as the rect moves up the screen, it automatically goes behind other objects it passes. As long as you’re ok with discard rather than translucency, this would work well for an isometric/forced perspective game:
If you have lots of objects moving around every frame, experiment with modifying setRectZ so that you store a normal table for the entire mesh, and set the entire normal table just before you draw the mesh. Could be quicker than setting a whole bunch of individual normals.
-- setRectZ
--uses normal to set rectangle z, to stop setRect resetting z to zero
function setup()
m = mesh()
m.shader = shader(RectZShader.vert, RectZShader.frag)
local img = readImage("Small World:Court")
m.texture = img
w, h = img.width, img.height
p = {a=vec2(WIDTH*0.5, HEIGHT*0.3), b=vec2(WIDTH*0.5, HEIGHT*0.6)} --point a and point b
m:addRect(p.a.x, p.a.y, w, h)
local col = color(84, 174, 231, 255)
m:setRectColor(1, col) --tint rect 1 blue so we can tell them apart
m:addRect(p.b.x, p.b.y, w, h)
tween(2, p, {a=vec2(WIDTH*0.5, HEIGHT*0.9)}, {easing=tween.easing.cubicInOut, loop=tween.loop.pingpong}) --point a tweens to point b and back
rectZ = 0
setRectZ(m,2,-p.b.y-h*0.5) --set z of rect 2 to inverse y of baseline
end
function draw()
ortho(0, WIDTH, 0, HEIGHT,-2000,2000) --orthogonal projection
background(40, 40, 50)
m:setRect(1,p.a.x, p.a.y, w, h)
setRectZ(m,1,-p.a.y-h*0.5) --set z to inverse y of baseline
m:draw()
end
function setRectZ(m, rec, z) --mesh, rect number, z value
local off = (rec-1)*6 --convert rect number to vertex number
for i=1,6 do --6 points in rect
m:normal(off+i, 0, 0, z) --set z using normal
end
end
RectZShader={
vert=[[
uniform mat4 modelViewProjection;
attribute vec3 position;
attribute vec3 normal;
attribute vec4 color;
attribute vec2 texCoord;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
vColor = color;
vTexCoord = texCoord;
//z position taken fron normal
gl_Position = modelViewProjection * vec4(position.xy, normal.z, 1.);
}
]],
frag=[[
precision highp float;
uniform lowp sampler2D texture;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
lowp vec4 col = texture2D( texture, vTexCoord ) * vColor;
if (col.a<0.3) discard; //discard for alpha clipping
else gl_FragColor = col;
}
]]
}