My PS1 Shading techniques for Unreal

This site showcases how I make my unreal engine projects look like PS1 games.

First off, None of my PS1 effects are post processed. I do it all inside my materials. All my materials are unlit.

Lighting

I redo all lighting calculations inside my materials so that I can use Gouraud Shading through the Vertex Interpolator node.

You can get the lighting data any way you want, in some projects I used a static light direction like above, in others I poll all lights and send that data to Render Targets to be processed inside the shader.

The important part is the Vertex Interpolator node.

Dithering

An important part of the PS1 look is the reduced colours, and the hardware dithering applied. I also do this inside my materials, by placing a material function i made at the end of every material. The last node plugged into the Emissive Colour in all of my materials is this function.

Here is the Material Function. Copy everything in this txt file, then paste it into your material window.
if the above doesn't work, e.g. crashes unreal (it can do that), Here is the code for the custom nodes.

Vertex Snapping

When drawing triangles on the PS1, You had to send to the GPU the position of each vertex on the 2D Screen. The positions sent had to be integers. This is why the PS1 has a noticable 'jitter', as triangles couldn't be drawn "between" pixels.

Here is the Material Function. Copy everything in this txt file, then paste it into your material window.
if the above doesn't work, you can take the "Transform to Clip" node from the TransformToClipSpace engine material function.
The "Transform to World" node uses the same code except "View.WorldToClip" is changed to "View.ClipToWorld".

NOTE: This function takes over your WPO, you won't be able to use it with this! If WPO matters to you, then this method won't work.
Thank you to Marcis for this code!

Affine Texture Mapping

Affine texture mapping is an important part of the PS1 look. However, currently there exist no ways to recreate it accurately inside Unreal through vertex shaders alone.
Plus, with no way to do Adaptive Subdivision, affine mapping can look much worse then it would on most real PS1 games as most people don't account for it, and making multiple LODs for subdivision is time consuming.
you wouldn't even be able to use LODs for larger meshes, since adaptive subdivision is based on the distance between the camera and the triangle, not the camera and the object like LODs are.

There are a few good enough methods already available online.
Currently, I am writing a custom Mesh Component plugin to help with pre-processing triangles in scenes to flatten and subdivide them. Check back here later.