Welcome, Guest.
Username: Password: Remember me

TOPIC: Shader Programming Discussion

Shader Programming Discussion 1 year 8 months ago #1

This is a general thread about shader programming. Talk about anything HLSL, GLSL or anything graphical programming!

THIS IS NOT A REQUEST THREAD!!!!!

Enjoy!
The administrator has disabled public write access.

Tonemapping 1 year 8 months ago #2

Tonemapping is a simple task on paper, but can be a pain sometimes... From looking at all of the various methods of tonemapping in games, it seems like every game engine has a customized version of their own... "ACES" being a very common one, still used in Unreal Engine 4 today, in fact. One thing that has always intrigued me, though, is that most tonemapppers end up looking very similar when it comes down to code.

For example:
float3 ACESFilm( float3 x )
{
    float a = 0.98f; //Slope
    float b = 0.3f; // Toe
    float c = 0.22f; // Shoulder
    float d = 0.0f; // Black Clip
    float e = 0.025f; // White Clip
    return saturate((x * (a * x + b)) / (x * (c * x + d) + e));
}

This is the base code for the "ACE Filmic Tonemapping" algorithm. Then you compare that to something like "Hable Tonemapping" and you realize it looks very similar.
    float hA = 0.15;
    float hB = 0.50;
    float hC = 0.10;
    float hD = 0.20;
    float hE = 0.02;
    float hF = 0.30;

    return ((x*(hA*x+hC*hB)+hD*hE) / (x*(hA*x+hB)+hD*hF)) - hE/hF;

And this is interesting because of how different they look...



Case and point...

The reason I even bring this up is because I wonder about different tonemapping algorithms, and how they function. I know that there is only so much you can do with a couple of pixels and some color ranges, but still.

There seems to be a big craze recently on these forums from not only me, but other members as well, about "Reverse Tonemapping"... Well this is exactly what I wanted to talk about briefly: "Reverse" or "Inverse" tonemapping is the simple idea of reversing the effects of a game's tonemapping algorithm, effectively giving you access to colors that weren't there... However, if any of you understand how "HDR" works, you'll know that "Inverse" tonemapping is far from magical, and can't bring back color accuracy. Because what ends up happening in practically every game on the planet, is that the game's output color depth is limited to 8-bit. Some games go above that, but this very rarely happens. Because of this, we're stuck with what's known as "Color Banding", aka this shit:



Yeah... not pretty to look at. Anyways, to sum up a long post; Tonemapping is cool, inverse tonemapping is intriguing. I'm far from a professional shader programmer, but from what I've learned thus far, it's an art form. An art form disregarded by most.
Last Edit: 1 year 8 months ago by NoMansReshade.
The administrator has disabled public write access.

Tonemapping 1 year 8 months ago #3

On the subject of reverse tonemapping, here is a reversed tonemap algorithm I came up with (very shitty, not for productive use) based off of the "Hable (Uncharted 2)" algorithm to use in a bloom shader.

This screenshot is from the game "Portal 2"



VS ACES Filmic Tonemapping:



Very pretty... but it can get buggy very easily D:



Here is the code (Used for magic bloom):
float3 i_Uncharted2Tonemap(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target
{
	float3 x = blur(ReShade::BackBuffer, texcoord, 2.0 * fBloom_Radius);
	float A = 0.15f * fBloom_Threshold;
	float B = 0.50f * fBloom_Threshold;
	float C = 0.10f * fBloom_Threshold;
	float D = 0.20f * fBloom_Threshold;
	float E = 0.02f + fBloom_Threshold;
	float F = 0.30f * fBloom_Threshold;
   return saturate((x/(A/x-C/B)-D/E) / pow(x/(A/x-B)-D/F+E*F, 0.001));
}

Hable seems to be more accurate color wise. But I will continue to do some more testing.

Edit:

Okay, Hable is like 50000x better than ACES in terms of inverse tonemapping...




I'm in bloom heaven :D
Last Edit: 1 year 8 months ago by NoMansReshade.
The administrator has disabled public write access.
The following user(s) said Thank You: MaxG3D, andrew

Tonemapping 1 year 8 months ago #4

1. Does it work for all Source based games, or does every Source Engine game need different tonemapping?
2. Could you please make a super dumbed down tutorial on how to achieve that?
3. Is it possible to use it for other effects than bloom, like DOF or Motion Blur?
Last Edit: 1 year 8 months ago by MaxG3D.
The administrator has disabled public write access.

Tonemapping 1 year 8 months ago #5

@tonemappers looking similar: they're mostly just different polynom terms after another, written like this to avoid pow(x,natural number) and to force compiler to compile them in a way that ensures minimum instruction count. Also, I'm not sure if you inversed formula is correct, WolframAlpha gives me a much bigger formula. Also, just plainly scaling all parameters won't do, you have to scale the bloom before the inverse tonemap. So basically: backbuffer >contrast/threshold adjustments > inverse tonemap > n bloom blur steps > merging bloom and color with some formula incorporating the regular tonemap step.
The administrator has disabled public write access.
The following user(s) said Thank You: NoMansReshade

Tonemapping 1 year 8 months ago #6

@MaxG3D Yes it should. Maybe when I find the time. Other bloom shaders... Yes, but I don't see how this would be useful in too many other types of effects.

@Marty Thanks for the heads up! As soon as I figure out how to use WolframAlpha, I should be good to go :D Until then, I'll take your other suggestions into account, thanks!
Last Edit: 1 year 8 months ago by NoMansReshade.
The administrator has disabled public write access.

Tonemapping 1 year 8 months ago #7

Hmmm... So looking at this ENB thread, that's how the inverted tonemapping should look like for F4?:
float3 i_Uncharted2Tonemap(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target
{
float3 x = blur(ReShade::BackBuffer, texcoord, 2.0 * fBloom_Radius);
	
    float A = 0.30;
    float B = 0.50;
    float C = 0.10;
    float D = 0.10;
    float E = fBloom_Radius
    float F = 0.30;
    float W = 5.60;
    float4 res = float4(i_Uncharted2Tonemap.rgb, W);	
return (saturate ((x/(A/x-C/B)-D/E) / pow(x/(A/x-B)-D/F+E*F, 0.001))*res.w);
}
Last Edit: 1 year 8 months ago by MaxG3D.
The administrator has disabled public write access.

Tonemapping 1 year 8 months ago #8

I don't know where you get your ideas but how can the bloom radius have anything to do with a factor inside the tonemapper? And you're calling i_Uncharted2Tonemap as a variable and name the function like that. Not gonna work.
Also, as the exact tonemapper is almost never known and we want a generic solution (it's ReShade after all), you can take any tonemapper. A simple pow(color, contrast) before the inversed tonemap is enough to control how strongly the inversed tonemapper boosts colors.
Last Edit: 1 year 8 months ago by Marty McFly.
The administrator has disabled public write access.

Tonemapping 1 year 8 months ago #9

You must have missed the link from the previous post, for some reason this forums doesn't highlight links at all. I simply copied the code from Enbeffect Kingeric explenation, and replaced it with ReShade counterparts.
Last Edit: 1 year 8 months ago by MaxG3D.
The administrator has disabled public write access.

Tonemapping 1 year 8 months ago #10

I'm aware that my "Inversed" algorithm isn't really inverse at all... But for now it seems to be working fine. I still haven't fiddled around with WolframAlpha, but it seems like it would be a useful tool when used correctly :P
Last Edit: 1 year 8 months ago by NoMansReshade.
The administrator has disabled public write access.

Tonemapping 1 year 8 months ago #11

MaxG3D wrote:
You must have missed the link from the previous post, for some reason this forums doesn't highlight links at all. I simply copied the code from Enbeffect Kingeric explenation, and replaced it with ReShade counterparts.

But you did it the wrong way, man ;)

@NoMansReShade: well, as long as you only do it on bloom, it doesn't really matter. I do tonemap(inv(color)+bloom) so if there's no bloom, the original color must be there. Otherwise you mess up the colors.
Last Edit: 1 year 8 months ago by Marty McFly.
The administrator has disabled public write access.

Motion Blur 1 year 8 months ago #12

So I was looking around, and I stumbled across this GPU Gems entry: http.developer.nvidia.com/GPUGems3/gpugems3_ch27.html

The chapter that came to my attention was "27.2 Extracting Object Positions from the Depth Buffer"
I remember suggesting in a thread that the depth buffer could possibly be used to "Fake" motion vectors.

My question is: Could this be translated to Reshade? And if so, how hard would it be to achieve?
It seems pretty self explanatory from looking at the examples they gave... So there must be something
I'm missing.
Last Edit: 1 year 8 months ago by NoMansReshade.
The administrator has disabled public write access.

Motion Blur 1 year 8 months ago #13

g_ViewProjectionInverseMatrix :silly:

Well, that's just how it works, reconstructing world position from image goes per depth buffer, texcoord and projection matrices. That's the standard way to do that in pixel shaders (I don't even know of any other one), it's no secret trick. I did that in GTASA to draw water surface (height map tracing) in ENB. Given the above projection matrices. With ReShade, all I can do is reconstruct the positions of objects relative to camera, by faking FoV value. But this has no object memory, so a shader cannot identify and track objects over several frames.
Last Edit: 1 year 8 months ago by Marty McFly.
The administrator has disabled public write access.

Blending 1 year 8 months ago #14

Since this is a general programming discussion, how do you use blending in passes?
Is it possible to add a texture to another without running into the "no read/write on the same texture" issue? (can't use backbuffer in this case)

For example, I'm building a shader for combining various HDR effects (using inverse tonemapping), so we can have HDR bloom, DoF etc.
Because of the I/O limitation, I have to use two HDR textures, but I was wondering if I could use pass blending to, for example, blend the bloom textures with one of the HDR textures WITHOUT having to write to another one (aka avoiding ping-pong).

This is to allow all effects to be pilled up together in order to have correct adaptation and tonemap in the end.
Likes to reinvent the wheel.

My shaders repository: www.github.com/luluco250/FXShaders
Last Edit: 1 year 8 months ago by luluco250.
The administrator has disabled public write access.

Blending 1 year 8 months ago #15

I think src and dest blending options in technique work, never tested it though.
The administrator has disabled public write access.

Blending 1 year 7 months ago #16

I tried using this additive blending but it didn't work, I wonder if blending doesn't actually work in ReShade.
Setting SrcBlend to ZERO did make the image black though.
BlendEnable = true;
BlendOp = ADD;
SrcBlend = ONE;
DestBlend = ONE;
Likes to reinvent the wheel.

My shaders repository: www.github.com/luluco250/FXShaders
The administrator has disabled public write access.

Blending 1 year 7 months ago #17

That's what I've been using on ENB, which uses regular HLSL syntax.
AlphaBlendEnable = true;
SrcBlend = One;
DestBlend = One;

Assuming AlphaBlendEnable (HLSL) and BlendEnable (ReShade FX) are the same thing, maybe all you need to do is removing BlendOp.
Last Edit: 1 year 7 months ago by Marty McFly.
The administrator has disabled public write access.

Blending 1 year 7 months ago #18

Blending should work. The default blend operator is "ADD", so it should not matter if it's there or not.
Cheers, crosire =)
The administrator has disabled public write access.

Shader Programming Discussion 1 year 6 months ago #19

@NoMansReshade

Hey, is there any follow up on the HDR bloom research that you've showed off? That stuff looks pretty amazing :)
The administrator has disabled public write access.