User Guide (v1.8)

Requirements

The package has the following minimum requirements*:

Please let me know if you find it working without these requirements, or not working with them!

I have tested using the following versions of Unity:

Build Targets

I've tested:

If you are interested in how ProPixelizer works, I give a brief description of the pixelization process in this article, under Attempt #3. I intend to write more technical articles in the future. Feel free to contact me on Discord or twitter with questions!

Getting started

First, make sure you have the Universal Render Pipeline package added to the project (you can add this using the Unity Package Manager). 

Import ProPixelizer from the Unity Package Manager; it must be located at Assets/ProPixelizer, which is the default location Unity suggests.

If the Shader Variant Limit is set too low, ProPixelizer will raise a warning in the console. You can increase the setting (e.g. to 256) via Edit > Preferences > Shader Graph. After raising the limit, right click and reimport the ProPixelizer folder to recompile the shaders.

Setting up the Project

You can either 

You will need to set the Render Pipeline Assets in both Project Settings > Graphics  and Project Settings > Quality. ProPixelizer will warn you if one of these is unset, or if they are not equal. In recent versions of URP there are multiple RenderPipelineAssets by default, with one associated with each different quality setting.

Adding ProPixelizer to your own Render pipeline asset

In the Universal Render Pipeline Asset, make sure 

(you can override both of these at the camera level too)

Select the Renderer asset (here - ForwardRenderer, in the RendererList). Below Render Features click Add Render Feature, and select Pixelisation Feature to add the render feature required for ProPixelizer.


Note that some Unity versions have a crash bug in the SRPBatcher - if you experience crashes, try disabling the SRPBatcher - see 'Crashing in 2021/2022' below. The unity bug report on this issue is here. The bug has been fixed in recent versions.

In 2021 LTS, if the RenderPipelineAsset for your chosen Quality setting uses the SSAO render feature, change the 'source' property of the SSAO feature from DepthNormals to Depth.

Setting up the camera

Configure the camera as follows:

Post processing can be used, e.g. Bloom and Vignette, and configured through a Volume as per the usual Unity workflow.

For best results, it is strongly recommended to use orthographic rather than perspective projection. This is because pixel creep can only be fully eradicated for cameras using orthographic projection; under orthographic projections the size of an object does not change as it moves around the screen.

Add the Camera Snap SRP MonoBehaviour to the camera game object. This behavior is used to snap pixelated objects and prevent 'swimming' artefacts. More information can be found in the section Eradicating Pixel Creep below.

Updating from previous versions

Updating to v1.4

Updating to v1.6

Updating to v1.7

Updating to v1.8

Check out the examples!

ProPixelizer includes a number of examples to show various setups:

Pixelized objects: materials setup

Objects can be pixelized into macropixels of size 1x, 2x, 3x, 4x, and 5x screen pixels.

ProPixelizer draws pixelated objects by applying two passes:

ProPixelizer provides a PixelizedWithOutline material shader, which adds all required passes to an object. The forward 'appearance' passes are generated by a Shader Graph shader called ProPixelizerBase, which are included in the PixelizedWithOutline shader using Unity's UsePass ShaderLab feature.

PixelizedWithOutline material

The PixelizedWithOutline material adds all passes required to draw and outline the object. It uses a custom editor inspector and categorizes the shader properties as follows:

Technical note for advanced users: If you are writing your own ShaderLab shaders, you can perform the pixelisation and outline within a single material shader. In the fragment shader, you should clip() the output of PixelClipAlpha_float in PixelUtils.hlsl, and also add a separate Pass with Tags "LightMode" = "Outlines", which you can create by including  OutlinePass.hlsl

Eradicating pixel creep

Pixel creep is a problem that occurs frequently when rendering 3D objects as pixel art - the object appears to shimmer as it moves across the screen. An example can be seen in this video: https://www.youtube.com/watch?v=lO8O5tY-wZI . The creep occurs because both the number of pixels that an object occludes, and the alignment of the object with respect to the pixels, changes as it moves across the screen.

Pixel creep can be removed by aligning objects to the pixels of the screen before rendering them. Pixel creep can only ever be solved for orthographic projections; in a perspective projection, the object size changes as it moves on the screen.

For orthographic projections, ProPixelizer provides functionality to handle this for you, through two MonoBehaviours:

These MonoBehaviours will snap object positions before rendering and restore them afterwards. The implementation respects transform hierarchies.

Snapping angles

The ObjectRenderSnapable MonoBehaviour can also snap the angles of objects being rendered. Set ShouldSnapAngles to true if object angles should also be snapped, by the desired Angle Resolution. If you have nested transformations (eg for equipment), I recommend you only do this on the root transform.

Aligning pixel grids

The ObjectRenderSnapable MonoBehaviour also provides a way to align the pixel grids of child objects to their root transform. This is useful for things like equipment - you have different meshes but want the complete object to look like one sprite. Set the property Align Pixel Grid to true to cause the object's pixel grid to be aligned with the Pixel Grid Reference transform, or the root transform of the heirachy if this property is none.

An example is given in the picture on the left, showing how the blue/green shield looks when it is and is not aligned to the pixels of the root transform. Look closely within the circles - on the unaligned you should be able to see the slightly 1 pixel misalignment of the two objects with 3x3 pixelsizes.


(Optional) Control over object outlines

Exterior outlines are drawn whenever two adjacent pixels have a different ID, as determined from the Outline/ID material property.

The OutlineControl MonoBehaviour provides some extra ways to control the outlines of your objects:

Note that many of these changes will only take place once you hit play mode (they require instancing the material).

Technical note for advanced users: The ID is rendered into the ProPixelizer metadata buffer with 8-bit precision, so only 256 different values of ID can be specified.

Depth Test outlines

This option is found on the PixelisationFeature on the ForwardRenderer asset. When enabled, outlines will only be drawn for edge pixels that are in front of their neighbors. This helps achieve the feel of a hand-drawn sprite, for which the outline would not change depending on the geometry in front of it. A comparison of the two settings is shown in the image here; take particular notice of the darker outline drawn over the vehicle inside the red box when Depth Test is off.

Color palettes and dither pattern tools

Many old games used reduced color palettes, often due to hardware limitations! For example, the original GameBoy could only display 4 different brightness values, and the SNES could only display 256 colors at once. Games sometimes employed dithering to emulate an increased color depth.

ProPixelizer gives you a set of tools to create reduced color palettes and dither patterns. Both are combined into a texture Look-Up Table (LUT) which is sampled when rendering the object to color grade with minimal overhead.

Dither patterns

ProPixelizer supports 4x4 dither patterns. You can design your own dither pattern by creating a dither pattern asset (Create -> ProPixelizer -> Dither Pattern). The editor will display a 4x4 grid of values, and a preview of how the dither pattern will appear for a smooth monochrome gradient. Each 'value' in the grid ranges from 0 to 16, and shows the 'threshold' at which this pixel in the 4x4 pattern will be enabled. Some example patterns are included (ProPixelizer/Palettes/DitherPatterns).

Color palettes

You can configure your own palettes using a palette asset (Create -> ProPixelizer -> Palette). After configuring the palette, use the 'Generate' button to create a texture LUT that you can use in your ProPixelizer materials.

A number of properties can be configured:

Stepped animation tools

Traditional pixel-art games used hand-drawn sprite sheets, and characters were animated by changing which sprite was displayed - the result was like a 'flipbook', with a few well defined poses. For instance, the cycle for a run animation could be ~5 frames long. 3D animations, on the other hand, commonly interpolate between key frames to produce smooth movement.

To help users achieve a flipbook effect, ProPixelizer provides a utility for automatically converting animation clips into stepped versions. A copy of the animation clip is created, keyframes are decimated, and the interpolation is set to None. This utility allows you to use many standard animations (e.g. from the Asset Store) in a way that keeps the pixel art aesthetic.

To use these tools, create a Stepped Animation asset (Create -> ProPixelizer -> Stepped Animation). After configuring, click 'generate' to create copies of the source clips.

Lastly, if you are using clips with anim trees, you may also wish to turn off the blending for the anim tree - otherwise changes of state will interpolate between frames, and break the flipbook feel.

Tips for achieving a good pixel-art feel

Below are a collection of tips to bear in mind when using ProPixelizer:

Note that you can also do neat things not normally seen in pixel art games, such as depth-of-field post processing, procedural animations, etc.

I hope you enjoy using ProPixelizer. Please do message me if you have any questions or problems. I'm always very pleased to hear what you make with it!

Cheers,

Elliot

FAQ

My object looks like a bunch of dots?

The problem: Pixelated objects appear as a bunch of dots when rendered, as if dithered.

The solution: The Pixelisation Feature needs to be added to the Render Features of the Scriptable Render Pipeline - see 'Setting Up The Render Pipeline' under 'Getting Started', above.

If you are interested in why it looks like this, you can find the answer in this Medium article which describes how ProPixelizer works. The method used for ProPixelizer is described under Attempt #3; objects are first drawn as a dithered matrix of dots, then the post process fills the surrounding screen pixels to produce the final pixelated image.

If you see a shader error in the console when compiling the ScreenPostProcessing shader, please email me with details! The dots will also appear when the post process is not working, which is a bug.

Note that ProPixelizer also implements dithering for transparency when the materials alpha is not 1 - this applies to both texture and color. If the example scenes are rendering correctly, but your assets are appearing dithered, check that the alpha of your material color and textures.

The shaders are coming up pink!

This means that the ProPixelizer shaders have not been correctly compiled by Unity. There are typically two possible reasons this occurs:

Objects became invisible!

Sometimes Unity's library seems to incorrectly compile the PixelizedWithOutline shader. You can fix it by just right-clicking and reimporting the ProPixelizer/SRP/PixelizerWithOutline shader. In v1.7 I have added some tools to do this automatically, e.g. when the editor starts up or when you press play. This issue is also related to the SRPBatcher issues - see my post on the forums reporting this for a non-ProPixelizer use case.

[Worker0] Texture creation failed. 'None' is not supported for Render usage on this platform. and Blank Thumbnails

This error is currently occurring on some Unity 2021 and 2022 versions when the Opaque Textures checkbox is enabled in the Render Pipeline Asset. For more information see this thread on the unity forums.

You can disable Opaque Textures in the Render Pipeline Asset and ProPixelizer will still work.

Crashing in 2021/2022

Some users are experienced when using recent versions of 2021 and 2022. After investigation, these appear to be the result of a bug recently introduced to the SRPBatcher. It does not affect builds, only editor. The Unity Issue Tracker for this issue is here.

As a temporary workaround, either roll back to 2021.3.6f1 LTS (where the bug does not occur) or disable the SRPBatcher by finding the option in your Forward Renderer Asset, using the inspector in debug mode (right click the 'Inspector' tab and click debug):

Update history

Version 2.0 (under development)

Version 1.9 gradually evolved into a large enough update to warrant skipping to 2.0. 

Version 1.8

Version 1.7

Version 1.6

v1.6 adds significant new functionality to outlining. You are strongly recommended to use the Appearance+Outline material.

Version 1.5

Version 1.4

Version 1.3

Version 1.2

Feel free to email with feature requests and suggestions!