Using Vertex Colors for UV Coordinates?

Hi all,
I’m trying to figure out how to use Vertex Colors for UV Coordinates in my Material, so that I can have a plane divided in 15 square faces, each face UV-Mapped to the top-left of the texture, and using Vertex Color information to know which UV Shell the move.

Can anyone point me in the right direction? Thanks in advance!

Stephane

First of all, vertex colors store as 8 bit which means you can store values 0-255 but they will be first divided by 255. So you can control exactly which values are written knowing this.

You just need to use the material function “1d to 2d Index” to do this. Out of pure coincidence I made this about an hour ago for myself and its the exact same thing you are doing:

In this example “Tiles” is the number of sub tiles on each axis which for this 2x2 case means there are 4 tiles total. It could be a V2 but my image was only going to be square so I kept it a scalar. Then when vertex painting the meshes, you just paint the first one as 0/TotalTiles, the second one as 1/TotalTiles, third as 2/TotalTiles and so on. If you have more than 256 total tiles this won’t work.

With just a bit more work you can actually support each sub-texture to be tiling without any seams.

Hey Ryan,
I can’t find that function anywhere in Engine Content, I’m using 4.12.5, was it added in 4.13 perhaps?

I’ll give it a try as soon as I get my hands on it. Thanks for your help!

Yes I added that function for 4.13. No reason to wait for it though as it is extremely simple to recreate yourself:

eb8f087f1ffed3dcbfb2acd5118854d3e014dc77.jpeg

in code form its just:

//** input int idx ** 1d index
//** input int2 sizexy ** size of 2d grid

return float2 ( fmod( idx, sizexy.x) , floor(idx / sizexy.x);

Note you don’t need to care about the Y size unless you are handling wrapping outside of the specified size which I am not, except for the separate output that returns centered UV position which I omitted from the above image for simplicity.

Hi Ryan, and thanks a lot for your help so far!
I tried using the 1Dto2DIndex function, and I am having a hard time getting it to work for my specific needs. I’m also a little confused about this statement:

“Then when vertex painting the meshes, you just paint the first one as 0/TotalTiles, the second one as 1/TotalTiles, third as 2/TotalTiles and so on”

What do you mean by that? Is it how I get the correct grayscale value with which to paint the vertex color? I attached a few images of my setup explaining in more details what I need to do. If you wouldn’t mind taking a quick look to see if I’m on the right track or not, would really appreciate it :slight_smile:

Thanks again!

If you have a 4x4 array of frames like that, you will paint the vertex colors as follows :

4x4 = 16 total frames

frame 0: 0/16 = 0
frame 1: 1/16 = 0.0625
frame 2: 2/16 = 0.125
frame 3: 3/16 = 0.1875

and so on.

Of course sometimes due to rounding errors you have to go slightly above or below those values if your frame counts aren’t powers of two. You can also just put a scalar multiplier on the vertex color that is defaulted to 1.0 to allow for quickly pushing all the values in case that pops up anyways. You don’t want to have to go repainting all the values.

Btw for this type of thing I am using procedural mesh these days so it can just spit out whatever vertex colors automatically. I can post something on this soon.

Thanks for the info, I tried it and am now able to display all 10 numbers in each face, but I haven’t figured out yet how to change only 1 face at a time, instead of all 3 changing to a different number. I’ll look into it a little more and see if I can come up with a solution before I bug you again :slight_smile:

I would like to see the procedural mesh system you mentioned though, that sounds really interesting! Thanks again for your help, I appreciate it.

If you are trying to use UE4 to paint those colors, you will need to have a good sized space between each frame since the vertex painting tools are missing a fill button that works where you click. It only fills the whole mesh. You could use separate individual meshes and paint them with the fill tool and then use the developer tools-> merge actors tool and make sure you select “merge vertex data” to get the vertex colors.

Yeah I ended up separating them a bit to give me enough room to paint only the vertices of each plane. What I need to do is change only 1 number at a time, so for example, set the middle face to number 3 and leave the other 2 faces the same, or set the left face to 0, the middle face to let’s say 9, and the right face to let’s say 3. Basically, each time those 3 faces are updated, they will display a specific number, not a random one, so I need individual control for each face.

I know I could do it with 3 different material instances, or by using 3 vertex colors as masks, 1 for each face, and then adding them together, but we have other scenarios that could really benefit from using vertex colors as UV coords, and I wanted to try and get it working on something simple first :slight_smile:

Then you can easily just remap using a set of parameters. You can use the math I have to establish which polygon is the original 0, 1, 2 etc, then you just use that to figure out which value from a Vector Parameter where you set them, effectively remapping.

ie, if you make vector param “Digits” and wanted to display 0, 1, 2, 3 the vector would be:

R = 0
G = 0.0625
B = 0.125
A = 0.1875

but if you wanted it to be reversed you would flip the order

R = 0.1875
G = 0.125
B = 0.0625
A = 0.0

how many total digits are you talking about using total at one time?

We only need to display 3 digit numbers at one time. So basically I would only need RGB. Would you mind showing me how to establish which polygon is the original 0, 1 & 2? I think it’s the only piece I am missing to make this work.

Thanks again Ryan!

There is probably a more elegant way of doing this but this works:

aa652aead8c5c1aaef7036782c805d0b147eeb05.jpeg

This works great! I’ll try and figure out a more elegant way of doing this, as you put it, but in the meantime this is perfect.

Thanks a lot for all your help and for how quickly you responded as well :slight_smile:

Currently I’m using vertex color to assign a tile in an atlas to a mesh in editor and am wondering if there is a way to get Lightmass to respect the assignment. Currently the color is thrown away and am getting only a white result after bake. Any help on this would be greatly appreciated.

The way Lightmass works, per-vertex and per-object data in the material does not survive (you can’t use world position either).

Thank you for the reply. Was hoping someone had figured out a workaround for this.