Skip to content

Commit

Permalink
Use standard RGB-YIQ matrix coefficients
Browse files Browse the repository at this point in the history
https://forums.nesdev.org/viewtopic.php?p=172817#p172817

Bisqwit originally intended to match a certain palette using different
display primaries ("FCC D65"). This resulted in colors that looked off.
The modification here is to more closely match Bisqwit's own palette
generator, which uses a more standard RGB-YIQ matrix.
at hue 0, saturation 1.0, contrast 1.0, brightness 1.0, gamma 2.2
https://bisqwit.iki.fi/utils/nespalette.php

IQ component coefficients are derived from the NTSC base matrix of
luminance and color-difference. with color reduction factors and an
additional 33 degree rotation of each respective component.
https://www.nesdev.org/wiki/NTSC_video#Converting_YUV_to_signal_RGB
  • Loading branch information
Gumball2415 committed Oct 23, 2023
1 parent fa7c32f commit d597f21
Showing 1 changed file with 24 additions and 9 deletions.
33 changes: 24 additions & 9 deletions Core/NES/BisqwitNtscFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ BisqwitNtscFilter::BisqwitNtscFilter(Emulator* emu) : BaseVideoFilter(emu)
//Adjust outputbuffer to start at the middle of the picture
outputBuffer += frameInfo.Width * (frameInfo.Height / 2);

DecodeFrame(120, 239 - GetOverscan().Bottom, _ppuOutputBuffer, outputBuffer, GetVideoPhaseOffset() + 120*341*_signalsPerPixel);
DecodeFrame(120, 239 - GetOverscan().Bottom, _ppuOutputBuffer, outputBuffer, GetVideoPhaseOffset() + 120 * 341 * _signalsPerPixel);

_workDone = true;
}
Expand Down Expand Up @@ -133,14 +133,29 @@ void BisqwitNtscFilter::OnBeforeApplyFilter()

_y = contrast / _yWidth;

_ir = (int)(contrast * 1.994681e-6 * saturation / _iWidth);
_qr = (int)(contrast * 9.915742e-7 * saturation / _qWidth);

_ig = (int)(contrast * 9.151351e-8 * saturation / _iWidth);
_qg = (int)(contrast * -6.334805e-7 * saturation / _qWidth);

_ib = (int)(contrast * -1.012984e-6 * saturation / _iWidth);
_qb = (int)(contrast * 1.667217e-6 * saturation / _qWidth);
// https://forums.nesdev.org/viewtopic.php?p=172817#p172817
// Bisqwit originally intended to match a certain palette using different
// display primaries ("FCC D65"). This resulted in colors that looked off.
// The modification here is to more closely match Bisqwit's own palette
// generator, which uses a more standard RGB-YIQ matrix.
// at hue 0, saturation 1.0, contrast 1.0, brightness 1.0, gamma 2.2
// https://bisqwit.iki.fi/utils/nespalette.php

// for some reason the original coefficients of bisqwit's decoding matrix
// has been reduced by at least 10^-6
double saturationFactor = 1000000;

// IQ coefficients are derived from the NTSC base matrix of luminance and color-difference
// with color reduction factors and an additional 33 degree rotation of each respective component.
// https://www.nesdev.org/wiki/NTSC_video#Converting_YUV_to_signal_RGB
_ir = (int)(contrast * ( 0.956084 / saturationFactor) * saturation / _iWidth);
_qr = (int)(contrast * ( 0.620888 / saturationFactor) * saturation / _qWidth);

_ig = (int)(contrast * (-0.272281 / saturationFactor) * saturation / _iWidth);
_qg = (int)(contrast * (-0.646901 / saturationFactor) * saturation / _qWidth);

_ib = (int)(contrast * (-1.105617 / saturationFactor) * saturation / _iWidth);
_qb = (int)(contrast * ( 1.702501 / saturationFactor) * saturation / _qWidth);
}

void BisqwitNtscFilter::RecursiveBlend(int iterationCount, uint64_t *output, uint64_t *currentLine, uint64_t *nextLine, int pixelsPerCycle, bool verticalBlend)
Expand Down

0 comments on commit d597f21

Please sign in to comment.