Use/add a per vertex color to meshes

Are there any plans to improve the mesh functionality?

If I haven’t missed something, it is, at the moment, not possible to define a per vertex color or use any per vertex data? At the base, it’s already there as 4 floats are added to each vertex through CoronaVertexUserData. Right now it’s just that these are the same 4 values for each vertex.

Hi.

I believe the plan is to add per-vertex colors or userdata, though I forget where it’s been mentioned.

Actually, if you don’t need an image, here’s something I showed Vlad a while back that hijacks the texture coordinates:

local rect = display.newRect(0, 0, 200, 200) local mesh = display.newMesh{ x = 100, y = 100, mode = "indexed", vertices = { 0, 0, 0, 100, 50, 0, 100, 100, 100, 0 }, indices = { 1, 2, 3, 2, 3, 4, 3, 4, 5 } } mesh:translate( mesh.path:getVertexOffset() ) rect:translate(mesh.x, mesh.y) rect:setFillColor(1, 0, 1) -- some background for some alpha tests -- Kernel -- local kernel = { category = "generator", name = "corner\_colors" } kernel.vertex = [[P\_DEFAULT vec2 TenBitsPair (P\_DEFAULT float xy) { P\_DEFAULT float axy = abs(xy); P\_DEFAULT float bin = floor(log2(axy)); P\_DEFAULT float num = exp2(16. - bin) \* axy - 65536.; P\_DEFAULT float rest = floor(num / 1024.); P\_DEFAULT float y = num - rest \* 1024.; P\_DEFAULT float y\_bias = step(0., -xy); return vec2(bin \* 64. + rest, y + y\_bias); } P\_DEFAULT vec2 UnitPair (P\_DEFAULT float xy) { return TenBitsPair(xy) / 1024.; } varying P\_COLOR vec4 v\_RGBA; P\_POSITION vec2 VertexKernel (P\_POSITION vec2 pos) { v\_RGBA.rg = UnitPair(CoronaTexCoord.x); v\_RGBA.ba = UnitPair(CoronaTexCoord.y); return pos; }]] kernel.fragment = [[varying P\_COLOR vec4 v\_RGBA; P\_COLOR vec4 FragmentKernel (P\_UV vec2 uv) { return v\_RGBA; }]] graphics.defineEffect(kernel) mesh.fill.effect = "generator.custom.corner\_colors" -- local assert = assert local floor = math.floor local function EncodeTenBitsPair (x, y) assert(x \>= 0 and x \<= 1024, "Invalid x") assert(y \>= 0 and y \<= 1024, "Invalid y") x, y = floor(x + .5), floor(y + .5) local signed = y == 1024 if signed then y = 1023 end local xhi = floor(x / 64) local xlo = x - xhi \* 64 local xy = (1 + (xlo \* 1024 + y) \* 2^-16) \* 2^xhi return signed and -xy or xy end local function Encode (x, y) return EncodeTenBitsPair(x \* 1024, y \* 1024) end local function SetColor (index, r, g, b, a) mesh.path:setUV(index, Encode(r, g), Encode(b, a)) end SetColor(1, 0, 0, 1, 1) -- upper-left SetColor(2, 1, 0, 0, 1) -- lower-left SetColor(3, 0, 1, 1, 1) -- upper-center SetColor(4, 0, 0, 1, 1) -- lower-right SetColor(5, 0, 1, 0, 1) -- upper-right --[[timer.performWithDelay(300, function() local index = math.random(5) SetColor(index, math.random(), math.random(), math.random(), 1) end, 0) --]]

This might be occasionally useful. I was thinking, for instance, of trying to port this on some weekend.

This does some stuff with IEEE float representation, so I would actually be curious if it runs aground on any of your Android devices (or anywhere else, of course).

Ah that’s pretty creative work around.

I thought a bit about the problem and there might be some other creative workarounds too. I haven’t thought about it in detail (well as said, no experience using shaders so far) but given the vertexIds it may be possible to calculate a textureCoordinate based on this and, in the fragment shader, use this to lookup into a second texture which encodes the colors for each vertex (or group of vertices).

Might not work due to whatever reason I didn’t pay attention too.

Quite fun do dive into this whole topic and creative solutions. 

I used to do games on J2ME devices and there was no way to reliably and fast change colors of an image. So what you had to do there was to load the PNG as a binary blob, find the palette entry, modify the palette to your needs, and then load the image :slight_smile:

With regards to the port you want to do … while I love IMGUI I’m not sure how you want this to be done in Corona as it’s kind of the exact opposite to the fundamental way code and graphics work in Corona? You’d have to create the mesh(es) for all of the IMGUI each single frame which I’d expect to not be that efficient and also create lot’s of garbage.

Which brings me to some more possible improvements with regards to creating the mesh - but I’ll probably write this in another topic in in the next few days.

Some friends from school, including a couple roommates, went to work for some movie studios and were doing licensed phone games for a while, so I got to hear about their many travails with J2ME. It all sounded pretty crazy.  :smiley:

I did some stuff like your first idea back when canvases first came out, to make a proof of concept for meshes… I forget the name of the thread, though, and my search skills are failing me; this is basically the code I’d supplied. For non-color data you usually want to change the filtering mode (since the hardware will try to blend neighboring “colors”, by default) and then index into the texture with values between 0 and 1.

As for the IMGUI bit, I figured I would just create a generously-sized mesh (and if necessary, additional ones on demand), filling it with degenerate triangles (all vertices mashed to a single pixel, say) that the hardware will throw away. With higher workloads, most of these will be fleshed out; when it eases up, I’d just re-degenerate them. (For that matter, I’ve also had some really nagging ideas the last couple months for a big mesh-based game architecture, so it would be a good test run.)

Ah I did a quick check and the vertexID requires GL ES 3.0 so it’s not an option when the target includes mobile devices (it works on my Desktop PC though). But if I need per vertex colors, I’ll just split my mesh and use different fill colors.

Hm creating a huge mesh is an interesting idea - could work reasonably well. You’ll still have huge loads of Lua->c calls to update the mesh each frame but it should not generate any Garbage.

Hi.

I believe the plan is to add per-vertex colors or userdata, though I forget where it’s been mentioned.

Actually, if you don’t need an image, here’s something I showed Vlad a while back that hijacks the texture coordinates:

local rect = display.newRect(0, 0, 200, 200) local mesh = display.newMesh{ x = 100, y = 100, mode = "indexed", vertices = { 0, 0, 0, 100, 50, 0, 100, 100, 100, 0 }, indices = { 1, 2, 3, 2, 3, 4, 3, 4, 5 } } mesh:translate( mesh.path:getVertexOffset() ) rect:translate(mesh.x, mesh.y) rect:setFillColor(1, 0, 1) -- some background for some alpha tests -- Kernel -- local kernel = { category = "generator", name = "corner\_colors" } kernel.vertex = [[P\_DEFAULT vec2 TenBitsPair (P\_DEFAULT float xy) { P\_DEFAULT float axy = abs(xy); P\_DEFAULT float bin = floor(log2(axy)); P\_DEFAULT float num = exp2(16. - bin) \* axy - 65536.; P\_DEFAULT float rest = floor(num / 1024.); P\_DEFAULT float y = num - rest \* 1024.; P\_DEFAULT float y\_bias = step(0., -xy); return vec2(bin \* 64. + rest, y + y\_bias); } P\_DEFAULT vec2 UnitPair (P\_DEFAULT float xy) { return TenBitsPair(xy) / 1024.; } varying P\_COLOR vec4 v\_RGBA; P\_POSITION vec2 VertexKernel (P\_POSITION vec2 pos) { v\_RGBA.rg = UnitPair(CoronaTexCoord.x); v\_RGBA.ba = UnitPair(CoronaTexCoord.y); return pos; }]] kernel.fragment = [[varying P\_COLOR vec4 v\_RGBA; P\_COLOR vec4 FragmentKernel (P\_UV vec2 uv) { return v\_RGBA; }]] graphics.defineEffect(kernel) mesh.fill.effect = "generator.custom.corner\_colors" -- local assert = assert local floor = math.floor local function EncodeTenBitsPair (x, y) assert(x \>= 0 and x \<= 1024, "Invalid x") assert(y \>= 0 and y \<= 1024, "Invalid y") x, y = floor(x + .5), floor(y + .5) local signed = y == 1024 if signed then y = 1023 end local xhi = floor(x / 64) local xlo = x - xhi \* 64 local xy = (1 + (xlo \* 1024 + y) \* 2^-16) \* 2^xhi return signed and -xy or xy end local function Encode (x, y) return EncodeTenBitsPair(x \* 1024, y \* 1024) end local function SetColor (index, r, g, b, a) mesh.path:setUV(index, Encode(r, g), Encode(b, a)) end SetColor(1, 0, 0, 1, 1) -- upper-left SetColor(2, 1, 0, 0, 1) -- lower-left SetColor(3, 0, 1, 1, 1) -- upper-center SetColor(4, 0, 0, 1, 1) -- lower-right SetColor(5, 0, 1, 0, 1) -- upper-right --[[timer.performWithDelay(300, function() local index = math.random(5) SetColor(index, math.random(), math.random(), math.random(), 1) end, 0) --]]

This might be occasionally useful. I was thinking, for instance, of trying to port this on some weekend.

This does some stuff with IEEE float representation, so I would actually be curious if it runs aground on any of your Android devices (or anywhere else, of course).

Ah that’s pretty creative work around.

I thought a bit about the problem and there might be some other creative workarounds too. I haven’t thought about it in detail (well as said, no experience using shaders so far) but given the vertexIds it may be possible to calculate a textureCoordinate based on this and, in the fragment shader, use this to lookup into a second texture which encodes the colors for each vertex (or group of vertices).

Might not work due to whatever reason I didn’t pay attention too.

Quite fun do dive into this whole topic and creative solutions. 

I used to do games on J2ME devices and there was no way to reliably and fast change colors of an image. So what you had to do there was to load the PNG as a binary blob, find the palette entry, modify the palette to your needs, and then load the image :slight_smile:

With regards to the port you want to do … while I love IMGUI I’m not sure how you want this to be done in Corona as it’s kind of the exact opposite to the fundamental way code and graphics work in Corona? You’d have to create the mesh(es) for all of the IMGUI each single frame which I’d expect to not be that efficient and also create lot’s of garbage.

Which brings me to some more possible improvements with regards to creating the mesh - but I’ll probably write this in another topic in in the next few days.

Some friends from school, including a couple roommates, went to work for some movie studios and were doing licensed phone games for a while, so I got to hear about their many travails with J2ME. It all sounded pretty crazy.  :smiley:

I did some stuff like your first idea back when canvases first came out, to make a proof of concept for meshes… I forget the name of the thread, though, and my search skills are failing me; this is basically the code I’d supplied. For non-color data you usually want to change the filtering mode (since the hardware will try to blend neighboring “colors”, by default) and then index into the texture with values between 0 and 1.

As for the IMGUI bit, I figured I would just create a generously-sized mesh (and if necessary, additional ones on demand), filling it with degenerate triangles (all vertices mashed to a single pixel, say) that the hardware will throw away. With higher workloads, most of these will be fleshed out; when it eases up, I’d just re-degenerate them. (For that matter, I’ve also had some really nagging ideas the last couple months for a big mesh-based game architecture, so it would be a good test run.)

Ah I did a quick check and the vertexID requires GL ES 3.0 so it’s not an option when the target includes mobile devices (it works on my Desktop PC though). But if I need per vertex colors, I’ll just split my mesh and use different fill colors.

Hm creating a huge mesh is an interesting idea - could work reasonably well. You’ll still have huge loads of Lua->c calls to update the mesh each frame but it should not generate any Garbage.