View Full Version : Shader implementation of the NEDI algorithm
If you're doing this in floating point back and forth, there is no loss in doing this in YCbCr. Its just math.
but the result is "only" stored in 16 bit not float point so this should be faster and more precision.
nevcairiel
8th June 2014, 16:01
but the result is "only" stored in 16 bit not float point so this should be faster and more precision.
Its 16-bit float to my knowledge.
madshi
8th June 2014, 16:21
Lossless conversion between RGB <-> YCbCr is useless for me. I'm calculating in 32bit+ float and storing results in 16bit+ int/float, and final output is only 8bit. So there's gigantic headroom, no need for lossless conversion. It's *MUCH* more important to use a conversion that matches human perception. So BT.709 is a much better choice than YCgCo in this specific situation.
i only ask this to understand this better.
It's *MUCH* more important to use a conversion that matches human perception
if a RGB is lossless transform to YCgCo doesn't that mean it doesn't matter what colorspace RGB was before? it's the same colorspace again after the YCbCr -> RGB as long as the MATH done with it doesn't change the colorspace?
i don't understand this. i'm just missing the knowledge.
nevcairiel
8th June 2014, 16:44
His point is that he does processing on the luma plane after the color decorrelation, and for that to be really useful, this luma plane should match what we humans perceive as luma the most closely.
YCgCo was designed with compression efficiency and ease of computation in mind, not to match the human perception.
i never thought there is a different between luma in YCbCr and YCgCo. so luma information aren't simply luma informations good to know.
enough off topic from me i'm sorry.
madshi
8th June 2014, 17:07
His point is that he does processing on the luma plane after the color decorrelation, and for that to be really useful, this luma plane should match what we humans perceive as luma the most closely.
YCgCo was designed with compression efficiency and ease of computation in mind, not to match the human perception.
Exactly.
I could also scale RGB directly with NNEDI3. I'm not converting to YCbCr because I *have* to. I do that only because I get a better quality/performance ratio if I apply NNEDI3 only on the information which is most important to the human eye (= luma information). Scaling directly in RGB is 3x slower than scaling only the Luma channel.
Shiandow
8th June 2014, 17:11
Minor change to chromaNEDI-III: the line "//a /= dot(a,1)" shouldn't be commented out after all, doing so causes too many artefacts. The same line in chromaNEDI-I and -II doesn't seem to cause problems.
Asmodian
8th June 2014, 18:28
I could also scale RGB directly with NNEDI3. I'm not converting to YCbCr because I *have* to. I do that only because I get a better quality/performance ratio if I apply NNEDI3 only on the information which is most important to the human eye (= luma information). Scaling directly in RGB is 3x slower than scaling only the Luma channel.
To make sure I remember correctly; if one wants NNEDI3 to scale RGB directly, without a RGB->YCbCr->RGB conversion, one simply needs to set both madVR's luma and chroma doubling to the same neuron value? Maybe this would be a better way to compare the algorithms? Though it does make NNEDI3 even slower in comparison.
madshi
8th June 2014, 19:28
I always do the RGB->YCbCr->RGB conversion because you usually want to use more neurons for luma than for chroma, even if you enable both luma+chroma doubling.
Asmodian
8th June 2014, 22:39
I always do the RGB->YCbCr->RGB conversion because you usually want to use more neurons for luma than for chroma, even if you enable both luma+chroma doubling.
Wow, I had badly misread your explanation (http://forum.doom9.org/showthread.php?p=1664703#post1664703). :o
Of course separate luma and chroma doubling (only doubling luma) has always been better in my tests but if it is low effort maybe a special case for the future when we can all run NNEDI3 256 Luma + Chroma doubling? Or does the math workout the same either way?
On what channel does MadVR perform nnedi3 resizing in YCbCr mode? Because if I use the chromaNEDI shaders and add a pre-resize shader that converts to RGB the resulting image is quite noticeably better: resized from YCbCr (http://i.imgur.com/e6FZaI6.jpg) / resized from RGB (http://i.imgur.com/xMztLRj.jpg).
From my limited understanding there would be a difference between NNEDI3 or NEDI on R, G, and B vs NNEDI3 or NEDI on Y, U, V converted to RGB. The HVS important luma information is more connected to R, G, and B than it is to U or V and both NNEDI3 and NEDI might be sort of human like as far as edge recognition goes? Also the source usually starts with half resolution U and V. Combining the chroma with the higher resolution luma information (via YUV -> RGB) might result in sharper easier to recognize edges for NNEDI3 or NEDI? Of course there is no longer a luma channel so all channels would have low resolution chroma mixed into them but your example seems to say RGB is better. :p
madshi
9th June 2014, 08:53
if it is low effort maybe a special case for the future when we can all run NNEDI3 256 Luma + Chroma doubling? Or does the math workout the same either way?
I think the math would either work out the same, or if it does not, YCbCr might be better than RGB. Just a guess, though.
On what channel does MadVR perform nnedi3 resizing in YCbCr mode? Because if I use the chromaNEDI shaders and add a pre-resize shader that converts to RGB the resulting image is quite noticeably better: resized from YCbCr (http://i.imgur.com/e6FZaI6.jpg) / resized from RGB (http://i.imgur.com/xMztLRj.jpg).
Hmmmm... I'm not sure what you mean exactly with this. The pre-resize shader should already run in RGB. All of madVR's custom pixel shaders (both pre-resize and post-resize) are always fed with RGB data. So why would you convert to RGB, if the data is already RGB? Can you list the exact processing chain for both of these images?
Shiandow
9th June 2014, 14:24
I think the math would either work out the same, or if it does not, YCbCr might be better than RGB. Just a guess, though.
Since NNEDI3 is nonlinear the math doesn't exactly work out to be the same. I think all other algorithms in MadVR (except spline) are linear so in those cases it doesn't really matter which colour space you use (unless you change the gamma).
Hmmmm... I'm not sure what you mean exactly with this. The pre-resize shader should already run in RGB. All of madVR's custom pixel shaders (both pre-resize and post-resize) are always fed with RGB data. So why would you convert to RGB, if the data is already RGB? Can you list the exact processing chain for both of these images?
I fear I've been slightly unclear. This is happened when I put an empty file called YCbCr in the MadVR folder, and used NNEDI3 for luma doubling and Jinc3AR for image upscaling. It seems that MadVR skips the YCbCr -> RGB conversion but doesn't skip the RGB -> YCbCr conversion after the pre-resize pixel shaders. Which means that it's performing NNEDI3 on the wrong colour space which lowers the picture quality.
It seems that this is also the reason I thought NEDI looked superior, and it may be the reason that improving chroma upscaling seemed to slightly improve the luma upscaling in some of those images.
madshi
9th June 2014, 14:56
Since NNEDI3 is nonlinear the math doesn't exactly work out to be the same.
Yeah, it won't be identical, but probably in the end it will look similar.
I fear I've been slightly unclear. This is happened when I put an empty file called YCbCr in the MadVR folder, and used NNEDI3 for luma doubling and Jinc3AR for image upscaling. It seems that MadVR skips the YCbCr -> RGB conversion but doesn't skip the RGB -> YCbCr conversion after the pre-resize pixel shaders. Which means that it's performing NNEDI3 on the wrong colour space which lowers the picture quality.
Oooh, I think you're right! Sorry about that. I had implemented the "YCbCr" empty file hack just a long time ago for testing purposes and when implementing the RGB->YCbCr->RGB conversions for NNEDI3 I didn't think of that the "YCbCr" would need special treatment. So it seems NNEDI3 image doubling doesn't work well with the "YCbCr" empty file hack atm. Will put that on my to do list to fix...
Shiandow
9th June 2014, 21:21
It seems that the current versions of the ChromaNEDI shaders only use the directional information very weakly, apparently this is still enough to outperform most other algorithms but it causes a loss of detail. I think I've been able to fix this using a few of the same tricks I used in the NEDI shaders (and then some). I'll post these improved versions and a couple of comparisons when I have time, they still require some fine-tuning.
Edit: Later I'll post a more detailed explanation of what I changed but first some comparisons between the new and old method:
(Chroma only)
New method (http://i.imgur.com/IVtA8oc.jpg)
Old method (http://i.imgur.com/9BAfkrE.jpg)
Bicubic (http://i.imgur.com/jOoK1WN.jpg)
With luma (http://i.imgur.com/xS2qGfw.jpg)
One thing I find worrying is that Bicubic seems to be shifted slightly to the left, I've been unable to confirm if this is correct. For my implementation I assumed that the chroma channel corresponded to the average of each 2x2 block.
pie1394
12th June 2014, 04:54
Edit: Later I'll post a more detailed explanation of what I changed but first some comparisons between the new and old method:
(Chroma only)
New method (http://i.imgur.com/IVtA8oc.jpg)
Old method (http://i.imgur.com/9BAfkrE.jpg)
Bicubic (http://i.imgur.com/jOoK1WN.jpg)
With luma (http://i.imgur.com/xS2qGfw.jpg)
Personal opinions ...
[High-frequency details]
New method > Bicubic >> Old method
[Low-frequency details]
Bicubic > New method > Old method
This time I use the Sony Fit 11A's 11.6" 1920x1080 to view these samples. This monitor's backlit is QD-LED --- so richer colors than most LCD monitors, and more similar to a good TV set. But it has ridiculous high gamma value by factory default setting. The object / skin-tone colors also look weird (too vivid) if its RGB LUT settings are not adjusted in the display driver.
Anyway it looks impressive with your new method's sample on this monitor. The little dinosaur's head looks more pop/stereo. The girl's hair colors are also distinguishable one by one even on such small-sized FHD panel.
madshi
12th June 2014, 06:56
One thing I find worrying is that Bicubic seems to be shifted slightly to the left, I've been unable to confirm if this is correct. For my implementation I assumed that the chroma channel corresponded to the average of each 2x2 block.
All modern compression algorithms (MPEG2, VC1, h264, h265) have Chroma moved half a pixel to the left for 4:2:0 content:
chroma placement image (http://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Yuvformats420samplingMPEG-2.svg/504px-Yuvformats420samplingMPEG-2.svg.png)
Shiandow
12th June 2014, 10:41
All modern compression algorithms (MPEG2, VC1, h264, h265) have Chroma moved half a pixel to the left for 4:2:0 content:
Then it seems that I have made the current version for the wrong "type" of 4:2:0. Although, on the bright side, that means that the image quality can be improved even further.
Edit: Well luckily that was somewhat easy to fix, and the resulting image (http://i.imgur.com/4v2Lr70.jpg) is definitely better.
leeperry
12th June 2014, 13:25
Then it seems that I have made the current version for the wrong "type" of 4:2:0
While on that subject, would that be possible to write a PS script that would map the chroma alignment from MPEG2/H264 to MPEG1? There is no way to get properly aligned MPEG1 chroma in mVR when not feeding it RGB so a "hotfix" PS script would be full of win :)
Shiandow
12th June 2014, 13:26
Allright, I think the improved chroma shaders are now more or less ready. The new shaders only use a 2nd order interpolation instead of a 4th order, the linear equation that you needed to solve for a 4th order interpolation has the annoying property that it becomes unstable if you get close to an edge, which means that you either have a lot of artefacts or you can only use the directional information very weakly. The new shaders also use a more stable method for solving these equations which also reduces artefacts. I've also added a smarter way of limiting the resulting coefficients, which forces the chroma intensity to stay the same and prevents it from interpolating too strongly in one direction.
I'll add the new shaders to the first post.
By the way, the only purpose of the third shader is to shift the chroma channel half a pixel upwards; it would probably be better to do this simultaneously with scaling.
huhn
12th June 2014, 13:47
While on that subject, would that be possible to write a PS script that would map the chroma alignment from MPEG2/H264 to MPEG1? There is no way to get properly aligned MPEG1 chroma in mVR when not feeding it RGB so a "hotfix" PS script would be full of win :)
a h264 stream with: chromaloc 1 should provide all infos needed. and mpeg1 input should work too.
Shiandow
12th June 2014, 13:54
While on that subject, would that be possible to write a PS script that would map the chroma alignment from MPEG2/H264 to MPEG1? There is no way to get properly aligned MPEG1 chroma in mVR when not feeding it RGB so a "hotfix" PS script would be full of win :)
A slight adaptation of chromaNEDI-II should do it; it currently shifts things half a pixel vertically, but it could just as well shift them horizontally. Although I would like it better if the shifting was done simultaneously with scaling. Anyway the following code should shift the chroma channels half a pixel to the right. It expects the input to be in YCbCr, and should be used pre-resize. It tries to convert the result to RGB but I can't guarantee that that part will always work; it might be wrong about the colour space.
// $MinimumShaderProfile: ps_3_0
sampler s0 : register(s0);
float4 p0 : register(c0);
#define width (p0[0])
#define height (p0[1])
#define px (1.0 / (p0[0]))
#define py (1.0 / (p0[1]))
#define sqr(x) (dot(x,x))
#define I (float2x2(1,0,0,1))
//Conjugate residual
float2 solve(float2x2 A,float2 b) {
float2 x = 1/2.0;
float2 r = b - mul(A,x);
float2 p = r;
float2 Ar = mul(A,r);
float2 Ap = Ar;
for (int k = 0;k < 3; k++){
float a = min(100,dot(r,Ar)/dot(Ap,Ap));
x = x + a*p;
float2 rk = r; float2 Ark = Ar;
r = r - a*Ap;
Ar = mul(A,r);
float b = dot(r,Ar)/dot(rk,Ark);
p = r + b*p;
Ap = Ar + b*Ap;
}
return x;
}
float4 toRGB(float4 s1) {
s1.yz -= 0.5;
if(width < 1120 && height < 630) return float3(s1.x+1.402*s1.z, dot(s1, float3(1, -.202008/.587, -.419198/.587)), s1.x+1.772*s1.y).rgbb;// SD Y'CbCr to RGB output
return float3(s1.x+1.5748*s1.z, dot(s1, float3(1, -.1674679/.894, -.4185031/.894)), s1.x+1.8556*s1.y).rgbb;// HD Y'CbCr to RGB output
}
#define Col(xy) (tex2D(s0,tex+float2(px,py)*(xy)).yz-0.5)
#define Get(xy) (tex2D(s0,tex+float2(px,py)*(xy)).x+0.25)
#define Get4(xy) (float2(Get(xy+dir[0]),Get(xy+dir[1])))
float4 main(float2 tex : TEXCOORD0) : COLOR {
float4 c0 = tex2D(s0,tex);
float2 dir[2] = {{-1,0},{1,0}};
float2 wind[4] = {{-1,0},{1,0},{0,1},{0,-1}};
float2 pos[2] = {{0,0},{1,0}};
float w = 2;
float2x2 R = w*mul(float2x1(Get4(0)),float1x2(Get4(0)));
float2 r = w*Get(0)*Get4(0);
float4x2 C = {Get4(wind[0]),Get4(wind[1]),Get4(wind[2]),Get4(wind[3])};
float4 y = {Get(wind[0]),Get(wind[1]),Get(wind[2]),Get(wind[3])};
R += mul(transpose(C),C);
r += mul(y,C);
//Normalize coefficients
float n = 16;
R/= n; r /= n;
//Solve equations
float2 a = solve(R+0.000001*I,r);
//Limit the coefiicents of a
float2 b = float2(a[0]+a[1]-1,a[0]-a[1]);
b[0] = clamp(b[0],-.02,.02); //Clamp intensity
b[1] = clamp(b[1],-1,1); //Clamp "directedness"
a = .5 + float2(.5,.5)*b[0] + float2(.5,-.5)*b[1];
c0.a = dot(c0.gb,1);
c0.gb = 0.5+mul(a,float2x2(Col(pos[0]),Col(pos[1])));
return toRGB(c0);
}
FireFreak111
12th June 2014, 14:57
Running the chroma shaders in MPC-HC in pre-resize in order, the first two blur the image, and with the third one the image looks blown out and grainy. With the YbCbCr file, basically the same problem. Chroma set to NN.
Clearly not working here.
GTX 660, newest Madvr, nightly MPC-HC, Windows 8.1.1.
From the samples shown however, this looks like a great middle-ground between Chroma Jinc and NNEDI3, which for DVD and lower quality content I just cant combine with Luma NNEDI3 16N with both double and quad enabled on this 660 and i7 870.
Wish NNEDI3 ran on DirectCompute.
Shiandow
12th June 2014, 15:11
Could you post a few screenshots of what happens?
FireFreak111
12th June 2014, 15:30
Nearest Neighbour
http://i1292.photobucket.com/albums/b568/FireFreak111/Screenshot176_zpse8df30f7.png~original
Chrome-NEDI
http://i1292.photobucket.com/albums/b568/FireFreak111/Screenshot177_zps105b58a0.png~original
madshi
12th June 2014, 15:30
Thanks for your efforts so far, Shiandow, I'll definitely play with your shaders when I find some time!
Shiandow
12th June 2014, 15:32
Oh it turns out that I copied the wrong shader for chromaNEDI-III, it should work with the current one. Thanks FireFreak111 for noticing that.
FireFreak111
12th June 2014, 15:54
Sorry for the full size images, photobuckets linking is messed when trying to use a full size image.
There is a distinct blur when using these shaders, it doesn't appear to be working correctly.
Nearest Neighbour:
http://i1292.photobucket.com/albums/b568/FireFreak111/Screenshot183_zpsbef10c1d.png~original
Chroma-NEDI
http://i1292.photobucket.com/albums/b568/FireFreak111/Screenshot182_zpse2f23ff7.png~original
Shiandow
12th June 2014, 15:58
Are you sure that the input is in YCbCr? Because it looks like the kind of images you get when the input is RGB.
FireFreak111
12th June 2014, 16:02
Thankyou, I had named the YCbCr file wrong. The YCbCr to RGB should be post Chroma-NEDI right? It seems to be working correctly now. :)
Shiandow
12th June 2014, 16:11
Yes the YCbCr shader should be after Chroma-NEDI. Glad it's working!
FireFreak111
12th June 2014, 16:24
Small thing, your YCbCr to RGB shader is bugged for SD, its only outputting 16:235 (example being a fully black 1st frame is grey). On HD, Blacks is fully functional.
For this SD content, the primaries are apparently SMPTE C (not BT.709, as usual). The shader isn't handling this type.
Shiandow
12th June 2014, 16:54
I added a different RGBtoYCbCr shader to the first post that should also work for SD content, but again likely not all. You could also use the RGBtoYCbCr shader I added instead of using the YCbCr hack, this should at least keep the colours the same.
FireFreak111
13th June 2014, 02:40
Absolutely perfect, working completely without the hack (which was messing with my gamma for some reason). Thankyou for this shader.
Shiandow
13th June 2014, 19:28
Minor update: the shaders chromaNEDI-I and II have been improved a bit by using a slightly larger (more disk shaped) window, the difference is most noticeable when not using chromaNEDI-III (which seems to remove some detail, including aliasing).
FireFreak111
14th June 2014, 09:20
Is there a way to view Chroma only, so I can compare different algorithms? Is there a shader I could use?
Shiandow
14th June 2014, 14:22
You can just modify the YCbCrtoRGB shader slightly so it will remove the luma channel:
sampler s0;
float2 c0;
float4 main(float2 tex : TEXCOORD0) : COLOR
{
float3 s1 = tex2D(s0, tex).rgb;// original pixel
s1.yz -= 0.5;
s1.r = 0.3; // erase luma
if(c0.x < 1120 && c0.y < 630) return float3(s1.x+1.402*s1.z, dot(s1, float3(1, -.202008/.587, -.419198/.587)), s1.x+1.772*s1.y).rgbb;// SD Y'CbCr to RGB output
return float3(s1.x+1.5748*s1.z, dot(s1, float3(1, -.1674679/.894, -.4185031/.894)), s1.x+1.8556*s1.y).rgbb;// HD Y'CbCr to RGB output
}
FireFreak111
14th June 2014, 14:42
This works perfectly except when the Chroma-NEDI shader is in the middle, then everything shows as normal, so I cant compare your shader to others. (Luma is included when using your shader, with just RGB-YCbCr-RGB I see chroma.
Also, alot of grey in this chroma, no blacks, is that normal? First frame of a movie for example is grey, it's black when the new value you added is at 0.0
http://i1292.photobucket.com/albums/b568/FireFreak111/Screenshot188_zps371ed53f.png
Shiandow
14th June 2014, 14:59
What I usually do when I want to compare is to add a RGBtoYCbCr shader followed by the chroma only shader post-resize, then I can toggle chromaNEDI on/off by enabling disabling the pre-resize shaders. You could also use it instead of the YCbCrtoRGB shader but that makes it harder to compare.
You see a lot of grey because it fixes the luma to 0.25, if you set it to 0 then it's usually too dark to see anything.
FireFreak111
14th June 2014, 16:01
Using Frozen for chroma investigation, due to the movie's good chroma compression and heavy use of it, especially in the pink cloak constantly used.
NEDI seems to fare well against NNEDI3, except for some blur on distinct edges (pillars, characters lower cloak, reflection, shoes). Jinc3 (not shown) has the same definition here as NNEDI3, so its distinctly NEDI's problem, not an advantage of NNEDI3.
NEDI
http://i1292.photobucket.com/albums/b568/FireFreak111/Screenshot198_zpsaa40bef4.png~original
NNEDI3-16
http://i1292.photobucket.com/albums/b568/FireFreak111/Screenshot199_zps13293d9a.png~original
To be fair, NEDI is 2-3x faster then NNEDI3, entire chain taking only 11.7ms on 1080p24 content (at 1080p48 with no SM).
Shiandow
14th June 2014, 17:50
One key difference between NEDI and other chroma upscaling algorithms is that NEDI only makes edges sharp if the luma channel is sharp. Without the luma channel it's hard to tell if NEDI is blurring an edge that it shouldn't or NNEDI3 is sharpening an edge that it shouldn't. Both are very well possible. I also found it interesting that NEDI seems to be better at bringing out detail on the pillars itself.
leeperry
14th June 2014, 23:45
A slight adaptation of chromaNEDI-II should do it; it currently shifts things half a pixel vertically, but it could just as well shift them horizontally. Although I would like it better if the shifting was done simultaneously with scaling. Anyway the following code should shift the chroma channels half a pixel to the right. It expects the input to be in YCbCr, and should be used pre-resize. It tries to convert the result to RGB but I can't guarantee that that part will always work; it might be wrong about the colour space.
Sweet, thanks! All MPEG1 movies are using BT.601 but fair enough, if there can't a fail-safe way to work it out afterwards I'll just feed mVR with RGB32 for MPEG1. Would need to run test patterns in order to ensure that ffdshow does it properly duh ^^
FireFreak111
15th June 2014, 01:45
Chroma.rar (https://mega.co.nz/#!t9MkXAaS!akDh2MHzzdq4bsmHqVpQyjZvIZEM8OFS8fG31q4-ZR4)
Here is some screenshots with Luma shots for NEDI and NNEDI3, Chroma for NEDI, NNEDI3, Jinc3 and Bicubic, compressed into a RAR. This is after disabling the no DXVA copyback option in madVR, which was bluring the Chroma channel (still a blur difference between NEDI and NNEDI3, causing some minor artifacts like the bottom of the character's cloak in the Luma shot)
On another note, is it possible to combine the first two shaders, considering there's only a one line difference between them? Functions possibly?
Shiandow
15th June 2014, 16:03
On another note, is it possible to combine the first two shaders, considering there's only a one line difference between them? Functions possibly?
The second shader needs the results of the first one so it's not really easy to do it in just one shader. It would be possible to split them in a slightly different way but I think it will obfuscate the code and it will only be faster because I haven't found a way to make the shader skip processing for a particular pixel.
Shiandow
19th June 2014, 19:46
With the current discussion around chroma channel alignment I thought it would be useful to add support for different chroma patterns. I've therefore updated the chromaNEDI shaders.
cyberbeing
21st June 2014, 16:23
One key difference between NEDI and other chroma upscaling algorithms is that NEDI only makes edges sharp if the luma channel is sharp.
Is this why the NEDI chroma shaders don't remove distinct 2x2 block aliasing steps like the others do? The source video in question was a 640x360 x264 1200Kbps stream.
__________
http://i.imgbox.com/RCePQhlS.png
Nearest Neighbor Chroma (400% zoom) (http://i.imgbox.com/RCePQhlS.png)
__________
http://i.imgbox.com/OQgsmgOJ.png
NEDI Chroma (400% zoom) (http://i.imgbox.com/OQgsmgOJ.png)
__________
http://i.imgbox.com/6mazhDjy.png
Catmull-Rom Chroma (400% zoom) (http://i.imgbox.com/6mazhDjy.png)
__________
http://i.imgbox.com/xwmMcj59.png
NNEDI3 64 Chroma (400% zoom) (http://i.imgbox.com/xwmMcj59.png)
__________
madVR's YCbCr hack also seems to result in an elevated purplish black level on SD video with the provided YCbCrtoRGB shader as the last step pre-resize. [Edit: This was caused by using a 3DLUT with the YCbCr hack, which I guess must not be supported]. The above images used madVR in normal mode with both RGBtoYCbCr (first step) and YCbCrtoRGB (last step) shaders to workaround this.
madshi
21st June 2014, 17:09
@cyberbeing, it might be interesting to look at the luma channel, to check if the blocking is visible there. That might explain (or not) why the NEDI Chroma shader produces that kind of output.
cyberbeing
21st June 2014, 17:21
@cyberbeing, it might be interesting to look at the luma channel, to check if the blocking is visible there. That might explain (or not) why the NEDI Chroma shader produces that kind of output.
Okay, I've just sent a PM with a sample to you and Shiandow.
Shiandow
21st June 2014, 17:22
There seems to be a mismatch between what the shader thinks the chroma channels are and what they actually are. As a result some part of the chroma channel isn't scaled. Using the RGBtoYCbCr shader will ensure that the colours remain accurate even if it guesses the colour space incorrectly, but instead it will use the shaders on the wrong chroma channels. If you use the YCbCr hack you should get a smooth(er) result but the colours might be inaccurate.
If you use the chroma only shader I posted a few posts back, you'll see that the "chroma" part looks perfectly smooth. Unfortunately it is the wrong chroma channel.
Edit: Using the shaders with the YCbCr hack seems to remove all chroma aliasing, and changes the colour. I'm guessing that the BT.601 part of the RGB <-> YCbCr shaders doesn't work correctly.
cyberbeing
21st June 2014, 19:47
Edit: Using the shaders with the YCbCr hack seems to remove all chroma aliasing, and changes the colour. I'm guessing that the BT.601 part of the RGB <-> YCbCr shaders doesn't work correctly.
If you think those shaders are incorrect, you could try adapting NVIDIA's sample vertex/pixel shaders for RGB <-> YCbCr conversions which I'd assume should be accurate.
NVIDIA RGBA to YUVA sample (http://developer.download.nvidia.com/shaderlibrary/packages/post_RGB_to_YUV.fx.zip) | NVIDIA YUVA to RGBA sample (http://developer.download.nvidia.com/shaderlibrary/packages/post_RGB_from_YUV.fx.zip)
The actual pixel shader portion of these samples seems to be the following, but would need to be made MPC-HC compatible:
#define QUAD_REAL float
#define QUAD_REAL2 float2
#define QUAD_REAL3 float3
#define QUAD_REAL4 float4
QUAD_REAL4 ToYUV(QuadVertexOutput IN,
uniform sampler2D SceneSampler) : COLOR
{
QUAD_REAL4 rgba = tex2D(SceneSampler, IN.UV);
QUAD_REAL3 ctr = QUAD_REAL3(0,.5,.5);
return QUAD_REAL4(rgb_to_yuv(rgba.xyz)+ctr,rgba.w); // don't lose alpha
}
QUAD_REAL3 rgb_to_yuv(QUAD_REAL3 RGB)
{
QUAD_REAL y = dot(RGB,QUAD_REAL3(0.299,0.587,0.114));
QUAD_REAL u = (RGB.z - y) * 0.565;
QUAD_REAL v = (RGB.x - y) * 0.713;
return QUAD_REAL3(y,u,v);
}
QUAD_REAL4 FromYUV(QuadVertexOutput IN,
uniform sampler2D SceneSampler) : COLOR
{
QUAD_REAL4 yuva = tex2D(SceneSampler, IN.UV) - QUAD_REAL4(0,.5,.5,0);
return QUAD_REAL4(yuv_to_rgb(yuva.xyz),yuva.w); // don't lose alpha
}
QUAD_REAL3 yuv_to_rgb(QUAD_REAL3 YUV)
{
QUAD_REAL u = YUV.y;
QUAD_REAL v = YUV.z;
QUAD_REAL r = YUV.x + 1.403*v;
QUAD_REAL g = YUV.x - 0.344*u - 1.403*v;
QUAD_REAL b = YUV.x + 1.770*u;
return QUAD_REAL3(r,g,b);
}
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.