Last active
November 1, 2024 04:01
-
-
Save ompuco/3209f1b32213cec5b7bccf0e67caf3e9 to your computer and use it in GitHub Desktop.
Color dither & truncation based on Sony's PlayStation (1) hardware features & limitations.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef PSXDTH | |
#else | |
#define PSXDTH | |
//PS1 Hardware Dithering & Color Precision Truncation Function | |
//by ompu co | Sam Blye (c) 2020 | |
//PS1 dither table from PSYDEV SDK documentation | |
static const float4x4 psx_dither_table = float4x4 | |
( | |
0, 8, 2, 10, | |
12, 4, 14, 6, | |
3, 11, 1, 9, | |
15, 7, 13, 5 | |
); | |
//if desired, this can also be stored as an int4x4 | |
#define useDither 1 //set to 0 to disable dithering and only truncate raw color input | |
//col - your high-precision color input | |
//p - screen position in pixel space | |
float3 DitherCrunch(float3 col, int2 p){ | |
col*=255.0; //extrapolate 16bit color float to 16bit integer space | |
if(useDither==1) | |
{ | |
int dither = psx_dither_table[p.x % 4][p.y % 4]; | |
col += (dither / 2.0 - 4.0); //dithering process as described in PSYDEV SDK documentation | |
} | |
col = lerp((uint3(col) & 0xf8), 0xf8, step(0xf8,col)); | |
//truncate to 5bpc precision via bitwise AND operator, and limit value max to prevent wrapping. | |
//PS1 colors in default color mode have a maximum integer value of 248 (0xf8) | |
col /= 255; //bring color back to floating point number space | |
return col; | |
} | |
//NOTE: | |
//For best results, run DitherCrunch() during initial rasterization by adding this at the end of your | |
//material's fragment shader, & not in post processing. | |
//This allows for proper high quality dithering directly from the full-fidelity vertex gradients, | |
//more accurate behaviors, use with lower-precision rendertextures without perceived color loss, | |
//and setting per-object dithering by changing the definition of useDither from 1 to 0 when needed. | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment