I would like to do pixel-perfect motion of image planes, to simulate older video game graphics and how background scrolling worked. My current method of getting pixel perfect rendering is to import images as planes, and have their plane dimensions as 1 dot per Blender Unit. Works fine when rendering a static image, but as motion is functionally infinitely smooth, I get aliasing when it’s animated. The stepped interpolation curve modifier seems like a step in the right direction, but I’m not sure what values to put in to get it to work the way I want.
Another thing, for simulating parallax scrolling, I parent a bunch of planes to an empty at increasingly lower influence strengths. How could that be accounted for?
I don’t think a step modifier is what you want here. Its controlled only by the step size in time, and you want the step size in space.
The easiest thing to do is to make a big ol’ grid and give everything a shrinkwrap constraint to nearest vertex on that grid. Not sure how many objects you have or how much space your transformations occupy. For the number of sprites and resolution of an old game, it would certainly be doable.
A different thing you could do is to use drivers on your objects that snapped them to the nearest grid point. I believe that would require that you had the keyframed animation on parent objects. Then you could read the parents XYZ pos as driver inputs and return round(X) as pos.X for example.
Not sure what you mean. You mean child-of constraints? Either technique above should work fine with that (although I’m nervous about child-of constraints at <1.0 influence, seems like a dangerous idea; I’d probably be moving background planes with transformation constraints or drivers, or by parenting to a rotating bone without inheriting rotation.)
Ooh, drivers! I didn’t think of that, but that’s brilliant!
Yes, I meant Child Of constraints. Why would you consider <1.0 influence dangerous?
How would the parenting to a rotating bone work? Rotation to transformation constraint?
Because there’s not really any such thing as semi-parenting, so it’s really vague how Blender decided to implement that. You see issues when dealing with other stuff (like character animation) when you interpolate from a child-of 1.0 to 0.0 or vice versa. It’s not the same as interpolating between original and child-of transforms. You may be using some settings where it turns out okay (like maybe if you only child-of location) but in that case, there are other constraints that do that too.
Notice that the planes’ individual bones have “inherit rotation” disabled in properties/bone/relations. If you wanted to, you could floor those bones, or limit location, to prevent them from moving in world Y, but I figure you’re using an orthogonal camera where it doesn’t matter what anything’s world Y pos is. (The bones could also be shrinkwrapped to a grid as described above, or we could give them a driver to get rounded world X position.)
I’m working on a solution! Your input really helped me think about it, and here’s what I’m doing:
Drivers for each transformation channel, except Z, referencing the corresponding transformation of an input object, then rounding the value. I can apply the same thing to scale and rotation if I want dynamic scaling and rotation.
This can easily be done with empties and objects directly, but since I set up bones and parenting, I’m doing that for my test scene. Will update with results!
After testing and comparing my solution with an unmodified version…
I have to say there isn’t any discernible difference between absolute snapping and no absolute snapping.
Probably because I matched up the pixels to blender units perfectly already, and I’m rendering at such a low resolution (320x240px), that it naturally acts pixel perfect. Thanks for the help, though, it was a fun puzzle to figure out!