Diff
checker
Texte
Texte
Images
Documents
Excel
Dossiers
Legal
Enterprise
Application de bureau
Prix
Se connecter
Télécharger Diffchecker Desktop
Comparer le texte
Trouver la différence entre deux fichiers texte
Outils
Historique
Éditeur live
Masquer les espaces
Cacher identiques
Sans retour à la ligne
Vue
Divisé
Unifié
Niveau de précision
Intelligent
Mot
Caractère
Styles de texte
Modifier l’apparence
Coloration syntaxique
Choisir la syntaxe
Ignorer
Transformer le texte
Aller au premier écart
Modifier l'entrée
Diffchecker Desktop
La façon la plus sécurisée d'utiliser Diffchecker. Obtenez l'application Diffchecker Desktop : vos diffs ne quittent jamais votre ordinateur !
Obtenir Desktop
Untitled diff
Créé
il y a 11 ans
Le diff n'expire jamais
Effacer
Exporter
Partager
Expliquer
25 suppressions
Lignes
Total
Supprimé
Caractères
Total
Supprimé
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
284 lignes
Copier tout
27 ajouts
Lignes
Total
Ajouté
Caractères
Total
Ajouté
Pour continuer à utiliser cette fonctionnalité, passez à
Diff
checker
Pro
Voir les prix
292 lignes
Copier tout
// Copyright (c) 2015, bacondither
// Copyright (c) 2015, bacondither
// All rights reserved.
// All rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// modification, are permitted provided that the following conditions
// are met:
// are met:
// 1. Redistributions of source code must retain the above copyright
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer
// notice, this list of conditions and the following disclaimer
// in this position and unchanged.
// in this position and unchanged.
// 2. Redistributions in binary form must reproduce the above copyright
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// documentation and/or other materials provided with the distribution.
//
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copier
Copié
Copier
Copié
// Adaptive sharpen - version 2015-11-
05
- (requires ps >= 3.0)
// Adaptive sharpen - version 2015-11-
17
- (requires ps >= 3.0)
// Tuned for use post resize, EXPECTS FULL RANGE GAMMA LIGHT
// Tuned for use post resize, EXPECTS FULL RANGE GAMMA LIGHT
/* Modified for ReShade by JPulowski
/* Modified for ReShade by JPulowski
Changelog:
Changelog:
1.0 - Initial release
1.0 - Initial release
1.1 - Updated to version 2015-11-05
1.1 - Updated to version 2015-11-05
Copier
Copié
Copier
Copié
1.2 - Updated to version 2015-11-17, fixed tanh overflow causing black pixels
Copier
Copié
Copier
Copié
Known issues:
- Does not work as intended on DX11.
*/
*/
NAMESPACE_ENTER(CFX)
NAMESPACE_ENTER(CFX)
#include CFX_SETTINGS_DEF
#include CFX_SETTINGS_DEF
#if (USE_ADAPTIVESHARPEN == 1)
#if (USE_ADAPTIVESHARPEN == 1)
texture edgeTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; };
texture edgeTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; };
sampler edgeSampler { Texture = edgeTex; };
sampler edgeSampler { Texture = edgeTex; };
// Edge channel offset, must be the same in both passes
// Edge channel offset, must be the same in both passes
#define w_offset 2.0
#define w_offset 2.0
// Get destination pixel values
// Get destination pixel values
#define get1(x, y) ( saturate(tex2D(RFX_backbufferColor, texcoord + (RFX_PixelSize * float2(x, y))).rgb) )
#define get1(x, y) ( saturate(tex2D(RFX_backbufferColor, texcoord + (RFX_PixelSize * float2(x, y))).rgb) )
// Compute diff
// Compute diff
#define b_diff(z) ( abs(blur-c[z]) )
#define b_diff(z) ( abs(blur-c[z]) )
// Saturation loss reduction
// Saturation loss reduction
#define minim_satloss ( (c[0].rgb*(CtL(c[0].rgb + sharpdiff)/c0_Y) + (c[0].rgb + sharpdiff))/2 )
#define minim_satloss ( (c[0].rgb*(CtL(c[0].rgb + sharpdiff)/c0_Y) + (c[0].rgb + sharpdiff))/2 )
Copier
Copié
Copier
Copié
// Soft if
// Soft if
, fast
#define soft_if(a,b,c) ( saturate((3*((a.w + b.w + c.w - 3*w_offset)/maxedge))-0.85) )
#define soft_if(a,b,c) ( saturate((3*((a.w + b.w + c.w - 3*w_offset)/maxedge))-0.85) )
Copier
Copié
Copier
Copié
// Soft limit
#define soft_lim(v,s) ( ((exp(2*min(abs(v), s*16)/s) - 1)/(exp(2*min(abs(v), s*16)/s) + 1))*s )
// Get destination pixel values
// Get destination pixel values
Copier
Copié
Copier
Copié
#define get2(x,y)
( tex2D(edgeSampler, texcoord + (RFX_PixelSize * float2(x, y))) )
#define get2(x,y)
( tex2D(edgeSampler, texcoord + (RFX_PixelSize * float2(x, y))) )
#define sat(input) ( float4(saturate((input).xyz), (input).w) )
#define sat(input) ( float4(saturate((input).xyz), (input).w) )
// Maximum of four values
// Maximum of four values
#define max4(a,b,c,d) ( max(max(a,b), max(c,d)) )
#define max4(a,b,c,d) ( max(max(a,b), max(c,d)) )
Copier
Copié
Copier
Copié
// Edge threshold, mod. smoothstep
float nonedge(float w) { w = saturate((w - w_offset - 0.01)/0.13); return w*w*(2.99 - 2*w) + 0.01;}
// Colour to luma, fast approx gamma
// Colour to luma, fast approx gamma
#define CtL(RGB) ( sqrt(dot(float3(0.256, 0.651, 0.093), saturate((RGB).rgb*abs(RGB).rgb))) )
#define CtL(RGB) ( sqrt(dot(float3(0.256, 0.651, 0.093), saturate((RGB).rgb*abs(RGB).rgb))) )
// Center pixel diff
// Center pixel diff
#define mdiff(a,b,c,d,e,f,g) ( abs(luma[g]-luma[a]) + abs(luma[g]-luma[b]) \
#define mdiff(a,b,c,d,e,f,g) ( abs(luma[g]-luma[a]) + abs(luma[g]-luma[b]) \
+ abs(luma[g]-luma[c]) + abs(luma[g]-luma[d]) \
+ abs(luma[g]-luma[c]) + abs(luma[g]-luma[d]) \
+ 0.5*(abs(luma[g]-luma[e]) + abs(luma[g]-luma[f])) )
+ 0.5*(abs(luma[g]-luma[e]) + abs(luma[g]-luma[f])) )
void AdaptiveSharpenP0(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 edgeR : SV_Target0) {
void AdaptiveSharpenP0(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 edgeR : SV_Target0) {
// Get points and saturate out of range values (BTB & WTW)
// Get points and saturate out of range values (BTB & WTW)
// [ c22 ]
// [ c22 ]
// [ c24, c9, c23 ]
// [ c24, c9, c23 ]
// [ c21, c1, c2, c3, c18 ]
// [ c21, c1, c2, c3, c18 ]
// [ c19, c10, c4, c0, c5, c11, c16 ]
// [ c19, c10, c4, c0, c5, c11, c16 ]
// [ c20, c6, c7, c8, c17 ]
// [ c20, c6, c7, c8, c17 ]
// [ c15, c12, c14 ]
// [ c15, c12, c14 ]
// [ c13 ]
// [ c13 ]
float3 c[25] = { get1( 0, 0), get1(-1,-1), get1( 0,-1), get1( 1,-1), get1(-1, 0),
float3 c[25] = { get1( 0, 0), get1(-1,-1), get1( 0,-1), get1( 1,-1), get1(-1, 0),
get1( 1, 0), get1(-1, 1), get1( 0, 1), get1( 1, 1), get1( 0,-2),
get1( 1, 0), get1(-1, 1), get1( 0, 1), get1( 1, 1), get1( 0,-2),
get1(-2, 0), get1( 2, 0), get1( 0, 2), get1( 0, 3), get1( 1, 2),
get1(-2, 0), get1( 2, 0), get1( 0, 2), get1( 0, 3), get1( 1, 2),
get1(-1, 2), get1( 3, 0), get1( 2, 1), get1( 2,-1), get1(-3, 0),
get1(-1, 2), get1( 3, 0), get1( 2, 1), get1( 2,-1), get1(-3, 0),
get1(-2, 1), get1(-2,-1), get1( 0,-3), get1( 1,-2), get1(-1,-2) };
get1(-2, 1), get1(-2,-1), get1( 0,-3), get1( 1,-2), get1(-1,-2) };
// Blur, gauss 3x3
// Blur, gauss 3x3
float3 blur = (2*(c[2]+c[4]+c[5]+c[7]) + (c[1]+c[3]+c[6]+c[8]) + 4*c[0])/16;
float3 blur = (2*(c[2]+c[4]+c[5]+c[7]) + (c[1]+c[3]+c[6]+c[8]) + 4*c[0])/16;
float blur_Y = (blur.r/3 + blur.g/3 + blur.b/3);
float blur_Y = (blur.r/3 + blur.g/3 + blur.b/3);
// Contrast compression, center = 0.5
// Contrast compression, center = 0.5
float c_comp = min((0.8+2.7*pow(2, (-7.4*blur_Y))), 3.0);
float c_comp = min((0.8+2.7*pow(2, (-7.4*blur_Y))), 3.0);
// Edge detection
// Edge detection
// Matrix weights
// Matrix weights
// [ 1/4, ]
// [ 1/4, ]
// [ 4, 1, 4 ]
// [ 4, 1, 4 ]
// [ 1/4, 4, 1, 4, 1/4 ]
// [ 1/4, 4, 1, 4, 1/4 ]
// [ 4, 1, 4 ]
// [ 4, 1, 4 ]
// [ 1/4 ]
// [ 1/4 ]
float edge = length( b_diff(0) + b_diff(1) + b_diff(2) + b_diff(3)
float edge = length( b_diff(0) + b_diff(1) + b_diff(2) + b_diff(3)
+ b_diff(4) + b_diff(5) + b_diff(6) + b_diff(7) + b_diff(8)
+ b_diff(4) + b_diff(5) + b_diff(6) + b_diff(7) + b_diff(8)
+ 0.25*(b_diff(9) + b_diff(10) + b_diff(11) + b_diff(12)) );
+ 0.25*(b_diff(9) + b_diff(10) + b_diff(11) + b_diff(12)) );
edge = min(((edge*c_comp)/3 + w_offset), 32 + w_offset);
edge = min(((edge*c_comp)/3 + w_offset), 32 + w_offset);
edgeR = float4( (tex2D(RFX_backbufferColor, texcoord).rgb), edge );
edgeR = float4( (tex2D(RFX_backbufferColor, texcoord).rgb), edge );
}
}
float4 AdaptiveSharpenP1(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target {
float4 AdaptiveSharpenP1(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target {
float4 orig = tex2D(edgeSampler, texcoord);
float4 orig = tex2D(edgeSampler, texcoord);
// Displays a green screen if the edge data is not inside a valid range in the .w channel
// Displays a green screen if the edge data is not inside a valid range in the .w channel
if (orig.w > (w_offset+33) || orig.w < (w_offset-0.5) ) { return float4(0, 1, 0, 1.0); }
if (orig.w > (w_offset+33) || orig.w < (w_offset-0.5) ) { return float4(0, 1, 0, 1.0); }
// Get points, saturate color data in c[0]
// Get points, saturate color data in c[0]
// [ c22 ]
// [ c22 ]
// [ c24, c9, c23 ]
// [ c24, c9, c23 ]
// [ c21, c1, c2, c3, c18 ]
// [ c21, c1, c2, c3, c18 ]
// [ c19, c10, c4, c0, c5, c11, c16 ]
// [ c19, c10, c4, c0, c5, c11, c16 ]
// [ c20, c6, c7, c8, c17 ]
// [ c20, c6, c7, c8, c17 ]
// [ c15, c12, c14 ]
// [ c15, c12, c14 ]
// [ c13 ]
// [ c13 ]
Copier
Copié
Copier
Copié
float4 c[25] = {
sat( orig), get2(-1,-1), get2( 0,-1), get2( 1,-1), get2(-1, 0),
float4 c[25] = {
sat( orig), get2(-1,-1), get2( 0,-1), get2( 1,-1), get2(-1, 0),
get2( 1, 0), get2(-1, 1), get2( 0, 1), get2( 1, 1), get2( 0,-2),
get2( 1, 0), get2(-1, 1), get2( 0, 1), get2( 1, 1), get2( 0,-2),
get2(-2, 0), get2( 2, 0), get2( 0, 2), get2( 0, 3), get2( 1, 2),
get2(-2, 0), get2( 2, 0), get2( 0, 2), get2( 0, 3), get2( 1, 2),
get2(-1, 2), get2( 3, 0), get2( 2, 1), get2( 2,-1), get2(-3, 0),
get2(-1, 2), get2( 3, 0), get2( 2, 1), get2( 2,-1), get2(-3, 0),
get2(-2, 1), get2(-2,-1), get2( 0,-3), get2( 1,-2), get2(-1,-2) };
get2(-2, 1), get2(-2,-1), get2( 0,-3), get2( 1,-2), get2(-1,-2) };
// Allow for higher overshoot if the current edge pixel is surrounded by similar edge pixels
// Allow for higher overshoot if the current edge pixel is surrounded by similar edge pixels
float maxedge = max4( max4(c[1].w,c[2].w,c[3].w,c[4].w), max4(c[5].w,c[6].w,c[7].w,c[8].w),
float maxedge = max4( max4(c[1].w,c[2].w,c[3].w,c[4].w), max4(c[5].w,c[6].w,c[7].w,c[8].w),
max4(c[9].w,c[10].w,c[11].w,c[12].w), c[0].w );
max4(c[9].w,c[10].w,c[11].w,c[12].w), c[0].w );
maxedge = saturate(maxedge - w_offset)*3 + 0.02;
maxedge = saturate(maxedge - w_offset)*3 + 0.02;
// [ x ]
// [ x ]
// [ z, x, w ]
// [ z, x, w ]
// [ z, z, x, w, w ]
// [ z, z, x, w, w ]
// [ y, y, y, 0, y, y, y ]
// [ y, y, y, 0, y, y, y ]
// [ w, w, x, z, z ]
// [ w, w, x, z, z ]
// [ w, x, z ]
// [ w, x, z ]
// [ x ]
// [ x ]
float var = soft_if(c[2],c[9],c[22]) *soft_if(c[7],c[12],c[13]) // x dir
float var = soft_if(c[2],c[9],c[22]) *soft_if(c[7],c[12],c[13]) // x dir
+ soft_if(c[4],c[10],c[19])*soft_if(c[5],c[11],c[16]) // y dir
+ soft_if(c[4],c[10],c[19])*soft_if(c[5],c[11],c[16]) // y dir
+ soft_if(c[1],c[24],c[21])*soft_if(c[8],c[14],c[17]) // z dir
+ soft_if(c[1],c[24],c[21])*soft_if(c[8],c[14],c[17]) // z dir
+ soft_if(c[3],c[23],c[18])*soft_if(c[6],c[20],c[15]); // w dir
+ soft_if(c[3],c[23],c[18])*soft_if(c[6],c[20],c[15]); // w dir
float s[2] = { lerp( L_compr_low, L_compr_high, smoothstep(2, 3.1, var) ),
float s[2] = { lerp( L_compr_low, L_compr_high, smoothstep(2, 3.1, var) ),
lerp( D_compr_low, D_compr_high, smoothstep(2, 3.1, var) ) };
lerp( D_compr_low, D_compr_high, smoothstep(2, 3.1, var) ) };
// RGB to luma
// RGB to luma
float c0_Y = CtL(c[0]);
float c0_Y = CtL(c[0]);
float luma[25] = { c0_Y, CtL(c[1]), CtL(c[2]), CtL(c[3]), CtL(c[4]), CtL(c[5]), CtL(c[6]),
float luma[25] = { c0_Y, CtL(c[1]), CtL(c[2]), CtL(c[3]), CtL(c[4]), CtL(c[5]), CtL(c[6]),
CtL(c[7]), CtL(c[8]), CtL(c[9]), CtL(c[10]), CtL(c[11]), CtL(c[12]),
CtL(c[7]), CtL(c[8]), CtL(c[9]), CtL(c[10]), CtL(c[11]), CtL(c[12]),
CtL(c[13]), CtL(c[14]), CtL(c[15]), CtL(c[16]), CtL(c[17]), CtL(c[18]),
CtL(c[13]), CtL(c[14]), CtL(c[15]), CtL(c[16]), CtL(c[17]), CtL(c[18]),
CtL(c[19]), CtL(c[20]), CtL(c[21]), CtL(c[22]), CtL(c[23]), CtL(c[24]) };
CtL(c[19]), CtL(c[20]), CtL(c[21]), CtL(c[22]), CtL(c[23]), CtL(c[24]) };
Copier
Copié
Copier
Copié
//
Laplacian p
ixel
weighting
//
P
ixel
weights for the laplace kernel
float mdiff_c0 = 0.02 + 3*( abs(luma[0]-luma[2]) + abs(luma[0]-luma[4])
float mdiff_c0 = 0.02 + 3*( abs(luma[0]-luma[2]) + abs(luma[0]-luma[4])
+ abs(luma[0]-luma[5]) + abs(luma[0]-luma[7])
+ abs(luma[0]-luma[5]) + abs(luma[0]-luma[7])
+ 0.25*(abs(luma[0]-luma[1]) + abs(luma[0]-luma[3])
+ 0.25*(abs(luma[0]-luma[1]) + abs(luma[0]-luma[3])
+abs(luma[0]-luma[6]) + abs(luma[0]-luma[8])) );
+abs(luma[0]-luma[6]) + abs(luma[0]-luma[8])) );
Copier
Copié
Copier
Copié
float weights[12] = { ( 0.25 ), ( 0.25 ), ( 0.25 ), ( 0.25 ), // c2, // c4, // c5, // c7
float weights[12] = { ( 0.25 ), ( 0.25 ), ( 0.25 ), ( 0.25 ), // c2, // c4, // c5, // c7
( min((mdiff_c0/mdiff(24, 21, 2, 4, 9, 10, 1)), 1) ), // c1
( min((mdiff_c0/mdiff(24, 21, 2, 4, 9, 10, 1)), 1) ), // c1
( min((mdiff_c0/mdiff(23, 18, 5, 2, 9, 11, 3)), 1) ), // c3
( min((mdiff_c0/mdiff(23, 18, 5, 2, 9, 11, 3)), 1) ), // c3
( min((mdiff_c0/mdiff(4, 20, 15, 7, 10, 12, 6)), 1) ), // c6
( min((mdiff_c0/mdiff(4, 20, 15, 7, 10, 12, 6)), 1) ), // c6
( min((mdiff_c0/mdiff(5, 7, 17, 14, 12, 11, 8)), 1) ), // c8
( min((mdiff_c0/mdiff(5, 7, 17, 14, 12, 11, 8)), 1) ), // c8
( min((mdiff_c0/mdiff(2, 24, 23, 22, 1, 3, 9)), 2) ), // c9
( min((mdiff_c0/mdiff(2, 24, 23, 22, 1, 3, 9)), 2) ), // c9
( min((mdiff_c0/mdiff(20, 19, 21, 4, 1, 6, 10)), 2) ), // c10
( min((mdiff_c0/mdiff(20, 19, 21, 4, 1, 6, 10)), 2) ), // c10
( min((mdiff_c0/mdiff(17, 5, 18, 16, 3, 8, 11)), 2) ), // c11
( min((mdiff_c0/mdiff(17, 5, 18, 16, 3, 8, 11)), 2) ), // c11
( min((mdiff_c0/mdiff(13, 15, 7, 14, 6, 8, 12)), 2) ) }; // c12
( min((mdiff_c0/mdiff(13, 15, 7, 14, 6, 8, 12)), 2) ) }; // c12
weights[4] = (max(max((weights[8] + weights[9])/4, weights[4]), 0.25) + weights[4])/2;
weights[4] = (max(max((weights[8] + weights[9])/4, weights[4]), 0.25) + weights[4])/2;
weights[5] = (max(max((weights[8] + weights[10])/4, weights[5]), 0.25) + weights[5])/2;
weights[5] = (max(max((weights[8] + weights[10])/4, weights[5]), 0.25) + weights[5])/2;
weights[6] = (max(max((weights[9] + weights[11])/4, weights[6]), 0.25) + weights[6])/2;
weights[6] = (max(max((weights[9] + weights[11])/4, weights[6]), 0.25) + weights[6])/2;
weights[7] = (max(max((weights[10] + weights[11])/4, weights[7]), 0.25) + weights[7])/2;
weights[7] = (max(max((weights[10] + weights[11])/4, weights[7]), 0.25) + weights[7])/2;
Copier
Copié
Copier
Copié
// Calculate the negative part of the laplace kernel and the low threshold weight
float lowthsum = 0;
float lowthsum = 0;
float weightsum = 0;
float weightsum = 0;
float neg_laplace = 0;
float neg_laplace = 0;
int order[12] = { 2, 4, 5, 7, 1, 3, 6, 8, 9, 10, 11, 12 };
int order[12] = { 2, 4, 5, 7, 1, 3, 6, 8, 9, 10, 11, 12 };
Copier
Copié
Copier
Copié
[unroll]
for (int pix = 0; pix < 12; ++pix)
for (int pix = 0; pix < 12; ++pix)
{
{
Copier
Copié
Copier
Copié
float
lowth
=
nonedge(
c[order[pix]].w
);
float
x
=
saturate((
c[order[pix]].w
- w_offset - 0.01)/0.12
);
neg_laplace += pow(luma[order[pix]], 2
)*(weights[pix]*lowth);
float lowth = x*x*(2.99 - 2*x) + 0.01;
neg_laplace += pow(luma[order[pix]], 2
.0
)*(weights[pix]*lowth);
weightsum += weights[pix]*lowth;
weightsum += weights[pix]*lowth;
lowthsum += lowth;
lowthsum += lowth;
}
}
Copier
Copié
Copier
Copié
neg_laplace = pow((neg_laplace/weightsum), (1.0/2.0));
// Compute sharpening magnitude function
// Compute sharpening magnitude function
float c_edge = abs(c[0].w - w_offset);
float c_edge = abs(c[0].w - w_offset);
float sharpen_val = (lowthsum/12)*(curve_height/(curveslope*pow(c_edge, 3.5) + 0.5));
float sharpen_val = (lowthsum/12)*(curve_height/(curveslope*pow(c_edge, 3.5) + 0.5));
// Calculate sharpening diff and scale
// Calculate sharpening diff and scale
Copier
Copié
Copier
Copié
float sharpdiff = (c0_Y -
sqrt(
neg_laplace
/weightsum)
)*(sharpen_val*0.8 + 0.01);
float sharpdiff = (c0_Y -
neg_laplace
)*(sharpen_val*0.8 + 0.01);
// Calculate local near min & max, partial cocktail sort (No branching!)
// Calculate local near min & max, partial cocktail sort (No branching!)
Copier
Copié
Copier
Copié
[unroll]
// ps_4_0+ does not unroll without this
[unroll]
for (int i = 0; i < 3; ++i)
for (int i = 0; i < 3; ++i)
{
{
for (int i1 = 1+i; i1 < 25-i; ++i1)
for (int i1 = 1+i; i1 < 25-i; ++i1)
{
{
float temp = luma[i1-1];
float temp = luma[i1-1];
luma[i1-1] = min(luma[i1-1], luma[i1]);
luma[i1-1] = min(luma[i1-1], luma[i1]);
luma[i1] = max(temp, luma[i1]);
luma[i1] = max(temp, luma[i1]);
}
}
for (int i2 = 23-i; i2 > i; --i2)
for (int i2 = 23-i; i2 > i; --i2)
{
{
float temp = luma[i2-1];
float temp = luma[i2-1];
luma[i2-1] = min(luma[i2-1], luma[i2]);
luma[i2-1] = min(luma[i2-1], luma[i2]);
luma[i2] = max(temp, luma[i2]);
luma[i2] = max(temp, luma[i2]);
}
}
}
}
float nmax = max(((luma[22] + luma[23]*2 + luma[24])/4), c0_Y);
float nmax = max(((luma[22] + luma[23]*2 + luma[24])/4), c0_Y);
float nmin = min(((luma[0] + luma[1]*2 + luma[2])/4), c0_Y);
float nmin = min(((luma[0] + luma[1]*2 + luma[2])/4), c0_Y);
// Calculate tanh scale factor, pos/neg
// Calculate tanh scale factor, pos/neg
float nmax_scale = min(((nmax - c0_Y) + L_overshoot), max_scale_lim);
float nmax_scale = min(((nmax - c0_Y) + L_overshoot), max_scale_lim);
float nmin_scale = min(((c0_Y - nmin) + D_overshoot), max_scale_lim);
float nmin_scale = min(((c0_Y - nmin) + D_overshoot), max_scale_lim);
// Soft limit sharpening with tanh, lerp to control maximum compression
// Soft limit sharpening with tanh, lerp to control maximum compression
Copier
Copié
Copier
Copié
sharpdiff = lerp(
(tanh(
(max(sharpdiff, 0)
)/
nmax_scale)
*nmax_scale
),
(
max(sharpdiff, 0)
)
, s[0] )
sharpdiff = lerp(
(soft_lim
(max(sharpdiff, 0)
,
nmax_scale)
),
max(sharpdiff, 0)
, s[0] )
+ lerp(
(tanh(
(min(sharpdiff, 0)
)/
nmin_scale)
*nmin_scale
),
(
min(sharpdiff, 0)
)
, s[1] );
+ lerp(
-(soft_lim
(min(sharpdiff, 0)
,
nmin_scale)
),
min(sharpdiff, 0)
, s[1] );
/*if (video_level_out == true)
/*if (video_level_out == true)
{
{
Copier
Copié
Copier
Copié
[flatten]
if (sharpdiff > 0) { return float4( orig.rgb + (minim_satloss - c[0].rgb), 1.0 ); }
if (sharpdiff > 0) { return float4( orig.rgb + (minim_satloss - c[0].rgb), 1.0 ); }
else { return float4( (orig.rgb + sharpdiff), 1.0 ); }
else { return float4( (orig.rgb + sharpdiff), 1.0 ); }
}*/
}*/
// Normal path
// Normal path
Copier
Copié
Copier
Copié
[flatten]
if (sharpdiff > 0) { return float4( minim_satloss, 1.0 ); }
if (sharpdiff > 0) { return float4( minim_satloss, 1.0 ); }
else { return float4( (c[0].rgb + sharpdiff), 1.0 ); }
else { return float4( (c[0].rgb + sharpdiff), 1.0 ); }
}
}
technique AdaptiveSharpen_Tech <bool enabled = RFX_Start_Enabled; int toggle = AdaptiveSharpen_ToggleKey; >
technique AdaptiveSharpen_Tech <bool enabled = RFX_Start_Enabled; int toggle = AdaptiveSharpen_ToggleKey; >
{
{
pass AdaptiveSharpenPass1
pass AdaptiveSharpenPass1
{
{
VertexShader = RFX_VS_PostProcess;
VertexShader = RFX_VS_PostProcess;
PixelShader = AdaptiveSharpenP0;
PixelShader = AdaptiveSharpenP0;
RenderTarget = edgeTex;
RenderTarget = edgeTex;
}
}
pass AdaptiveSharpenPass2
pass AdaptiveSharpenPass2
{
{
VertexShader = RFX_VS_PostProcess;
VertexShader = RFX_VS_PostProcess;
PixelShader = AdaptiveSharpenP1;
PixelShader = AdaptiveSharpenP1;
}
}
}
}
#undef w_offset
#undef w_offset
#undef get1
#undef get1
#undef b_diff
#undef b_diff
#undef minim_satloss
#undef minim_satloss
#undef soft_if
#undef soft_if
Copier
Copié
Copier
Copié
#undef soft_lim
#undef get2
#undef get2
#undef sat
#undef sat
#undef max4
#undef max4
#undef CtL
#undef CtL
#undef mdiff
#undef mdiff
#endif
#endif
#include CFX_SETTINGS_UNDEF
#include CFX_SETTINGS_UNDEF
NAMESPACE_LEAVE()
NAMESPACE_LEAVE()
Différences enregistrées
Texte d'origine
Ouvrir un fichier
// Copyright (c) 2015, bacondither // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer // in this position and unchanged. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Adaptive sharpen - version 2015-11-05 - (requires ps >= 3.0) // Tuned for use post resize, EXPECTS FULL RANGE GAMMA LIGHT /* Modified for ReShade by JPulowski Changelog: 1.0 - Initial release 1.1 - Updated to version 2015-11-05 Known issues: - Does not work as intended on DX11. */ NAMESPACE_ENTER(CFX) #include CFX_SETTINGS_DEF #if (USE_ADAPTIVESHARPEN == 1) texture edgeTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; sampler edgeSampler { Texture = edgeTex; }; // Edge channel offset, must be the same in both passes #define w_offset 2.0 // Get destination pixel values #define get1(x, y) ( saturate(tex2D(RFX_backbufferColor, texcoord + (RFX_PixelSize * float2(x, y))).rgb) ) // Compute diff #define b_diff(z) ( abs(blur-c[z]) ) // Saturation loss reduction #define minim_satloss ( (c[0].rgb*(CtL(c[0].rgb + sharpdiff)/c0_Y) + (c[0].rgb + sharpdiff))/2 ) // Soft if #define soft_if(a,b,c) ( saturate((3*((a.w + b.w + c.w - 3*w_offset)/maxedge))-0.85) ) // Get destination pixel values #define get2(x,y) ( tex2D(edgeSampler, texcoord + (RFX_PixelSize * float2(x, y))) ) #define sat(input) ( float4(saturate((input).xyz), (input).w) ) // Maximum of four values #define max4(a,b,c,d) ( max(max(a,b), max(c,d)) ) // Edge threshold, mod. smoothstep float nonedge(float w) { w = saturate((w - w_offset - 0.01)/0.13); return w*w*(2.99 - 2*w) + 0.01;} // Colour to luma, fast approx gamma #define CtL(RGB) ( sqrt(dot(float3(0.256, 0.651, 0.093), saturate((RGB).rgb*abs(RGB).rgb))) ) // Center pixel diff #define mdiff(a,b,c,d,e,f,g) ( abs(luma[g]-luma[a]) + abs(luma[g]-luma[b]) \ + abs(luma[g]-luma[c]) + abs(luma[g]-luma[d]) \ + 0.5*(abs(luma[g]-luma[e]) + abs(luma[g]-luma[f])) ) void AdaptiveSharpenP0(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 edgeR : SV_Target0) { // Get points and saturate out of range values (BTB & WTW) // [ c22 ] // [ c24, c9, c23 ] // [ c21, c1, c2, c3, c18 ] // [ c19, c10, c4, c0, c5, c11, c16 ] // [ c20, c6, c7, c8, c17 ] // [ c15, c12, c14 ] // [ c13 ] float3 c[25] = { get1( 0, 0), get1(-1,-1), get1( 0,-1), get1( 1,-1), get1(-1, 0), get1( 1, 0), get1(-1, 1), get1( 0, 1), get1( 1, 1), get1( 0,-2), get1(-2, 0), get1( 2, 0), get1( 0, 2), get1( 0, 3), get1( 1, 2), get1(-1, 2), get1( 3, 0), get1( 2, 1), get1( 2,-1), get1(-3, 0), get1(-2, 1), get1(-2,-1), get1( 0,-3), get1( 1,-2), get1(-1,-2) }; // Blur, gauss 3x3 float3 blur = (2*(c[2]+c[4]+c[5]+c[7]) + (c[1]+c[3]+c[6]+c[8]) + 4*c[0])/16; float blur_Y = (blur.r/3 + blur.g/3 + blur.b/3); // Contrast compression, center = 0.5 float c_comp = min((0.8+2.7*pow(2, (-7.4*blur_Y))), 3.0); // Edge detection // Matrix weights // [ 1/4, ] // [ 4, 1, 4 ] // [ 1/4, 4, 1, 4, 1/4 ] // [ 4, 1, 4 ] // [ 1/4 ] float edge = length( b_diff(0) + b_diff(1) + b_diff(2) + b_diff(3) + b_diff(4) + b_diff(5) + b_diff(6) + b_diff(7) + b_diff(8) + 0.25*(b_diff(9) + b_diff(10) + b_diff(11) + b_diff(12)) ); edge = min(((edge*c_comp)/3 + w_offset), 32 + w_offset); edgeR = float4( (tex2D(RFX_backbufferColor, texcoord).rgb), edge ); } float4 AdaptiveSharpenP1(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target { float4 orig = tex2D(edgeSampler, texcoord); // Displays a green screen if the edge data is not inside a valid range in the .w channel if (orig.w > (w_offset+33) || orig.w < (w_offset-0.5) ) { return float4(0, 1, 0, 1.0); } // Get points, saturate color data in c[0] // [ c22 ] // [ c24, c9, c23 ] // [ c21, c1, c2, c3, c18 ] // [ c19, c10, c4, c0, c5, c11, c16 ] // [ c20, c6, c7, c8, c17 ] // [ c15, c12, c14 ] // [ c13 ] float4 c[25] = { sat( orig), get2(-1,-1), get2( 0,-1), get2( 1,-1), get2(-1, 0), get2( 1, 0), get2(-1, 1), get2( 0, 1), get2( 1, 1), get2( 0,-2), get2(-2, 0), get2( 2, 0), get2( 0, 2), get2( 0, 3), get2( 1, 2), get2(-1, 2), get2( 3, 0), get2( 2, 1), get2( 2,-1), get2(-3, 0), get2(-2, 1), get2(-2,-1), get2( 0,-3), get2( 1,-2), get2(-1,-2) }; // Allow for higher overshoot if the current edge pixel is surrounded by similar edge pixels float maxedge = max4( max4(c[1].w,c[2].w,c[3].w,c[4].w), max4(c[5].w,c[6].w,c[7].w,c[8].w), max4(c[9].w,c[10].w,c[11].w,c[12].w), c[0].w ); maxedge = saturate(maxedge - w_offset)*3 + 0.02; // [ x ] // [ z, x, w ] // [ z, z, x, w, w ] // [ y, y, y, 0, y, y, y ] // [ w, w, x, z, z ] // [ w, x, z ] // [ x ] float var = soft_if(c[2],c[9],c[22]) *soft_if(c[7],c[12],c[13]) // x dir + soft_if(c[4],c[10],c[19])*soft_if(c[5],c[11],c[16]) // y dir + soft_if(c[1],c[24],c[21])*soft_if(c[8],c[14],c[17]) // z dir + soft_if(c[3],c[23],c[18])*soft_if(c[6],c[20],c[15]); // w dir float s[2] = { lerp( L_compr_low, L_compr_high, smoothstep(2, 3.1, var) ), lerp( D_compr_low, D_compr_high, smoothstep(2, 3.1, var) ) }; // RGB to luma float c0_Y = CtL(c[0]); float luma[25] = { c0_Y, CtL(c[1]), CtL(c[2]), CtL(c[3]), CtL(c[4]), CtL(c[5]), CtL(c[6]), CtL(c[7]), CtL(c[8]), CtL(c[9]), CtL(c[10]), CtL(c[11]), CtL(c[12]), CtL(c[13]), CtL(c[14]), CtL(c[15]), CtL(c[16]), CtL(c[17]), CtL(c[18]), CtL(c[19]), CtL(c[20]), CtL(c[21]), CtL(c[22]), CtL(c[23]), CtL(c[24]) }; // Laplacian pixel weighting float mdiff_c0 = 0.02 + 3*( abs(luma[0]-luma[2]) + abs(luma[0]-luma[4]) + abs(luma[0]-luma[5]) + abs(luma[0]-luma[7]) + 0.25*(abs(luma[0]-luma[1]) + abs(luma[0]-luma[3]) +abs(luma[0]-luma[6]) + abs(luma[0]-luma[8])) ); float weights[12] = { ( 0.25 ), ( 0.25 ), ( 0.25 ), ( 0.25 ), // c2, // c4, // c5, // c7 ( min((mdiff_c0/mdiff(24, 21, 2, 4, 9, 10, 1)), 1) ), // c1 ( min((mdiff_c0/mdiff(23, 18, 5, 2, 9, 11, 3)), 1) ), // c3 ( min((mdiff_c0/mdiff(4, 20, 15, 7, 10, 12, 6)), 1) ), // c6 ( min((mdiff_c0/mdiff(5, 7, 17, 14, 12, 11, 8)), 1) ), // c8 ( min((mdiff_c0/mdiff(2, 24, 23, 22, 1, 3, 9)), 2) ), // c9 ( min((mdiff_c0/mdiff(20, 19, 21, 4, 1, 6, 10)), 2) ), // c10 ( min((mdiff_c0/mdiff(17, 5, 18, 16, 3, 8, 11)), 2) ), // c11 ( min((mdiff_c0/mdiff(13, 15, 7, 14, 6, 8, 12)), 2) ) }; // c12 weights[4] = (max(max((weights[8] + weights[9])/4, weights[4]), 0.25) + weights[4])/2; weights[5] = (max(max((weights[8] + weights[10])/4, weights[5]), 0.25) + weights[5])/2; weights[6] = (max(max((weights[9] + weights[11])/4, weights[6]), 0.25) + weights[6])/2; weights[7] = (max(max((weights[10] + weights[11])/4, weights[7]), 0.25) + weights[7])/2; float lowthsum = 0; float weightsum = 0; float neg_laplace = 0; int order[12] = { 2, 4, 5, 7, 1, 3, 6, 8, 9, 10, 11, 12 }; for (int pix = 0; pix < 12; ++pix) { float lowth = nonedge(c[order[pix]].w); neg_laplace += pow(luma[order[pix]], 2)*(weights[pix]*lowth); weightsum += weights[pix]*lowth; lowthsum += lowth; } // Compute sharpening magnitude function float c_edge = abs(c[0].w - w_offset); float sharpen_val = (lowthsum/12)*(curve_height/(curveslope*pow(c_edge, 3.5) + 0.5)); // Calculate sharpening diff and scale float sharpdiff = (c0_Y - sqrt(neg_laplace/weightsum))*(sharpen_val*0.8 + 0.01); // Calculate local near min & max, partial cocktail sort (No branching!) [unroll] // ps_4_0+ does not unroll without this for (int i = 0; i < 3; ++i) { for (int i1 = 1+i; i1 < 25-i; ++i1) { float temp = luma[i1-1]; luma[i1-1] = min(luma[i1-1], luma[i1]); luma[i1] = max(temp, luma[i1]); } for (int i2 = 23-i; i2 > i; --i2) { float temp = luma[i2-1]; luma[i2-1] = min(luma[i2-1], luma[i2]); luma[i2] = max(temp, luma[i2]); } } float nmax = max(((luma[22] + luma[23]*2 + luma[24])/4), c0_Y); float nmin = min(((luma[0] + luma[1]*2 + luma[2])/4), c0_Y); // Calculate tanh scale factor, pos/neg float nmax_scale = min(((nmax - c0_Y) + L_overshoot), max_scale_lim); float nmin_scale = min(((c0_Y - nmin) + D_overshoot), max_scale_lim); // Soft limit sharpening with tanh, lerp to control maximum compression sharpdiff = lerp( (tanh((max(sharpdiff, 0))/nmax_scale)*nmax_scale), (max(sharpdiff, 0)), s[0] ) + lerp( (tanh((min(sharpdiff, 0))/nmin_scale)*nmin_scale), (min(sharpdiff, 0)), s[1] ); /*if (video_level_out == true) { if (sharpdiff > 0) { return float4( orig.rgb + (minim_satloss - c[0].rgb), 1.0 ); } else { return float4( (orig.rgb + sharpdiff), 1.0 ); } }*/ // Normal path if (sharpdiff > 0) { return float4( minim_satloss, 1.0 ); } else { return float4( (c[0].rgb + sharpdiff), 1.0 ); } } technique AdaptiveSharpen_Tech <bool enabled = RFX_Start_Enabled; int toggle = AdaptiveSharpen_ToggleKey; > { pass AdaptiveSharpenPass1 { VertexShader = RFX_VS_PostProcess; PixelShader = AdaptiveSharpenP0; RenderTarget = edgeTex; } pass AdaptiveSharpenPass2 { VertexShader = RFX_VS_PostProcess; PixelShader = AdaptiveSharpenP1; } } #undef w_offset #undef get1 #undef b_diff #undef minim_satloss #undef soft_if #undef get2 #undef sat #undef max4 #undef CtL #undef mdiff #endif #include CFX_SETTINGS_UNDEF NAMESPACE_LEAVE()
Texte modifié
Ouvrir un fichier
// Copyright (c) 2015, bacondither // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer // in this position and unchanged. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Adaptive sharpen - version 2015-11-17 - (requires ps >= 3.0) // Tuned for use post resize, EXPECTS FULL RANGE GAMMA LIGHT /* Modified for ReShade by JPulowski Changelog: 1.0 - Initial release 1.1 - Updated to version 2015-11-05 1.2 - Updated to version 2015-11-17, fixed tanh overflow causing black pixels */ NAMESPACE_ENTER(CFX) #include CFX_SETTINGS_DEF #if (USE_ADAPTIVESHARPEN == 1) texture edgeTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; sampler edgeSampler { Texture = edgeTex; }; // Edge channel offset, must be the same in both passes #define w_offset 2.0 // Get destination pixel values #define get1(x, y) ( saturate(tex2D(RFX_backbufferColor, texcoord + (RFX_PixelSize * float2(x, y))).rgb) ) // Compute diff #define b_diff(z) ( abs(blur-c[z]) ) // Saturation loss reduction #define minim_satloss ( (c[0].rgb*(CtL(c[0].rgb + sharpdiff)/c0_Y) + (c[0].rgb + sharpdiff))/2 ) // Soft if, fast #define soft_if(a,b,c) ( saturate((3*((a.w + b.w + c.w - 3*w_offset)/maxedge))-0.85) ) // Soft limit #define soft_lim(v,s) ( ((exp(2*min(abs(v), s*16)/s) - 1)/(exp(2*min(abs(v), s*16)/s) + 1))*s ) // Get destination pixel values #define get2(x,y) ( tex2D(edgeSampler, texcoord + (RFX_PixelSize * float2(x, y))) ) #define sat(input) ( float4(saturate((input).xyz), (input).w) ) // Maximum of four values #define max4(a,b,c,d) ( max(max(a,b), max(c,d)) ) // Colour to luma, fast approx gamma #define CtL(RGB) ( sqrt(dot(float3(0.256, 0.651, 0.093), saturate((RGB).rgb*abs(RGB).rgb))) ) // Center pixel diff #define mdiff(a,b,c,d,e,f,g) ( abs(luma[g]-luma[a]) + abs(luma[g]-luma[b]) \ + abs(luma[g]-luma[c]) + abs(luma[g]-luma[d]) \ + 0.5*(abs(luma[g]-luma[e]) + abs(luma[g]-luma[f])) ) void AdaptiveSharpenP0(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 edgeR : SV_Target0) { // Get points and saturate out of range values (BTB & WTW) // [ c22 ] // [ c24, c9, c23 ] // [ c21, c1, c2, c3, c18 ] // [ c19, c10, c4, c0, c5, c11, c16 ] // [ c20, c6, c7, c8, c17 ] // [ c15, c12, c14 ] // [ c13 ] float3 c[25] = { get1( 0, 0), get1(-1,-1), get1( 0,-1), get1( 1,-1), get1(-1, 0), get1( 1, 0), get1(-1, 1), get1( 0, 1), get1( 1, 1), get1( 0,-2), get1(-2, 0), get1( 2, 0), get1( 0, 2), get1( 0, 3), get1( 1, 2), get1(-1, 2), get1( 3, 0), get1( 2, 1), get1( 2,-1), get1(-3, 0), get1(-2, 1), get1(-2,-1), get1( 0,-3), get1( 1,-2), get1(-1,-2) }; // Blur, gauss 3x3 float3 blur = (2*(c[2]+c[4]+c[5]+c[7]) + (c[1]+c[3]+c[6]+c[8]) + 4*c[0])/16; float blur_Y = (blur.r/3 + blur.g/3 + blur.b/3); // Contrast compression, center = 0.5 float c_comp = min((0.8+2.7*pow(2, (-7.4*blur_Y))), 3.0); // Edge detection // Matrix weights // [ 1/4, ] // [ 4, 1, 4 ] // [ 1/4, 4, 1, 4, 1/4 ] // [ 4, 1, 4 ] // [ 1/4 ] float edge = length( b_diff(0) + b_diff(1) + b_diff(2) + b_diff(3) + b_diff(4) + b_diff(5) + b_diff(6) + b_diff(7) + b_diff(8) + 0.25*(b_diff(9) + b_diff(10) + b_diff(11) + b_diff(12)) ); edge = min(((edge*c_comp)/3 + w_offset), 32 + w_offset); edgeR = float4( (tex2D(RFX_backbufferColor, texcoord).rgb), edge ); } float4 AdaptiveSharpenP1(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target { float4 orig = tex2D(edgeSampler, texcoord); // Displays a green screen if the edge data is not inside a valid range in the .w channel if (orig.w > (w_offset+33) || orig.w < (w_offset-0.5) ) { return float4(0, 1, 0, 1.0); } // Get points, saturate color data in c[0] // [ c22 ] // [ c24, c9, c23 ] // [ c21, c1, c2, c3, c18 ] // [ c19, c10, c4, c0, c5, c11, c16 ] // [ c20, c6, c7, c8, c17 ] // [ c15, c12, c14 ] // [ c13 ] float4 c[25] = { sat( orig), get2(-1,-1), get2( 0,-1), get2( 1,-1), get2(-1, 0), get2( 1, 0), get2(-1, 1), get2( 0, 1), get2( 1, 1), get2( 0,-2), get2(-2, 0), get2( 2, 0), get2( 0, 2), get2( 0, 3), get2( 1, 2), get2(-1, 2), get2( 3, 0), get2( 2, 1), get2( 2,-1), get2(-3, 0), get2(-2, 1), get2(-2,-1), get2( 0,-3), get2( 1,-2), get2(-1,-2) }; // Allow for higher overshoot if the current edge pixel is surrounded by similar edge pixels float maxedge = max4( max4(c[1].w,c[2].w,c[3].w,c[4].w), max4(c[5].w,c[6].w,c[7].w,c[8].w), max4(c[9].w,c[10].w,c[11].w,c[12].w), c[0].w ); maxedge = saturate(maxedge - w_offset)*3 + 0.02; // [ x ] // [ z, x, w ] // [ z, z, x, w, w ] // [ y, y, y, 0, y, y, y ] // [ w, w, x, z, z ] // [ w, x, z ] // [ x ] float var = soft_if(c[2],c[9],c[22]) *soft_if(c[7],c[12],c[13]) // x dir + soft_if(c[4],c[10],c[19])*soft_if(c[5],c[11],c[16]) // y dir + soft_if(c[1],c[24],c[21])*soft_if(c[8],c[14],c[17]) // z dir + soft_if(c[3],c[23],c[18])*soft_if(c[6],c[20],c[15]); // w dir float s[2] = { lerp( L_compr_low, L_compr_high, smoothstep(2, 3.1, var) ), lerp( D_compr_low, D_compr_high, smoothstep(2, 3.1, var) ) }; // RGB to luma float c0_Y = CtL(c[0]); float luma[25] = { c0_Y, CtL(c[1]), CtL(c[2]), CtL(c[3]), CtL(c[4]), CtL(c[5]), CtL(c[6]), CtL(c[7]), CtL(c[8]), CtL(c[9]), CtL(c[10]), CtL(c[11]), CtL(c[12]), CtL(c[13]), CtL(c[14]), CtL(c[15]), CtL(c[16]), CtL(c[17]), CtL(c[18]), CtL(c[19]), CtL(c[20]), CtL(c[21]), CtL(c[22]), CtL(c[23]), CtL(c[24]) }; // Pixel weights for the laplace kernel float mdiff_c0 = 0.02 + 3*( abs(luma[0]-luma[2]) + abs(luma[0]-luma[4]) + abs(luma[0]-luma[5]) + abs(luma[0]-luma[7]) + 0.25*(abs(luma[0]-luma[1]) + abs(luma[0]-luma[3]) +abs(luma[0]-luma[6]) + abs(luma[0]-luma[8])) ); float weights[12] = { ( 0.25 ), ( 0.25 ), ( 0.25 ), ( 0.25 ), // c2, // c4, // c5, // c7 ( min((mdiff_c0/mdiff(24, 21, 2, 4, 9, 10, 1)), 1) ), // c1 ( min((mdiff_c0/mdiff(23, 18, 5, 2, 9, 11, 3)), 1) ), // c3 ( min((mdiff_c0/mdiff(4, 20, 15, 7, 10, 12, 6)), 1) ), // c6 ( min((mdiff_c0/mdiff(5, 7, 17, 14, 12, 11, 8)), 1) ), // c8 ( min((mdiff_c0/mdiff(2, 24, 23, 22, 1, 3, 9)), 2) ), // c9 ( min((mdiff_c0/mdiff(20, 19, 21, 4, 1, 6, 10)), 2) ), // c10 ( min((mdiff_c0/mdiff(17, 5, 18, 16, 3, 8, 11)), 2) ), // c11 ( min((mdiff_c0/mdiff(13, 15, 7, 14, 6, 8, 12)), 2) ) }; // c12 weights[4] = (max(max((weights[8] + weights[9])/4, weights[4]), 0.25) + weights[4])/2; weights[5] = (max(max((weights[8] + weights[10])/4, weights[5]), 0.25) + weights[5])/2; weights[6] = (max(max((weights[9] + weights[11])/4, weights[6]), 0.25) + weights[6])/2; weights[7] = (max(max((weights[10] + weights[11])/4, weights[7]), 0.25) + weights[7])/2; // Calculate the negative part of the laplace kernel and the low threshold weight float lowthsum = 0; float weightsum = 0; float neg_laplace = 0; int order[12] = { 2, 4, 5, 7, 1, 3, 6, 8, 9, 10, 11, 12 }; [unroll] for (int pix = 0; pix < 12; ++pix) { float x = saturate((c[order[pix]].w - w_offset - 0.01)/0.12); float lowth = x*x*(2.99 - 2*x) + 0.01; neg_laplace += pow(luma[order[pix]], 2.0)*(weights[pix]*lowth); weightsum += weights[pix]*lowth; lowthsum += lowth; } neg_laplace = pow((neg_laplace/weightsum), (1.0/2.0)); // Compute sharpening magnitude function float c_edge = abs(c[0].w - w_offset); float sharpen_val = (lowthsum/12)*(curve_height/(curveslope*pow(c_edge, 3.5) + 0.5)); // Calculate sharpening diff and scale float sharpdiff = (c0_Y - neg_laplace)*(sharpen_val*0.8 + 0.01); // Calculate local near min & max, partial cocktail sort (No branching!) [unroll] for (int i = 0; i < 3; ++i) { for (int i1 = 1+i; i1 < 25-i; ++i1) { float temp = luma[i1-1]; luma[i1-1] = min(luma[i1-1], luma[i1]); luma[i1] = max(temp, luma[i1]); } for (int i2 = 23-i; i2 > i; --i2) { float temp = luma[i2-1]; luma[i2-1] = min(luma[i2-1], luma[i2]); luma[i2] = max(temp, luma[i2]); } } float nmax = max(((luma[22] + luma[23]*2 + luma[24])/4), c0_Y); float nmin = min(((luma[0] + luma[1]*2 + luma[2])/4), c0_Y); // Calculate tanh scale factor, pos/neg float nmax_scale = min(((nmax - c0_Y) + L_overshoot), max_scale_lim); float nmin_scale = min(((c0_Y - nmin) + D_overshoot), max_scale_lim); // Soft limit sharpening with tanh, lerp to control maximum compression sharpdiff = lerp( (soft_lim(max(sharpdiff, 0), nmax_scale)), max(sharpdiff, 0), s[0] ) + lerp( -(soft_lim(min(sharpdiff, 0), nmin_scale)), min(sharpdiff, 0), s[1] ); /*if (video_level_out == true) { [flatten] if (sharpdiff > 0) { return float4( orig.rgb + (minim_satloss - c[0].rgb), 1.0 ); } else { return float4( (orig.rgb + sharpdiff), 1.0 ); } }*/ // Normal path [flatten] if (sharpdiff > 0) { return float4( minim_satloss, 1.0 ); } else { return float4( (c[0].rgb + sharpdiff), 1.0 ); } } technique AdaptiveSharpen_Tech <bool enabled = RFX_Start_Enabled; int toggle = AdaptiveSharpen_ToggleKey; > { pass AdaptiveSharpenPass1 { VertexShader = RFX_VS_PostProcess; PixelShader = AdaptiveSharpenP0; RenderTarget = edgeTex; } pass AdaptiveSharpenPass2 { VertexShader = RFX_VS_PostProcess; PixelShader = AdaptiveSharpenP1; } } #undef w_offset #undef get1 #undef b_diff #undef minim_satloss #undef soft_if #undef soft_lim #undef get2 #undef sat #undef max4 #undef CtL #undef mdiff #endif #include CFX_SETTINGS_UNDEF NAMESPACE_LEAVE()
Trouver la différence