Vector to Retro: Pixelate Your Art in Godot with One Shader

published today
A conceptual image showing a smooth vector graphic transitioning into a pixelated version, highlighting the Godot shader's effect.
Unlock a fast path to pixel art aesthetics by 'demaking' your clean vector graphics with a surprisingly simple Godot shader.

Pixel art has a timeless charm, but crafting it meticulously pixel by pixel can be a demanding skill. What if you prefer drawing with clean lines and smooth curves, but still want that retro aesthetic for your game? One approach is to "demake" your existing art.

Instead of building up from individual pixels, you can start with higher-resolution art and then intelligently reduce its detail. This post covers a simple Godot shader that does exactly that, transforming your vector-style graphics into fun pixel art with minimal fuss.

Visualizing the Transformation

Before getting into code, the best way to understand the shader's impact is to see it in action. Let's use the Godot logo as the clean piece of digital art and take a look at the different variations produced by the shader.

Pixel Size Variations (Colors Unchanged)

Original clean vector art before pixelation

Original Art

Art pixelated with 8px block size, colors unchanged

8px Block Size

Art pixelated with 16px block size, colors unchanged

16px Block Size

Art pixelated with 32px block size, colors unchanged

32px Block Size

Color Steps Variations (at 16px Block Size)

Art with 16px blocks and 1 color step (2 shades per channel)

1 Color Step (at 16px)

Art with 16px blocks and 2 color steps (4 shades per channel)

2 Color Steps (at 16px)

Art with 16px blocks and 3 color steps (8 shades per channel)

3 Color Steps (at 16px)

Art with 16px blocks and 4 color steps (16 shades per channel)

4 Color Steps (at 16px)

This visual comparison makes it clear how you can quickly dial in different levels of pixelation and color reduction to achieve the exact retro style you're aiming for, from subtly chunky to more pixelated.

The Simple "Demake" Shader

This Godot shader takes your clean, potentially vector-like, artwork and gives it a pixelated appearance. It works by effectively reducing the resolution of the image in real-time. Additionally, it includes an option to limit the color palette, pushing the retro feel even further.

Let's look at the code. It's pretty concise for the effect it achieves:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
shader_type canvas_item;

// controls how big each "pixel" will be.
// higher numbers = bigger pixels = more pixelated look
uniform float pixel_size = 1.0;

// turn on to reduce the number of colors for that classic retro look
uniform bool reduce_colors = true;
// higher numbers = more colors = smoother look
// lower numbers = fewer colors = more 8-bit retro feel
uniform int color_steps = 4;

void fragment() {
    // find how big the texture is
    vec2 tex_size = vec2(textureSize(TEXTURE, 0));
    
    // where the magic happens!
    // 1. divide the texture into big squares (pixel_size × pixel_size)
    // 2. find which big square the current pixel belongs to
    // 3. use that big square's color for ALL pixels inside it
    vec2 pixel_uv = floor(UV * tex_size / pixel_size) * pixel_size / tex_size;
    
    // get the color at our big pixel position
    vec4 color = texture(TEXTURE, pixel_uv);
    
    // optional: reduce the number of colors for extra retro feel
    if (reduce_colors) {
        float step_amount = 1.0 / pow(2.0, float(color_steps));
        color.rgb = floor(color.rgb / step_amount) * step_amount;
    }
    
    COLOR = color;
}

Key parameters you can control:

  • pixel_size: This determines the size of the "virtual" pixels. A higher value means larger blocks, resulting in a more pronounced pixelation. Start with values like 4.0, 8.0, or 16.0 and play with it.
  • reduce_colors: A toggle that, when true, will reduce the color palette to a smaller number of colors.
  • color_steps: An integer that dictates how many distinct color values per channel (Red, Green, Blue) you'll get when reduce_colors is active. Lower numbers (e.g., 2 or 3) give a more 8-bit look since each color channel has fewer values/steps.

Lightning Fast Godot Setup

Applying this shader in Godot is incredibly straightforward. Here's how you can get it running in under a minute:

  1. Create or Select a Sprite2D Node: In your scene, either add a new Sprite2D node or select an existing one that you want to pixelate.
  2. Assign Your Texture: In the Inspector panel for theSprite2D, assign your clean PNG (or other image format) asset to the Texture property.
  3. Create a New Shader Material:
    • Scroll down to the Material property under CanvasItem section in the Inspector.
    • Click on [empty] and select New ShaderMaterial.
  4. Create and Edit the Shader:
    • Click on the newly created ShaderMaterial resource to expand its properties.
    • Find the Shader property, click on [empty], and select New Shader.
    • Click on the new Shader resource. This will open the Shader Editor at the bottom of the Godot interface.
  5. Paste the Code: Copy the shader code provided above and paste it into the Shader Editor, replacing any default code.
  6. Adjust Uniforms: Back in the Inspector, with the ShaderMaterial selected, you'll now see a "Shader Parameters" section. Here you can tweak Pixel Size, toggle Reduce Color, and set Color Step directly.

That's it! Your art should now be pixelated in the game view. You can experiment with the pixel_size and color reduction settings interactively to find the perfect look. Use the image below if you need help finding the right settings to be able to tune the shader.

A screenshot of the Godot interface showing the shader setup process.

Why This Approach Shines

The beauty of this shader-based method lies in its flexibility and non-destructive nature:

  • Speed and Iteration: You can draw or obtain high-resolution assets and then quickly see how they look pixelated without redoing any artwork.
  • Maintain Original Assets: Your source art remains clean. If you decide against pixel art or want a different style later, you haven't lost your original work.
  • Dynamic Control: You could even animate the pixel_size or color_steps via script for interesting visual effects during gameplay.
  • Accessibility: It lowers the barrier to achieving a pixel art look. You don't need to master specialized pixel art tools or techniques upfront; you can leverage your existing drawing skills.

This technique empowers you to explore a popular aesthetic without being locked into a time-intensive creation process. It's just one example of how Godot's shader system can provide powerful visual transformations with minimal code, letting you spend more time on your game's design and feel.

Happy demaking,
James