PS1 Vertex Distortion / Quantization Material?

How can I make my models or model materials have that weird distortion that old PlayStation 1 games had with the vertex distortion/shaky-ness or what some would call it quantization? I have seen the marketplace item called Oldskooler but I don’t have the money for it and don’t want the other effects that come with it (also, I’m not sure if it will work well with my game graphics, I just want to experiment with the graphics, maybe I won’t like it and remove it), I just want the distortion effect. Also, there is a PC game that got that weird effect too, Unreal Tournament GOTY 1999 had it too with the character models, but not quite like PS1 games.

Here’s an example comparison of a PS1 game with and without distortion due to lack of z-buffer:

https://www.youtube.com/watch?v=yOASkImiNeU

The reason it was called quantization is because that is literally what was happening. Vertex positions were being passed to the rasterization hardware as integers instead of as floating points so the coordinates would “snap” into place. It also quantized based on screen resolution. You can do the same thing with a vertex shader but simply rounding your vertex positions to the nearest “pixel.” Of course, we can control what this made up screen resolution is so you can simulate an old 320x240 screen even if your real resolution is 1920x1080.

I don’t know what your familiarity is with creating materials but you can use the world position offset to adjust the vertex position. The pseudocode of what you want to do is

  1. Get post-projection vertex position
  2. Divide by vertex.w component to remove projection warping
  3. Round x and y of vertex to nearest “virtual pixel” (floor(vertex * dim) / dim)
  4. Multiply by the vertex w component to reapply warping
  5. Get difference between quantized and non-quantized vertex and set it to world position offset in material

Hopefully that makes sense. I don’t know if that is enough to get you where you want to be.

someone actually made a post process material for this.
Here you go:

This method sounds like what I’m looking to do, but I’m having trouble following your pseudo-code. I think you’re using some unity lingo with the vertex.w bit. Would you be able to further explain how to do this in blueprints?

Sorry to necro this post, but for anyone who wants to do it this way here’s a step by step guide.

You’ll want to quantize the vertex in screen space like so (I named this PixelSnap):

The WorldToClip function looks like this:

The ClipToWorld function looks like this:

After you do all of that, you’ll use the first material function to calculate an offset like so:

The first material function has a parameter to control the “scale” of the screen, so you can snap a vertex to every other pixel with 0.5, or every 10 pixels with 0.1, etc. This effect works fairly well, but generally speaking snapping the vertex in view space looks better. Your mileage may vary though.

4 Likes

Sorry to necro the post! I’ve been looking for ways to recreate this effect in my own project and I think @SK83RJOSH’s solution is close to what I’ve been trying to find, although I’m confused about what I do after subtracting world position from the result of the pixel snap function? I’m somewhat of a newbie when it comes to creating materials so there’s a bit that I’m trying to pick up on

Thanks so much for sharing, this setup works really well, although it does flicker quite a lot even with simple cubes. Thank you a lot again though, gonna be fun to build on top on!

EDIT: The flickering was due to temporalAA, be sure to turn it off if you’re trying out this setup. It works really well now and the flickering is gone!