ProPixelizer is a package for Unity that renders 3D objects to look like 2D pixel art, in realtime.
If you have any questions, please feel free to email me (elliot.bentine@gmail.com - please include ProPixelizer in the subject!) or contact me via Discord (elliotb256). There is also a Discord server for ProPixelizer users.
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!
If you are new, check out Getting Started and then the Examples Below. If you are upgrading from a previous version, see the section at the bottom of the guide for changes and requirements. You may also want to check out the Examples to see what is new!
Cheers,
Elliot
ProPixelizer has been tested using the following versions of Unity:
ProPixelizer v1.8.1
Unity 2020.3.48f1 + URP 10.10.1
Unity 2021.3.33f1 + URP 12.1.13
Unity 2022.3.16f1 + URP 14.0.9
Unity 2023.2.3f1 + URP 16.0.4
The following build targets have been built and tested:
Windows PC (Direct X, openGL and Vulkan APIs)
Mac (Metal API)
webGL ES 2.0 (firefox and chrome), running on a desktop
Android
First, make sure you have the Universal Render Pipeline package added to the project (either add URP using the Unity Package Manager, or use a URP project template if you are starting from scratch).
Second, import ProPixelizer from the Unity Package Manager; it must be located at Assets/ProPixelizer, which is the default location Unity Package Manager suggests.
You can either
use the included ProPixelizer render pipeline asset, or
follow the instructions below to add ProPixelizer to your own Render Pipeline Asset.
By default, the Unity Editor will use the Render Pipeline Asset assigned to the active Project Settings > Quality. If one is not assigned there, the Render Pipeline Asset in Project Settings > Graphics will be used.
Select the Renderer asset (here - ForwardRenderer, in the RendererList). Below Render Features click Add Render Feature, and select ProPixelizer Render Feature to add the render feature required for ProPixelizer.
In the Universal Render Pipeline Asset, make sure that MSAA is Disabled.
Note that cameras in URP can override these settings - although they will use the render pipeline settings by default - so you may need to check your cameras.
Configure the camera as follows:
In Rendering, set Anti-aliasing to None (for nice, crisp pixel edges!)
In Output, make sure MSAA is disabled (if set to Use Pipeline Settings, make sure your pipeline has it disabled!)
Add the ProPixelizerCamera MonoBehaviour to the camera game object. This component provides extra control over ProPixelizer and is required to remove pixel creep.
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.
ProPixelizer comes with a number of example scenes to showcase features and show you how to use the package, which can be found in the ProPixelizer/ExampleAssets folder. Each example scene also contains a 'readme' in the scene heirachy, which you can inspect to find out more information.
ExampleAssets/Example
A simple scene showing a few different ProPixelizer materials. If you see this scene correctly, you've successfully installed ProPixelizer!
ExampleAssets/Edges and Outlines
Shows off the different edge and outline options in ProPixelizer.
ExampleAssets/World Space Pixel Size
A scene that configures a camera to use pixel sizes defined in world-space units. ProPixelizer automatically handles render target scaling and sub-pixel camera movement for you to smoothly maintan the desired pixel size across different camera ortho-sizes and screen resolutions.
ExampleAssets/No Creep
An example demonstrating how to use ProPixelizer to eliminate creep from moving objects.
ExampleAssets/Color Palettes
A scene that randomly changes material settings to show off a wide range of color palette and dither pattern styles. ProPixelizer contains tools for creating your own dither patterns and palettes.
ExampleAssets/Pixel Alignment
Shows you how to restrict sub-pixel relative motion between different objects - useful for aligning inventory items with characters, for example.
ExampleAssets/Camera Stacking
An example scene where ProPixelizer is applied to different cameras in a URP camera stack.
ExampleAssets/Multiple Lights
Demonstrates the use of additional lights in a scene.
Note that you may need to change your Render Pipeline Asset or Universal Renderer Data to enable additional lights and shadows in your project.
The ProPixelizer package includes a number of things to achieve perfect pixelisation in your game.
The PixelizedWithOutline uber shader.
The ProPixelizerCamera and ObjectRenderSnapable MonoBehaviors, which you can use to control pixelization in your scene and remove pixel creep for moving objects.
The ProPixelizerRenderFeature, a scriptable Render Feature which adds ProPixelizer to URP's draw instructions.
All of these components are described in more detail below:
Objects can be pixelized into macropixels of size 1x, 2x, 3x, 4x, and 5x screen pixels.
ProPixelizer draws pixelated objects by applying two passes:
An appearance pass, which reduces the color, adds dither if required, and quantises the shading.
An outline pass, which fills a buffer with information required to draw object outlines (outline color, object ID).
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.
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.
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:
Appearance: Properties for albedo maps, normals maps, emission maps, and whether to color grade the object using a palette.
The Albedo is the base color of the object, further tinted by the Color. The alpha values of these control dithered transparency.
Use Color Grading toggles color grading. The Palette texture property is a texture look-up table (LUT) used for the color grading. A number of LUTs to emulate well-known devices (eg NES, PAL, GameBoy) are shipped with ProPixelizer.
You can create your own palettes by using a palette asset (Right Click -> Create -> ProPixelizer -> Palette) which is used to generate the LUTs. The LUT can also include color dither patterns as demonstrated here. For more information, see the Color palettes and dither patterns section of the user guide below.
Emission and Emission Color can be used to provide unlit colors for your material. Think of laser beams, red eyes on skeletons, etc.
Diffuse and Emissive Vertex Color Weight control how the model's vertex coloring is included in the calculation. Unity's particle system uses vertex color for 'per particle' coloring. Some Synty models have black vertex colors on some mesh areas.
Use Dithered Transparency toggles whether partial alpha (in the range 0 to 1) should be ignored or drawn as dithered transparency.
Alpha Clip Threshold specifies a minimum alpha value required to draw parts of the mesh.
Lighting: Shadow and lighting ramp.
Lighting Ramp is a texture ramp used for cell shading, which helps give a pixel-art aesthetic. When rendering the object, the calculated color Value is used as to sample the lighting ramp.
Ambient Light provides additional light to the object. You can control a blend between block color and scene ambient color/spherical harmonics. This can be helpful to tweak the appearance, in conjunction with the color grading.
Pixelize: Properties to pixelate the object.
Pixel size in the range 1-5. This sets the size of one 'macropixel' in screen pixels.
Outline: Outline related properties.
ID: A number. Outlines are drawn when pixels have an ID different to those around them. If two objects should have outlines when they meet, give them different IDs (eg, two enemies). If they should not have outlines (eg, a character and their equipment), give them the same ID. The value should be an integer in the range (0, 255).
Outline Color: The color to use for the outline. The alpha value controls blending with the scene color. Alpha values of 0 can be used for invisible outlines, 1.0 can be used for block color, and fractions to blend with the appearance material color.
Edge Highlight: This property is used to lighten or darken edges detected by inspection of scene normals. To use it, make sure that 'Use Normals For Edge Detection' is enabled on the Pixelisation Feature of your Forward Renderer Asset. Color values less than 0.5 will darken edges, color values above 0.5 will lighten edges, and values of 0.5 will make no difference.
The ProPixelizerCamera component snaps the position of the camera and any ObjectRenderSnapable objects in the scene when rendering, to remove pixel creep artefacts. It also provides options to configure ProPixelizer independently for each camera:
The Pixel size control affects how the scene is pixelated using ProPixelizer's render target.
Fixed World Space Pixel Size mode: For orthographic cameras ProPixelizer will automatically change the resolution of the render target so that a single pixel is Pixel Size in world space units. This allows you to preserve the pixelization appearance across different screen resolutions, and to smoothly zoom the scene by just changing camera ortho size. For performance reasons the maximum target resolution is limited to that of the screen. When Clamp Camera Ortho Size is enabled, then the camera ortho size will be restricted to whatever is the largest size that can maintain the desired Pixel Size. When disabled, the size of a pixel will not be maintained at large camera ortho sizes.
Fixed Downscaling Ratio: the ProPixelizer render target's resolution is set to a fixed scale of the screen resolution, controlled by the Target Scale.
Render Feature Overrides allow you to control ProPixelizer per-camera:
Enable ProPixelizer controls whether ProPixelizer is used for this camera.
Fullscreen Color Grading LUT specifies a color grading and dither pattern LUT to apply to the scene. You can use this for full screen color grading - although I still recommend per object where possible, because it allows the dither pattern to move with the object.
Use Pixel Expansion specifies whether to use pixel expansion for this camera (see pixelization methods).
The ProPixelizer Render Feature adds the rendering instructions to URP. The settings provide a way to tweak ProPixelizer to your particular use case, as described below:
The Pixelization group configures the methods ProPixelizer uses to pixelate the scene.
Use Pixel Expansion allows pixelated objects to move with apparent sub-pixel motion relative to one another, without pixel creep. I created the method specifically for ProPixelizer, and an overview of how it works can be found here, under Attempt 3. It requires an additional post-process shader to be applied to the scene, but the smooth sub-pixel motion can make certain games feel more responsive.
The Pixelization Filter controls what objects should be pixelated.
Full Scene allows you to pixelate the entire render.
Only ProPixelizer will only pixelate ProPixelizer materials.
Layers will pixelate any objects on the given layer mask. When using Layers, ProPixelizer materials must be on the pixelated layers to draw properly.
The Outline Detection Controls are used to configure properties of the outline and edge detection shaders. More detail is given in the Outlines section of the user guide.
Fullscreen Options allow you to apply Color Grading or dithering to the entire scene by specifying a color palette (you can use ProPixelizer to create your own). These can also be overriden for individual cameras. Note: It's still my firm belief that dithering looks better when applied at the object level, so that the dither pattern can move with the object. ProPixelizer now supports both of these approaches, so don't take my word for it - decide for yourself what you like best!
The Editor Scene Tab gives you options to change the behavior of ProPixelizer in the Editor's Scene tab only.
Debugging allows you to disable warnings generated by ProPixelizer.
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. The creep occurs because both (i) the number of pixels that an object occludes, and (ii) 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 will always change as it moves on the screen.
For orthographic projections, ProPixelizer provides functionality to handle this for you, through two MonoBehaviours:
The ProPixelizerCameraSnap MonoBehaviour, which is attached to your camera.
An ObjectRenderSnapable MonoBehaviour, which is attached to meshes that you are rendering. In ProPixelizer v2.0, the snap behavior is only required for meshes that move in world space; static and stationary objects do not require it.
These MonoBehaviours will snap object positions before rendering and restore them afterwards. The implementation respects transform hierarchies.
An example scene is included to show you how to set this up in ProPixelizer/Example Assets/Floating.
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.
lorem ipsum
lorem ipsum
lorem ipsum
lorem ipsum
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.
My goal with ProPixelizer is to provide you with ways to produce really good-looking, crisp pixel art. Pixel art comes in a variety of styles, hammered out through decades of changing hardware limitations and favored aesthetics. Practically, this means that a good pixelart package must be flexible enough to render a whole range of different styles, because everyone wants something slightly different.
Starting from v2.0, ProPixelizer provides a number of different methods and options for controlling pixelization.
The most common technique used to pixelize 3D scenes is to render them at a resolution lower than the screen, then increase their scale using nearest/point filtering to retain 'crisp' pixels. There are numerous tutorials and assets that use this technique in Unity. In ProPixelizer v2.0, a low-resolution render target is used for some or all of the pixelation, depending on your settings.
ProPixelizer will automatically create the low-resolution render target for you. The resolution of the low-resolution render target is controlled through the properties of the Camera Snap monobehavior, and can either be set to a fixed ratio of the screen resolution, or defined such that a single pixel has a specified size in world space units. The render target's resolution cannot exceed the screen's resolution, for performance reasons.
You may choose to have either the full scene rendered to the low-resolution render target, just ProPixelizer materials, or a selection of layers. This allows you to either create 100% pixel art scenes, or 'hybrid' scenes that combine polygons and pixelart. This later 'hybrid' style is reminiscent of games from the 90s like Breath of Fire IV, Final Fantasy, and Populous: The Beginning where characters where often rendered as sprites and the background often rendered as low-poly 3d models.
As your camera moves through the world, the low-resolution render target will automatically move smoothly with respect to the screen resolution.
Despite being a popular method, using a low-resolution render target has a significant drawback. In order to prevent pixel creep artefacts from occuring, objects must be snapped to the pixels of the low-resolution target. As the target becomes more pixelated, the freedom to move objects becomes more and more constrained. This has a negative effect on the 'controller feel' for games that require precise feedback; motion becomes clunkier because small 'sub-pixel' increments are not possible.
To solve this problem, ProPixelizer provides a pixel expansion method. I created this method specifically for ProPixelizer, and describe its implementation here, under attempt 3. This technique works by drawing objects as a dithered pattern, and then expanding these dots into larger pixels through a post process. The result is that a given level of pixelization can be achieved using a smaller low-resolution target pixel size, and thus smooth movement can be retained. The method also supports per-object pixel sizes.
This image is taken from the Floating example scene, with world-space pixel size turned up, a material pixel size of 5, and pixel expansion enabled. The white lines show a grid aligned to the pixels of the sphere on the left. The cubes on the right are free to move at apparent 'sub-pixel' resolution, without exhibiting pixel creep.
If you want to use Pixel Expansion, simply tick the checkbox in the render feature to enable it.
Some performance guidelines for different platforms can be found below. Note that you can specify different render pipeline assets for different quality settings, so you can automatically build e.g. mobile or webGL with different ProPixelizer settings than PC or console.
Highest performance (android, iOS, webGL)
Full-screen pixelization filter, disable pixel expansion.
Highest fidelity (PC, consoles)
pixel expansion
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:
You can specify an ID to use, or set Use Random ID to true to generate a random ID at runtime.
Set UseRootID to true if the outline material should use the ID of the root transform. This also requires an OutlineControl MonoBehaviour to be present on the root transform. Like with aligning the pixel grids, this is useful for child objects such as equipment attached to a player model - it ensures the outline is drawn around the entire player, and not around each individual piece of equipment. In the image on the left, I have set UseRootID to true on all attached equipment (eg the shield, crossbow, window, etc) but not around the wheels.
The same is also true of color. You can specify the color to use for the outline with Color, and also whether to UseRootColor.
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.
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.
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).
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:
Source Texture: The texture to sample the set of colors from. The text below will tell you how many colors were identified in the source - these are used for color matching when generating the look up table.
Color reduction algorithm: The method to use when deciding which colors are most similar. The comparison can be made in RGB-space, HSV-space, or just using the 'value' of the HSV space (which can work well for monochrome palettes in which hue does not matter).
Dithering: Whether to use a dither pattern.
Output: Options for generated LUT file name.
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.
Below are a collection of tips to bear in mind when using ProPixelizer:
Try to avoid small features in geometry that are less than a pixel in size - otherwise they can flicker in and out of visibility. Low poly assets, like those produced by Synty, work well because they do not have small details present.
ProPixelizer's cel shading looks much better if you import low poly models with 'smooth normals', because it will allow color bands to appear across each face.
Old school sprite art typically only has a few different viewing angles; snap the angles of your objects to achieve the same feel.
Reduce the number of keyframes in animation and use 'constant' interpolation to give it a stepped feel, as if flicking through pages of a sprite sheet.
When using Color Grading, it helps to create your assets while targeting a particular color palette. There are significant differences between the various old-school color palettes. GameBoy is monochrome, for instance, while PAL is dark and grungy.
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
Updating to v2.0
2.0 is a very large update for ProPixelizer! Almost the entire codebase has been rewritten, and many new features have been added.
Despite this, you will not have to do anything to your project or materials. I've taken care to preserve the .meta guids, even when class names have changed or files have been moved, so Unity should use the new class names correctly.
Please first delete the old ProPixelizer folder, and then import the new version to your project. Deleting is required because UPM's import button does nothing more than copy files into the folder, so file paths that exist in v1.8.1 and not in v2.0 will remain in place and cause compilation errors.
Dithered transparency is now disabled by default, but can be enabled through a material keyword via the inspector.
You must now use the single Appearance+Outline material (PixelizedWithOutline) - Appearance will no longer work.
Source Buffer option has been removed - pixelization is now determined only using the ProPixelizer Metadata buffer for better support across the different platforms. The appearance material does not have the passes required to render to the ProPixelizer Metadata buffer (these are added by the PixelizedWithOutline shader).
Some material properties have been named from randomized ShaderGraph strings into more meaningful names.
An automatic material updater has been added to fix both of the above issues. If your materials need to be updated, an update button will appear in inspector which will migrate your materials and properties to the PixelizedWithOutline shader.
You no longer need to add things to 'Always Included Shaders'.
2019 is no longer supported, but both 2020 and 2021 now have LTS versions you can use instead. There is early support for 2022, but please bear in mind the URP API for this version is currently still changing frequently.
Many of the updates can be automatically applied to your materials using the tool at Window/ProPixelizer/Update and Verify Materials. Please back up your project before using it, it will search through all materials looking for ProPixelizer materials to update.
There are now some features of ProPixelizer which require the Outline pass to run. Use the Appearance+Outline material (which includes this pass), not the Appearance material. If you want to remove the outline, just set the outline alpha to zero.
There is now another material to add to the Always Include Shaders under Project Settings > Graphics: Hidden/ProPixelizer/SRP/OutlineDetection. You can see the full list in the 'setting up the project' part of this guide.
I changed the name of some shader keywords to be consistent between outline and appearance materials. After you update, run the tool Window/ProPixelizer/Verify Materials to fix any broken materials in your project (this will update all materials to use the new keywords).
The previous versions of ProPixelizer have been tested on the following versions of Unity:
ProPixelizer v1.8
2022.2.1f1
2021.3.16f1 LTS
2020.3.43f1 LTS
ProPixelizer v1.7
2020.3.36f1 + URP 10.9.0
2021.3.6f1 + URP 12.1.7
2022.1.8f1 + URP 13.1.8
ProPixelizer v1.6
2019.4.33 LTS + URP 7.7.1
2020.3.24 LTS + URP 10.7.0
2021.2.5 + URP 12.1.2
ProPixelizer v1.5
2019.4.28 LTS + URP 7.6.0
2020.3.13 LTS + URP 10.5.0
ProPixelizer v1.4
2019.4.23f1 (LTS) + URP 7.3.1
2020.2.1f1 + URP 10.2.22
ProPixelizer v1.3
2019.3.0 + URP 7.4.x
2020.1.2f1 + URP 8.2.0
2020.2.1f1 + URP 10.2.22
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.
This means that the ProPixelizer shaders have not been correctly compiled by Unity. There are typically two possible reasons this occurs:
In some cases, Unity Package Manager will add the files to the project but not import them correctly.
Solution: Right-click the ProPixelizer folder in your project Assets and click 'Reimport'
In some versions of unity, the shader graph fails to compile because it is generating too many variants. The below error may be seen:
Error in Graph at Assets/ProPixelizer/ShaderGraph/Pixelised.shadergraph at node PBR Master: Graph is generating too many variants. Either delete Keywords, reduce Keyword variants or increase the Shader Variant Limit in Preferences > Shader Graph.
Solution: This can be fixed by increasing the Shader Variant Limit using Edit > Preferences > Shader Graph, e.g. changing from the default 128 to 256. Afterwards, right click the ProPixelizer folder and reimport, then all should be fine.
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.
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.
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):
Added Low-res render target mode.
Added Hybrid low-res render target mode.
Added Full screen pixelisation mode.
Added Full screen color grading option.
Added Full screen dither option.
Added depth testing to normal-derived edges (e.g. to reveal steps)
Added Automatic rescaling to preserve world-space pixel size when zooming.
Added Automatic rescaling to preserve world-space pixel size when changing screen resolution.
Added ProPixelizer SubTarget for ShaderGraph (for advanced users).
Added 'Bevel' edge highlight option (where edges use average surrounding normal for lighting).
Added Automatic world-space pixel alignment of static and unmoving objects.
Added Screen resolution movement for low res targets ('camera subpixel motion').
Added Lots of new example content and notes, showing you how to get the most out of ProPixelizer!
Added Support for Forward+ rendering path.
Reduced The number of material keywords and changed some to shader_feature_local, which should give faster compile times.
Fixed Depth buffer post-processing effects in 2022.
Fixed greatly improved the edge detection kernels to give 1px edges more reliably.
Renamed ProPixelizer material properties to match Universal Lit convention (run Window > ProPixelizer > Update and Verify Materials)
Version 1.9 gradually evolved into a large enough update to warrant skipping to 2.0.
Added ObjectRenderSnapable no longer required for static objects - snapping will occur automatically!
Added Warning when MSAA is enabled (this is a common cause of confusion).
Fixed Line artefact on iOS and some mobile targets (caused by numerical imprecision).
Fixed Support null render pipeline in quality settings/graphics settings.
Fixed WebGL: error on some browsers for 'Active draw buffers with missing fragment shader outputs'.
Fixed WebGL: depth output/transparents not working on some browsers.
Fixed ProPixelizer namespace used for everything.
Fixed _ProPixelizer_Pixel_Scale affects outline buffer (thanks gridmaniac for report!).
Fixed unsubscribe from camera events when camera disabled (thanks GamingLee for report!).
Fixed 'cannot implicitly convert from 'Texture2D<float4>' error.
Fixed Scene tab camera depth in 2021 and 2022 (affects Gizmos and grids).
Fixed Preview cameras for ProPixelizer materials.
Added support for Unity 2022.2. This required significant work to get things running in URP14, which contained a number of breaking API changes.
Added support for scene ambient light and SH probes. The AmbientLight property now has an alpha channel - use this to control blending between scene ambient light or the color specified by the AmbientLight property.
Added weights to control how vertex colors should be used (e.g. emissive, diffusive, or not at all). Vertex colors are used to store per-particle color by unity's particle system.
Added an example scene with randomized materials to give an idea of how to achieve different looks.
Added a global shader variable (float) _ProPixelizer_Pixel_Scale, which can be used to change scale of all ProPixelizer materials.
Added a keyword toggle to enable/disable the use of dithered transparency when alpha < 1.
Reintroduced alpha clip threshold property.
Fixed depthAttachment error on Mac/Metal
Fixed inconsistent dither pattern over large objects.
Fixed line artifacts on extremely high resolution screens.
Fixed artifacts when URP RenderScale is not 1.
Fixed Preview window not working in some versions.
Known bug (2021.3/2022): Crash or invisibility when SRPBatcher is enabled. The SRPBatcher remains broken with any USEPASS shaders in recent versions of Unity. I have reported this to Unity, and given minimal examples (see here), but all I can do is wait for them to fix. Does not affect builds.
Known bug (2022.2): Dots in preview window. The preview window is bugged in this Unity version, see here and here for more details.
Added [MainColor] property attribute for PixelizedWithOutline shader.
Added option to snap object angles in camera space, to help create a 'billboard' effect.
Added alpha support for Edge Highlight Color - set alpha to zero to disable edge highlights.
Added an example showing camera stacking setup, and how to avoid creep on moving cameras.
Added tool to the shader GUI to detect if materials need to be upgraded, and to handle upgrade.
Added _EmissionColor property. _EmissionColor is multiplied by the emission texture to determine unlit appearance. It's great for damage flashes!
Added additional messages to warn users when they haven't set the RenderPipelineAsset in the Graphics or Quality settings.
Added Palette option HSV_Weighted_SquareDistance.
Added Larger selection of preset dither patterns.
Fixed Mac M1 soft crash bug (caused by index out of bounds exception when sampling the 4x4 dithered order array for transparency).
Fixed no longer required to add shaders to the always included list when setting up the project.
Fixed support for vertex colors, so that particles are now colored.
Fixed Incorrect blending with transparent materials on some platforms/engine versions.
Fixed Some bugs in the RenderSnapable system, added new features.
Fixed annoying console error messages from incorrect PostProcessPass format.
Fixed unpixelized objects appear pixelated when occluding a pixelated object.
Fixed objects dithered using _BaseColor.alpha < 1 will now no longer prevent objects behind them from being seen.
Fixed Null reference exception if user has render pipeline set in GraphicsSettings but not in QualitySettings.
Fixed material properties have been given more sensible names (e.g. _Albedo instead of Texture2D_FBC26130). Examples have been tidied, with example separate appearance and outline materials removed. I've added migration tools to enable material properties to be automatically upgraded through the inspector.
Fixed Saturation/Value weights in Palette.
Fixed Disappearing materials when opening Unity (caused by UsePass in PixelizedWithOutline failing to import forward rendered passes from the shader graph if imported before the shader graph).
Fixed RTHandle support required for 2022b (URP 13.1 and higher).
Removed the Object outline shader, added OutlinePass.hlsl.
Removed Option to choose source buffer used for pixelisation. ProPixelizer now always uses the ProPixelizer buffer.
Renamed Pixelized to ProPixelizerBase and changed the shader GUI to redirect users to use the PixelizedWithOutline material instead.
Dropped support for 2019 LTS, remade all example assets (e.g. Render pipeline, post process data, shadergraph) in 2020 LTS.
v1.6 adds significant new functionality to outlining. You are strongly recommended to use the Appearance+Outline material.
Added outlines now respect color palette, per-object control.
Added outline appearance now controlled via shadergraph (add your own dashed patterns, blinking outlines, etc!).
Added interior outlines using normal/depth post processing, per-object control.
Added color property to the ProPixelizer shader.
Added ability to define curve for mapping when using palette style V_Nearest (for monochrome palettes).
Added Support for HDR.
Added Fixed time delay mode to stepped animation tool.
Added Ordered-dither transparency (e.g. for fading objects in/out)
Added Option for camera snap to use orthographic size defined on camera, rather than just pixel size in world space units.
Fixed Post-process does not flatten depth buffer, works with transparent again.
Fixed Specular highlights no longer appear for very bright light sources.
Fixed Shadows work for multiple cascades.
Fixed Stepped animation tool doesn't create a new UUID when regenerating clips.
Fixed SRPBatcher now works properly with ProPixelizer Appearance+Outline material. You should see a performance improvement!
Fixed Additional light shadows (for URP 11+, thanks to Cyanilux's excellent repo.)
Fixed Incorrect color grading on linear color space.
Fixed Color grading bug, color grading is now 1-1 and limited only by 16-color/channel bit depth.
Fixed Pixelization post-process for overlay cameras (requires Pixelisation source to be set to 'ProPixelizer Metadata', URP 10.5+).
Fixed Camera snap supported for multiple cameras.
Fixed Camera snap for moving cameras.
Tidied up the example ShaderGraph, added more useful subgraphs.
Added improved workflow for palettes. Individual palettes are now assets, so the values used for generating LUTs are saved.
Added editor tool for user-defined 4x4 dither patterns.
Added editor tool for creating stepped animations, to help replicate a flipbook/spritesheet feel.
Fixed Bug for game view on Metal.
Fixed Bug when RenderScale != 1.
Fixed Correct pixelation for material preview, material icons and shader graph preview (fix for 2020+ only, URP on 2019 LTS doesn't expose required properties).
Fixed editor warning when selecting in inspector (fix for 2020+ only, URP on 2019 LTS doesn't expose required properties).
Added dither pattern support.
Added single material to produce both outlines and appearance.
Added example scene (Floating) to show new shader and a no-creep setup.
Fixed occasional 'tearing' due to numerical precision error.
Fixed creep in rare cases.
Improved Palette Builder tool.
Made shader keywords consistent - run Window/ProPixelizer/Verify Materials to fix broken materials.
Added option for depth-tested outlines, to prevent outlines when objects overlap (see option in render feature).
Added alpha cutout support.
Added custom GUI for Appearance materials (for ShaderGraph versions that support it, 2020+).
Fixed Object flashing bug for Orthographic projections when near plane was negative.
Fixed gaps at screen edge.
Fixed various truncation warnings.
Fixed support for Unity 2020.2 and URP 10.2
Performance improvement: Large performance improvement on all platforms (3 pixelation passes for color/outline/depth now reduced to a single 'Pixelization Map' pass).
Fixed creep/malformation at some resolutions.
Fixed tearing in perspective projection.
Fixed 3x3 pixelation on AMD+openGL targets.
Quality of life: the '_ID' property in the ObjectOutline shader is now specified as integer in the range (0,255). No change is required if using the OutlineControl MonoBehaviour.
Feel free to email with feature requests and suggestions!