TUTORIAL: easy lo-fi Pixel Goodness in Unity
pre-disclaimer: this used to be on my patreon! and is old and maybe bad! :) it was also pre-URP!
Hi!! I’m Max. If you know me from my in-development LAUNDRY GAME (yes, that is a shameless plug), then you know my visual style is based around BIG CRUNCHY PIXELS IN 3D. Low-res 3D is my absolute shit. I get a lot of questions about it!! so!! Here’s how I do it!!
disclaimer: this is just how i do it! there are ways that involve shaders and blitting graphics and all sortsa nonsense but for a small, solo project, this is quick and easy and works well for me :)
edit 1: certified smart human Pete Brisbourne replied here with a script in case you don’t want to do the “quad in the sky” trick (steps 4–6)!
STEP 1: SET UP YOUR INITIAL SCENE
First off, set up your scene!!! I made this lil cube nightmare starring Oscar J. Ruffles, certified bird friend. He runs around and he shouts a whole bunch. (This is just a thrown together character controller and animator.)
BUT look at all those gross anti-aliased lines ew ew lets get rid of em
STEP 2: REMOVE THE MSAA FROM THE CAMERA
Grab your Main Camera and untick that “Allow MSAA” box.
As you can say, this crisps things up a LOT already. But there’s no upscaling! Which means the pixels will all be tiny :(
So we’re gonna change that!!! :)
STEP 3: RENDER THE CAMERA TO A RENDER TEXTURE
SO!!!! The way I do the upscaling (to get those BIG old crunchy pixels) is by creating a RenderTexture and rendering my Main Camera to that. This allows us to use that RenderTexture as we would any other texture!
Here are the settings I would use on your RenderTexture. The size is the size that you’re gonna upscale from. The smaller the number, the bigger the pixels. I tend to use something around the 300 to 600 region for both values (the excellent Celeste, for example, upscales from 320x180).
Filter Mode is how the texture handles up/downscaling. “Point” adds no smoothing and as such keeps those crunchy pixels that we so desperately desire.
but, what’s this now
Now that we’re rendering our Camera to a RenderTexture instead of the screen, there’s nothing rendering to the screen! OH NO!!!
To fix that, we need to set up another Camera, but this one a little differently.
STEP 4: CREATING YOUR UPSCALING CAMERA + QUAD
To begin with, I create a new Camera in the scene (naming it QuadCamera) and attach a 3D quad as a child object.
STEP 5: STICK IT IN THE VOID SOMEWHERE
We then want to take our new QuadCamera and shove it somewhere. It doesn’t really matter where, as long as it’ll never be visible by the Main Camera. I tend to throw it way up into the sky or way down into the dark, uncaring void below.
STEP 6: ATTACH THE RENDER TEXTURE TO THE QUAD AND PUT IT IN FRONT OF THE CAMERA
Next, we take our quad. I have the material set as “Sprites-Default” (an unlit material that comes with Unity) just so it isn’t affected by any stray lighting in the scene. Then, drag your RenderTexture onto the quad. Now the quad is showing our scene! Then we move the quad so its in front of the QuadCamera, which is the camera that is now rendering to our target screen.
As you can see, we’re now rendering upscaled!!!!! Oscar can flap his big pixelly beak all day long!!!!!!!! But we’re also a lot closer to his feathery face than we probably should be (bird flu and all that).
STEP 7: ADJUST THE CAMERAS
As a final step, I scoot on back to my Main Camera and adjust it so the amount we see is roughly the same as it was when we first looked at the scene. From there, you may want to increase the size of the render texture so the pixels are a bit smaller, or you may be a lo-fi dork like me and want a total of 7 pixels on your screen at any given time!! This is the part where you can just play around with what you have and find what works for you :)
BONUS: MAKING SURE YOUR TEXTURES AREN’T BLURRY
As you’ve seen so far, the texture for this model (Oscar’s big birb eye) has been blurry this whole time. That’s because importing textures in Unity gives them a default properties set up to generate mip maps and to scale smoothly. BUT as with everything else, we don’t want that. So, when importing your textures, make sure to switch off Generate Mip Maps and change the Filter Mode to Point.
AND WE’RE DONE
As usual, these tutorials aren’t exhaustive. If you have a better way to do it, feel free to let people know in the comments! if not, I hope it helps someone :-)
THANK YOU FOR READING LOVE YOU BYE