Welcome, Guest.
Username: Password: Remember me

TOPIC: Line thinning

Line thinning 1 week 5 days ago #1

Designed to thin lines to increase acutance:

S-curves + Line thinning + Gamma on right (for the PES 2020 screenshots):










#include "ReShadeUI.fxh";

uniform float LOD < __UNIFORM_DRAG_FLOAT1
	ui_min = -1.0; ui_max = 10.0;
	ui_tooltip = "Lower retains more detail.";
> = 0.25;

uniform float Brightness < __UNIFORM_DRAG_FLOAT1
	ui_min = -1.0; ui_max = 10.0;
	ui_tooltip = "Adjust LOD with this at 1 first, then adjust this. Higher => darker.";
> = 1.0;


uniform int dxy < __UNIFORM_SLIDER_INT1
	ui_min = 0; ui_max = 100;
	ui_tooltip = "No. of adjacent pixels to include in the sample.";
> = 2;

uniform bool Final_grey_S_curve <> = false;

uniform float greyChangeAmnt < __UNIFORM_DRAG_FLOAT1
	ui_min = 0.0; ui_max = 5.0;
> = 1;

uniform bool Omit_centre_pixel <> = false;

uniform bool Debug <
ui_tooltip = "Shows adjustment in greyscale.";
> = false;

uniform bool Split <> = false;

uniform bool Flip_split <> = false;

uniform float Split_position < __UNIFORM_SLIDER_FLOAT1
	ui_min = 0; ui_max =1;
	ui_tooltip = "0 is on the far left, 1 on the far right.";
> = 0.5;


#include "ReShade.fxh"

float4 thinner(int dxy,float2 tex){

float4 c0=tex2D(ReShade::BackBuffer, tex);
float c0Max=max(c0.r,max(c0.g,c0.b));
float4 c1=c0;
int x=0;
int y=0;
float count=0;
float accm=0;

			for (x=-1*dxy; x<=dxy; x+=1){
			for (y=-1*dxy; y<=dxy; y+=1){
			
			float4 current=tex2Dlod(ReShade::BackBuffer, float4(tex.x+float(x)*BUFFER_RCP_WIDTH, tex.y+float(y)*BUFFER_RCP_HEIGHT, 0, 0));
			float currentMax=max(current.r,max(current.g,current.b));
			
			float omit=(float2(float(x),float(y))==float2(0,0))?1:0;
			
			accm=(omit*Omit_centre_pixel==1)?accm:accm+currentMax;
			count=(omit*Omit_centre_pixel==1)?count:count+1;

				}
				}
				
float surrAvg=accm*pow(count,-1);

float dMax=max(1-surrAvg,max(surrAvg,max(1-c0Max,c0Max)));
float finalVal=pow(abs(c0Max),LOD*(dMax+1));
finalVal=pow(finalVal,Brightness);

c1.rgb=finalVal*(c1.rgb/c0Max);


float color=max(c1.r,max(c1.g,c1.b));
float colorOG=color;
color*=2;
color=(color<0.5)?pow(abs(0.5*color),greyChangeAmnt):1-(0.5*pow(abs(2-color),greyChangeAmnt));

c1.rgb=(Final_grey_S_curve==1)?saturate(color*(c0.rgb/colorOG)):c1.rgb;

float c2=max(c1.r,max(c1.g,c1.b));

float c3=(Final_grey_S_curve==1)?c2:finalVal;

c1.rgb=(Debug!=1)?c1.rgb:c3;

return c1;

}

float4 PS_LineThin(float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target
{	

float4 c0=tex2D(ReShade::BackBuffer, texcoord);
float4 c1=thinner(dxy,texcoord);


float4 c2=(texcoord.x>=Split_position*Split)?c1:c0;
float4 c3=(texcoord.x<=Split_position*Split)?c1:c0;

float4 c4=(Flip_split*Split==1)?c3:c2;

float divLine = abs(texcoord.x - Split_position) < BUFFER_RCP_WIDTH;
c4 =(Split==0)?c4: c4*(1.0 - divLine); //invert divline

return c4;

}


technique Line_Thinning {
	pass LineThin {
		VertexShader=PostProcessVS;
		PixelShader=PS_LineThin;
	}
}

Video shader version is here.
Last Edit: 2 days 13 hours ago by crabshank. Reason: Optimised
The administrator has disabled public write access.
The following user(s) said Thank You: Wicked Sick, jas01, Viper_Joe, valur432

Line thinning 1 week 4 days ago #2

  • Wicked Sick
  • Wicked Sick's Avatar
  • Offline
  • Die young or suffer (Forgive my poor English)
I really liked that shader, helped be have more control over the brightness of my many blooms haha But I did not understand the purpose of the DXY slider. It can cripple my PC. What does it does exactly to the image? I did not perceive a difference. Sorry for asking this if it is obvious.

EDIT: By the way. the split slider to test the changes should be default in all shaders and also in ReShade itself, maybe haha Thanks for this.
Finding relief somewhere between a tree's branch and its shade.
Last Edit: 1 week 4 days ago by Wicked Sick.
The administrator has disabled public write access.
The following user(s) said Thank You: crabshank

Line thinning 1 week 4 days ago #3

Apologies, I totally messed up that port lol. It's fixed now and you're gonna get the effect I intended.
The administrator has disabled public write access.
The following user(s) said Thank You: Wicked Sick

Line thinning 1 week 4 days ago #4

  • Wicked Sick
  • Wicked Sick's Avatar
  • Offline
  • Die young or suffer (Forgive my poor English)
I have pasted the code from the OP onto the original file I made when I saw your topic, overwriting everything, and stuff looks really bright now, also, there is an option with an out of pattern name:

Finding relief somewhere between a tree's branch and its shade.
Last Edit: 1 week 4 days ago by Wicked Sick.
The administrator has disabled public write access.

Line thinning 1 week 3 days ago #5

Judging from the name, I take it this is similar to MadVR's "Thin Edges" algorithm?
Last Edit: 1 week 3 days ago by Viper_Joe.
The administrator has disabled public write access.

Line thinning 1 week 3 days ago #6

No idea tbh.
The administrator has disabled public write access.

Line thinning 1 week 2 days ago #7

What is the purpose of this shader?
The administrator has disabled public write access.

Line thinning 1 week 2 days ago #8

Originally a video shader to thin lines in upscaled video (where the upscaler made them too thick IMO).

EDIT: Just updated the code to add a final grey S-curve after the thinning as a finishing touch.
Last Edit: 1 week 2 days ago by crabshank.
The administrator has disabled public write access.

Line thinning 1 week 2 days ago #9

EDIT: Comment removed by me.
Last Edit: 1 week 1 day ago by TreyM.
The administrator has disabled public write access.

Line thinning 1 week 2 days ago #10

TreyM wrote:
There is no need for this in gaming...
Really? This would be great for Borderlands to reduce the often exagerrated black outlines while maintaining the rest of the visuals.

Just bizarre you've posted this response to him in two of his threads now. You may not be able to think of a use for a shader, but everyone else is not you.

Thank you Crabshank for sharing your shaders. Please keep doing so. The more shaders Reshade has, the more flexible and powerful it becomes.
The administrator has disabled public write access.
The following user(s) said Thank You: Wicked Sick, Viper_Joe, crabshank

Line thinning 1 week 2 days ago #11

Martigen wrote:
TreyM wrote:
There is no need for this in gaming...
Really? This would be great for Borderlands to reduce the often exagerrated black outlines while maintaining the rest of the visuals.

Just bizarre you've posted this response to him in two of his threads now. You may not be able to think of a use for a shader, but everyone else is not you.

Thank you Crabshank for sharing your shaders. Please keep doing so. The more shaders Reshade has, the more flexible and powerful it becomes.

Just because you create something for one purpose doesn't mean it can't be useful for other things, this is the basis of ingenuity.
The administrator has disabled public write access.

Line thinning 1 week 2 days ago #12

These are video filters designed to run on the CPU (you can see this easily if you look at the code) for dealing with artifacts from video codecs. Game input to reshade is not compressed with a codec... There is no need for these filters in reshade for gaming.

My response is not "bizarre." It's grounded in reality, and if you want to adjust the outlines in BL2, just go edit the shader manually in the game files.
The administrator has disabled public write access.

Line thinning 1 week 2 days ago #13

TreyM wrote:
These are video filters designed to run on the CPU (you can see this easily if you look at the code) for dealing with artifacts from video codecs. Game input to reshade is not compressed with a codec... There is no need for these filters in reshade for gaming.
A ps shader running on the CPU? :D
Video post processing also runs on GPUs, why bother doing that on a CPU if a GPU is much more efficient for that?
My response is not "bizarre." It's grounded in reality, and if you want to adjust the outlines in BL2, just go edit the shader manually in the game files.
There's no need for this kind of reply, someone made a shader, you don't like it, big deal.

PS: your attitude like in the post above was the main reason I left the Reshade discord.
The administrator has disabled public write access.
The following user(s) said Thank You: Wicked Sick, Aelius Maximus

Line thinning 1 week 1 day ago #14

There is no "attitude" here Otis, I'm simply stating the facts here. And if anyone has an attitude on these forums, it's been you repeatedly, mostly in Marty's direction, and even now with you throwing shade at me on an unrelated forum post basically because you don't like me. I couldn't care any less why you left the ReShade discord.

EDIT: Someone please lock this thread before it gets pointless.
Last Edit: 1 week 1 day ago by TreyM.
The administrator has disabled public write access.

Line thinning 1 week 1 day ago #15

Video stuff like H264 decoding also commonly runs on the CPU.

That being said, the shaders from crabshank making excessive use of branching and often not leveraging vector types suggests that the original code (if it's a port) was originally done for something else than a shader language or the author is used to CPU programming so Trey isn't that far off with his assumption.
In which case I'd suggest to read up a bit on the ReShade reference, make use of newest UI widgets and also follow some coding style guideline to make it more readable for future maintainers - I ported many old ReShade shaders to newest format and more often than not it was a huge pain.
Personally I don't see a point in this shader since its changes are miniscule but then again, I think that about 80% of shaders and my opinion isn't universal. Let everyone have their opinions, as long as it's not insulting anyone, I guess it's fine.

@Otis: Lol I haven't noticed you left. Don't let your fun be spoiled by one singular person, that's what the blocking feature in Discord is for. If I left every Discord where I don't like someone, I would be on none. And you're also more than capable of voicing your opinion if you dislike something :D I should know :whistle:

@Trey: If you see no purpose in something, that's fine. If the shader is in fact useless, no one will use it, no harm done. As long as it's not bloating the ReShade repository, it's fine to share them, that's why we have this section.

@crabshank: It would be cool if you followed some coding guidelines since your code seems a bit all over the place but that might be due to me copying it from the browser. Useful variable names also help. Video cards dislike it a lot if you use branching, better use alternatives, Otis for example learned the hard way that in a DoF shader, it's faster to compute stuff you might need and then throw it away than only computing it if required. Branching is only fast when a lot of neighbouring pixels follow the same path and also larger code chunks are skipped. Also in several of your filters you reuse the same code, if you plan to add more shaders, consider using a common file for shared code. To only use luma, just do dot(color.rgb, 0.333) or some luma weight to compute it, miles faster than doing the entire HSV conversion.
Last Edit: 1 week 1 day ago by Marty McFly.
The administrator has disabled public write access.
The following user(s) said Thank You: Wicked Sick, TreyM, crabshank

Line thinning 1 week 1 day ago #16

@crabshank - I am truly sorry if my comments here came off as pointlessly rude to you. I did not consider that what I was saying could be viewed that way until speaking with one of my friends here on the forum.
The administrator has disabled public write access.

Line thinning 1 week 1 day ago #17

@Otis Please consider returning to the discord. We'd miss you if you left.
Your interests and expertise supplement ours - we are better as a whole.

Trey have promised to improve going forward.
He has already taken the first and most important step and acknowledged that he is often rude, and wants to change that.
The administrator has disabled public write access.

Line thinning 1 week 1 day ago #18

Marty McFly wrote:
Video stuff like H264 decoding also commonly runs on the CPU.

That being said, the shaders from crabshank making excessive use of branching and often not leveraging vector types suggests that the original code (if it's a port) was originally done for something else than a shader language or the author is used to CPU programming so Trey isn't that far off with his assumption.
In which case I'd suggest to read up a bit on the ReShade reference, make use of newest UI widgets and also follow some coding style guideline to make it more readable for future maintainers - I ported many old ReShade shaders to newest format and more often than not it was a huge pain.
Personally I don't see a point in this shader since its changes are miniscule but then again, I think that about 80% of shaders and my opinion isn't universal. Let everyone have their opinions, as long as it's not insulting anyone, I guess it's fine.

@Otis: Lol I haven't noticed you left. Don't let your fun be spoiled by one singular person, that's what the blocking feature in Discord is for. If I left every Discord where I don't like someone, I would be on none. And you're also more than capable of voicing your opinion if you dislike something :D I should know :whistle:

@Trey: If you see no purpose in something, that's fine. If the shader is in fact useless, no one will use it, no harm done. As long as it's not bloating the ReShade repository, it's fine to share them, that's why we have this section.

@crabshank: It would be cool if you followed some coding guidelines since your code seems a bit all over the place but that might be due to me copying it from the browser. Useful variable names also help. Video cards dislike it a lot if you use branching, better use alternatives, Otis for example learned the hard way that in a DoF shader, it's faster to compute stuff you might need and then throw it away than only computing it if required. Branching is only fast when a lot of neighbouring pixels follow the same path and also larger code chunks are skipped. Also in several of your filters you reuse the same code, if you plan to add more shaders, consider using a common file for shared code. To only use luma, just do dot(color.rgb, 0.333) or some luma weight to compute it, miles faster than doing the entire HSV conversion.

@Marty McFly -
TL; DR: I don't fully know what you mean.

You've made me see that I'm a noob lol. When you speak of coding guidelines, I'm not sure what you mean because the .hlsl versions of my code look like a lot of other hlsl code I've seen. I don't know if such code is written differently for Reshade than for .hlsl but if it is I'd like to see the best practice for Reshade so that I could port it better. Until I know how best to do it I'll write code as I have been then re-port when I find out.

By branching I'm guessing you mean if statements but I don't know a better alternative, step functions?

Would adding a common file look like "#include "crabshanksCommon.fx";''? I've written the code the same way I would write Javascript. The variable names make sense to me but maybe that's just because I know the code intimately. I will look at optimisations once I'm sure everything's finalised and update then, thanks for your feedback.

@TreyM - I was wondering if you only posted on shaders you disagreed with.
Last Edit: 1 week 1 day ago by crabshank.
The administrator has disabled public write access.

Line thinning 1 week 1 day ago #19

@TreyM, yeah whatever man. Just *read* what you wrote as reply to someone who posts shader code here. Very welcoming for people who would like to join this community. You act like you run the place. Please...

@crabshank: imperative programming doesn't work well in shaders, as it's not a single thread you're focusing on but a part that's run in parallel many times, and parallelism can only be reached if they're doing a lot of work that's equal, e.g. working on pixels that are next to each other. 'If statements' create different code paths and a 'wave' of threads therefore can't operate as a block over the data but has to wait for the various threads doing different work.

Often the if statement simply contains 2 different calculations, which is then assigned to a variable, and for that the ?: instruction is the best way, as it doesn't cause a branch. If an operation is very expensive it still hurts your performance if you calculate it and throw it away in situations, so in those cases precalculation is the best way (doing a pass over the data, calculate your new values and store them in a texture with a format that can contain the values, e.g. RG16 for 2 floats with 16bit precision)

E.g. you can write:
if(Omit_centre_pixel==1)
{
	if(x==0)
	{
		if(y==0)
		{
			accm=accm;
		}
		else
		{
			accm+=rgb2hsv(tex2Dlod(ReShade::BackBuffer, float4(tex.x+float(x)*BUFFER_RCP_WIDTH, tex.y+float(y)*BUFFER_RCP_HEIGHT, 0, 0)).rgb).z;
			count+=1;
		}
	}
	else
	{
		accm+=rgb2hsv(tex2Dlod(ReShade::BackBuffer, float4(tex.x+float(x)*BUFFER_RCP_WIDTH, tex.y+float(y)*BUFFER_RCP_HEIGHT, 0, 0)).rgb).z;
		count+=1;
	}
}
else
{
	accm+=rgb2hsv(tex2Dlod(ReShade::BackBuffer, float4(tex.x+float(x)*BUFFER_RCP_WIDTH, tex.y+float(y)*BUFFER_RCP_HEIGHT, 0, 0)).rgb).z;
	count+=1;
}
as:
if(x==0 && (Omit_centre_pixel==1))
{
	accm+=y==0 ? 0 : rgb2hsv(tex2Dlod(ReShade::BackBuffer, float4(tex.x+float(x)*BUFFER_RCP_WIDTH, tex.y+float(y)*BUFFER_RCP_HEIGHT, 0, 0)).rgb).z;
	count+=(y!=0);
}
else
{
	accm+=rgb2hsv(tex2Dlod(ReShade::BackBuffer, float4(tex.x+float(x)*BUFFER_RCP_WIDTH, tex.y+float(y)*BUFFER_RCP_HEIGHT, 0, 0)).rgb).z;
	count+=1;
}
Multiplying with something that turns out to be 0 makes an add a no-op. Now, these operations above are kind of heavy, as they're doing a texture read, so you'd want to move operations a bit around so texture reads are done more in a sequential fashion: read the pixel and then do the operation needed on the pixel vs. what you're doing: do the operation and read the pixels you need. The former is much faster as pixels are read sequentially and GPU hw can do that very fast. You also have a lot of nested loops: make sure you can remove those if needed and if you absolutely can't, make sure you run them just once, not over and over calculating effectively the same information. E.g. calculating x * some static value in a loop where x doesn't change is a waste, move that outside the loop so the calculation is done once.
Last Edit: 1 week 23 hours ago by OtisInf.
The administrator has disabled public write access.
The following user(s) said Thank You: brussell, crabshank

Line thinning 1 week 23 hours ago #20

@OtisInf - Wow! Thanks for the tips man. This should help me with the optimisations when I get a chance to do them. I wasn't thinking about the assembly, I just wanted something that worked lol.
Last Edit: 1 week 23 hours ago by crabshank.
The administrator has disabled public write access.
  • Page:
  • 1
  • 2