Color casts from different shadow masks

I went ahead and measured an 100 IRE signal using each of the masks specified in subpixel_masks.h using a colorimeter. https://github.com/libretro/slang-shaders/blob/master/include/subpixel_masks.h

What I found is that most of the masks have a very significant green cast on my RGB 4K monitor. It seems that the smaller mask patterens trump the larger ones. I will do another test on my 4K TV when I have a chance. For sanity I only recorded the dE. The number refers to the ‘phosphor_layout’ variable.

Reference white point (no mask): dE 0.5 relative to D65

1 - 2.1

2 - 2.7

3 - 1.0 (best SLOT MASK)

4 - 1.4 (best color APERTURE)

5 - 0.8 (best SHADOW MASK)

6 - 23.6

7 - 13.9

8 - 5.0

9 - 3.9

10 - 8.5

11- 26.4

12 - 4.5

13 - 8.2

14 - 1.7

15 - 10.3

16 - 18.8

17 - 19.1

18 - 13.8

19 - 11.1

20 - 7.9

21 - 23.8

22 - 0.8

24 - 0.5 (best APERTURE)

25 - 11.1

2 Likes

Interesting results! I’m surprised that the magenta/green masks varied on how much tint they imparted and that the BGR masks did so well. What model monitor do you have?

Interesting what colorimeter did you use? Also how did you test those masks? In what shader I mean.

1 Like

Hi Hunter, I’m glad you saw my thread! Here is some more information on the tests:

The monitor I used was a NEC EA271U-BK. Actually I’m not sure if it is RGB. The pixels are so small I can’t see them. I’ll see if I can find a loupe. This is a good monitor (for 4K) with linear characteristics (e.g. if I increase the brightness, the gamma stays relatively the same).

I used a rather old i1Display Pro but I’m confident in its accuracy.

I used my own shader which adds scanlines and upscales. It does a slight color transformation as well, but this doesn’t matter at 100 IRE. From my experience, adding scanlines does not impact the linearity of the signal, as long as the scanlines are all the same size.

1 Like

I’d be very surprised if it’s not RGB. It’s about as rare to find a BGR monitor is it is to find an RGB TV :stuck_out_tongue:

22 and 23 (24 and 25 are typos, I assumed?) are black and white masks, IIRC, so I’m also surprised to see tinting with those.

4 gives my monitor a pretty noticeable green tint and 5 is slightly pink here. 10 and 11 look identical for tint here vs the big discrepancy on yours.

You mentioned that you’re testing on top of your scanline shader, right? (which looks great, btw) Have you tried taking that out of the mix and using a solid white background from the 240p test suite?

Here’s a basic test mask testing shader. Just put it alongside the subpixel_masks.h file:

#version 450

layout(push_constant) uniform Push
{
	vec4 SourceSize;
	vec4 OriginalSize;
	vec4 OutputSize;
	uint FrameCount;
	float picker, toggle;
} params;

#pragma parameter picker "Mask Picker" 0.0 0.0 24.0 1.0
int mask_picker = int(params.picker);
#pragma parameter toggle "Mask Toggle" 1.0 0.0 1.0 1.0
bool mask_toggle = bool(params.toggle);

layout(std140, set = 0, binding = 0) uniform UBO
{
	mat4 MVP;
} global;

#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;

void main()
{
   gl_Position = global.MVP * Position;
   vTexCoord = TexCoord;
}

#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;

#include "subpixel_masks.h"

void main()
{
   vec3 img = texture(Source, vTexCoord).rgb;
   img *= (mask_toggle) ? mask_weights(vTexCoord.xy * params.OutputSize.xy, 1.0, mask_picker) : vec3(1.0);
   FragColor = vec4(img, 1.0);

Okay, this is what I got with solid:

0 - 0.4

1 - 0.6

2 - 0.7

3 - 2.6

4 - 0.7

5 - 2.2

6 - 13.5

7 - 4.4

8 - 3.9

9 - 2.9

10 - 4.3

11 - 16.0

12 - 3.3

13 - 5.4

14 - 0.4

15 - 5.7

16 - 8.7

17 - 9.6

18 - 8.9

19 - 7.2

20 - 7.0

21 - 17.5

22 - 0.6

23 - 0.5

24 - 6.6

Now it’s interesting that my dE is low when scanlines are on and I have no mask, and they are low when I use a B&W mask regardless of scanlines, but when I have scanlines on and a mask, the error from the mask is compounded. Why? Is it due to some aberration because of the subpixel layout? Possibly. But I’m also wondering how the black parts of the image affect the colorimeter’s reading. To us, the black is just black, but the colorimeter does read a color at this level, and it is usually very different from the white point. So, what I think I need to do is test these masks at the same perceptual brightness, compensating by simply increasing the brightness of the display. My hope is that this will provide a better ‘SNR’ and reduce the error overall. My monitor isn’t bright enough to do this, but my TV should be. So, I will try that when I get a chance.

1 Like

i guess you could also drop the brightness to match the darkest one… :slight_smile: