Skip to content

Instantly share code, notes, and snippets.

@dleslie
Last active Jan 31, 2021
Embed
What would you like to do?
Modified Windows Terminal retro renderer
// The original retro pixel shader
Texture2D shaderTexture;
SamplerState samplerState;
cbuffer PixelShaderSettings {
float Time;
float Scale;
float2 Resolution;
float4 Background;
};
#define SCANLINE_FACTOR 0.3
#define SCALED_SCANLINE_PERIOD Scale
#define SCALED_GAUSSIAN_SIGMA (2.0*Scale)
#define BLUR_SAMPLES 3
#define DESATURATION_FACTOR 0.3
#define WARP_FACTOR 0.2
static const float M_PI = 3.14159265f;
float Gaussian2D(float x, float y, float sigma)
{
return 1/(sigma*sqrt(2*M_PI)) * exp(-0.5*(x*x + y*y)/sigma/sigma);
}
float4 Blur(Texture2D input, float2 tex_coord, float sigma)
{
uint width, height;
shaderTexture.GetDimensions(width, height);
float texelWidth = 1.0f/width;
float texelHeight = 1.0f/height;
float4 color = { 0, 0, 0, 0 };
int sampleCount = BLUR_SAMPLES;
for (int x = 0; x < sampleCount; x++)
{
float2 samplePos = { 0, 0 };
samplePos.x = tex_coord.x + (x - sampleCount/2) * texelWidth;
for (int y = 0; y < sampleCount; y++)
{
samplePos.y = tex_coord.y + (y - sampleCount/2) * texelHeight;
if (samplePos.x <= 0 || samplePos.y <= 0 || samplePos.x >= width || samplePos.y >= height) continue;
color += input.Sample(samplerState, samplePos) * Gaussian2D((x - sampleCount/2), (y - sampleCount/2), sigma);
}
}
return color;
}
float SquareWave(float y)
{
return 1 - (floor(y / SCALED_SCANLINE_PERIOD) % 2) * SCANLINE_FACTOR;
}
float4 Scanline(float4 color, float4 pos)
{
float wave = SquareWave(pos.y);
// TODO:GH#3929 make this configurable.
// Remove the && false to draw scanlines everywhere.
if (length(color.rgb) < 0.2 && false)
{
return color + wave*0.1;
}
else
{
return color * wave;
}
}
float4 Desaturate(float4 color)
{
float l = 0.3 * color.r + 0.6 * color.g + 0.1 * color.b;
color.r = color.r + DESATURATION_FACTOR * (l - color.r);
color.g = color.g + DESATURATION_FACTOR * (l - color.g);
color.b = color.b + DESATURATION_FACTOR * (l - color.b);
return color;
}
// https://www.shadertoy.com/view/WsVSzV
float2 WarpToTex(float4 pos)
{
float2 uv = pos / Resolution;
float2 dc = abs(0.5 - uv);
dc *= dc;
uv.x -= 0.5;
uv.x *= 1.0 + (dc.y * (0.3 * WARP_FACTOR));
uv.x += 0.5;
uv.y -= 0.5;
uv.y *= 1.0 + (dc.x * (0.4 * WARP_FACTOR));
uv.y += 0.5;
if (uv.y > 1.0 || uv.y < 0.0 || uv.x < 0.0 || uv.x > 1.0)
return float4(0.0, 0.0, 0.0, 1.0);
return uv;
}
float4 main(float4 pos : SV_POSITION, float2 tex : TEXCOORD) : SV_TARGET
{
Texture2D input = shaderTexture;
tex = WarpToTex(pos);
// TODO:GH#3930 Make these configurable in some way.
float4 color = input.Sample(samplerState, tex);
//float4 color = WarpSampleToTex(tex);
color += Blur(input, tex, SCALED_GAUSSIAN_SIGMA)*0.3;
color = Scanline(color, pos);
color = Desaturate(color);
return color;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment