So, here's the shader in RetroArch-compatible Cg format:
/* COMPATIBILITY
- HLSL compilers
- Cg compilers
*/
/*
Interlacing
Author: hunterk
License: Public domain
*/
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
float frame_count;
float frame_direction;
float frame_rotation;
sampler2D texture : TEXUNIT0;
};
void main_vertex
(
float4 position : POSITION,
out float4 oPosition : POSITION,
uniform float4x4 modelViewProj,
float4 color : COLOR,
out float4 oColor : COLOR,
float2 texCoord : TEXCOORD,
out float2 oTexCoord : TEXCOORD,
uniform input IN
)
{
oPosition = mul(modelViewProj, position);
oColor = color;
oTexCoord = texCoord;
}
float4 main_fragment (in float2 texCoord : TEXCOORD, uniform input IN) : COLOR
{
float4 res = tex2D(IN.texture, texCoord);
float y = 0.0;
// assume anything with a vertical resolution greater than 400 lines is interlaced
if (IN.video_size.y > 400.0) y = IN.texture_size.y * texCoord.y + IN.frame_count;
else
y = 2.0 * IN.texture_size.y * texCoord.y;
if (fmod(y, 2.0) > 0.99999) return res;
else
return float4(0.0);
}
It has two branching 'if' statements, which is horrible for performance in shaders, but this one is simple enough--and only needs to run at 2x--that it shouldn't matter.
UPDATE: In the comments, Monroe88 mentioned another very useful shader for use with 31 kHz CRT monitors: aliaspider's TVoutTweaks, which lets you add some nice effects, such as composite color correction and horizontal bandwidth (blends things like SNES' pseudo-hires transparency and other dithering effects), which will make the image a little closer to a 15 kHz TV. See Monroe88's comment below for more info and a pic.