Accurate(ish) CRT TV simulation theory
Accurate(ish) CRT TV simulation theory
Version 6 30-08-2008
Simplified and optimized the hell out of the process, its now only a 7 step process regardless of source (progressive/interlaced)
The first number is for NTSC the second is for PAL
1.Decide of the target is a NTSC tv or a PAL tv depending on user settings
2.Check if height =<243/288, if so double the height by inserting black lines
3.Pad the height with black lines(equally above and below) to 486/576
4.Pad black pixels(equally left and right) for pixels generated beyond the input image
5.Stretch the image horizontally to 640/786 (This will result in the correct pixel aspect ratio)
6.Apply Kell factor between 0% and 50% depeding on user settings
7.Apply Overscan between -5% and +5% depending on user settings
Step 4 can be calculated with the following formula:
(PixelClock)*0.00005266 = (NumberOfGeneratedPixels)
(NumberOfGeneratedPixels)-(OriginalWidth) = (TotalNumberOfBlackPixelsToAdd)
Step 6 is a guassian effect which causes the non-black scanlines to bleed out into the adjacent scanline. this effect is brightest in the center of the scanline and gets darker as the end of the bleed is reached.
Step 7 is not as easy as it seems. A possible solution is to insert it between steps 1 and 2 and increase/decrease all other values with the same percentage as the overscan setting. A step 8 would be added: Crop to 640x486/786x576
A special thanks to:
blargg
creaothceann
Gil_Hamilton
Verdauga Greeneyes
For being so patient and correcting/confirming where needed.
Here is the best artists-impression of what the result looks like we have so far, it was made by blargg:
Overscan 0%, kell factor 0,4(60%)
Simplified and optimized the hell out of the process, its now only a 7 step process regardless of source (progressive/interlaced)
The first number is for NTSC the second is for PAL
1.Decide of the target is a NTSC tv or a PAL tv depending on user settings
2.Check if height =<243/288, if so double the height by inserting black lines
3.Pad the height with black lines(equally above and below) to 486/576
4.Pad black pixels(equally left and right) for pixels generated beyond the input image
5.Stretch the image horizontally to 640/786 (This will result in the correct pixel aspect ratio)
6.Apply Kell factor between 0% and 50% depeding on user settings
7.Apply Overscan between -5% and +5% depending on user settings
Step 4 can be calculated with the following formula:
(PixelClock)*0.00005266 = (NumberOfGeneratedPixels)
(NumberOfGeneratedPixels)-(OriginalWidth) = (TotalNumberOfBlackPixelsToAdd)
Step 6 is a guassian effect which causes the non-black scanlines to bleed out into the adjacent scanline. this effect is brightest in the center of the scanline and gets darker as the end of the bleed is reached.
Step 7 is not as easy as it seems. A possible solution is to insert it between steps 1 and 2 and increase/decrease all other values with the same percentage as the overscan setting. A step 8 would be added: Crop to 640x486/786x576
A special thanks to:
blargg
creaothceann
Gil_Hamilton
Verdauga Greeneyes
For being so patient and correcting/confirming where needed.
Here is the best artists-impression of what the result looks like we have so far, it was made by blargg:
Overscan 0%, kell factor 0,4(60%)
Last edited by tetsuo55 on Sat Aug 30, 2008 7:50 pm, edited 6 times in total.
-
- Regular
- Posts: 347
- Joined: Tue Mar 07, 2006 10:32 am
- Location: The Netherlands
I'm having trouble understanding your choice of 800x600.. is this simply the lowest standard DirectX resolution larger than 720x576, or is there a more significant reason for choosing it? If not then I think you should drop it from your explanation, as it makes things pretty confusing: we should do any aspect ratio corrections in floating point and scale to whatever resolution the user may be using.
Okay let me put it this way
What i am trying to simulate is the TV screen.
The TV is basically a large glass canvas.
This canvas can be any size but has to maintain a 4:3 aspect ratio
This canvas can be filled with "detail".
The amount of detail is limited however.
In the case of NTSC a maximum of 720x480 details.
In the case of PAL a maxmum of 720x576 details.
The 4:3 canvas is built out of phosphors
These phosphors are placed as vertical strips. Placed like this:
Red,black,green,black,blue,black
This pattern is repeated over the entire canvas
The minimum amount of phosphor6 needed to display all the details would be 720 of them.
So to create the glass canvas at 4:3 with the minimum amount of phosphors needed to display the maximum detail the resolution would be:
4320x3240
As each phosphor6 is in fact the same size as a single pixel on the monitor. We have to compress this down.
720x540
As you can see the problem here is that this resolution is unable to display pal resolutions
so if we take the pal maximum height 576 and conver that the 4:3 we end up with:
768x576
Now this is better than the 800x600 i had before, thanks.
768x576 is a 4:3 resolution that has enough detail to display both pal and ntsc signals at the correct aspect ratio.
Pal only needs a horizontal stretch, NTSC needs both horizontal and vertical.
Now why do we need the fixed resolution?
-the size of the TV does not change.
-It is needed for phosphor simulation
-It is needed for accurate mask simulation
-It is needed for accurate scanlines simulation
The fixed resolution also prevents the need for aspect ratio correction guestimates.
This resolution would simply be 1x, you can scale to any size as long as each step adds 4 pixels vertically and 3 horizontally
What i am trying to simulate is the TV screen.
The TV is basically a large glass canvas.
This canvas can be any size but has to maintain a 4:3 aspect ratio
This canvas can be filled with "detail".
The amount of detail is limited however.
In the case of NTSC a maximum of 720x480 details.
In the case of PAL a maxmum of 720x576 details.
The 4:3 canvas is built out of phosphors
These phosphors are placed as vertical strips. Placed like this:
Red,black,green,black,blue,black
This pattern is repeated over the entire canvas
The minimum amount of phosphor6 needed to display all the details would be 720 of them.
So to create the glass canvas at 4:3 with the minimum amount of phosphors needed to display the maximum detail the resolution would be:
4320x3240
As each phosphor6 is in fact the same size as a single pixel on the monitor. We have to compress this down.
720x540
As you can see the problem here is that this resolution is unable to display pal resolutions
so if we take the pal maximum height 576 and conver that the 4:3 we end up with:
768x576
Now this is better than the 800x600 i had before, thanks.
768x576 is a 4:3 resolution that has enough detail to display both pal and ntsc signals at the correct aspect ratio.
Pal only needs a horizontal stretch, NTSC needs both horizontal and vertical.
Now why do we need the fixed resolution?
-the size of the TV does not change.
-It is needed for phosphor simulation
-It is needed for accurate mask simulation
-It is needed for accurate scanlines simulation
The fixed resolution also prevents the need for aspect ratio correction guestimates.
This resolution would simply be 1x, you can scale to any size as long as each step adds 4 pixels vertically and 3 horizontally
Maybe i should go for a discrete simulation before attempting a simple filter.
Very basically this is how a TV works
-A horizontal and vertical frequence is fed to the TV
-In addition to this color information is also sent
Depending on the frequencies and timing of the changes in the color information in image is smeared over the screen.
This image will always look the same because some of the frequencies can not be altered and the TV is a 4:3 square box.
The TV can almost be seen like a painter painting a canvas, the length and height of each detail(pixel) depend on how long the painter keeps moving until he lifts his hand and does the same on the way back.
I believe the NTSC filter is doing this already. Its basically using the signals to create the image instead of the pixels.
What the NTSC filter does not do however is paint to a 4:3 canvas directly. It's the canvas itself with all its details that i want to simulate
Very basically this is how a TV works
-A horizontal and vertical frequence is fed to the TV
-In addition to this color information is also sent
Depending on the frequencies and timing of the changes in the color information in image is smeared over the screen.
This image will always look the same because some of the frequencies can not be altered and the TV is a 4:3 square box.
The TV can almost be seen like a painter painting a canvas, the length and height of each detail(pixel) depend on how long the painter keeps moving until he lifts his hand and does the same on the way back.
I believe the NTSC filter is doing this already. Its basically using the signals to create the image instead of the pixels.
What the NTSC filter does not do however is paint to a 4:3 canvas directly. It's the canvas itself with all its details that i want to simulate
I think i figured it out.
The target resolution(TV canvas) is 768*576 (a 4:3 square)
The quickest formula to get this accurately would be:
-input 256*224 image
-Stretch width by 3
-Insert black line between each image height line.
-Add 17 black lines to the top
-Add 16 black lines to the bottom
-Stretch height by 1.2
The color bleeding into the black scanlines is something we can save for later. (there are so many options)
The formulat for PAL would be
-input 256*224 image
-Stretch width by 3
-Insert black line between each image height line.
-Add 65 black lines to the top
-Add 64 black lines to the bottom
Using this method we get accurate(exact) pixel aspect ratio AND accurate scanlines as a bonus
The target resolution(TV canvas) is 768*576 (a 4:3 square)
The quickest formula to get this accurately would be:
-input 256*224 image
-Stretch width by 3
-Insert black line between each image height line.
-Add 17 black lines to the top
-Add 16 black lines to the bottom
-Stretch height by 1.2
The color bleeding into the black scanlines is something we can save for later. (there are so many options)
The formulat for PAL would be
-input 256*224 image
-Stretch width by 3
-Insert black line between each image height line.
-Add 65 black lines to the top
-Add 64 black lines to the bottom
Using this method we get accurate(exact) pixel aspect ratio AND accurate scanlines as a bonus
I think you're trying to fit a square peg in a round hole. LCDs aren't CRT televisions. They have fixed width square pixels. There's no stretching them to get around that, the best you can do with a source that otherwise would have had its pixels stretched is to duplicate lines in a way that gives the best illusion of such. And now that you're dealing with data that wasn't previously there, your dreams to apply the same math to get the same effect are shot.
not really.
You have to look at the LCD square pixels as Samples
What i'm trying to calculate here is the right samplerate to get the same image that you see on TV.
There is a lot of information about how to do it but most of it is wrong.
My mistake is simple, Height is a fixed value, its the width that is the variable
You have to look at the LCD square pixels as Samples
What i'm trying to calculate here is the right samplerate to get the same image that you see on TV.
There is a lot of information about how to do it but most of it is wrong.
My mistake is simple, Height is a fixed value, its the width that is the variable
-
- Trooper
- Posts: 376
- Joined: Tue Apr 19, 2005 11:08 pm
- Location: DFW area, TX USA
- Contact:
Yeah I've learned from experience with LCD's that the virtical must be in exact multiples of the original resolution if you want to have a scanline effect. This of course means you won't be able to do any virtical stretching or the scanlines will look like crap. This also means there will be black bars on the top and bottom of the image if your LCD's virtical res does not match an exact multiple of the emulator.
For example in bsnes NTSC games, I render at 4xscale, which gives 896 virtical res with scanlines. Since my LCD monitor is 1050 virtical, there ends up being a 77 pixel tall border on the top and bottom of the screen.
For example in bsnes NTSC games, I render at 4xscale, which gives 896 virtical res with scanlines. Since my LCD monitor is 1050 virtical, there ends up being a 77 pixel tall border on the top and bottom of the screen.
i think i cracked it.
first we create the accurate height:
we start with the 256x224 image
Double the height by repeating each pixel
256x448
Pad the height by adding 19 black pixels above and below
256x486 (At this point we have reached the accurate height)
Now on to the width, because ntsc pixels are 10/11 the target width is 704
Stretch 256 to 704
704 needs to be padded too by adding 8 black pixels to both left and right.
The resulting 720x486 image has the pixels correctly stored. However we still need to convert them to the correct frame/picture aspect ratio
To do this we scale horizontally by 10/11
720 > 654 6/11
Now crop to 640, equally on each side "7 3/11"
The resulting 640x486 image is square for both the content and the monitor
source:
http://en.wikipedia.org/wiki/Pixel_aspect_ratio
http://lurkertech.com/lg/pixelaspect/
http://en.wikipedia.org/wiki/Aspect_ratio_(image)
For pal its:
Start:256x224
Double: 256x448
Pad height: 64 black pixels top and 64 black pixels bottom: 256x576
Stretch image to 704x576
Pad to 720 by adding 8 black pixels left and right
scale horizontally by 59/54 to 786 2/3
Crop to 768 by deleting "9 1/3" pixels left and right
Resulting 768x576 image should be sqaure for both content and monitor
first we create the accurate height:
we start with the 256x224 image
Double the height by repeating each pixel
256x448
Pad the height by adding 19 black pixels above and below
256x486 (At this point we have reached the accurate height)
Now on to the width, because ntsc pixels are 10/11 the target width is 704
Stretch 256 to 704
704 needs to be padded too by adding 8 black pixels to both left and right.
The resulting 720x486 image has the pixels correctly stored. However we still need to convert them to the correct frame/picture aspect ratio
To do this we scale horizontally by 10/11
720 > 654 6/11
Now crop to 640, equally on each side "7 3/11"
The resulting 640x486 image is square for both the content and the monitor
source:
http://en.wikipedia.org/wiki/Pixel_aspect_ratio
http://lurkertech.com/lg/pixelaspect/
http://en.wikipedia.org/wiki/Aspect_ratio_(image)
For pal its:
Start:256x224
Double: 256x448
Pad height: 64 black pixels top and 64 black pixels bottom: 256x576
Stretch image to 704x576
Pad to 720 by adding 8 black pixels left and right
scale horizontally by 59/54 to 786 2/3
Crop to 768 by deleting "9 1/3" pixels left and right
Resulting 768x576 image should be sqaure for both content and monitor
Last edited by tetsuo55 on Tue Aug 26, 2008 1:33 pm, edited 2 times in total.
-
- Buzzkill Gil
- Posts: 4294
- Joined: Wed Jan 12, 2005 7:14 pm
It won't work. Not with current LCDs. Even ignoring the resampling artifacts(however slight they are, they WILL exist), there's brightness and contrast issues that just aren't avoidable, as well as coloration problems.tetsuo55 wrote:not really.
You have to look at the LCD square pixels as Samples
What i'm trying to calculate here is the right samplerate to get the same image that you see on TV.
It's the same bitter suffering that vector game fans have had to suffer with for years. Emulating one display technology on another is wildly different one is doomed to failure.
Come back later when variable LED-backlit LCDs are commonplace and we can get decent, even, controllable lighting with reasonably accurate color.
And then we can start working on bizarre artifacts like scanline length varying with brightness(sometimes accuracy is NOT desirable).
Read my post above, i cracked it.
Scanlines are now easily possible:
Every other line of pixels should be a blend of the line above it and the line below it.
then the intesity of that line should be decreased by XX << this value should be changable from 0 to 100 as every TV/Brand was different. with 0 being black.
Scanlines are now easily possible:
Every other line of pixels should be a blend of the line above it and the line below it.
then the intesity of that line should be decreased by XX << this value should be changable from 0 to 100 as every TV/Brand was different. with 0 being black.
I made some estimations with paint. Does contain rounding errors so its not 100% accurate but very close
NTSC Original
NTSC2PAL (The NTSC picture has been streched to PAL widht/height)
Pal Original
PAL2NTSC (The PAL picture has been shrunk to NTSC widht/height)
EDIT:
As a comparison i added:
RGB2PAL (direct stretch of the RGB data to pal resolution)
RGB2NTSC (direct stretch of the RGB data to ntsc resolution)
The original image can be found on byuu's website
EDIT2:
Awesome pixel counting the NTSC image i can confirm that appart from the rounding error all the shapes are accurate!
The formula is correct !!
NTSC Original
NTSC2PAL (The NTSC picture has been streched to PAL widht/height)
Pal Original
PAL2NTSC (The PAL picture has been shrunk to NTSC widht/height)
EDIT:
As a comparison i added:
RGB2PAL (direct stretch of the RGB data to pal resolution)
RGB2NTSC (direct stretch of the RGB data to ntsc resolution)
The original image can be found on byuu's website
EDIT2:
Awesome pixel counting the NTSC image i can confirm that appart from the rounding error all the shapes are accurate!
The formula is correct !!
-
- Regular
- Posts: 347
- Joined: Tue Mar 07, 2006 10:32 am
- Location: The Netherlands
LOL i forgotVerdauga Greeneyes wrote:Good work, tetsuo; I'll have to read it all again before I understand what you're doing By the way, you know the PAL resolution is 256x239, right?
i did all my math with NTSC, so there are no errors there. But that little difference does explain some of the problems with the PAL examples
The input resolution does NOT matter at all. see my updated first post.
All the modern display devices are digital and therefore have actual representation of their own resolution. All video data should be stretched to device's own resolution.
1) correct SNES resolution by TV aspect ratio
2) correct 1 by monitor own aspect ratio (no 1:1 mapping is guaranteed, for example 17"-19" LCD monitors)
3) stretch 2 up to monitor resolution.
Of course the image get's scaled only once by aggregated aspect ratio multipliers for width and height.
1) correct SNES resolution by TV aspect ratio
2) correct 1 by monitor own aspect ratio (no 1:1 mapping is guaranteed, for example 17"-19" LCD monitors)
3) stretch 2 up to monitor resolution.
Of course the image get's scaled only once by aggregated aspect ratio multipliers for width and height.
[url=http://quake2xp.quakedev.com]quake2xp[/url] audio engineer
-For the above example square pixels are the target._willow_ wrote:All the modern display devices are digital and therefore have actual representation of their own resolution. All video data should be stretched to device's own resolution.
1) correct SNES resolution by TV aspect ratio
2) correct 1 by monitor own aspect ratio (no 1:1 mapping is guaranteed, for example 17"-19" LCD monitors)
3) stretch 2 up to monitor resolution.
Of course the image get's scaled only once by aggregated aspect ratio multipliers for width and height.
-We assume the monitor is able to display square pixels at its native resolution
-The image is windowed or centered within the native resolution, stretching it to monitor resolution will distort the otherwise perfect image.
The idea here is to display the image exactly like it would look on a TV
Monitors will always have a 1:1 aspect ratio when the native resolution is used. The make 100% sure use DVI/HDMI.
The aspect ratio only becomes a problem again when you try to fill the entire screen with the image(without black bars)
EDIT:
You could double every pixel for the NTSC resolution and get a 1280x972 image, this would leave you with only 108 black lines (54 below and 54 above) but the pal signal would not fit because it requires 1536x1152
Haha, by making screenshots you assumed i do watch them 1:1, right? Well, it's true and blind luck of it.-For the above example square pixels are the target.
Tell this to any 17"-19" owner.-We assume the monitor is able to display square pixels at its native resolution
256x239, Is it joke? If you are going to double, quad the pixels then excessive edge sharpness will do bad job for correct TV emulation. No way i will call it perfect image because....-The image is windowed or centered within the native resolution, stretching it to monitor resolution will distort the otherwise perfect image.
Exactly! Because it should look like TV, well we want it to be..The idea here is to display the image exactly like it would look on a TV
That is questionable. Even 4:3 LCD matrix can have not squared pixels, like the one on my 2nd PC.Monitors will always have a 1:1 aspect ratio when the native resolution is used. The make 100% sure use DVI/HDMI.
Can you rephrase please? While filling the image to the entire screen you are most likely to destroy the correct ratioThe aspect ratio only becomes a problem again when you try to fill the entire screen with the image(without black bars)
Any scaling is not an improvement, it's just a guessing. Neither float scaler nor integer scaler are better.EDIT:
You could double every pixel for the NTSC resolution and get a 1280x972 image, this would leave you with only 108 black lines (54 below and 54 above) but the pal signal would not fit because it requires 1536x1152
[url=http://quake2xp.quakedev.com]quake2xp[/url] audio engineer
Uh, I don't think this is true. Pixel aspect and frame aspect are two different things. I've never seen a consumer LCD display using rectangular pixels, though they come in many different frame aspects._willow_ wrote: That is questionable. Even 4:3 LCD matrix can have not squared pixels, like the one on my 2nd PC.
You scaled horizontally by 704/256*10/11 = 2.5 and vertically by 2, for 2.5:2 = 1.25:1. The correct aspect is around 1.141:1. Same error as before. Forget about the frame; focus only on the ratio of horizontal to vertical scaling.tetsuo55 wrote:- we start with the 256x224 image
- Double the height by repeating each pixel 256x448
- Pad the height by adding 19 black pixels above and below 256x486 (At this point we have reached the accurate height) [...]
- Stretch 256 to 704
- 704 needs to be padded too by adding 8 black pixels to both left and right.
- The resulting 720x486 image has the pixels correctly stored. However we still need to convert them to the correct frame/picture aspect ratio
- To do this we scale horizontally by 10/11
- 720 > 654 6/11
- Now crop to 640, equally on each side "7 3/11"
- The resulting 640x486 image is square for both the content and the monitor
Fitzroy is right.FitzRoy wrote:Uh, I don't think this is true. Pixel aspect and frame aspect are two different things. I've never seen a consumer LCD display using rectangular pixels, though they come in many different frame aspects._willow_ wrote: That is questionable. Even 4:3 LCD matrix can have not squared pixels, like the one on my 2nd PC.
There is a lot of confusion about this, there are 2 completely seperate things at work here
Pixel aspect ratio (the squareness of each individual pixel)
Picture aspect ratio (the squareness of the entire screen as a whole)
What i am trying to do here is get both correct on a computer monitor. And that's exactly what my calculation does.
A better explenation of why this is wrong (i used you're formulat before)_willow_ wrote:All the modern display devices are digital and therefore have actual representation of their own resolution. All video data should be stretched to device's own resolution.
1) correct SNES resolution by TV aspect ratio
2) correct 1 by monitor own aspect ratio (no 1:1 mapping is guaranteed, for example 17"-19" LCD monitors)
3) stretch 2 up to monitor resolution.
Of course the image get's scaled only once by aggregated aspect ratio multipliers for width and height.
1. You are assuming the RGB pixels you are getting represent a squished TV pixel (it doesn't)
2. You are correcting to the monitor picture aspect ratio not the tv picture aspect ratio
The frame aspect on those monitors is not 4:3, it's 5:4. Correct calculation:_willow_ wrote:calculate yourself
common 17", 19" LCD displays
4:3 - aspect ratio
resolution 1280x1024
1280/4 = 320
1024/3 = 341.3333(3)
341.3333(3) not equal to 320 so the pixels are rectangular
pixel aspect = 320 : 341.3333(3)
1280/5 = 256
1024/4 = 256
The myth that 1280x1024 is a 4:3 resolution has its roots in CRT monitor days when this resolution was more popular than 1280x960 for some reason, despite the fact that the latter was the correct one to use for a 4:3 frame aspect. 1280x1024 stretched to fit a 4:3 aspect CRT results in a distorted image because it's a 5:4 resolution in a 4:3 frame. I don't know who started it, but they should be shot immediately.
-
- Regular
- Posts: 347
- Joined: Tue Mar 07, 2006 10:32 am
- Location: The Netherlands
It was a popular resolution in games because of something about the way RAM on graphics cards was clustered, IIRC (as usual I don't remember the specifics), which made the 5:4 1280x1024 faster than the 4:3 1280x960.FitzRoy wrote:The myth that 1280x1024 is a 4:3 resolution has its roots in CRT monitor days when this resolution was more popular than 1280x960 for some reason, despite the fact that the latter was the correct one to use for a 4:3 frame aspect. 1280x1024 stretched to fit a 4:3 aspect CRT results in a distorted image because it's a 5:4 resolution in a 4:3 frame. I don't know who started it, but they should be shot immediately.