Setting up Blender for 3d pixel art modelling and texturing

I’m fascinated by very low-poly 3d models with low resolution textures. It’s something that I adore. Alongside it, I’m also interested in trying to combine pixel art with 3d models. Thus, I’m writing this article mostly for myself since I tend to forget this stuff.

“Lowpoly Bear Mech” by KennethFejer “Lowpoly Bear Mech” by KennethFejer

For 3d modelling I use Blender – a powerful, free and open-source 3d modelling software, hence these instructions are very much Blender specific. Specifically Blender v3.4.1 specific.

Setting up the modeling environment

First and foremost, we have to get rid of the units. Meters, freedom-units or whatever. What we want is the None units. If you haven’t changed the default Blender layout, you can change the units by going to the right side where properties panel resides and find Scene properties. There you’ll find Units. Expand it and change the Unit system to None.

Instructions for setting the unit system to none in Blender Instructions for setting the unit system to none in Blender

By setting our unit system to none, we have unlocked a setting of the most importance – the grid’s subdivision. Access the Viewport Overlays located at the top-right of your default 3d cube model (see image bellow). There, change the Scale to 0.0625. Also, set the Subdivisions to 16 which will become our “pixel-perfect” grid.

Instructions for setting the scale and grid subdivisions in Blender Instructions for setting the scale and grid subdivisions in Blender

You can change the subdivision to whatever you want. But for pixel-art related work people often work in power-of-2 sizes (meaning that the default subdivision of 10 doesn’t fit in with our wishes). If we’d like to use 8 for our subdivisions, then the scale would be 0.125. By setting scale accordingly to our grid subdivision quantity we make sure that 1 unit of our unit-less system is always correctly subdivided on our grid. As you probably already noticed, the formula for scale is scale = 1 / subdivisions.

Notice that each different viewport has their own Viewport Overlays settings. You’ll have to set the scale and subdivisions in each of them separately if needed (e.g. UV Editing).

Now if we press the key “1” on your NumPad (if you’re rich enough to have one), you’ll enter the Orthographic view of the front of your model. To the less keyboard-able people you can achieve the same by navigating the menu above View > Viewport > Front. As you can see, we now have a grid of 16 “pixels” every major grid line. Because our default cube is 2 by 2 by 2 in unit size, that means every single face is 32 by 32 “pixels”.

Example of our 16 subdivision grid for every 1 unit-less unit in the Front Orthographic view of our default 3d cube Example of our 16 subdivision grid for every 1 unit-less unit in the Front Orthographic view of our default 3d cube

Don’t forget to snap your vertices to the grid while moving or extruding. You can also navigate the menu in Edit Mode to fix off-grid vertices by selecting them and navigating to Mesh > Snap > Selection to Grid if needed.

Setting up the materials

Before diving in into UVs and texturing our polys, we should first set up our materials. I assume that we’re smart enough to know about the basics of materials, unwrapping, and texturing so I won’t explain them here. I’ll only mention the things that I often forget or misremember.

Create a new material and switch to the shading workspace. There, add an Image texture node and load some low resolution texture by clicking on the folder icon. Setting Texture interpolation to Closest is what keeps our textures pixelated. Then add Emission, Transparent BSDF and Mix Shader shaders. Emission gets our texture’s color while the Mix Shader‘s Fac gets our texture’s alpha value.

Emission is the colors of our material in “full-bright” mode while Transparent BSDF, as the name implies, is what brings transparency into our material. While mixing the shaders, the order matters! Transparency goes first, and emission goes bellow it. Otherwise we’d need to inverse the alpha value which would involve an additional Math node (inverted_alpha = 1 - alpha). That is because when Fac is at 0 the shader above is used. Vice versa, when Fac is at 1 the shader bellow is used. Anything between 0 and 1 returns the blend between the two.

Needless to say, if you won’t use transparent textures, you can throw the Transparent BSDF and Mix Shader away and pipe the Emission to the Material Output‘s Surface input directly.

Blender material node graph with an Image Texture, Emission, Transparent BSDF, Mix Shader and Material Output nodes and the connections between them Blender material node graph with an Image Texture, Emission, Transparent BSDF, Mix Shader and Material Output nodes and the connections between them

We can now switch to the UV viewport and start unwrapping our models. But take note that the scaling and grid subdivision that we set before don’t carry over to all viewports. Hence we need to open the Viewport Overlays again and set the Scale and Subdivisions to 0.0625 and 16 accordingly (just like we did before).

When editing UVs, lets not forget about making sure our UVs snap to pixels. Because UV points are stored as floats, we have two rounding to pixel options: round to corner and round to center. Pick Corner as Center would snap right in the middle of the pixel leaving us with less than half of a pixel which is not really ideal for us most of the time.

Menu navigation that enables snapping UV vertices to pixels Menu navigation that enables snapping UV vertices to pixels

Lets not forget to enable Viewport Shading so that we could see how our textures look on our models while unwrapping.

How to select Viewport Shading if it’s hidden by using middle mouse button to scroll the menu bar horizontally How to select Viewport Shading if it’s hidden by using middle mouse button to scroll the menu bar horizontally

Animation of grabbing and dragging a menu with middle mouse button in Blender Animation of grabbing and dragging a menu with middle mouse button in Blender

Once done, your pixelated textures should more or less look pixelated.

A most basic 3d example with our pixelated materials A most basic 3d example with our pixelated materials

Compositing and rendering

If you want to have a pixelated render of your 3d mesh right inside blender, you’ve come to the right place.

A demo animation of a pixelated render where a weird yellow smiley face moves around the wooden crate surrounded by stone tiles A demo animation of a pixelated render where a weird yellow smiley face moves around the wooden crate surrounded by stone tiles

First of all, we need to “disable” anti-aliasing in our renders. To do that we go to the Render Properties and expand the Film tab. There, we set the Pixel Filter‘s Width to the lowest possible value (which seems to be 0.01px). And lets not forget to enable Transparent while we’re at it.

A reminder: if we want to save our renders with transparency lets not forget to save in a file format that supports transparency like PNG. It’s also best to use PNG for transparent animations if possible. Most if not all video editors allow to import image sequences as video thus preventing any frame-rate issues between video projects and ensuring lossless image quality.

Settings to make rendered lines more jagged and how to enable transparent background for our renders “Disabling” anti-aliasing and turning on transparency Settings to make rendered lines more jagged and how to enable transparent background for our renders “Disabling” anti-aliasing and turning on transparency

What we need next is to node-up a simple compositing tree. It’s a little complex to explain by text so I’ll only mention the key things. Refer to the image bellow on how to connect everything up.

The final render compositing node tree The final render compositing node tree

The gist of it is that we scale our rendered result down by 2 by the power of ScaleFactor (a simple Input > Value node), apply the Pixelate filter that will prevent the image’s colors from being interpolated once scaled back up, and upscale it again to the original render size. Very complex. Oh right, the Power and Divide nodes are both Converter > Math nodes.

Try scaling in whole numbers (e.g. 1, 2, 3, etc.) as we would like the pixels to grow by powers of 2 so that 1 pixel would become 4 pixels and 4 pixels would become 16 pixels and so on.

Hot tip: if you want to make your node wires more manageable, you can hold Shift + Right Mouse Button and drag your mouse over the wire/wires to create a point from which other wires can go from if needed.

Animation showing how cutting node wires with Shift + Right mouse button works in Blender Animation showing how cutting node wires with Shift + Right mouse button works in Blender

Isometric pixel art camera

If we are talking about isometric pixel art, what comes to mind is usually the 2:1 pixel ratio. Isometric pixel art doesn’t really use an isometric projection, but it uses a kind of dimetric projection instead.

Settings for setting up dimetric projection to achieve that “isometric pixel-art” camera angle Settings for setting up dimetric projection to achieve that “isometric pixel-art” camera angle

To achieve this “isometric” pixel art angle in blender, you have to select your camera, in the Lens property set Type from Perspective to Orthographic and we can enter 4.5 for our Orthographic scale. We’ll change this scale later depending on our model/scene size. Then press “N” to open up the Transform properties and set 60, 0, 45 to X, Y, Z respectively.

The Location property of your camera depends on your model’s or scene’s size. But a good starting point would be 20, -20, 16 for X, Y, Z respectively.

Ending notes

I’d recommend sticking to quads as much as possible when modeling. It’s a true headache trying to make triangles not look ugly with pixelated textures.

I know there are at least a few great pixel-art shaders out there that also do fixed color palettes, dithered colors, and good pixelated shadows. There are also blender addons that help minimize texture stretching and do other fancy things. But I’m not that deep into this whole mess, so you have no choice but to forgive me.

I don’t claim that this is the best nor even the correct way of doing this, but it’s what I’m rolling with. I hope I won’t forget to update this article some time later if I find something else that I’d like to write it down as to not forget.

Tags: 3d 3d pixel art blender isometric pixel art