Pixelart camera shader

Hello! Its been a year when i started my journey with unity and gameart. I’ve learnt a lot, but more about gameart and 3d modelling, than about technical aspects of graphics.

Recently, i’ve came across this video:

The thing is, while i know how to recreate the effect inside of blender for example - i have no idea where to start with unity. And i would absolutely love to create some small project based on this idea.

Here is my question, since i cant really find any reliable materials covering this topic - anything else i’ve found on the internet isn’t exactly what i would want, or is kinda unreliable. How does this work? Is it entirely based on the idea of using render textures, or is it something else? The shading really reminds me of cell shading, but pixelated. Its also Pixel Perfect - which i cant really seem to achieve with my current knowledge. I would love if someone would share me their thoughts on how this can work - and how can i try to achieve this.

Cheers everyone :wink:

There is quite a lot that would go into creating these visuals, so I’ll address many of the main details here (but still glossing over full implementation of them).

This appears to be reproducible through a combination of elements:

Modified lighting (Shader) to Ceil/Round/Floor (or whichever) the light intensity.

// There's a whole lot more to this, but this is the
// gist of applying intentional color-banding.

float avgLight; // example using a single value for light intensity
// ...
// Example: 5 light intensities, ranging from 0-1
// Only an initial light value of 1.0 will be "lost", transforming
// into the same intensity as the (0.8-0.9999) range
float lightBands = saturate(floor(avgLight * 5.0) / 4.0);

A reduced render resolution for the scene. This can be done in numerous ways, but doing so without changing the base display resolution (i.e. the video’s example of 1920x1080 Screen Resolution) would involve setting the main camera’s Rect (Camera.rect) to the target size during OnPreRender(), then changing it back to the base resolution at the start of OnRenderImage(RenderTexture, RenderTexture). Specifically, this approach would keep the UI rendering at the screen’s native resolution while reducing the 3D render resolution:

void OnPreRender()
	baseRect = myCam.rect;
	scaledRect.Set(baseRect.x, baseRect.y, targetWidth, targetHeight);
	myCam.rect = scaledRect;

void OnRenderImage(RenderTexture source, RenderTexture destination)
	myCam.rect = baseRect;
	// rest of general function usage: Blit(), etc.

Well, I guess those are really the only two primary elements with respect to this question. The video describes an orthographic camera rather than perspective and the water looks like it probably shows reflections, but the light bands and scaled render resolution are a bit more involved to fully implement (especially if you intend to apply lighting changes to both forward and deferred rendering and/or URP/HDRP).

For reference, a post-processing Shader could be used as a substitute for either/both elements, but would potentially have less versatility for lighting-based effects and would potentially be a more-expensive way to render a lower-resolution version of your scene. It’s a valid option, but this is a situation where investing more effort into script and shader-related (lighting) elements could potentially have cleaner/more efficient results overall.

It just looks like a 3D scene. You may need to create a scene with lights, objects and terrain in the correct locations (maybe using post processing and light emission for some fancier graphics), and to give it a pixel look, you could try reducing your camera resolution.

Idk how good of an effect it will produce, but setting your camera to render at a lower resolution may produce a pixely look. Have a look at: Set screen resolution