Welcome, Guest.
Username: Password: Remember me

TOPIC: Deblur

Deblur 1 month 1 week ago #1

I'm posting this if someone wants toy around a bit with "downsampling".
Still stuck on a 1080p display, so feedback is welcome. :P

Edit: new version (23.7.2019), is faster and better looking.

Deblur.fx
/*
   Deblur shader
   
   Copyright (C) 2006 - 2019 guest(r) - 

   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; either version 2
   of the License, or (at your option) any later version.

   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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "ReShadeUI.fxh"
#include "ReShade.fxh" 

static const float3  dt = float3(1.0,1.0,1.0);

uniform float OFFSET < __UNIFORM_SLIDER_FLOAT1
	ui_min = 0.5; ui_max = 2.0;
	ui_label = "Filter Width";
	ui_tooltip = "Filter Width";
> = 1.0; 
 
uniform float DBL < __UNIFORM_SLIDER_FLOAT1
	ui_min = 1.0; ui_max = 9.0;
	ui_label = "Deblur Strength";
	ui_tooltip = "Deblur Strength";
> = 6.0; 

uniform float SMART < __UNIFORM_SLIDER_FLOAT1
	ui_min = 0.0; ui_max = 1.0;
	ui_label = "Smart Deblur";
	ui_tooltip = "Smart Deblur intensity";
> = 0.7; 

float3 DEB(float4 pos : SV_Position, float2 uv : TexCoord) : SV_Target
{
	// Calculating texel coordinates
	float2 inv_size = OFFSET * ReShade::PixelSize;	

	float2 dx = float2(inv_size.x,0.0);
	float2 dy = float2(0.0, inv_size.y);
	float2 g1 = float2(inv_size.x,inv_size.y);
	float2 g2 = float2(-inv_size.x,inv_size.y);
	
	float2 pC4 = uv;	
	
	// Reading the texels
	float3 c00 = tex2D(ReShade::BackBuffer,pC4 - g1).rgb; 
	float3 c10 = tex2D(ReShade::BackBuffer,pC4 - dy).rgb;
	float3 c20 = tex2D(ReShade::BackBuffer,pC4 - g2).rgb;
	float3 c01 = tex2D(ReShade::BackBuffer,pC4 - dx).rgb;
	float3 c11 = tex2D(ReShade::BackBuffer,pC4     ).rgb;
	float3 c21 = tex2D(ReShade::BackBuffer,pC4 + dx).rgb;
	float3 c02 = tex2D(ReShade::BackBuffer,pC4 + g2).rgb;
	float3 c12 = tex2D(ReShade::BackBuffer,pC4 + dy).rgb;
	float3 c22 = tex2D(ReShade::BackBuffer,pC4 + g1).rgb;

	float3 d11 = c11;
	
	float3 mn1 = min (min (c00,c01),c02);
	float3 mn2 = min (min (c10,c11),c12);
	float3 mn3 = min (min (c20,c21),c22);
	float3 mx1 = max (max (c00,c01),c02);
	float3 mx2 = max (max (c10,c11),c12);
	float3 mx3 = max (max (c20,c21),c22);
   
	mn1 = min(min(mn1,mn2),mn3);
	mx1 = max(max(mx1,mx2),mx3);
	float3 contrast = mx1 - mn1;
	float m = max(max(contrast.r,contrast.g),contrast.b);
	
	float DB1 = DBL; float dif;

	float3 dif1 = abs(c11-mn1) + 0.0001; float3 df1 = pow(dif1,float3(DB1,DB1,DB1));
	float3 dif2 = abs(c11-mx1) + 0.0001; float3 df2 = pow(dif2,float3(DB1,DB1,DB1)); 

	dif1 = pow(dif1,float3(2.5,2.5,2.5));
	dif2 = pow(dif2,float3(2.5,2.5,2.5));
	
	float3 df = df1/(df1 + df2);
	float3 ratio = abs(dif1-dif2)/(dif1+dif2);
	d11 = lerp(c11, lerp(mn1,mx1,df), ratio);
	
	c11 = lerp(c11, d11, saturate(2.0*m-0.1));
	
	d11 = lerp(d11,c11,SMART);
	
	return d11;  
}

technique Deblur
{
	pass
	{
		VertexShader = PostProcessVS;
		PixelShader = DEB;
	}
}
Last Edit: 4 weeks 22 hours ago by guest.r. Reason: New Deblur shader version.
The administrator has disabled public write access.
The following user(s) said Thank You: Wicked Sick, jas01, Qsimil, Viper_Joe

Deblur 1 month 1 week ago #2

Looks nice. I made a choice to put it before SMAA, due to more visible edge aliasing with Deblur turned on.
The administrator has disabled public write access.
The following user(s) said Thank You: guest.r

Deblur 1 month 1 week ago #3

May I ask you to write a little more about your Smart Deblur option? Higher values are not giving me much of a (visible) difference.
The administrator has disabled public write access.

Deblur 1 month 1 week ago #4

jas01 wrote:
May I ask you to write a little more about your Smart Deblur option? Higher values are not giving me much of a (visible) difference.
Sure :) , below 0.5 it's turned off, above 0.5 it's on. By turning it on it deblurs only high contrast areas. This can also be managed by two other variables:

Smart Deblur Threshold: higher values prevent deblur on subtler edges,
Smart Deblur Intensity: higher values do deblur in more situations in general.

Nevertheless, i decided to publish a light version also, very easy to use:

Edit: light version is obsolete now, so are some parameters. New version is posted above, is a very nice improovement.
Last Edit: 4 weeks 1 day ago by guest.r. Reason: Removed obsolete shader version.
The administrator has disabled public write access.
The following user(s) said Thank You: jas01

Deblur 1 month 1 week ago #5

This is a sharpening shader? Can someone post screenshot comparisons?
The administrator has disabled public write access.

Deblur 1 month 17 hours ago #6

aaronth07 wrote:
This is a sharpening shader? Can someone post screenshot comparisons?

It's more deblurring than sharpening, but i added sharpen to the next version. :)
Speaking of next version, i've managed to resolve some issues and it's in an usable state now as an upscaling shader.

As i mentioned, i'm stuck a bit with 1080p, so anyone with a 4k could try 2k->4k upscaling, would be awsome. ;)
It's quite usable with a FXAA pass after the effect...

Some screenshot comparison. It's taken with PCSX2 as an ideal case of filter usage, since there is a lot of blur.
www.framecompare.com/image-compare/scree...tcomparison/ZPYWNNNX

Code - DeblurUpscaler.fx
/*
   Deblur Upscaling shader
   
   Copyright (C) 2006 - 2019 guest(r) - 

   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; either version 2
   of the License, or (at your option) any later version.

   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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "ReShadeUI.fxh"
#include "ReShade.fxh" 

static const float3  dt = float3(1.0,1.0,1.0);

uniform float OFFSET < __UNIFORM_SLIDER_FLOAT1
	ui_min = 0.5; ui_max = 2.0;
	ui_label = "Filter Width";
	ui_tooltip = "Filter Width";
> = 1.0; 
 
uniform float DBL < __UNIFORM_SLIDER_FLOAT1
	ui_min = 1.0; ui_max = 9.0;
	ui_label = "Deblur Strength";
	ui_tooltip = "Deblur Strength";
> = 6.0; 

uniform float SMART < __UNIFORM_SLIDER_FLOAT1
	ui_min = 0.0; ui_max = 1.0;
	ui_label = "Smart Deblur";
	ui_tooltip = "Smart Deblur intensity";
> = 0.7; 

uniform float SHARPEN < __UNIFORM_SLIDER_FLOAT1
	ui_min = 0.0; ui_max = 0.7;
	ui_label = "Sharpen";
	ui_tooltip = "Sharpen intensity";
> = 0.20; 

texture TextureDAA { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; };
sampler TextureDAAS { Texture = TextureDAA; };
 
float3 DEB(float4 pos : SV_Position, float2 uv : TexCoord) : SV_Target
{
	// Calculating texel coordinates
	float2 inv_size = OFFSET * ReShade::PixelSize;	
	float2 size     = 1.0/inv_size;

	float2 dx = float2(inv_size.x,0.0);
	float2 dy = float2(0.0, inv_size.y);
	float2 g1 = float2(inv_size.x,inv_size.y);
	float2 g2 = float2(-inv_size.x,inv_size.y);
	
	float2 pC4 = uv;	
	
	// Reading the texels
	float3 c00 = tex2D(ReShade::BackBuffer,pC4 - g1).rgb; 
	float3 c10 = tex2D(ReShade::BackBuffer,pC4 - dy).rgb;
	float3 c20 = tex2D(ReShade::BackBuffer,pC4 - g2).rgb;
	float3 c01 = tex2D(ReShade::BackBuffer,pC4 - dx).rgb;
	float3 c11 = tex2D(ReShade::BackBuffer,pC4     ).rgb;
	float3 c21 = tex2D(ReShade::BackBuffer,pC4 + dx).rgb;
	float3 c02 = tex2D(ReShade::BackBuffer,pC4 + g2).rgb;
	float3 c12 = tex2D(ReShade::BackBuffer,pC4 + dy).rgb;
	float3 c22 = tex2D(ReShade::BackBuffer,pC4 + g1).rgb;

	float3 d11 = c11;
	
	float3 mn1 = min (min (c00,c01),c02);
	float3 mn2 = min (min (c10,c11),c12);
	float3 mn3 = min (min (c20,c21),c22);
	float3 mx1 = max (max (c00,c01),c02);
	float3 mx2 = max (max (c10,c11),c12);
	float3 mx3 = max (max (c20,c21),c22);
   
	mn1 = min(min(mn1,mn2),mn3);
	mx1 = max(max(mx1,mx2),mx3);
	float3 contrast = mx1-mn1;
	float m = max(max(contrast.r,contrast.g),contrast.b);
	
	float DB1 = DBL; float dif;

	float3 dif1 = abs(c11-mn1) + 0.0001; float3 df1 = pow(dif1,float3(DB1,DB1,DB1));
	float3 dif2 = abs(c11-mx1) + 0.0001; float3 df2 = pow(dif2,float3(DB1,DB1,DB1)); 

	dif1 *= dif1*dif1;
	dif2 *= dif2*dif2;
	
	float3 df = df1/(df1 + df2);
	float3 ratio = abs(dif1-dif2)/(dif1+dif2);
	d11 = lerp(c11, lerp(mn1,mx1,df), ratio);
	
	c11 = lerp(c11, d11, saturate(2.0*m-0.15));
	
	d11 = lerp(d11,c11,SMART);
	
	return d11;  
}

// Sharpen table, can be edited

static const float SW[12] = { 0.40, 0.45, 0.5, 0.55, 0.50, 0.40, 0.30, 0.23, 0.15, 0.08, 0.05, 0.05 };

float3 GetWeight(float3 color)
{
	color = color*10.0;
	int i1 = int(color.r);
	int i2 = int(color.g);
	int i3 = int(color.b);
	return lerp(float3(SW[i1], SW[i2], SW[i3]), float3(SW[i1+1], SW[i2+1], SW[i3+1]), frac(color));
}


float3 DEB1 (float4 pos : SV_Position, float2 uv : TexCoord) : SV_Target
{
	float3 c10 = tex2Doffset(TextureDAAS, uv, int2( 0,-1)).rgb;
	float3 c01 = tex2Doffset(TextureDAAS, uv, int2(-1, 0)).rgb;
	float3 c11 = tex2Doffset(TextureDAAS, uv, int2( 0, 0)).rgb;
	float3 c21 = tex2Doffset(TextureDAAS, uv, int2( 1, 0)).rgb;
	float3 c12 = tex2Doffset(TextureDAAS, uv, int2( 0, 1)).rgb;

	float3 w10 = GetWeight(abs(c11-c10));
	float3 w01 = GetWeight(abs(c11-c01));
	float3 w21 = GetWeight(abs(c11-c21));
	float3 w12 = GetWeight(abs(c11-c12));
	
	float3 s11 = (3.5*c11 - w10*c10 - w01*c01 - w21*c21 - w12*c12)/(3.5 - w10 - w01 - w21 - w12);
	
	return saturate(lerp(c11,s11,SHARPEN));
} 

technique DeblurUpscaler
{
	pass deblur1
	{
		VertexShader = PostProcessVS;
		PixelShader = DEB;
		RenderTarget = TextureDAA;		
	}
	pass deblur2
	{
		VertexShader = PostProcessVS;
		PixelShader = DEB1;
	}	
}
Last Edit: 3 weeks 5 days ago by guest.r. Reason: New Deblur shader version.
The administrator has disabled public write access.
The following user(s) said Thank You: jas01, Martigen, Qsimil, Ryukou36, Viper_Joe, Marty, PureEvilWindom, aaronth07

Deblur 1 month 16 hours ago #7

guest.r : that looks interesting, thanks for sharing it :)
<-MB-> ASROCK B450M Pro4 | <-CPU-> AMD Ryzen 2600 | <-RAM-> 16GB (2x8) DDR4 Kingston HyperX Predator 3200Mhz CAS16
<-SSD-> 120GB Kingston HyperX Fury + 512GB Adata XPG SX8200 Pro
<-GPU-> Sapphire Radeon RX 5700 | 23.8" LCD Acer SA240YA
The administrator has disabled public write access.
The following user(s) said Thank You: guest.r

Deblur 4 weeks 2 days ago #8

Too bad downscaling isn't possible with ReShade yet. Would be so much better than any sharpening effect. I remember using GeDoSaTo (some time ago - now it's not working for me). It was a cool little program.

A few small questions for you:
- What about 720p -> 1080p upscaling? Is it a bad idea (looking for a little performance boost)?
- Could you find a way to add "Contrast Adaptive Sharpening" algorithm to your sharpening shader (sharpening, not deblur) to make it a little more "contrast aware" (no sharpening in higher contrast areas)? BlueSkyKnight did something like this to his Smart Sharp shader.
Last Edit: 3 weeks 4 days ago by jas01. Reason: .
The administrator has disabled public write access.
The following user(s) said Thank You: guest.r

Deblur 4 weeks 2 days ago #9

What about 720p -> 1080p upscaling? Is it a bad idea (looking for a little performance boost)?
If your gpu is semi-decent then 900p -> 1080p is probably a better idea, since you get almost 50% FPS boost and the quality is much better compared with 720p.
The details are already fine with 1080p but beyond this performance can be an issue. I'm buying a new setup soon, but choosing the right display can be PITA. I guess a high refresh rate 1440p IPS one would do fine. :silly:
That is the reason i'm playing a bit around with such shaders since i'm a great fan of 1080p framerates and better image quality. :P
Could you find a way to add "Contrast Adaptive Sharpening" algorithm to your sharpening shader...
I corrected the last posted shader, the sharpening was a bit boinked by saturating the sharpened color. Now it works much better and is somewhat contrast aware.
By setting the sharpness parameter to 0.0 you can use lot of sharpening shaders instead, like CAS, luma sharpen, adaptive sharpen etc. I implemented the sharpen effect because i could use the same code for deblur and sharpening, is a bit faster compared with another shader pass.
The administrator has disabled public write access.
The following user(s) said Thank You: jas01

Deblur 4 weeks 2 days ago #10

That screenshot comparison you posted looks really good. Which one do I use for native resolution? The first one you posted? Or the deblur upscaler?

Also, what does the shader actually do to get that effect? I'm not that good at reading HLSL.
Last Edit: 4 weeks 2 days ago by aaronth07.
The administrator has disabled public write access.
The following user(s) said Thank You: guest.r

Deblur 4 weeks 2 days ago #11

guest.r wrote:
Could you find a way to add "Contrast Adaptive Sharpening" algorithm to your sharpening shader...
I corrected the last posted shader, the sharpening was a bit boinked by saturating the sharpened color. Now it works much better and is somewhat contrast aware.
By setting the sharpness parameter to 0.0 you can use lot of sharpening shaders instead, like CAS, luma sharpen, adaptive sharpen etc. I implemented the sharpen effect because i could use the same code for deblur and sharpening, is a bit faster compared with another shader pass.
Just wanted to say thank you for this shader, it's most excellent! I don't 'up-sample' games (I have 1080Ti SLI and am usually down sampling if anything!) but there a few games which, when even though they run at native res (3440x1440 for me), are actually scaling their assets from a clearly lower-resolution source (probably designed for 720p or 1080p). Two such games I've been playing recently are Sunless Skies and Star Traders: Frontiers.

My current Reshade profiles for these use Adaptive Sharpening to bring out some details, and this helps a lot, but your De-blur is considerably better! It really cleans up the image and provides definition, even before you add sharpening. It actually makes some assets almost look like they're near-native in original resolution.

Funnily enough, I found the in-built sharpener a bit aggressive even on low values and had already done as you were suggesting and set it to 0 and used another sharpener. I added Adaptive Sharpening again (though less strong time, no need for it to be as strong now) and also played with the new ported AMD Contrast Adaptive Sharpening, and both work really well with Deblur.

Thank you for making this :)
The administrator has disabled public write access.
The following user(s) said Thank You: jas01, Qsimil, guest.r

Deblur 4 weeks 18 hours ago #12

aaronth07 wrote:
That screenshot comparison you posted looks really good. Which one do I use for native resolution? The first one you posted? Or the deblur upscaler?

Also, what does the shader actually do to get that effect? I'm not that good at reading HLSL.

I updated the first shader to match the new standards, and yeah, for native resolution it's best to use this one. Deblur upscaler has to do stronger sharpening to void the linear upscaling blurring effect (i think it mostly happens when using HW scaling). Using display scaling can varry from type to type, but i'm no expert.

About the shader functionality, i was amused realizing that if a color lies between two other color values, then using weighted linear differences to interpolate between edging colors returns the original color. I thought what about using non-linear ("powered") differences? It turned out this had some nice properties like debluring and even scaling. So the shader interpolates between "min" and "max" local values based on difference of current color between them, Recently i resolved an issue regarding darkening and brighting in some situations, so im quite pleased with the result. The remaining issue can be that it sometimes recognizes anitaliasing as blur to be removed. :whistle:

@Martigen: thanks for giving it a proper try. :cheer:
Last Edit: 4 weeks 17 hours ago by guest.r.
The administrator has disabled public write access.
The following user(s) said Thank You: Qsimil, Viper_Joe, aaronth07

Deblur 3 weeks 6 days ago #13

I have tested in GW: Wildlands, and I think it looks good (although Wildlands doesn't have the best scaling anyways). I do think the actual deblur effect needs to be stronger though, even at maximum deblur, I still needed sharpening for more than a slight deblurring effect.
The administrator has disabled public write access.
The following user(s) said Thank You: guest.r

Deblur 3 weeks 6 days ago #14

aaronth07 wrote:
I have tested in GW: Wildlands, and I think it looks good (although Wildlands doesn't have the best scaling anyways). I do think the actual deblur effect needs to be stronger though, even at maximum deblur, I still needed sharpening for more than a slight deblurring effect.

Yes, sharpening is needed for crisp upscaling, i updated the DeblurUpscaler above with a better sharpen algorithm, prior was to unaccurate for my taste.
And the deblur itself is crisper, tweaked a variable...

Next you have to see if you need smart deblurring, since it leaves low contrast areas alone, can look nice. Otherwise the value can be lowered.
If you use FXAA for example, it can hurt deblurring quite a bit. Sharpening can compensate for it's blurring too, stronger value is recommended.

Otherwise a case of ideal use would be to apply the shader on the already upscaled texture, but this isn't supported in general.
The administrator has disabled public write access.
The following user(s) said Thank You: jas01, Qsimil, Viper_Joe, aaronth07

Deblur 3 weeks 5 days ago #15

The DeblurUpscaler has a sharpening aftereffect attached and i developed the shader a bit and made it better quality. Noticed a funny thing, that sometimes using a static const float array totally destroys the performance (20ms frame time) in some games (Borderlands GOTY), so rather an approximate approach was used. I think it looks pretty the same. :cheer:
Otherwise it should perform good, not much haloing and such...

ColorSharpen.fx (old):

mega.nz/#!0lo2HIDB!I2ZxkiZswPpduZxV1Bidzu8Qr9znns1G8X7zuqKG1Wg

Edit: i think i developed a great upscaler now, much better than DeblurUpscaler and better then the old version.

The benefits are the shader is now capable of slight deblurring without hurting the AA, so it can be put after the aa pass NP.
The halo effect is not a great issue also.

ColorSharpen.fx (28.7.2019):

mega.nz/#!F4xUGSzQ!_rwnmSGuJ5K6ehYRtIIv92yKtCed9vadkdlOOjDS6a4

Cheers! :P
Last Edit: 3 weeks 3 days ago by guest.r. Reason: New shader version.
The administrator has disabled public write access.
The following user(s) said Thank You: jas01, Qsimil, Ryukou36, Viper_Joe, Marty, someone_for

Deblur 3 weeks 3 days ago #16

Using some "free" HW resources can speed things up a bit and i managed to develop a fast sharpen/deblur shader which does a nice job.
It could run a bit faster, but i rather used better quality anti-ringing, which is also capable of deblurring with low contrast variable setting.
I think that's it, have run out of ideas... :)

FastSharpen.fx:
mega.nz/#!olZCUajI!XrAfexdU2sLF_R9lyi8WtaPvml6grctxyKXPKjfupnU

Edit: please grab the new version .
Last Edit: 3 weeks 3 days ago by guest.r. Reason: New shader version.
The administrator has disabled public write access.
The following user(s) said Thank You: Wicked Sick, jas01, Qsimil, Viper_Joe, someone_for

Deblur 3 weeks 1 day ago #17

  • Wicked Sick
  • Wicked Sick's Avatar
  • Offline
  • Die young or suffer (Forgive my poor English)
Hey, man, why don't you use the github to host the Shaders?

Also, thanks a lot for your work!
Finding relief somewhere between a tree's branch and its shade.
The administrator has disabled public write access.

Deblur 3 weeks 18 hours ago #18

Wicked Sick wrote:
Hey, man, why don't you use the github to host the Shaders?
Also, thanks a lot for your work!

I'm planning to use Github for quite a while now, but there seemed a lot of work involved for my other shader projects and i kept postponing it... :)
Nevertheless, this sounds like a good plan and i pushed my Reshade shaders to the repo.

github.com/guestrr/ReshadeShaders
The administrator has disabled public write access.
The following user(s) said Thank You: Wicked Sick, jas01, Viper_Joe

Deblur 3 weeks 9 hours ago #19

I would really like to see them being added to the official Reshade's repositories (so it would be possible to simply choose your shaders during ReShade installation process). Could you submit to Crosire for inclusion? If not now maybe in the near future?

Regarding your sharpening shaders. What's your opinion on adding depth buffer mask to such effects? Something like with FilmicAnamorphSharpen (shader by Fu-Bama).
Last Edit: 3 weeks 9 hours ago by jas01. Reason: .
The administrator has disabled public write access.

Deblur 3 weeks 8 hours ago #20

  • Wicked Sick
  • Wicked Sick's Avatar
  • Offline
  • Die young or suffer (Forgive my poor English)
Yes, this should be official, is too good. Also, there is some other users that too have some nice shaders that I think they should be part of the official package. Wonder why they aren't yet...
Finding relief somewhere between a tree's branch and its shade.
The administrator has disabled public write access.