• Please review our updated Terms and Rules here

Apple IIGS NTSC artifact colors in SHR graphics mode

resman

Veteran Member
Joined
Jan 1, 2014
Messages
604
Location
Lake Tahoe
I've posted most of the material from my KansasFest 2017 session: NTSC artifact colors - TNG on Github including some screenshots. I was greatly inspired by the 8088 MPH! demo and playing around with CGA composite color over last winter. Hopefully this leads to some cool IIGS demos in the future.

https://github.com/dschmenk/SHR-NTSC

Dave...
 
Very nice! I'm glad we were able to inspire you.

I have some suggestions about improvements to your converter: you might find you're able to get even better results by using a different metric. It looks like you're currently using delta_red^2 + delta_green^2 + delta_blue^2. However, sRGB is not a particularly perceptually uniform space. It's slightly more complicated, but I've found I get better results by using the metric described at https://www.compuphase.com/cmetric.htm (there are more sophisticated metrics, but I haven't had good results from those - not sure if it's because they're unsuitable or due to bugs in my implementation).

Also, it looks like you're diffusing errors in sRGB space. This works better than not diffusing errors at all, but the resulting images will be too dark in regions where you're diffusing between two colours with different luminosities (it may also be contributing to the chroma-ringing you mentioned). Ideally you should be doing the diffusion in a linear (gamma-corrected) colour space. Again, it's a little tricky to get working (you may find you have to clamp your errors within a particular range to avoid getting bleeding effects due to some target colours being outside the machine's gamut) but if everything's calibrated correctly you should be able to get results so good that (if you squint a bit to counteract the low resolution) you'll get output images that look identical to the input.

One other thing: some of your pictures seem to be suffering from so much moire and aliasing that it's difficult to see how good your conversion is. I'm guessing that's an artefact of the camera's pixel grid and isn't visible when looking at the monitor in person? If so you may be able to get better results by taking a high-resolution image from your camera and resizing it to the desired resolution using a good (again, gamma-aware) software scaler. I've also found it helpful to use a longer exposure and a tripod when photographing CRTs to avoid raster beam synchronization effects like the one in your "Super Hi-Res Graphics mapping 160 pixels" photo. The ideal thing would be to use an electronic shutter trigger synchronized to the CRT beam (which is a project I've been meaning to try for a while, but haven't had time for yet).

Anyway, great work!
 
Very nice! I'm glad we were able to inspire you.

Thanks for taking the time to check out my project!

I have some suggestions about improvements to your converter: you might find you're able to get even better results by using a different metric. It looks like you're currently using delta_red^2 + delta_green^2 + delta_blue^2. However, sRGB is not a particularly perceptually uniform space. It's slightly more complicated, but I've found I get better results by using the metric described at https://www.compuphase.com/cmetric.htm (there are more sophisticated metrics, but I haven't had good results from those - not sure if it's because they're unsuitable or due to bugs in my implementation).

That's the equation used to find the nearest match. The code to generate the RGB values from the NTSC chroma cycle (as it intercepts the IIGS's SHR pixels) is near the top and suffers from a number of sins. I went through a large number of iterations trying to generate a more accurate YUV->RGB mapping by doing the perceptual conversions in this step. But that didn't give me the results I expected. Everything turned grey in the dimmer areas. Maybe using the technique described in your reference might clean that up.

Also, it looks like you're diffusing errors in sRGB space. This works better than not diffusing errors at all, but the resulting images will be too dark in regions where you're diffusing between two colours with different luminosities (it may also be contributing to the chroma-ringing you mentioned). Ideally you should be doing the diffusion in a linear (gamma-corrected) colour space. Again, it's a little tricky to get working (you may find you have to clamp your errors within a particular range to avoid getting bleeding effects due to some target colours being outside the machine's gamut) but if everything's calibrated correctly you should be able to get results so good that (if you squint a bit to counteract the low resolution) you'll get output images that look identical to the input.

The error diffusion was a quick and dirty version to get something better than without it. It could certainly use more time. One advantage the IIGS has over the CGA is that it can generate four levels of intensity using the color palette. I ended up using black, 25% grey, 50% grey, and white levels. This should most likely be revisited along with the color matching to improve the areas of subtle luminosity changes. The worst looking images are smooth shading of the same color. But given the strange color "palette" I had to choose from makes this a bit of a challenge.

One other thing: some of your pictures seem to be suffering from so much moire and aliasing that it's difficult to see how good your conversion is. I'm guessing that's an artefact of the camera's pixel grid and isn't visible when looking at the monitor in person? If so you may be able to get better results by taking a high-resolution image from your camera and resizing it to the desired resolution using a good (again, gamma-aware) software scaler. I've also found it helpful to use a longer exposure and a tripod when photographing CRTs to avoid raster beam synchronization effects like the one in your "Super Hi-Res Graphics mapping 160 pixels" photo. The ideal thing would be to use an electronic shutter trigger synchronized to the CRT beam (which is a project I've been meaning to try for a while, but haven't had time for yet).

Yeah, this was the "quick take an iPhone picture with the wife yelling to come up for dinner" setup. Oh well. I'll try getting better pictures when time permits.

Anyway, great work!

Thanks!
 
If it matters for your calculations, the dot clock for SHR mode on the IIgs is 16.3636Mhz, as opposed to the 14.32Mhz used by CGA and 8-bit Apple II DHR graphics.
 
If it matters for your calculations, the dot clock for SHR mode on the IIgs is 16.3636Mhz, as opposed to the 14.32Mhz used by CGA and 8-bit Apple II DHR graphics.

That's what dictated the 4.57145827... SHR pixels per NTSC chroma cycle. It is both a blessing and a curse. A curse in that is is much harder to calculate the color artifacting, but a blessing in that it gives you a larger "palette" to choose from - just not a very convenient palette.

Another way to look at it is there are 32 SHR pixels in the same space as 28 DHGR pixels in a "macro pixel block". There are 20 of these "macro pixel blocks" across the screen so you get 640 SHR pixels per line and 560 DHGR pixels per line.
 
Last edited:
If it matters for your calculations, the dot clock for SHR mode on the IIgs is 16.3636Mhz, as opposed to the 14.32Mhz used by CGA and 8-bit Apple II DHR graphics.

I hope it's ok to resurrect this thread.

The above assertion makes sense in that to display 640 pixels in the same time as the 560 pixels of, for example, Apple IIe DHGR modes, the clock would have to be 14.31818 * 640 / 560 = 16.3636 Mhz. However, is it actually true that the 640 pixels of SHR modes are displayed in the same time at the 560 pixels of DHGR? I ask because I don't see a source for the 16.3636 Mhz clock on the Apple IIgs schematics.
 
I hope it's ok to resurrect this thread.

The above assertion makes sense in that to display 640 pixels in the same time as the 560 pixels of, for example, Apple IIe DHGR modes, the clock would have to be 14.31818 * 640 / 560 = 16.3636 Mhz. However, is it actually true that the 640 pixels of SHR modes are displayed in the same time at the 560 pixels of DHGR? I ask because I don't see a source for the 16.3636 Mhz clock on the Apple IIgs schematics.

There has been a lot of discussion about this over the years. John Brooks can probably explain this better than anyone. I had to empirically determine this for myself by plotting pixels and looking at the NTSC color output. I honestly don't understand why this is the case. It seems to me to be much harder than just using the same pixel clock and having a slight larger image for the SHR graphics modes. It's not as if the CGA had been doing it for years. It would also keep the GS/OS desktop from looking like a moire mess on an NTSC color monitor, not to mention my little project would have been trivial. Mysteries of the VGC.
 
There has been a lot of discussion about this over the years. John Brooks can probably explain this better than anyone. I had to empirically determine this for myself by plotting pixels and looking at the NTSC color output. I honestly don't understand why this is the case. It seems to me to be much harder than just using the same pixel clock and having a slight larger image for the SHR graphics modes. It's not as if the CGA had been doing it for years. It would also keep the GS/OS desktop from looking like a moire mess on an NTSC color monitor, not to mention my little project would have been trivial. Mysteries of the VGC.

Thanks for your reply. In the meantime I found US patent 4823120 which pretty clearly shows an 8M/7M multiplexer. So as long as the Apple IIgs actually implements something like that patent, I guess it can be considered documented. The frequency must be generated internal to the VGC.
 
Back
Top