quark-shaders icon indicating copy to clipboard operation
quark-shaders copied to clipboard

Interlacing in ares and bsnes accurate PPU

Open Michael-Prince-Sharpe opened this issue 4 years ago • 2 comments

When using the crt-royale or crt-royale-kurozumi shaders it's very noticeable with jittery flickering interlacing. The ares/higan/bsnes accurate PPU seems to think it's interlaced.

Michael-Prince-Sharpe avatar Feb 25 '21 12:02 Michael-Prince-Sharpe

Yeah, the accuracy PPU runs everything at 512x480 whether it needs to be at that moment or not (IIRC, the PPU can change between high-res within a single scanline and between interlaced within a single frame and the only way to reproduce this is to provide a window/context large enough to do this at all times).

However, you can put a downsample pass in front of the other shader passes to squash the image down to 50% height and width to compensate:

#version 150

uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 targetSize;

in Vertex {
   vec2 texCoord;
};

out vec4 fragColor;

void main() {
   vec2 one_px = texCoord.xy * sourceSize[0].zw;
   fragColor = texture(source[0], texCoord - vec2(float(mod(one_px, 2.00001))));
}

and then in the manifest do:

program
  filter: nearest
  fragment: downsample.fs
  height: 50%
  width: 50%

as your first pass.

hizzlekizzle avatar Feb 26 '21 03:02 hizzlekizzle

Yeah, the accuracy PPU runs everything at 512x480 whether it needs to be at that moment or not (IIRC, the PPU can change between high-res within a single scanline and between interlaced within a single frame and the only way to reproduce this is to provide a window/context large enough to do this at all times).

However, you can put a downsample pass in front of the other shader passes to squash the image down to 50% height and width to compensate:

#version 150

uniform sampler2D source[];
uniform vec4 sourceSize[];
uniform vec4 targetSize;

in Vertex {
   vec2 texCoord;
};

out vec4 fragColor;

void main() {
   vec2 one_px = texCoord.xy * sourceSize[0].zw;
   fragColor = texture(source[0], texCoord - vec2(float(mod(one_px, 2.00001))));
}

and then in the manifest do:

program
  filter: nearest
  fragment: downsample.fs
  height: 50%
  width: 50%

as your first pass.

Thanks very much, Hizzlekizzle, works like charm. If it's alright, I put the new files in a fork specifically for the bsnes accurate PPU, Higan or ares if anybody wants them?

Michael-Prince-Sharpe avatar Feb 26 '21 14:02 Michael-Prince-Sharpe