Diff
checker
文本
文本
图像
文档
Excel
文件夹
Legal
Enterprise
桌面版
定价
登录
下载 Diffchecker 桌面版
比较文本
查找两个文本文件之间的差异
工具
历史
实时编辑器
隐藏空白更改
折叠未更改行
关闭换行
视图
拆分
统一
比对精度
智能
单词
字符
文本样式
更改外观
语法高亮
选择语法
忽略
文本转换
转到第一个差异
编辑输入
Diffchecker Desktop
运行Diffchecker最安全的方式。获取Diffchecker桌面应用:您的差异永远不会离开您的电脑!
获取桌面版
Untitled diff
创建于
11年前
差异永不过期
清除
导出
分享
解释
25 删除
行
总计
删除
字符
总计
删除
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
284 行
全部复制
27 添加
行
总计
添加
字符
总计
添加
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
292 行
全部复制
// 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.
复制
已复制
复制
已复制
// 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
复制
已复制
复制
已复制
1.2 - Updated to version 2015-11-17, fixed tanh overflow causing black pixels
复制
已复制
复制
已复制
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 )
复制
已复制
复制
已复制
// 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) )
复制
已复制
复制
已复制
// 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
复制
已复制
复制
已复制
#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)) )
复制
已复制
复制
已复制
// 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 ]
复制
已复制
复制
已复制
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]) };
复制
已复制
复制
已复制
//
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])) );
复制
已复制
复制
已复制
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;
复制
已复制
复制
已复制
// 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 };
复制
已复制
复制
已复制
[unroll]
for (int pix = 0; pix < 12; ++pix)
for (int pix = 0; pix < 12; ++pix)
{
{
复制
已复制
复制
已复制
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;
}
}
复制
已复制
复制
已复制
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
复制
已复制
复制
已复制
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!)
复制
已复制
复制
已复制
[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
复制
已复制
复制
已复制
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)
{
{
复制
已复制
复制
已复制
[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
复制
已复制
复制
已复制
[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
复制
已复制
复制
已复制
#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()
已保存差异
原始文本
打开文件
// 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()
更改后文本
打开文件
// 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()
查找差异