Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Hardware & Software > Software players

Reply
 
Thread Tools Display Modes
Old 27th July 2013, 04:47   #361  |  Link
XRyche
Registered User
 
Join Date: May 2008
Posts: 211
JanWillem32, First off.....Thank You for working on the hybrid shaders I've requested. I doubt if I would be able to find anyone else so willing to do that. Second, I have been doing some experimenting with different methods for cleaning up the image quality on a lot of my old XVID/DIVX/AVI files and it seems that they benefit more from deblocking (ffdshows raw filter mplayer deblocking) than denoising. I suppose since most of the files are old vhs to avi tv rips and old tvcard rips that makes sense. Anyways, would you be open to possibly doing an adjustable deblocking shader? I've read that ATI used to (I don't know if they still do) use it's shader core to do deblocking so I assume (whether correctly or not) it's possible to do it with an HLSL script. I don't have a clue what the math involved would be like so if you can't it's understandable.
XRyche is offline   Reply With Quote
Old 27th July 2013, 06:34   #362  |  Link
turbojet
Registered User
 
Join Date: May 2008
Posts: 1,840
MPEG4 ASP is notorious for banding (could be mistaken for blocks on flat surfaces and faces) are you sure it's not banding?

f3kdb is a must for me with ASP much less so for any decent AVC encode or MPEG2. Have you tried it through ffdshow's avisynth interface? Make sure to use setmemorymax(128 or more) to stop the leakage.
__________________
PC: FX-8320 GTS250 HTPC: G1610 GTX650
PotPlayer/MPC-BE LAVFilters MadVR-Bicubic75AR/Lanczos4AR/Lanczos4AR LumaSharpen -Strength0.9-Pattern3-Clamp0.1-OffsetBias2.0
turbojet is offline   Reply With Quote
Old 28th July 2013, 05:09   #363  |  Link
jerrymh
Registered User
 
Join Date: Jul 2013
Posts: 10
Quote:
Originally Posted by JanWillem32 View Post
About the f3kdb shader, I'm quite interested. There's a limit to what I can do, though. Shaders work very differently compared to many other graphics filters. In most cases, translating to shaders is rather hard. I'll just have to try and be creative. It may just as well be easier than the combination effect shader chain I'm trying to write for XRyche. Where do I start?

jerrymh, that kind of effect is easy. I made this effect two-pass. If you want something more specific (such as a better quality lowpass), I can change a few parts. Depending on the input/output resolution ratio, you might need to blur a bit more or less.
Code:
// (C) 2013 Jan-Willem Krans (janwillem32 <at> hotmail.com)
// This file is part of Video pixel shader pack.
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

// horizontal blur

sampler s0 : register(s0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	return (tex2D(s0, tex+float2(-3.*c1, 0))+tex2D(s0, tex+float2(-2.*c1, 0))+tex2D(s0, tex+float2(-c1, 0))+tex2D(s0, tex)+tex2D(s0, tex+float2(c1, 0))+tex2D(s0, tex+float2(2.*c1, 0))+tex2D(s0, tex+float2(3.*c1, 0)))/7.;// blur and output
}



// old CRT scan lines

#define scanlines 480// 480 for NTSC, 576 for PAL/SECAM, fractions, either decimal or not are allowed
#define gamma 1// higher is brighter, fractions, either decimal or not are allowed

sampler s0 : register(s0);
float2 c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float4 s1 = (tex2D(s0, tex+float2(0, -3.*c1.y))+tex2D(s0, tex+float2(0, -2.*c1.y))+tex2D(s0, tex+float2(0, -c1.y))+tex2D(s0, tex)+tex2D(s0, tex+float2(0, c1.y))+tex2D(s0, tex+float2(0, 2.*c1.y))+tex2D(s0, tex+float2(0, 3.*c1.y)))/7.;// blur input

	float br = 1.-pow(abs(frac(abs(tex.y*scanlines-.5*scanlines))*2.-1.), gamma);// generate scan lines
	return s1*br;// modulate brightness and output
}



// old CRT scan lines for XYZ rendering on 16-bit integer surfaces

#define scanlines 480// 480 for NTSC, 576 for PAL/SECAM, fractions, either decimal or not are allowed
#define gamma 1// higher is brighter, fractions, either decimal or not are allowed

sampler s0 : register(s0);
float2 c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float4 s1 = (tex2D(s0, tex+float2(0, -3.*c1.y))+tex2D(s0, tex+float2(0, -2.*c1.y))+tex2D(s0, tex+float2(0, -c1.y))+tex2D(s0, tex)+tex2D(s0, tex+float2(0, c1.y))+tex2D(s0, tex+float2(0, 2.*c1.y))+tex2D(s0, tex+float2(0, 3.*c1.y)))/7.;// blur input

	float br = 1.-pow(abs(frac(abs(tex.y*scanlines-.5*scanlines))*2.-1.), gamma);// generate scan lines
	return (s1-16384/65535.)*br+16384/65535.;// modulate brightness and output
}
Thank you very much,

How about a aperture grille like this on Final burn alpha, it feels like a real old crt, or LG plasma




Or a scanlines at 95%

Last edited by jerrymh; 28th July 2013 at 05:27.
jerrymh is offline   Reply With Quote
Old 28th July 2013, 08:19   #364  |  Link
XRyche
Registered User
 
Join Date: May 2008
Posts: 211
@turbojet...Yes there is some banding but some of JanWillem32's shaders+his modified EVR-CP already help with that (as well as madVR all but eliminating banding) but blocking is still there without using fddshow's raw filter. Not that the raw filter is bad I just would like to eliminate it from my playback chain. If JanWillem32 can kindly make a deblocking shader that does as good of a job or better as the raw filter I would much rather use that.

Most of my problem video files are from old vhs recordings of TV shows converted to .avi's as well as some TIVO-type files and early PC TV card recordings so blocking is kind of a given as well as massive banding . Considering that madVR doesn't do deblocking (it actually accentuates the blocking on some of my files) using madVR for these is sort of a no no without the raw filter or a shader script (one the madVR will not neuter because of gamma manipulation or such).
XRyche is offline   Reply With Quote
Old 28th July 2013, 14:17   #365  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
Deblocking is mostly decoder territory. Many video codecs don't use the typical macroblocks at all. For those that do, you need the general blocking info for the luma, chroma and interlacing to deal with it. For h.264 (and some newer codecs) organized (de)blocking is mandatory for both encoder and decoder. The custom shader stages of the video renderer are a bit late in the rendering chain to properly work on blocking and such. I'm not sure if I can write a normal shader that can help with deblocking.

jerrymh, that picture mostly shows hand-drawn pixel art. No decent video will convert nicely to high contrast, low quantization images like that. I can approximate the effect by combining a few techniques, but note that posterization is a really messy effect (even in common 8-bit video and worst of all, it's everywhere).
It's a two-pass shader chain again. The warning for "should be divisible by 4" isn't too strict, the few artifacts are hard to see. For common resolutions such as 720- and 1080-line systems I can also adapt special shaders to compensate for this issue. I can also try to boost some of the contrast or colorfulness before posterization as well, but I didn't see much improvement with those effects enabled on the samples I used.
Code:
// (C) 2013 Jan-Willem Krans (janwillem32 <at> hotmail.com)
// This file is part of Video pixel shader pack.
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

// horizontal 4-pixel averaging
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 4

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float pos = (trunc(tex.x*c0*.25)+.125)*c1*4.;// calculate the left positon of the current set of pixels
	return (tex2D(s0, float2(pos, tex.y))+tex2D(s0, float2(pos+c1, tex.y))+tex2D(s0, float2(pos+2*c1, tex.y))+tex2D(s0, float2(pos+3*c1, tex.y)))*.25;// blur and output
}



// vertical 4-pixel averaging, dithering, posterizing and old CRT scan lines
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 4

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.03125, .03125, .25);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.125)*c1.y*4.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y)))*.25;// blur input
#if posterizedegamma
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*br;// modulate brightness and output
#else
	s1 = round(s1*quantize+dithers);// dither and posterize
	return s1*(br*quantizer);// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// vertical 4-pixel averaging, dithering, posterizing and old CRT scan lines for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 4

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.03125, .03125, .25);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.125)*c1.y*4.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y)))*.25;// blur input
#if posterizedegamma
	s1 = s1*65535/32767.-16384/32767.;
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*(br*32767/65535.)+16384/65535.;// modulate brightness and output
#else
	s1 = round((s1*65535/32767.-16384/32767.)*quantize+dithers);// dither and posterize
	return s1*(br*quantizer*32767/65535.)+16384/65535.;// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// horizontal 5-pixel averaging
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 5

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float pos = (trunc(tex.x*c0*.2)+.1)*c1*5.;// calculate the left positon of the current set of pixels
	return (tex2D(s0, float2(pos, tex.y))+tex2D(s0, float2(pos+c1, tex.y))+tex2D(s0, float2(pos+2*c1, tex.y))+tex2D(s0, float2(pos+3*c1, tex.y))+tex2D(s0, float2(pos+4*c1, tex.y)))*.2;// blur and output
}



// vertical 5-pixel averaging, dithering, posterizing and old CRT scan lines
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 5

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.025, .025, .2);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.1)*c1.y*5.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y)))*.2;// blur input
#if posterizedegamma
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*br;// modulate brightness and output
#else
	s1 = round(s1*quantize+dithers);// dither and posterize
	return s1*(br*quantizer);// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// vertical 5-pixel averaging, dithering, posterizing and old CRT scan lines for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 5

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.025, .025, .2);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.1)*c1.y*5.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y)))*.2;// blur input
#if posterizedegamma
	s1 = s1*65535/32767.-16384/32767.;
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*(br*32767/65535.)+16384/65535.;// modulate brightness and output
#else
	s1 = round((s1*65535/32767.-16384/32767.)*quantize+dithers);// dither and posterize
	return s1*(br*quantizer*32767/65535.)+16384/65535.;// shrink interval back to normal after posterization, modulate brightness and output
#endif
}
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv

Last edited by JanWillem32; 29th July 2013 at 08:33. Reason: added extra shaders and functionality
JanWillem32 is offline   Reply With Quote
Old 28th July 2013, 22:35   #366  |  Link
jerrymh
Registered User
 
Join Date: Jul 2013
Posts: 10
Quote:
Originally Posted by JanWillem32 View Post
Deblocking is mostly decoder territory. Many video codecs don't use the typical macroblocks at all. For those that do, you need the general blocking info for the luma, chroma and interlacing to deal with it. For h.264 (and some newer codecs) organized (de)blocking is mandatory for both encoder and decoder. The custom shader stages of the video renderer are a bit late in the rendering chain to properly work on blocking and such. I'm not sure if I can write a normal shader that can help with deblocking.

jerrymh, that picture mostly shows hand-drawn pixel art. No decent video will convert nicely to high contrast, low quantization images like that. I can approximate the effect by combining a few techniques, but note that posterization is a really messy effect (even in common 8-bit video and worst of all, it's everywhere).
It's a two-pass shader chain again. The warning for "should be divisible by 4" isn't too strict, the few artifacts are hard to see. For common resolutions such as 720- and 1080-line systems I can also adapt special shaders to compensate for this issue. I can also try to boost some of the contrast or colorfulness before posterization as well, but I didn't see much improvement with those effects enabled on the samples I used.
Code:
// (C) 2013 Jan-Willem Krans (janwillem32 <at> hotmail.com)
// This file is part of Video pixel shader pack.
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

// horizontal 4-pixel averaging
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 4

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float pos = (trunc(tex.x*c0*.25)+.125)*c1*4.;// calculate the left positon of the current set of pixels
	return (tex2D(s0, float2(pos, tex.y))+tex2D(s0, float2(pos+c1, tex.y))+tex2D(s0, float2(pos+2*c1, tex.y))+tex2D(s0, float2(pos+3*c1, tex.y)))*.25;// blur and output
}



// vertical 4-pixel averaging, dithering, posterizing and old CRT scan lines
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 4

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.0625, .0625, .25);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z-.5), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.125)*c1.y*4.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y)))*.25;// blur input
#if posterizedegamma
	s1 = pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*br;// modulate brightness and output
#else
	s1 = round(s1*quantize+dithers);// dither and posterize
	return s1*(br*quantizer);// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// vertical 4-pixel averaging, dithering, posterizing and old CRT scan lines for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 4

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.0625, .0625, .25);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z-.5), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.125)*c1.y*4.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y)))*.25;// blur input
#if posterizedegamma
	s1 = pow(round(sqrt(s1*65535/32767.-16384/32767.)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*(br*32767/65535.)+16384/65535.;// modulate brightness and output
#else
	s1 = round((s1*65535/32767.-16384/32767.)*quantize+dithers);// dither and posterize
	return s1*(br*quantizer*32767/65535.)+16384/65535.;// shrink interval back to normal after posterization, modulate brightness and output
#endif
}

Maybe if you only try to draw the mask grille, not the other efects. (only a draw a mask in front the video)

Any way I found the source code for the shader mask, but am to about codes.

https://github.com/libretro/common-shaders/blob/master/crt/crt-geom-flat.cg

Also found this variants of the shader
http://emulation-general.wikia.com/wiki/CRT_Geom

and the image should look like this


Last edited by jerrymh; 28th July 2013 at 22:45.
jerrymh is offline   Reply With Quote
Old 29th July 2013, 00:27   #367  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
The host renderer for the shaders your link points to is organized very differently than the ones used for the shaders over here.
The first shaders I posted actually only blur and apply the scan line effect. The results are not stellar. The second version also properly degrades to low resolution and low quantization. It won't come close to pixel art like in that picture, but it will do a reasonable job on most typical video sources.
The default quantization in the shader is rather high compared to that picture. If it's a 256-color mode, try quantizationbits at 8/3., posterizedegamma 0 and probably a different gamma for the scan lines effect for the renderer in 8-bit mode or 17/6. and posterizedegamma 1 in quality mode. (Quality mode wastes a few percent at the top of the usual [0, 1] interval for two of the three channels.)
Note that I edited my previous post to fix a few bugs in the code with dithering and negative inputs.
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline   Reply With Quote
Old 29th July 2013, 07:20   #368  |  Link
turbojet
Registered User
 
Join Date: May 2008
Posts: 1,840
XRyche: can you post a short clip?
__________________
PC: FX-8320 GTS250 HTPC: G1610 GTX650
PotPlayer/MPC-BE LAVFilters MadVR-Bicubic75AR/Lanczos4AR/Lanczos4AR LumaSharpen -Strength0.9-Pattern3-Clamp0.1-OffsetBias2.0
turbojet is offline   Reply With Quote
Old 29th July 2013, 08:36   #369  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
Here are some extra shaders for larger pixels. I also edited the previous post because the forum has a maximum text length limit.
Code:
// (C) 2013 Jan-Willem Krans (janwillem32 <at> hotmail.com)
// This file is part of Video pixel shader pack.
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

// horizontal 8-pixel averaging
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 8

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float pos = (trunc(tex.x*c0*.125)+.0625)*c1*8.;// calculate the left positon of the current set of pixels
	return (tex2D(s0, float2(pos, tex.y))+tex2D(s0, float2(pos+c1, tex.y))+tex2D(s0, float2(pos+2*c1, tex.y))+tex2D(s0, float2(pos+3*c1, tex.y))+tex2D(s0, float2(pos+4*c1, tex.y))+tex2D(s0, float2(pos+5*c1, tex.y))+tex2D(s0, float2(pos+6*c1, tex.y))+tex2D(s0, float2(pos+7*c1, tex.y)))*.125;// blur and output
}



// vertical 8-pixel averaging, dithering, posterizing and old CRT scan lines
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 8

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.015625, .015625, .125);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.0625)*c1.y*8.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y))+tex2D(s0, float2(tex.x, pos+5*c1.y))+tex2D(s0, float2(tex.x, pos+6*c1.y))+tex2D(s0, float2(tex.x, pos+7*c1.y)))*.125;// blur input
#if posterizedegamma
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*br;// modulate brightness and output
#else
	s1 = round(s1*quantize+dithers);// dither and posterize
	return s1*(br*quantizer);// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// vertical 8-pixel averaging, dithering, posterizing and old CRT scan lines for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 8

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.015625, .015625, .125);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.0625)*c1.y*8.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y))+tex2D(s0, float2(tex.x, pos+5*c1.y))+tex2D(s0, float2(tex.x, pos+6*c1.y))+tex2D(s0, float2(tex.x, pos+7*c1.y)))*.125;// blur input
#if posterizedegamma
	s1 = s1*65535/32767.-16384/32767.;
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*(br*32767/65535.)+16384/65535.;// modulate brightness and output
#else
	s1 = round((s1*65535/32767.-16384/32767.)*quantize+dithers);// dither and posterize
	return s1*(br*quantizer*32767/65535.)+16384/65535.;// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// horizontal 10-pixel averaging
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 10

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float pos = (trunc(tex.x*c0*.1)+.05)*c1*10.;// calculate the left positon of the current set of pixels
	return (tex2D(s0, float2(pos, tex.y))+tex2D(s0, float2(pos+c1, tex.y))+tex2D(s0, float2(pos+2*c1, tex.y))+tex2D(s0, float2(pos+3*c1, tex.y))+tex2D(s0, float2(pos+4*c1, tex.y))+tex2D(s0, float2(pos+5*c1, tex.y))+tex2D(s0, float2(pos+6*c1, tex.y))+tex2D(s0, float2(pos+7*c1, tex.y))+tex2D(s0, float2(pos+8*c1, tex.y))+tex2D(s0, float2(pos+9*c1, tex.y)))*.1;// blur and output
}



// vertical 10-pixel averaging, dithering, posterizing and old CRT scan lines
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 10

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.0125, .0125, .1);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.05)*c1.y*10.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y))+tex2D(s0, float2(tex.x, pos+5*c1.y))+tex2D(s0, float2(tex.x, pos+6*c1.y))+tex2D(s0, float2(tex.x, pos+7*c1.y))+tex2D(s0, float2(tex.x, pos+8*c1.y))+tex2D(s0, float2(tex.x, pos+9*c1.y)))*.1;// blur input
#if posterizedegamma
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*br;// modulate brightness and output
#else
	s1 = round(s1*quantize+dithers);// dither and posterize
	return s1*(br*quantizer);// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// vertical 10-pixel averaging, dithering, posterizing and old CRT scan lines for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 10

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.0125, .0125, .1);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.05)*c1.y*10.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y))+tex2D(s0, float2(tex.x, pos+5*c1.y))+tex2D(s0, float2(tex.x, pos+6*c1.y))+tex2D(s0, float2(tex.x, pos+7*c1.y))+tex2D(s0, float2(tex.x, pos+8*c1.y))+tex2D(s0, float2(tex.x, pos+9*c1.y)))*.1;// blur input
#if posterizedegamma
	s1 = s1*65535/32767.-16384/32767.;
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*(br*32767/65535.)+16384/65535.;// modulate brightness and output
#else
	s1 = round((s1*65535/32767.-16384/32767.)*quantize+dithers);// dither and posterize
	return s1*(br*quantizer*32767/65535.)+16384/65535.;// shrink interval back to normal after posterization, modulate brightness and output
#endif
}
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline   Reply With Quote
Old 29th July 2013, 09:34   #370  |  Link
fagoatse
Registered User
 
Join Date: Feb 2012
Posts: 48
The shaders jerrymh posted are meant to be used with emulators(RetroArch/Libretro in this case) and they are tailored for a specific resolution as far as I know. RetroArch supports up to 8 passes and you can build https://github.com/libretro/libretro-ffmpeg if you wish to test them in video playback scenario.
fagoatse is offline   Reply With Quote
Old 4th August 2013, 07:11   #371  |  Link
jerrymh
Registered User
 
Join Date: Jul 2013
Posts: 10
Quote:
Originally Posted by JanWillem32 View Post
Here are some extra shaders for larger pixels. I also edited the previous post because the forum has a maximum text length limit.
Code:
// (C) 2013 Jan-Willem Krans (janwillem32 <at> hotmail.com)
// This file is part of Video pixel shader pack.
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

// horizontal 8-pixel averaging
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 8

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float pos = (trunc(tex.x*c0*.125)+.0625)*c1*8.;// calculate the left positon of the current set of pixels
	return (tex2D(s0, float2(pos, tex.y))+tex2D(s0, float2(pos+c1, tex.y))+tex2D(s0, float2(pos+2*c1, tex.y))+tex2D(s0, float2(pos+3*c1, tex.y))+tex2D(s0, float2(pos+4*c1, tex.y))+tex2D(s0, float2(pos+5*c1, tex.y))+tex2D(s0, float2(pos+6*c1, tex.y))+tex2D(s0, float2(pos+7*c1, tex.y)))*.125;// blur and output
}



// vertical 8-pixel averaging, dithering, posterizing and old CRT scan lines
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 8

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.015625, .015625, .125);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.0625)*c1.y*8.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y))+tex2D(s0, float2(tex.x, pos+5*c1.y))+tex2D(s0, float2(tex.x, pos+6*c1.y))+tex2D(s0, float2(tex.x, pos+7*c1.y)))*.125;// blur input
#if posterizedegamma
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*br;// modulate brightness and output
#else
	s1 = round(s1*quantize+dithers);// dither and posterize
	return s1*(br*quantizer);// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// vertical 8-pixel averaging, dithering, posterizing and old CRT scan lines for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 8

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.015625, .015625, .125);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.0625)*c1.y*8.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y))+tex2D(s0, float2(tex.x, pos+5*c1.y))+tex2D(s0, float2(tex.x, pos+6*c1.y))+tex2D(s0, float2(tex.x, pos+7*c1.y)))*.125;// blur input
#if posterizedegamma
	s1 = s1*65535/32767.-16384/32767.;
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*(br*32767/65535.)+16384/65535.;// modulate brightness and output
#else
	s1 = round((s1*65535/32767.-16384/32767.)*quantize+dithers);// dither and posterize
	return s1*(br*quantizer*32767/65535.)+16384/65535.;// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// horizontal 10-pixel averaging
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 10

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float pos = (trunc(tex.x*c0*.1)+.05)*c1*10.;// calculate the left positon of the current set of pixels
	return (tex2D(s0, float2(pos, tex.y))+tex2D(s0, float2(pos+c1, tex.y))+tex2D(s0, float2(pos+2*c1, tex.y))+tex2D(s0, float2(pos+3*c1, tex.y))+tex2D(s0, float2(pos+4*c1, tex.y))+tex2D(s0, float2(pos+5*c1, tex.y))+tex2D(s0, float2(pos+6*c1, tex.y))+tex2D(s0, float2(pos+7*c1, tex.y))+tex2D(s0, float2(pos+8*c1, tex.y))+tex2D(s0, float2(pos+9*c1, tex.y)))*.1;// blur and output
}



// vertical 10-pixel averaging, dithering, posterizing and old CRT scan lines
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 10

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.0125, .0125, .1);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.05)*c1.y*10.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y))+tex2D(s0, float2(tex.x, pos+5*c1.y))+tex2D(s0, float2(tex.x, pos+6*c1.y))+tex2D(s0, float2(tex.x, pos+7*c1.y))+tex2D(s0, float2(tex.x, pos+8*c1.y))+tex2D(s0, float2(tex.x, pos+9*c1.y)))*.1;// blur input
#if posterizedegamma
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*br;// modulate brightness and output
#else
	s1 = round(s1*quantize+dithers);// dither and posterize
	return s1*(br*quantizer);// shrink interval back to normal after posterization, modulate brightness and output
#endif
}



// vertical 10-pixel averaging, dithering, posterizing and old CRT scan lines for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a vertical resolution that is evenly divisible by 10

#define gamma 1// higher is brighter, fractions, either decimal or not are allowed
#define scanlinebasedarken .5// the default of .5 will darken outer pixels a bit on each set of vertical pixels to appear like old CRT scan lines, higher values will narrow the scan line beam
#define posterizedegamma 1// 0 or 1, apply dirty de-gamma for posterization, useful to preserve realistic gradients in low gamma modes
#define quantizationbits 4// posterization level, note that 'quantize' can actually take any amount, not just those based on powers of two

sampler s0 : register(s0);
float2 c0 : register(c0);
float2 c1 : register(c1);
static const float quantize = pow(2, quantizationbits)-1;
static const float quantizer = 1./quantize;
static const float qm = .0078125*quantizer;
static const float smalldithermap[8][8] = {
	{-63*qm, qm, -47*qm, 17*qm, -59*qm, 5*qm, -43*qm, 21*qm},
	{33*qm, -31*qm, 49*qm, -15*qm, 37*qm, -27*qm, 53*qm, -11*qm},
	{-39*qm, 25*qm, -55*qm, 9*qm, -35*qm, 29*qm, -51*qm, 13*qm},
	{57*qm, -7*qm, 41*qm, -23*qm, 61*qm, -3*qm, 45*qm, -19*qm},
	{-57*qm, 7*qm, -41*qm, 23*qm, -61*qm, 3*qm, -45*qm, 19*qm},
	{39*qm, -25*qm, 55*qm, -9*qm, 35*qm, -29*qm, 51*qm, -13*qm},
	{-33*qm, 31*qm, -49*qm, 15*qm, -37*qm, 27*qm, -53*qm, 11*qm},
	{63*qm, -qm, 47*qm, -17*qm, 59*qm, -5*qm, 43*qm, -21*qm}};

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 basepos = tex.xyy*c0.xyy*float3(.0125, .0125, .1);
	float3 basefrac = frac(basepos);
	float2 lookups = basefrac.xy*8.;
	float dithers = smalldithermap[lookups.x][lookups.y];

	float br = 1.-pow(abs(basefrac.z*2.*scanlinebasedarken-scanlinebasedarken), gamma);// generate scan lines

	float pos = (basepos.z-basefrac.z+.05)*c1.y*10.;// calculate the top positon of the current set of pixels
	float4 s1 = (tex2D(s0, float2(tex.x, pos))+tex2D(s0, float2(tex.x, pos+c1.y))+tex2D(s0, float2(tex.x, pos+2*c1.y))+tex2D(s0, float2(tex.x, pos+3*c1.y))+tex2D(s0, float2(tex.x, pos+4*c1.y))+tex2D(s0, float2(tex.x, pos+5*c1.y))+tex2D(s0, float2(tex.x, pos+6*c1.y))+tex2D(s0, float2(tex.x, pos+7*c1.y))+tex2D(s0, float2(tex.x, pos+8*c1.y))+tex2D(s0, float2(tex.x, pos+9*c1.y)))*.1;// blur input
#if posterizedegamma
	s1 = s1*65535/32767.-16384/32767.;
	float4 signbits = sign(s1);
	s1 = signbits*pow(round(sqrt(s1)*quantize+dithers)*quantizer, 2);// dither and posterize
	return s1*(br*32767/65535.)+16384/65535.;// modulate brightness and output
#else
	s1 = round((s1*65535/32767.-16384/32767.)*quantize+dithers);// dither and posterize
	return s1*(br*quantizer*32767/65535.)+16384/65535.;// shrink interval back to normal after posterization, modulate brightness and output
#endif
}
Thanks, long time without internet.
jerrymh is offline   Reply With Quote
Old 4th August 2013, 17:49   #372  |  Link
jerrymh
Registered User
 
Join Date: Jul 2013
Posts: 10
I found this on libreto ffmpeg video shader, really looks like and old crt monitor , but dont know if there any build for windows


Last edited by jerrymh; 4th August 2013 at 17:58.
jerrymh is offline   Reply With Quote
Old 11th August 2013, 22:30   #373  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
XRyche, I made a three-stage chain that might work. It's currently rather restricted and I'll probably need to change a few more parameters, but it's a good start. I only made one chain, meant for the combination of HD video with the renderer settings on 16-bit integer surfaces with the disable initial pass shaders option enabled. I can add more shaders later, if these work well.
Code:
// (C) 2013 Jan-Willem Krans (janwillem32 <at> hotmail.com)
// This file is part of Video pixel shader pack.
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

// R'G'B' to Y'CbCr for HD video input for XYZ rendering on 16-bit integer surfaces

sampler s0;

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 s1 = tex2Dlod(s0, float4(tex, 0, 0)).rgb;// original pixel
	return ((s1.rrr*float3(.2126, -.1063/.9278, .5)+s1.ggg*float3(.7152, -.3576/.9278, -.3576/.7874)+s1.bbb*float3(.0722, .5, -.0361/.7874))*32767/65535.+float3(16384/65535., 32767/65535., 32767/65535.)).rgbb;// HD RGB to Y'CbCr output
}



// horizontal pass sharpen complex, deband and denoise for HD video input for XYZ rendering on 16-bit integer surfaces

#define SharpenLimitLuma 2// valid interval [0, 10], luma-specific sharpening limit, 0 is disabled, lower numbers will allow more sharpening on contours
#define SharpenLimitChroma 2// valid interval [0, 10], chroma-specific sharpening limit, 0 is disabled, lower numbers will allow more sharpening on contours
#define LumaDetectionFactor 64// valid interval (65535/32767., 250], luma-specific detection factor, if set to the lowest amount no contours can be detected, higher numbers will shift the detection on color difference intervals of debanding to noise detection limit to mimimum sharpening to maximum sharpening toward more sharpening
#define ChromaDetectionFactor 64// valid interval (65535/32767., 250], chroma-specific detection factor, if set to the lowest amount no contours can be detected, higher numbers will shift the detection on color difference intervals of debanding to noise detection limit to mimimum sharpening to maximum sharpening toward more sharpening
#define NoiseThreshold .0078125// valid interval [0, 32767/65535.), banding treshold, higher numbers mean stronger deband and denoise

sampler s0 : register(s0);
float2 c1 : register(c1);
#define sp(a) tex2Dlod(s0, float4(tex+c1*float2(a, 0), 0, 0)).rgb
static const float3 slimits = float3(-SharpenLimitLuma, -SharpenLimitChroma, -SharpenLimitChroma);
static const float3 dfactors = float3(LumaDetectionFactor, ChromaDetectionFactor, ChromaDetectionFactor);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 n, p, s1 = sp(0);// original pixel
	{
		float3 s2 = sp(-1);
		float3 af = 1.;// accumulated amount of colors from the samples
		float3 ac = s1;// accumulate color
		float3 cd = abs(s1-s2);// color difference
		float3 rcd = max(slimits, 1.-dfactors*cd);// factor for both base and multiplicand is 1.0, the output will be in the interval (-inf, 1]
		// invert interval on sharpening
		if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
		if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
		if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
		af += abs(rcd);
		ac += s2*rcd;
		[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {// continue if all channels are below the noise threshold
			float3 s3 = sp(-2);
			cd = abs(s1-s3);
			rcd = max(slimits, 1.-dfactors*cd);
			if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
			if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
			if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
			af += abs(rcd);
			ac += s3*rcd;
			[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
				float3 s4 = sp(-3);
				cd = abs(s1-s4);
				rcd = max(slimits, 1.-dfactors*cd);
				if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
				if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
				if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
				af += abs(rcd);
				ac += s4*rcd;
				[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
					float3 s5 = sp(-4);
					cd = abs(s1-s5);
					rcd = max(slimits, 1.-dfactors*cd);
					if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
					if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
					if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
					af += abs(rcd);
					ac += s5*rcd;
					[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
						float3 s6 = sp(-5);
						cd = abs(s1-s6);
						rcd = max(slimits, 1.-dfactors*cd);
						if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
						if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
						if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
						af += abs(rcd);
						ac += s6*rcd;
					}
				}
			}
		}
		n = ac/af;
	}
	{
		float3 s2 = sp(1);
		float3 af = 1.;// accumulated amount of colors from the samples
		float3 ac = s1;// accumulate color
		float3 cd = abs(s1-s2);// color difference
		float3 rcd = max(slimits, 1.-dfactors*cd);// factor for both base and multiplicand is 1.0, the output will be in the interval (-inf, 1]
		if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
		if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
		if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
		af += abs(rcd);
		ac += s2*rcd;
		[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {// continue if all channels are below the noise threshold
			float3 s3 = sp(2);
			cd = abs(s1-s3);
			rcd = max(slimits, 1.-dfactors*cd);
			if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
			if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
			if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
			af += abs(rcd);
			ac += s3*rcd;
			[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
				float3 s4 = sp(3);
				cd = abs(s1-s4);
				rcd = max(slimits, 1.-dfactors*cd);
				if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
				if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
				if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
				af += abs(rcd);
				ac += s4*rcd;
				[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
					float3 s5 = sp(4);
					cd = abs(s1-s5);
					rcd = max(slimits, 1.-dfactors*cd);
					if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
					if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
					if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
					af += abs(rcd);
					ac += s5*rcd;
					[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
						float3 s6 = sp(5);
						cd = abs(s1-s6);
						rcd = max(slimits, 1.-dfactors*cd);
						if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
						if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
						if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
						af += abs(rcd);
						ac += s6*rcd;
					}
				}
			}
		}
		p = ac/af;
	}
	return ((n+p)*.5).rgbb;
}



// vertical pass sharpen complex, deband, denoise and color controls for HD video input for XYZ rendering on 16-bit integer surfaces

#define SharpenLimitLuma 2// valid interval [0, 10], luma-specific sharpening limit, 0 is disabled, lower numbers will allow more sharpening on contours
#define SharpenLimitChroma 2// valid interval [0, 10], chroma-specific sharpening limit, 0 is disabled, lower numbers will allow more sharpening on contours
#define LumaDetectionFactor 64// valid interval (65535/32767., 250], luma-specific detection factor, if set to the lowest amount no contours can be detected, higher numbers will shift the detection on color difference intervals of debanding to noise detection limit to mimimum sharpening to maximum sharpening toward more sharpening
#define ChromaDetectionFactor 64// valid interval (65535/32767., 250], chroma-specific detection factor, if set to the lowest amount no contours can be detected, higher numbers will shift the detection on color difference intervals of debanding to noise detection limit to mimimum sharpening to maximum sharpening toward more sharpening
#define NoiseThreshold .0078125// valid interval [0, 32767/65535.), banding treshold, higher numbers mean stronger deband and denoise

// YCbCrColorControls, 0 is disabled, 1 is enabled
#define YCbCrColorControls 0
// Brightness, interval [-10, 10], default 0
#define Brightness 0
// Contrast, interval [0, 10], default 1
#define Contrast 1
// GrayscaleGamma and ColorfulnessGamma, interval (0, 10], default 1
#define GrayscaleGamma 1
#define ColorfulnessGamma 1
// Hue, interval [-180, 180], default 0
#define Hue 0
// Saturation, interval [0, 10], default 1
#define Saturation 1
// VideoRedGamma, VideoGreenGamma and VideoBlueGamma, interval (0, 10], default 2.4, the video gamma input factors used to convert between the video input RGB and linear RGB
#define VideoRedGamma 2.4
#define VideoGreenGamma 2.4
#define VideoBlueGamma 2.4

sampler s0 : register(s0);
float2 c1 : register(c1);
#define sp(a) tex2Dlod(s0, float4(tex+c1*float2(0, a), 0, 0)).rgb
static const float3 slimits = float3(-SharpenLimitLuma, -SharpenLimitChroma, -SharpenLimitChroma);
static const float3 dfactors = float3(LumaDetectionFactor, ChromaDetectionFactor, ChromaDetectionFactor);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float3 n, p, s1 = sp(0);// original pixel
	{
		float3 s2 = sp(-1);
		float3 af = 1.;// accumulated amount of colors from the samples
		float3 ac = s1;// accumulate color
		float3 cd = abs(s1-s2);// color difference
		float3 rcd = max(slimits, 1.-dfactors*cd);// factor for both base and multiplicand is 1.0, the output will be in the interval (-inf, 1]
		// invert interval on sharpening
		if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
		if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
		if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
		af += abs(rcd);
		ac += s2*rcd;
		[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {// continue if all channels are below the noise threshold
			float3 s3 = sp(-2);
			cd = abs(s1-s3);
			rcd = max(slimits, 1.-dfactors*cd);
			if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
			if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
			if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
			af += abs(rcd);
			ac += s3*rcd;
			[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
				float3 s4 = sp(-3);
				cd = abs(s1-s4);
				rcd = max(slimits, 1.-dfactors*cd);
				if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
				if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
				if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
				af += abs(rcd);
				ac += s4*rcd;
				[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
					float3 s5 = sp(-4);
					cd = abs(s1-s5);
					rcd = max(slimits, 1.-dfactors*cd);
					if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
					if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
					if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
					af += abs(rcd);
					ac += s5*rcd;
					[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
						float3 s6 = sp(-5);
						cd = abs(s1-s6);
						rcd = max(slimits, 1.-dfactors*cd);
						if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
						if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
						if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
						af += abs(rcd);
						ac += s6*rcd;
					}
				}
			}
		}
		n = ac/af;
	}
	{
		float3 s2 = sp(1);
		float3 af = 1.;// accumulated amount of colors from the samples
		float3 ac = s1;// accumulate color
		float3 cd = abs(s1-s2);// color difference
		float3 rcd = max(slimits, 1.-dfactors*cd);// factor for both base and multiplicand is 1.0, the output will be in the interval (-inf, 1]
		if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
		if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
		if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
		af += abs(rcd);
		ac += s2*rcd;
		[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {// continue if all channels are below the noise threshold
			float3 s3 = sp(2);
			cd = abs(s1-s3);
			rcd = max(slimits, 1.-dfactors*cd);
			if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
			if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
			if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
			af += abs(rcd);
			ac += s3*rcd;
			[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
				float3 s4 = sp(3);
				cd = abs(s1-s4);
				rcd = max(slimits, 1.-dfactors*cd);
				if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
				if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
				if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
				af += abs(rcd);
				ac += s4*rcd;
				[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
					float3 s5 = sp(4);
					cd = abs(s1-s5);
					rcd = max(slimits, 1.-dfactors*cd);
					if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
					if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
					if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
					af += abs(rcd);
					ac += s5*rcd;
					[branch] if(max(max(cd.x, cd.y), cd.z) < NoiseThreshold) {
						float3 s6 = sp(5);
						cd = abs(s1-s6);
						rcd = max(slimits, 1.-dfactors*cd);
						if(rcd.x < 0) rcd.x = SharpenLimitLuma-abs(rcd.x);
						if(rcd.y < 0) rcd.y = SharpenLimitChroma-abs(rcd.y);
						if(rcd.z < 0) rcd.z = SharpenLimitChroma-abs(rcd.z);
						af += abs(rcd);
						ac += s6*rcd;
					}
				}
			}
		}
		p = ac/af;
	}
	float3 t0 = (n+p)*.5;
	t0 = t0*65535/32767.-float3(16384/32767., 32767/65535.+.5, 32767/65535.+.5);
#if YCbCrColorControls == 1
	t0.yz = mul(t0.yz, float2x2(cos(radians(Hue)), sin(radians(Hue)), -sin(radians(Hue)), cos(radians(Hue))));// process hue
	t0.xyz *= float3(Contrast, 2*Saturation, 2*Saturation);// process contrast and saturation, extend the chroma interval from [-.5, .5] to [-1, 1] for gamma processing
	t0.x += Brightness;// process brightness
	// preserve the sign bits of Y'CbCr values
	float3 sby = sign(t0);
	t0 = sby*pow(abs(t0), float3(GrayscaleGamma, ColorfulnessGamma, ColorfulnessGamma));// gamma processing	
	t0 = t0.rrr+float3(0, -.5*.1674679/.894, .5*1.8556)*t0.ggg+float3(.5*1.5748, -.5*.4185031/.894, 0)*t0.bbb;// HD Y'CbCr to RGB, compensate for the chroma ranges
#else
	t0 = t0.rrr+float3(0, -.1674679/.894, 1.8556)*t0.ggg+float3(1.5748, -.4185031/.894, 0)*t0.bbb;// HD Y'CbCr to RGB
#endif
	// preserve the sign bits of RGB values
	float3 sbl = sign(t0);
	t0 = sbl*pow(abs(t0), float3(VideoRedGamma, VideoGreenGamma, VideoBlueGamma));// linear RGB gamma correction
	t0 = mul(t0, float3x3(0.3786675215, 0.1952504408, 0.0177500401, 0.3283428626, 0.6566857251, 0.1094476209, 0.1657219631, 0.0662887852, 0.8728023391))*32767/65535.+16384/65535.;
	return t0.rgbb;// XYZ output
}
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline   Reply With Quote
Old 11th August 2013, 22:33   #374  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
The "contour color expose banding" shader is useful for denoise and deband testing purposes.
Code:
// (C) 2013 Jan-Willem Krans (janwillem32 <at> hotmail.com)
// This file is part of Video pixel shader pack.
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

// contour color expose banding for XYZ rendering on 16-bit integer surfaces
// This shader can be run as a screen space pixel shader.
// This shader requires compiling with ps_2_0, but higher is better, see http://en.wikipedia.org/wiki/Pixel_shader to look up what PS version your video card supports.
// Use this shader to add a color contoured effect to an image.

sampler s0;
float2 c1 : register(c1);
#define sp(a, b, c) float4 a = tex2D(s0, tex+c1*float2(b, c));

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	sp(s2, -1, -1) sp(s3, 0, -1) sp(s4, 1, -1) sp(s5, -1, 0) sp(s6, 1, 0) sp(s7, -1, 1) sp(s8, 0, 1) sp(s9, 1, 1)// sample surrounding pixels
	return smoothstep(.0625, 0, abs(s2+s3+s4-s7-s8-s9)+abs(s2+s5+s7-s4-s6-s9)+abs(s2+s3+s5-s6-s8-s9)+abs(s3+s4+s6-s5-s7-s8))*32767/65535.+16384/65535.;// color contour output
}
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline   Reply With Quote
Old 12th August 2013, 08:23   #375  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
I just wrote some simple shaders for usage as a third pass, after the "vertical x-pixel averaging, dithering, posterizing and old CRT scan lines"-type shaders. These shaders separate RGB channels of the input video into multiple real pixels, imitating aperture grilles that use rectangular masks. (Imitating the other common shadow mask pattern would be a lot harder to program. I'm not sure it's worth the effort.) The warnings about divisibility in these shaders are not that important. The artifacts are barely visible if the input isn't evenly divisible.
Code:
// horizontal 4-pixel RGB separation
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 4

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float scaletexx = tex.x*c0*.25;
	float prepos = trunc(scaletexx);// calculate the left positon of the current set of pixels
	float posdif = scaletexx-prepos;
	float4 mask;// create RGB mask based on the pixel location
	if(posdif < .25) mask = float4(1, 0, 0, 0);
	else if(posdif < .5) mask = float4(0, 1/3., 2/3., 0);
	else if(posdif < .75) mask = float4(0, 2/3., 1/3., 0);
	else mask = float4(0, 0, 1, 0);
	return tex2D(s0, tex)*mask;// mask and output
}



// horizontal 5-pixel RGB separation
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 5

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float scaletexx = tex.x*c0*.2;
	float prepos = trunc(scaletexx);// calculate the left positon of the current set of pixels
	float posdif = scaletexx-prepos;
	float4 mask;// create RGB mask based on the pixel location
	if(posdif < .2) mask = float4(1, 0, 0, 0);
	else if(posdif < .4) mask = float4(0, 2/3., 1/3., 0);
	else if(posdif < .6) mask = float4(0, 1, 0, 0);
	else if(posdif < .8) mask = float4(0, 1/3., 2/3., 0);
	else mask = float4(0, 0, 1, 0);
	return tex2D(s0, tex)*mask;// mask and output
}



// horizontal 8-pixel RGB separation
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 8

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float scaletexx = tex.x*c0*.125;
	float prepos = trunc(scaletexx);// calculate the left positon of the current set of pixels
	float posdif = scaletexx-prepos;
	float4 mask;// create RGB mask based on the pixel location
	if(posdif < .25) mask = float4(1, 0, 0, 0);
	else if(posdif < 0.375) mask = float4(0, 2/3., 1/3., 0);
	else if(posdif < 0.625) mask = float4(0, 1, 0, 0);
	else if(posdif < .75) mask = float4(0, 1/3., 2/3., 0);
	else mask = float4(0, 0, 1, 0);
	return tex2D(s0, tex)*mask;// mask and output
}



// horizontal 10-pixel RGB separation
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 10

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float scaletexx = tex.x*c0*.1;
	float prepos = trunc(scaletexx);// calculate the left positon of the current set of pixels
	float posdif = scaletexx-prepos;
	float4 mask;// create RGB mask based on the pixel location
	if(posdif < .3) mask = float4(1, 0, 0, 0);
	else if(posdif < .4) mask = float4(0, 1/3., 2/3., 0);
	else if(posdif < .6) mask = float4(0, 1, 0, 0);
	else if(posdif < .7) mask = float4(0, 2/3., 1/3., 0);
	else mask = float4(0, 0, 1, 0);
	return tex2D(s0, tex)*mask;// mask and output
}



// horizontal 4-pixel RGB separation for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 4

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float scaletexx = tex.x*c0*.25;
	float prepos = trunc(scaletexx);// calculate the left positon of the current set of pixels
	float posdif = scaletexx-prepos;
	float4 mask;// create RGB mask based on the pixel location
	if(posdif < .25) mask = float4(1, 0, 0, 0);
	else if(posdif < .5) mask = float4(0, 1/3., 2/3., 0);
	else if(posdif < .75) mask = float4(0, 2/3., 1/3., 0);
	else mask = float4(0, 0, 1, 0);
	return (tex2D(s0, tex)-16384/65535.)*mask+16384/65535.;// mask and output
}



// horizontal 5-pixel RGB separation for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 5

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float scaletexx = tex.x*c0*.2;
	float prepos = trunc(scaletexx);// calculate the left positon of the current set of pixels
	float posdif = scaletexx-prepos;
	float4 mask;// create RGB mask based on the pixel location
	if(posdif < .2) mask = float4(1, 0, 0, 0);
	else if(posdif < .4) mask = float4(0, 2/3., 1/3., 0);
	else if(posdif < .6) mask = float4(0, 1, 0, 0);
	else if(posdif < .8) mask = float4(0, 1/3., 2/3., 0);
	else mask = float4(0, 0, 1, 0);
	return (tex2D(s0, tex)-16384/65535.)*mask+16384/65535.;// mask and output
}



// horizontal 8-pixel RGB separation for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 8

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float scaletexx = tex.x*c0*.125;
	float prepos = trunc(scaletexx);// calculate the left positon of the current set of pixels
	float posdif = scaletexx-prepos;
	float4 mask;// create RGB mask based on the pixel location
	if(posdif < .25) mask = float4(1, 0, 0, 0);
	else if(posdif < 0.375) mask = float4(0, 2/3., 1/3., 0);
	else if(posdif < 0.625) mask = float4(0, 1, 0, 0);
	else if(posdif < .75) mask = float4(0, 1/3., 2/3., 0);
	else mask = float4(0, 0, 1, 0);
	return (tex2D(s0, tex)-16384/65535.)*mask+16384/65535.;// mask and output
}



// horizontal 10-pixel RGB separation for XYZ rendering on 16-bit integer surfaces
// this shader only works properly on inputs that have a horizontal resolution that is evenly divisible by 10

sampler s0 : register(s0);
float c0 : register(c0);
float c1 : register(c1);

float4 main(float2 tex : TEXCOORD0) : COLOR
{
	float scaletexx = tex.x*c0*.1;
	float prepos = trunc(scaletexx);// calculate the left positon of the current set of pixels
	float posdif = scaletexx-prepos;
	float4 mask;// create RGB mask based on the pixel location
	if(posdif < .3) mask = float4(1, 0, 0, 0);
	else if(posdif < .4) mask = float4(0, 1/3., 2/3., 0);
	else if(posdif < .6) mask = float4(0, 1, 0, 0);
	else if(posdif < .7) mask = float4(0, 2/3., 1/3., 0);
	else mask = float4(0, 0, 1, 0);
	return (tex2D(s0, tex)-16384/65535.)*mask+16384/65535.;// mask and output
}
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv

Last edited by JanWillem32; 12th August 2013 at 17:27.
JanWillem32 is offline   Reply With Quote
Old 11th November 2013, 23:54   #376  |  Link
leeperry
Kid for Today
 
Join Date: Aug 2004
Posts: 3,494
Hi Jan,

So following your advice in another thread that was asking for a "film grain" PS script, I've played around with your "semi-random grayscale noise.txt" which looks quite good but do you think it would be possible to make a PS script version of GrainFactory3()?

It allows you to choose the size, strength and sharpness of grain depending on dark/mid-tone/bright areas(whose limits can also be defined) and it can really be finetuned either for deblocking purposes, grain-based EE or artistic effects meant to mimick reel grain.

The problem with Didée's script is that it quickly becomes a CPU hog, Avisynth works in 8bit only and the idea would be to process it in 32fp after scaling to Jinc3AR in mVR....so if there is any way you could work your magic to do the same within a PS script, this would be too good to be true

you very much in advance for even considering it,
leeperry is offline   Reply With Quote
Old 12th November 2013, 05:37   #377  |  Link
JanWillem32
Registered User
 
JanWillem32's Avatar
 
Join Date: Oct 2010
Location: The Netherlands
Posts: 1,083
What I could find out about GrainFactory3 was: "noise generator that tries to simulate the behaviour of silver grain on film".
I already wrote some basic noise effect shaders, but maybe I could get closer to the look of silver grain on film.
When I start coding to create an effect, I start with looking at examples on images. I don't just duplicate/imitate other filters. When I've gathered enough research materials, I just start writing out possible parameters for methods in an effect. After that, I try a few methods. These are just calculations that spring to mind, and I usually copy a lot of previously written methods, too. After a bit of tinkering, I usually get the desirable effect from a shader. When transforming the prototype shader to a final type, I optimize first, and add comments. After that, I extract the set of constants, give them names and offer them as user-configurable parameters.
The reason I'm telling this is simple; I can practically guarantee that once I've finished something that resembles silver grain on film, the effect will not have a grand total 19 user input variables like GrainFactory3.
On the other hand, I don't see any options in GrainFactory3 for using color. I would probably add an option or options for this type of filter related to color, for example; to use the properties for sepia toning instead of silver. (This possibly requires separate filters, though.)

To start off simple, the pictures I could find of real film used in cinemas varied strongly over the decades. The most evident changes were the transition from grayscale or toned video to color. The form and amount of grain on film, and the cinema equipment varied, too. Some effects are available: projector film drive scratches, projector film dust, projector film lamp vignette, projector film sepia toning for SD&HD video input, grayscale, projector film shaking, semi-random colored surface noise and semi-random grayscale noise.
What era are you targeting for this kind of vintage look? Which effects are currently missing to complete the illusion of such a look? Please specify with some true vintage cinematic examples and name some very specific factors.
__________________
development folder, containing MPC-HC experimental tester builds, pixel shaders and more: http://www.mediafire.com/?xwsoo403c53hv
JanWillem32 is offline   Reply With Quote
Old 12th November 2013, 18:17   #378  |  Link
leeperry
Kid for Today
 
Join Date: Aug 2004
Posts: 3,494
Hi Jan, thanks for the swift reply.

Well, it would appear that to simulate silver film grain you'd need the ability to set different chunk sizes for dark/mid/bright pixels as grain would appear to look thicker in dark areas for instance. I think 21 grams is a good example of what excessive reel grain can do, of course I want to keep it less intrusive.

My real-world use of GrainF3 was to set very low values in order to deblock(which tends to increase the subjective pop-effect IME), add some subtle grain-based EE, give a DLP/silver reel look to sanitized "flat looking" digital movies the same way DLP videoprojectors look pretty grain in dark areas due to their very fast rotating mirrors for instance.

I don't think I would be interested in chroma grain, but I would need is the abilities to:
-choose the size and strength of grain depending on dark/mid/bright areas
-choose the limits for dark/mid/bright, like in GrainF3
-choose the grain pattern or make it random, much like what foxyshadis explained here. Once you find your favorite grain patterns for dark/mid/bright areas, you can use them permanently and the "movie grain" won't be quite random anymore as it'll be finetuned to your liking.

The intent of GrainF3 is not to mimick a 1930's sepia looking semi-busted projector but simply to add (possibly very subtle) silver looking grain. Once finetuned, it can really look great as adding grain does wonders for deblocking purposes IME. Of course it can also be used with excessive settings for artistic means.

The more I talk about it, the more I wanna play around with GrainF3 all over again but I would really rather have it done via a PS script for all the aforementioned reasons

PS: ouh, this looks impressive too: Cinema Film Grain Plugin for FCPX

Last edited by leeperry; 12th November 2013 at 18:30.
leeperry is offline   Reply With Quote
Old 9th December 2013, 18:17   #379  |  Link
leeperry
Kid for Today
 
Join Date: Aug 2004
Posts: 3,494
Hi again Jan, so I've tried my old GrainF3() calls that looked so great on CRT/DLP but they look darn noisy on LCD....would have to rework them again from scratch with much more subtle settings I guess.

Anyway, I've got a question for you

Here's another Avisynth script that has always impressed me: SmoothLevels()

It's gone DLL but it used to be an .AVS script and here are a few older versions of it: SmoothLevels.rar (11 KB)

Using it to convert TV to PC, I've always found its resulting picture to look "deeper" and simply more 3D-looking than whatever ffdshow or madVR could offer.

I mentioned it to madshi a while ago who told me that its error diffusion was technically more advanced than the dithering currently done in mVR and that PS scripts couldn't process Floyd-Steinberg.

I've made screenshots comparisons on a gray ramp and a REC709 test pattern available at SmoothL2.rar (15.3 MB)

I'm colorblind so judging on banding and colorimetry is a very tedious task for me, but I've been told that banding didn't look any better than in mVR and that it seemed to make colorimetry shifts?

Comparing screenshots back and forth it would appear to me that SmoothL is doing some sort of colorimetry-based EE? The borders of the color squares in that REC709 pattern look quite different with SmoothL, don't they?

My point is that for instance in this very short sample Prisoners.mkv (22.9 MB) when comparing SmoothLevels(preset="tv2pc",HQ=true) to anything else, that animal in the woods seems to appear much deeper in the picture and the passing cars on the road feel less "flat" and far more natural to me

"HQ" would stand for "HQ interpolation" BTW.

All this said, do you agree that the picture looks deeper with that sample when using SmoothL? Is that because its error diffusion is more advanced than what mVR can do, or because of some -as I'm suspecting- colorimetry-based EE? If so, could you possibly provide the same kind of trick with a PS script?

My problem is that SmoothL outputs 8bit from ffdshow to mVR, it's a real CPU hog(especially in HQ mode on 1.78 1080p) and I'm totally hooked to its 3D look

Hope you can look into it, in advance!

Last edited by leeperry; 9th December 2013 at 18:51.
leeperry is offline   Reply With Quote
Old 13th December 2013, 18:05   #380  |  Link
foxyshadis
Angel of Night
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Tangled in the silks
Posts: 9,568
Hi Jan! Excellent work with the new filters. Can I request that the main archive be updated to include the last couple of years' work, as well? I know some aren't 100% finished, but it'd be nice to have them all handy for quick downloading onto the various systems I have set up for media.
foxyshadis is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 11:29.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.