shader SuperRésolution 720p :
Shader dédié aux diffuseurs 720p (version 1080p en préparation) qui a pour objectif de faire croire que la réso augmente de 10 à 30% en gros.
A mettre uniquement en bout de chaine de traitement.
Principe :
le shader n'agit pas sur les maxima ou minima des edges vu qu'en principe ceux-ci ont déjà été boostés avant par des algos de sharpen. Par contre il modifie de manière adaptative le gamma à proximité de ces maxima ou minima. Plus la transition est forte et + le gamma est boosté. Loin des transitions, le shader accentue légèrement les textures par masque flou. La combi des deux donne l'effet SuperRésolution. L'effet est subtil mais se voit bien sur les plans larges à forte profondeur de champ.
Deux versions sont dispo, dont une pour les ANIME qui sature un peu + les couleurs.
Deux paramètres sont réglables : ForceGamma et diff (voir code). Les réglages par défauts sont ceux qui me plaisent le + sur mon écran LCD de test.
Version Film
- Code: Tout sélectionner
// SuperResolution720p - Beta1
// Emmanuel - 27/03/2010
// Filtre de super résolution adapté aux diffuseurs 720p
#define ForceGamma 0.5 // entre 0 et 1 (0: modif gamma faible, 1: forte)
#define diff 0.58 // influe sur le rendu "3D-Like"
// 0.2 => 3D-Like + présent
// 0.7 => 3D-Like - présent
// typ: 0.58 sur bon BD (après un unsharp mask à 19)
sampler s0 : register(s0);
float4 p1 : register(c1);
#define dx (p1[0])
#define dy (p1[1])
float4 main( float2 tex : TEXCOORD0 ) : COLOR
{
#define seuil 0.85 // ne devrait pas être modifié !
// pixels original, flouté, corrigé, final
float4 ori = tex2D(s0, tex);
float4 flou;
float4 cori;
float4 final;
// récupération de la matrice de 9 points
// [ 1, 2 , 3 ]
// [ 4,ori, 5 ]
// [ 6, 7 , 8 ]
float4 c1 = tex2D(s0, tex + float2(-dx,-dy));
float4 c2 = tex2D(s0, tex + float2(0,-dy));
float4 c3 = tex2D(s0, tex + float2(dx,-dy));
float4 c4 = tex2D(s0, tex + float2(-dx,0));
float4 c5 = tex2D(s0, tex + float2(dx,0));
float4 c6 = tex2D(s0, tex + float2(-dx,dy));
float4 c7 = tex2D(s0, tex + float2(0,dy));
float4 c8 = tex2D(s0, tex + float2(dx,dy));
// détection des contours
// par filtre de sobel
float delta1,delta2,value;
// Gradient horizontal
// [ -1, 0 ,1 ]
// [ -2, 0, 2 ]
// [ -1, 0 ,1 ]
delta1 = (c3 + 2*c5 + c8)-(c1 + 2*c4 + c6);
// Gradient vertical
// [ -1,- 2,-1 ]
// [ 0, 0, 0 ]
// [ 1, 2, 1 ]
delta2 = (c6 + 2*c7 + c8)-(c1 + 2*c2 + c3);
// calcul
value = sqrt(mul(delta1,delta1) + mul(delta2,delta2)) ;
// Gamma adaptatif à proximité d'une transition
cori = ori;
if ((value >= seuil-diff*1.15)&&(value <= seuil)) cori = pow(ori,1./(1-value/(10-ForceGamma)));
// Masque flou pour renforcer les textures
// calcul image floue (filtre gaussien)
// pour normaliser les valeurs, il faut diviser par la somme des coef
// 1/(1+2+1+2+4+2+1+2+1) = 1/ 16 = .0625
flou = (c1+c3+c6+c8 + 2*(c2+c4+c5+c7)+ 4*cori)*0.0625;
// Accentuation des textures si on est loin d'un bord
if (value > seuil-diff) final = cori; else final = 2*cori - flou;
return final;
}
Version ANIME
- Code: Tout sélectionner
// SuperResolution720p - Beta1
// Emmanuel - 27/03/2010
// Filtre de super résolution adapté aux diffuseurs 720p
#define ForceGamma 0.5 // entre 0 et 1 (0: modif gamma faible, 1: forte)
#define diff 0.58 // influe sur le rendu "3D-Like"
// 0.2 => 3D-Like + présent
// 0.7 => 3D-Like - présent
// typ: 0.58 sur bon BD (après un unsharp mask à 19)
sampler s0 : register(s0);
float4 p1 : register(c1);
#define dx (p1[0])
#define dy (p1[1])
float4 main( float2 tex : TEXCOORD0 ) : COLOR
{
#define seuil 0.85 // ne devrait pas être modifié !
// pixels original, flouté, corrigé, final
float4 ori = tex2D(s0, tex);
float4 flou;
float4 cori;
float4 final;
// récupération de la matrice de 9 points
// [ 1, 2 , 3 ]
// [ 4,ori, 5 ]
// [ 6, 7 , 8 ]
float4 c1 = tex2D(s0, tex + float2(-dx,-dy));
float4 c2 = tex2D(s0, tex + float2(0,-dy));
float4 c3 = tex2D(s0, tex + float2(dx,-dy));
float4 c4 = tex2D(s0, tex + float2(-dx,0));
float4 c5 = tex2D(s0, tex + float2(dx,0));
float4 c6 = tex2D(s0, tex + float2(-dx,dy));
float4 c7 = tex2D(s0, tex + float2(0,dy));
float4 c8 = tex2D(s0, tex + float2(dx,dy));
// détection des contours
// par filtre de sobel
float delta1,delta2,value;
// Gradient horizontal
// [ -1, 0 ,1 ]
// [ -2, 0, 2 ]
// [ -1, 0 ,1 ]
delta1 = (c3 + 2*c5 + c8)-(c1 + 2*c4 + c6);
// Gradient vertical
// [ -1,- 2,-1 ]
// [ 0, 0, 0 ]
// [ 1, 2, 1 ]
delta2 = (c6 + 2*c7 + c8)-(c1 + 2*c2 + c3);
// calcul
value = sqrt(mul(delta1,delta1) + mul(delta2,delta2)) ;
// Gamma adaptatif hormis sur le max d'une transition
if (value >seuil) cori = ori;
else cori = pow(ori,1./(1-value/(10-ForceGamma)));
// Masque flou pour renforcer les textures
// calcul image floue (filtre gaussien)
// pour normaliser les valeurs, il faut diviser par la somme des coef
// 1/(1+2+1+2+4+2+1+2+1) = 1/ 16 = .0625
flou = (c1+c3+c6+c8 + 2*(c2+c4+c5+c7)+ 4*cori)*0.0625;
// Accentuation des textures si on est loin d'un bord
if (value > seuil-diff) final = cori; else final = 2*cori - flou;
return final;
}
Exemple sur BR avec juste un unsharp mask à 19 ds ffdshow (sortie YV12) et un downsize bilinear 1080p->720p ds MPCHC en EVR Custom.
Iron man : Bon BR
Walk the line : BR correct
Into the Wild : BR pourri
L'age de Glace 3 : BR moyen (pour un animé)
![Image](http://img707.imageshack.us/img707/5376/ffdshowc.png)