Picking a mesh based on vertex color. Good way to do more than 3?

Hey folks, is there an efficient way to set up an Unreal material to to pick a mesh or part of a mesh based on it’s vertex color? I’d like to run a dynamic parameter from 0-1 to cycle through a series of complex meshes, either in sequence or to pick a specific mesh. My end goal is to create an “after image” effect of a character doing a set action (dodge, flip, attack, etc…) I’d like to just take snapshots of the mesh throughout the animation and pack all of them together as one mesh, and step through them.

I’ve made a material before that randomly picks a mesh based on it’s vertex color, but I’ve only done that with pure red, green and blue in the vertex color and using one IF expression.

Is there an efficient way to accomplish this? I’m using Max 2015, and I’m unsure if it has the means to export vertex animation out of the box like Andreas does in Houdini. The mesh also needs to keep its current UVs. I’m sure I could brute force a material to test and cycle through different values of vertex color with a bunch of IF statements. I feel like there’s a more elegant material solution if I did go the route of combined meshes with different vertex color values, I just can’t think of one atm

3 Likes

2nd uv channel - if you’ve packed all the snapshots into one mesh then you can just add a second uv set that has each whole mesh unwrapped along the X axis. then you just scroll a texture along it and you’ll get animation - super useful technique for things like butterflies or lightning meshes.

you could definitely also just do it with math too tbh - just using values of the red channel if you have eg 10 meshes - do Vert R + Parameter > Frac > - 0.9 > Clamp(0-1) * 10. This will only show Verts that were painted in the 0.9-1 range (the subtract then clamp hides the rest) and the Frac(Red Value + Parameter) allows you to cycle through which Verts are in that range.

hope that helps!

EDIT - you have to paint the meshes in values of Red in increments of 0.1 if that wasnt clear from the text, also you might want to do *100 and clamp again to ensure values of only 0 and 1)

4 Likes

Does Unreal read vertex color in a 0-1 space, or does it read and output it in the 0-255 range? I think a chunk of my problem with this problem is I don’t know what values it’s even outputting my color ranges as. I wish there was a node that would display the number values that it received from an input, like a voltage meter.

I’m pretty sure it’s all 0-1, linear space. Try using the debug scalar/vector nodes, they’re super useful.
Also, this is such a good idea! Never thought about doing this. Mesh flipbooks here I come

2 Likes

I figured out a setup if you want the info. It’s kinda brute forced, so I’m sure there’s a more robust way to accomplish what I did.

Also that DebugScalarValues is one of the most useful and greatest things ever, thanks! That would have saved me so many hours of tweaking for more than a few materials :sob:

I’m fairly new to game vfx but I do think this is a good case for vertex animation, using the dynamic parameter to set the shader to the specific frame you need to call. I recall seeing a vertex animation max script in the extras folder of unreal, but I am a Houdini user so I’m not sure if the features are the same. It would be a simple pipeline since you wouldn’t have to repaint anything if the mesh or animation change.

Yeah I used the Max script, but the method using vertex color could be used or useful in Unity and doesn’t use any Unreal-specific material nodes. You’d probably need shader forge to set it up, but that’s about it

1 Like

Ah smart. I tend to build effects to work best for the project at hand, but you may as well make it universal.

Vertex animation method gave smoother results, so I went with that, but the vert color method would be good for picking random meshes in a pack for something like debris chunks, mesh lightning, or modeled tech shapes (etc)

1 Like

You can pack 256 meshes in just the red channel. All you need to bit mask it. Basically, you assign a mesh to 1 bit instead of filtering it on the color channel like you used to. Then you can check if that bit is 1 or 0 and with use of the shift operators (<< and >>) you can have you shader look for a specific bit to find your specific mesh. This way you can filter meshes based on if the color of red channel is 1/256 or 2/256 etc…

This can help: https://stackoverflow.com/questions/141525/what-are-bitwise-shift-bit-shift-operators-and-how-do-they-work

3 Likes

Thanks a bunch! I’ve got some potentially cool stuff I can use this on in the near future

Hey @Travis, did you get this to work? Would love to see what you did. Very clever approach.

I did, though I don’t have the material handy to show right now

We used this technique on Robo recall as a draw call optimization for selecting multiple debris meshes in a single draw call. One thing to note: you are still processing all of your vertices on the vertex shader, they just aren’t being rendered (depending on if you collapse the unused verts to 0,0,0 or push them offscreen or both. Depending on how many vertices and frames you have, the shader can still be very expensive even though your final triangles on screen are reasonably low on any given frame.

1 Like

I ended up doing something similar myself actually. But I also needed the vertex color. So I used UV paging. Basically, the idea is to unwrap UV into say 0 to 1 space in the V coordinate, then offset the V coordinate for a group of verts that belong together by exactly 1, then do same for the 2nd group, but offest V by 2.

In the shader, it won’t change the texture since UV only really care for the fraction, but by checking the V coord unit integer, you get the ID of the sub mesh you want! Can do same with or without the U coord, depending how many layers you want or for things like cycle through U, but pick a random V row… Etc.