MassFX Shader Pack
- luluco250
- Topic Author
MassFX is a shader pack designed for simplicity, it is a work-in-progress and currently features the following effects:
- Fake HDR & Tonemapping:
Fake HDR can provide eye adaptation and tonemapping can increase the details of an image a lot, a white fix is also available for LDR games. - Physically-Based Bloom:
Inspired by the bloom shaders seen in Unreal 4 and Minecraft SEUS, although technically not 100% physically based it still allows for a very realistic effect. - Mouse-Based Motion Blur:
A simple motion blur effect that is based on mouse velocity and optionally depth as well. - Vignette:
Simple but great, tinting is also available. - LUT:
Color lookup table, color grading based on a texture, allowing for various color filters to be created with GIMP/Photoshop, a small tutorial is included as well as some presets in MassFX\Textures\LUTs. - Grain:
A simple shader that simulates film grain with a pseudo-random grain pattern, it can also be affected by brightness.
I mainly made this pack for learning and because I wanted better bloom than the one offered by the framework (it's still amazing though).
I plan on updating it on a regular basis, so keep an eye out every now and then, previously existing shaders may also be optimized over time.
License: Do Whatever You Want
These shaders are free for anyone looking to re-use them, learn from them or simply include them in their presets/packs, I only ask that you give credit to the author(me, luluco250).
To install simply download the ReShade Framework, take the .dll your game needs (32 or 64 bits), the "MassFX" folder and the MassFX "ReShade.fx" and place them in your game of choice's folder.
Screenshots: Imgur
Download: GitHub
Any feedback is more than welcome!
The name is a play on "Mass Effect", a game I test this pack a lot with and mainly what I tweak it with.
Release log:
- v4: HDR implemented, provides adaptation and can be combo'd with tonemapping to increase image details, white fix available for LDR games
A few tweaks to many shaders
Config.cfg has been organized a bit more, more descriptions etc
Many placebo shaders and features added as placeholders for future updates - v3b: Added a "LUT_Power" parameter, you can now set how much color correction you want applied.
- v3a: Fixed missing "message" in a #pragma in Grain.fx
- v3: A few improvements to the HDR shader, made a basis for auto-exposure although not implemented yet as it is WIP
New LUT shader
Re-added depth functionality
MBMB can optionally take depth in account now
New Grain shader
New depth visualization shader, like the one from ceejay
Created a logo for the pack and a shader that shows it for a brief while after starting up the game - v2: Major update to PBB shader, much smoother and customizable, now supports dirt textures as well.
New "HDR" shader, not true HDR but rather used for thresholding bright pixels for shaders like PBB. - v1: First release, contains PBB, MBMB and Vignette, ReShade.fx stripped down from the framework, depth-related functions removed as Mass Effect clears the depth buffer so it's just unnecessary overhead.
Planned additions:
- Finish a lens distortion based chromatic aberration shader I've been working on and implement it into the pack.
- Look into how MBMB can be optimized.
- Implement SMAA.
- Version 4 might have introduced a few performance issues, am going to try to fix that
Please Log in or Create an account to join the conversation.
I know it may be hard because of the LDR colorspace but, its worth a try.
Please Log in or Create an account to join the conversation.
- luluco250
- Topic Author
matsilagi wrote: If you add some lensdirt which gets the same color from Bloom i will certainly use this a lot.
I know it may be hard because of the LDR colorspace but, its worth a try.
Shouldn't be too hard, I'll look into it.
On gimp I usually do lens dirt using adition or overlay, I will see if the principle remains the same.
Please Log in or Create an account to join the conversation.
- ShoterXX
Please Log in or Create an account to join the conversation.
- luluco250
- Topic Author
I took a quick look at it, can't you just save position and velocity in the same texture? It saves you from using 2 different textures. And IIRC, RG16F has no improvement over RGBA16F, or atleast, it doesn't seem to.
I haven't took time to optimize the MBMB code yet, I was occupied with the PBB shader.
But I am looking forward to do so, you do have a point I could create a 2x2 texture where int2(0,0) is the last position and int2(1,1) is the velocity, will take a look at it.
Please Log in or Create an account to join the conversation.
- kingeric1992
A more viable approach would be to downscale gradually with gaussian filter, to sample on the texture one scale up, instead of sampling full scale texture every time. Otherwise, local discontinuity may occurred in lower scale textures and causing visual artifacts after blending.
A simple modification to your pixel shader input:
float3 Downsample1(v2f i) : SV_Target {
return Blur(2, ReShade::BackBuffer, i.uv).rgb;
}
float3 Downsample2(v2f i) : SV_Target {
return Blur(4, sTex1, i.uv).rgb;
}
float3 Downsample3(v2f i) : SV_Target {
return Blur(8, sTex2, i.uv).rgb;
}
float3 Downsample4(v2f i) : SV_Target {
return Blur(16,sTex3, i.uv).rgb;
}
float3 Downsample5(v2f i) : SV_Target {
return Blur(32, sTex4, i.uv).rgb;
}
float3 Downsample6(v2f i) : SV_Target {
return Blur(64, sTex5, i.uv).rgb;
}
float3 Downsample7(v2f i) : SV_Target {
return Blur(128, sTex6, i.uv).rgb;
}
float3 Downsample8(v2f i) : SV_Target {
return Blur(256, sTex7, i.uv).rgb;
}
btw, UE4 bloom has nothing to do with PBR... it is even in the description: docs.unrealengine.com/latest/INT/Engine/...cts/Bloom/index.html
The effect might not always be physically correct but it can help to hint the relative brightness of objects or add realism to the LDR (low dynamic range) image that is shown on the screen.
Please Log in or Create an account to join the conversation.
- ShoterXX
luluco250 wrote:
I took a quick look at it, can't you just save position and velocity in the same texture? It saves you from using 2 different textures. And IIRC, RG16F has no improvement over RGBA16F, or atleast, it doesn't seem to.
I haven't took time to optimize the MBMB code yet, I was occupied with the PBB shader.
But I am looking forward to do so, you do have a point I could create a 2x2 texture where int2(0,0) is the last position and int2(1,1) is the velocity, will take a look at it.
I actualy meant in a single pixel. RG for position and BA for velocity. That way, you don't even sample twice.
Please Log in or Create an account to join the conversation.
- kingeric1992
If you are referring this:luluco250 wrote: According to the Unreal 4 Elemental tech demo paper, they apply bloom the following way:
de45xmedrsdbp.cloudfront.net/Resources/f..._16x9-1248544805.pdf
then what I proposed is pretty much what they're doing. (see slider 61)
@ShoterXX
You can't read & write to a texture in same pass (except on framebuffer), meaning to acquire mouse pos from last frame by reading the texture, then calculate velocity and write to the same texture is impossible, no matter it is under 1x1 float4 format or 1x2 float2.
Please Log in or Create an account to join the conversation.
- ShoterXX
Please Log in or Create an account to join the conversation.
- luluco250
- Topic Author
Yeah that's the paper I referenced, like I said I'll apply that now and update the files at dropbox.If you are referring this:
de45xmedrsdbp.cloudfront.net/Resources/f..._16x9-1248544805.pdf
then what I proposed is pretty much what they're doing. (see slider 61)
btw, UE4 bloom has nothing to do with PBR... it is even in the description: docs.unrealengine.com/latest/INT/Engine/...cts/Bloom/index.html
Yeah it's not 100% physically accurate, but I like that the bloom generated using this method is actually glaring and can be very small to very big, which is kinda how imo bloom looks irl. Maybe I should just rename it to "Next-Gen Bloom"
By the way, how would actually PBR bloom be in code? (I'm not asking for you to write any shader code just the overall idea)
Please Log in or Create an account to join the conversation.
- kingeric1992
en.wikipedia.org/wiki/Airy_disk
But if ignoring the performance impact, the legit way is through
f = FFT(original image) * Aperture * lens dirt
result = InverseFFT( f )
and another paper,
resources.mpi-inf.mpg.de/lensflareRendering/pdf/flare.pdf
btw, reshade can also perform pixel shader based FFT and iFFT, there is a gpu gem on radix-2 algorithm.
however, higher radix should be possible with multiple render target setup.
Please Log in or Create an account to join the conversation.
- luluco250
- Topic Author
kingeric1992 wrote: Gaussian alone is a good approximation. (without stacking them, which is used to compensate the HDR range)
en.wikipedia.org/wiki/Airy_disk
Warning: Spoiler!
But if ignoring the performance impact, the legit way is throughBasically, Bloom and Lens Flares (the strip one, not the ghosting flare) are caused by same thing, light diffraction, under different characteristic aperture.f = FFT(original image) * Aperture * lens dirt result = InverseFFT( f )
and another paper,
resources.mpi-inf.mpg.de/lensflareRendering/pdf/flare.pdf
btw, reshade can also perform pixel shader based FFT and iFFT, there is a gpu gem on radix-2 algorithm.
however, higher radix should be possible with multiple render target setup.
That sounds...complicated, I'll just stick to this for now I guess. It looks good enough for me, but I'm fairly sure the actual Unreal 4 uses some sort of FFT bloom because it has some airy disk distortion near edges.
Please Log in or Create an account to join the conversation.
- kingeric1992
3dmark11 did use it in their benchmarks:
s3.amazonaws.com/futuremark-static/downl...rk_11_Whitepaper.pdf3dmark11 WhitePaper wrote: Bloom
The effect is computed by transforming the computed illumination to frequency domain using Fast Fourier
Transform (FFT) and applying bloom filter to the input in that domain. An inverse FFT is then applied to the
filtered image. The forward FFT, applying the bloom filter and inverse FFT are done with the Compute Shader
(CS). The effect is computed in reduced resolution. The input image resolution is halved twice and then
rounded up to nearest power of two. The FFTs are computed using DXGI_FORMAT_R32G32B32A32_FLOAT
textures. A procedurally precomputed texture is used as the bloom filter. The filter combines blur, streak,
lenticular halo and anamorphic flare effects.
The distortion you've seen could simply be the artifact from under-sampling blur.
Please Log in or Create an account to join the conversation.
- luluco250
- Topic Author
It also supports dirt textures now! I've provided a simple one I made on GIMP:
Here's a GIF to showcase the bloom:
I've decided to separate the thresholding into a separate shader because it may be useful for other shaders to have access to such thresholding. It also supports desaturating the threshold.
There's also a debug mode, 0 will display the regular image, 1 will display only the bloom and 2 will display the HDR texture.
Please Log in or Create an account to join the conversation.
- Iddqd
If i correctly understood your shader just need add to config:
#define PBB_Threshold 0.0
#define PBB_Tint float3(1.0, 1.0, 1.0)
#define PBB_TintLevel 1.0
and to main pass add
bloom = max(0.0,bloom-PBB_Threshold);
bloom *= PBB_Tint* PBB_TintLevel;
Please Log in or Create an account to join the conversation.
- Marty McFly
On ENB I can do it as I can retrieve the definite XY position of a light source but not on ReShade.
There have been attempts by Ganossa and myself to find the brightest pixel onscreen or large bright areas but that's extremely twerky. To create proper polygonal lensflares, one needs a polygonal blur on the source image.
To further smoothen the result without additional cost, you could modify the texture lookup to avoid the extrema of linear sampling. Here's a good implementation but you can do virtually anything with different curves:
www.shadertoy.com/view/XsfGDn
Also instead of using a lot of textures, might as well use the way it's handled in the SEUS bloom.
Please Log in or Create an account to join the conversation.
- luluco250
- Topic Author
As for tint, sure I'll look forward to implement it, although it's not physically realistic at all. I'll add it as a sort of optional thing if I can.
Edit: Marty, you mean by generating the effect in various "mini screens" and then re-upsampling them? That's a bit complex for me but I guess it can't hurt to try.
Please Log in or Create an account to join the conversation.
- Marty McFly
Oh and one thing with writing back and forth a texture. If you only have a single texture you want to change all the time and don't need HDR colorspace, backup the original color in one texture and use backbuffer., you can read and write to it in one pass. At the very end of your shader, when you need the original color again, just sample the backup texture.
About thresholding: my bloom shader also does it but it's not a good idea as it causes hue shift. Take float3(0.0,0.5,1.0) for example. It's greenish-blue. If you apply a thresholg of 0.5 on it, you get float3(0.0,0.0,0.5) which is pure blue. So the color after is not the same as before. Better threshold on luma by converting the color to HSV and back. For some of my WIP shaders I just use normalize(input+0.0000001) * max(0.0,length(input)-threshold) as crude approximation of luma. length(nullvector) is invalid, hence the very small incrementation.
Please Log in or Create an account to join the conversation.
- luluco250
- Topic Author
Edit: Any idea how I could upsample those mini screens? I'm still kinda clueless about that part since I don't have to worry about it with textures.
Please Log in or Create an account to join the conversation.
- Marty McFly
texcoord.xy / 0.2 - 0.3
to
(texcoord.xy + 0.3) * 0.2
Here is an effect.txt I used in one of my very old ENB mods:
pastebin.com/beP4CdxB
As I had no way to use a separate texture to do anything, I had to create bloom by putting the R G and B channel on different areas in the alpha channel, blur the alpha channel each pass and maximize it again in the last pass. Code is very old and the ENB version was very limited in features but you get the idea. First pass contains the code to write to alpha and last pass maximizes those again. If you compare the factors I used, the basic idea behind it should be very clear.
Please Log in or Create an account to join the conversation.