Hi.
First of all, those beams / halo look gorgeous.
I have some experience doing dynamic curved geometry, outside Corona. I’ve held back back on porting that, with the new shader availability, until the uniform userdata interface is revealed (since I want to do fairly parameter-heavy stuff), but if your effect is simple enough maybe you could get by with vertex userdata.
This all entails shaders, as I said. I’m assuming this is just graphical fluff, so you don’t need physics and stuff on them. The idea, roughly, goes as follows.
Basically, you want “tessellated” (left-to-right, at least) rects, so just rect-shaped polygons with lots of vertices, each of which gets evaluated in a vertex kernel. These will be wider than your old rects, since the tessellation lets you sculpt a curve.
In the vertex kernel, you read out CoronaTexCoord.** x**(when it’s a uv, it’s also common to use .s), which should be 0 for the leftmost coordinates and 1 for the rightmost. This can be used to calculate the alpha, though that’s better done in the fragment kernel. Here, you can use it to fit your points to a curve. I’ve found Catmull-Rom well-suited to this, but it’s your call.
You’ve only got four vertex userdata to work with, and a cubic curve takes four vectors, so you’ll have to encode them. For values between 0 and 1 (in this case, normalized screen coordinates), I’ve used the following scheme. For decoding them in the shader:
P\_POSITION vec2 UnitPair (P\_UV float xy) { P\_UV float axy = abs(xy); P\_UV float frac = fract(axy); return vec2((axy - frac) / 1023., sign(xy) \* frac + .5); }
and for encoding them in the first place, in Lua:
function Encode (x, y) y = y - .5 return (y \< 0 and -1 or 1) \* (math.floor(1023 \* x) + math.abs(y)) end
(The “1023” (2^10 - 1) values are made to comport with GLSL’s mediump precision and low-end fragment shaders. If this stuff will only be done on vertex kernels or higher-end devices, those could be “65535” (2^16 - 1) instead, I believe.)
So, you pass in four pieces of data (in the Catmull-Rom case, points along the curve, including the two endpoints of the “rect”), then in each vertex, evaluate the curve at t = CoronaTexCoord.x. From the derivative of the curve equation you can get the tangent, and from that the normal (-y, x) so you can position vertices “up” and “down” from the curve using CoronaTexCoord.y.
You’ll need to un-normalize these values, from [0, 1]. Unfortunately, the best idea I have here is to bake the content dimensions into the shader (since the kernel code is a string, this is easy enough to do at startup).
(The polygon display object’s coordinates don’t come into play, in my scheme. If you could come up with a way to use them instead, that might buy you back some userdata.)
Anyhow, that’s a very high-level overview, but maybe it gives you something to work with?