Need shader that shakes image up and down 1 pixel

I have a crt tv that i RGB modded, but it’s incapable of producing scanlines, in 240p it shakes the image up and down very fast to emulate 480i, it was probably done on purpose, to avoid the black lines between scanlines, but some of us retrogamers love that effect (480i content, like naomi and atomiswave, looks AMAZING, but 240p content looks ugly)

SO, when i add a shader, it shows only half the frames, the other half is black (tv blinks, 30hz of black, 30hz of image), and then the scanlines pop! what i’m looking for is a shader that can move the image up and down by 1 pixel every other frame, to undo whatever my tv is doing

any clues?

What model TV is it? Are you sure you’re getting 240p to it, as that sure sounds like 480i…?

Anyway, here’s a slang shader that should do it:

#version 450

layout(push_constant) uniform Push
	vec4 SourceSize;
	vec4 OriginalSize;
	vec4 OutputSize;
	uint FrameCount;
} params;

layout(std140, set = 0, binding = 0) uniform UBO
	mat4 MVP;
} global;

#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;

void main()
   gl_Position = global.MVP * Position;
   vTexCoord = TexCoord;

#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;

void main()
   float one_texel = params.SourceSize.w * 0.49999;
   FragColor = vec4(texture(Source, vTexCoord + vec2(0.0, one_texel) * float(mod(params.FrameCount, 2.0))).rgb, 1.0);

it certainly is receiving 240p, crt emu drive with a bunch of custom resolutions and all, retroarch properly set up

thanks! but how do i use this code? create a file and paste it in?

Yeah, it’s a slang shader, though, so it would be ‘shader.slang’ or whatever. If you’re using the default GL video driver (in settings > driver), you’ll need to switch it to ‘glcore’ instead.

i don’t have that driver, i’m using retroarch 1.7.6, i’ll try updating

updated and the driver was there, but only half of the screen is shaking but in a wrong way, but by half i mean diagonally lol

i tried reading the code but it’s way too foreign to me, can’t really modify it

crazy thing is, on video and in photos, it looks perfect lol

In this section:

void main()
   gl_Position = global.MVP * Position;
   vTexCoord = TexCoord;

Try changing the second line to:

vTexCoord = TexCoord * 1.00001;

This usually fixes diagonal line stuff, which is usually caused by rounding weirdness.

it fixed the diagonal bug, but still no scanlines

can the shaking be inverted? start from another line or something? or changed from 1 pixel to 2 maybe?

You can try doubling it just by deleting this bit:

* 0.49999

so the resulting line should be:

float one_texel = params.SourceSize.w;

Since the display is going to keep doing whatever it’s doing regardless of what’s happening on-screen, you should be able to just hit the ‘p’ hotkey to pause it and then hit it again to unpause and you’ll have a 50% chance of being lined up with the other set of fields.

following the picture below, what i observed by pausing is that at times the picture was fixed at positions red, blue or orange, and sometimes it flickered between red and orange, skipping the middle position