Skip to content

Commit 352e426

Browse files
committed
Use standard RGB-YIQ matrix coefficients
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
1 parent 838bd5f commit 352e426

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

Core/NES/BisqwitNtscFilter.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ BisqwitNtscFilter::BisqwitNtscFilter(Emulator* emu) : BaseVideoFilter(emu)
6666
int scale = 8 / _resDivider;
6767
outputBuffer += frameInfo.Width * ((120 - GetOverscan().Top) * scale);
6868

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

7171
_workDone = true;
7272
}
@@ -140,14 +140,28 @@ void BisqwitNtscFilter::OnBeforeApplyFilter()
140140

141141
_y = contrast / _yWidth;
142142

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

146-
_ig = (int)(contrast * 9.151351e-8 * saturation / _iWidth);
147-
_qg = (int)(contrast * -6.334805e-7 * saturation / _qWidth);
151+
// (<contrast at 0> * <saturation at 0>) / (<_iWidth or _qWidth at 0> / 2000)
152+
double saturationFactor = (167941.0 * 144044.0) / (12.0 * 2000.0);
148153

149-
_ib = (int)(contrast * -1.012984e-6 * saturation / _iWidth);
150-
_qb = (int)(contrast * 1.667217e-6 * saturation / _qWidth);
154+
// IQ coefficients are derived from the NTSC base matrix of luminance and color-difference
155+
// with color reduction factors and an additional 33 degree rotation of each respective component.
156+
// https://www.nesdev.org/wiki/NTSC_video#Converting_YUV_to_signal_RGB
157+
_ir = (int)(contrast * ( 0.956084 / saturationFactor) * saturation / _iWidth);
158+
_qr = (int)(contrast * ( 0.620888 / saturationFactor) * saturation / _qWidth);
159+
160+
_ig = (int)(contrast * (-0.272281 / saturationFactor) * saturation / _iWidth);
161+
_qg = (int)(contrast * (-0.646901 / saturationFactor) * saturation / _qWidth);
162+
163+
_ib = (int)(contrast * (-1.105617 / saturationFactor) * saturation / _iWidth);
164+
_qb = (int)(contrast * ( 1.702501 / saturationFactor) * saturation / _qWidth);
151165
}
152166

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

0 commit comments

Comments
 (0)