From ad2fb72fc4ebd3511b599cb67bc96e8f554dfd94 Mon Sep 17 00:00:00 2001 From: Mortalitas Date: Tue, 16 Jul 2024 06:43:42 -0400 Subject: [PATCH] Update BloomingHDR.fx --- Shaders/BloomingHDR.fx | 1147 ++++++++++++++++++++++++++++++---------- 1 file changed, 881 insertions(+), 266 deletions(-) diff --git a/Shaders/BloomingHDR.fx b/Shaders/BloomingHDR.fx index 2f0cabaf..f4e4703d 100644 --- a/Shaders/BloomingHDR.fx +++ b/Shaders/BloomingHDR.fx @@ -2,326 +2,901 @@ ///**Blooming HDR**/// //----------------//// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //* HDR Bloom AKA FakeHDR + Bloom *// - //* For Reshade 3.0 *// - //* -------------------------- *// - //* This work is licensed under a Creative Commons Attribution 3.0 Unported License. *// - //* So you are free to share, modify and adapt it for your needs, and even use it for commercial use. *// - //* I would also love to hear about a project you are using it with. *// - //* https://creativecommons.org/licenses/by/3.0/us/ *// - //* *// - //* Have fun, *// - //* Jose Negrete AKA BlueSkyDefender *// - //* *// - //* http://reshade.me/forum/shader-presentation/2128-sidebyside-3d-depth-map-based-stereoscopic-shader *// - //* --------------------------------- *// - //* *// - //* *// - //* Lightly optimized by Marot Satil for the GShade project. - //* - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#if GSHADE_DITHER - #include "TriDither.fxh" +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// *// +//*For Reshade 3.0+ HDR Bloom +//*-------------------------- +//* Blooming HDR +//* +//* Due Diligence +//* Eye Adaptation +//* https://knarkowicz.wordpress.com/2016/01/09/automatic-exposure/ Search Ref. Temporal Adaptation +//* Prods80 AKA ThatRedDot port of exposure. +//* Additional credits (exposure) +//* - Padraic Hennessy for the logic +//* https://placeholderart.wordpress.com/2014/11/21/implementing-a-physically-based-camera-manual-exposure/ +//* - Padraic Hennessy for the logic +//* https://placeholderart.wordpress.com/2014/12/15/implementing-a-physically-based-camera-automatic-exposure/ +//* - MJP and David Neubelt for the method +//* https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/Exposure.hlsl +//* License: MIT, Copyright (c) 2016 MJP +//* Reinhard by Tom Madams +//* http://imdoingitwrong.wordpress.com/2010/08/19/why-reinhard-desaturates-my-blacks-3/ +//* Uncharted2 Tone Mapper by Hable John +//* https://www.slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting +//* ACES Cinematic Tonemapping by Krzysztof Narkowicz and one by Stephen Hill +//* https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl +//* https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ +//* Timothy Lottes Tone mapper and information from this site. +//* https://bartwronski.com/2016/09/01/dynamic-range-and-evs/ +//* https://www.shadertoy.com/view/XljBRK +//* Generate Gold Noise image Based on this implamentation +//* https://www.shadertoy.com/view/wtsSW4 +//* Depth Bloom CeeJay.dk +//* His brain told me to do it...... I just added it. +//* Adyss Bloom used as Insperation for Bloom Rework. Miss you man. Hope you come back. +//* +//* Since it was already witten out nicely was ported from. FidelityFX LPM was it self was not ported. +//* https://github.com/GPUOpen-Effects/FidelityFX-LPM +//* Most of the code is LICENSED this way. +//* https://github.com/GPUOpen-Effects/FidelityFX-LPM/blob/4a1442bf7405d0f703f7cf9c0bfe47a7559cc69b/sample/src/DX12/LPMSample.h#L3-L18 +//* +//* The rest of the code below is under it's own license. +//* If I missed any please tell me. +//* +//* LICENSE +//* ============ +//* Blooming HDR is licenses under: Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) +//* +//* You are free to: +//* Share - copy and redistribute the material in any medium or format +//* for any purpose, even commercially. +//* The licensor cannot revoke these freedoms as long as you follow the license terms. +//* Under the following terms: +//* Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. +//* You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. +//* +//* ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original. +//* +//* No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. +//* +//* https://creativecommons.org/licenses/by-sa/4.0/ +//* +//* Have fun, +//* Jose Negrete AKA BlueSkyDefender +//* +//* https://github.com/BlueSkyDefender/Depth3D +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//Shared Texture for Blooming HDR or any other shader that want's to use it. +#if exists "Flair.fx" //Flair Interceptor// + #define Flare_A 1 +#else + #define Flare_A 0 +#endif + +#if exists "Flare.fx" //Flare Interceptor// + #define Flare_B 1 +#else + #define Flare_B 0 #endif +// Change this to set enable SRGB mode. +#define SRGB 0 + +//Do not Use. +//Use for real HDR. +#define HDR_Toggle 0 //For HDR10 10:10:10:2 use maybe 0.18/25.0 to start. Should only work with Thimothy +//Do not Use. + +#if !defined(__RESHADE__) || __RESHADE__ < 40000 + #define Compatibility 1 +#else + #define Compatibility 0 +#endif + +uniform int Auto_Bloom < + ui_type = "combo"; + ui_label = "Auto Bloom"; + ui_items = "Off\0Auto Intensity\0Auto Desaturation\0Auto Saturation\0Auto Intensity & Desaturation\0Auto Intensity & Saturation\0"; + ui_tooltip = "Auto Intensity will enable the shader to adjust Bloom Intensity automaticly though Bloom Opacity above.\n" + "Auto Saturation will enable the shader to adjust Bloom Saturation automaticly though Bloom Saturation above.\n" + "Default is Off."; + ui_category = "Bloom Adjustments"; +> = 0; + uniform float CBT_Adjust < + + #if Compatibility + ui_type = "drag"; + #else ui_type = "slider"; + #endif ui_min = 0.0; ui_max = 1.0; ui_label = "Extracting Bright Colors"; ui_tooltip = "Use this to set the color based brightness threshold for what is and what isn't allowed.\n" "This is the most important setting, use Debug View to adjust this.\n" - "Number 0.5 is default."; - ui_category = "HDR Adjustments"; + "Default Number is 0.5."; + ui_category = "Bloom Adjustments"; > = 0.5; -uniform float HDR_Adjust < - ui_type = "slider"; - ui_min = 0.5; ui_max = 2.0; - ui_label = "HDR Adjust"; - ui_tooltip = "Use this to adjust HDR levels for your content.\n" - "Number 1.125 is default."; - ui_category = "HDR Adjustments"; -> = 1.125; - -uniform bool Auto_Exposure < - ui_label = "Auto Exposure"; - ui_tooltip = "This will enable the shader to adjust exposure automaticly.\n" - "You will still need to adjust exposure below."; - ui_category = "HDR Adjustments"; -> = false; - -uniform float Exposure< +uniform float2 Bloom_Intensity< + #if Compatibility + ui_type = "drag"; + #else ui_type = "slider"; + #endif ui_min = 0.0; ui_max = 1.0; - ui_label = "Exposure"; - ui_tooltip = "Use this to set HDR exposure for your content.\n" - "Number 0.100 is default."; - ui_category = "HDR Adjustments"; -> = 0.100; - -uniform float Saturation < + ui_label = "Bloom Intensity & Bloom Opacity"; + ui_tooltip = "Use this to set Primary & Secondary Bloom Intensity and Overall Bloom Opacity for your content.\n" + //"The 2nd Option only works when Bloom Intensity Isolation is set above.\n" + "Number 0.1 & 0.5 is default."; + ui_category = "Bloom Adjustments"; +> = float2(0.1,0.5); + +uniform float BloomSensitivity < + #if Compatibility + ui_type = "drag"; + #else ui_type = "slider"; - ui_min = 0.0; ui_max = 2.5; - ui_label = "Bloom Saturation"; - ui_tooltip = "Adjustment The amount to adjust the saturation of the color.\n" - "Number 1.0 is default."; - ui_category = "HDR Adjustments"; + #endif + ui_min = 0.1; ui_max = 5.0; + ui_label = "Bloom Sensitivity"; + ui_tooltip = "A Curve that is applied to the bloom input."; + ui_category = "Bloom Adjustments"; > = 1.0; -uniform float Spread < +uniform float BloomCurve < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 0.1; ui_max = 5.0; + ui_label = "Bloom Curve"; + ui_tooltip = "Defines the way the bloom spreads."; + ui_category = "Bloom Adjustments"; +> = 2.0; + +uniform float2 Saturation < + #if Compatibility + ui_type = "drag"; + #else ui_type = "slider"; - ui_min = 25.0; ui_max = 50.0; ui_step = 0.5; + #endif + ui_min = 0.0; ui_max = 1.0; + ui_label = "Bloom Saturation & Auto Cutoff Point"; + ui_tooltip = "Adjustment The amount to adjust the saturation of the Bloom.\n" + "Number 0.25 is default for both."; + ui_category = "Bloom Adjustments"; +> = float2(0.25,0.25); + +uniform float Bloom_Spread < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 0.5; ui_max = 5.0; ui_label = "Bloom Spread"; - ui_tooltip = "Adjust This to have the Bloom effect to fill in areas.\n" - "This is used for Bloom gap filling.\n" - "Number 37.5 is default."; - ui_category = "HDR Adjustments"; -> = 37.5; + ui_tooltip = "Adjust to spread out the primary Bloom.\n" + "This is used for spreading Bloom.\n" + "Number 1.0 is default."; + ui_category = "Bloom Adjustments"; +> = 1.0; -uniform int Luma_Coefficient < +uniform float Dither_Bloom < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Bloom Dither"; + ui_tooltip = "Adjustment The amount Dither on bloom to reduce banding.\n" + "Number 0.25 is default."; + ui_category = "Bloom Adjustments"; +> = 0.125; + +uniform int Tonemappers < ui_type = "combo"; - ui_label = "Luma"; + ui_label = "Tonemappers"; ui_tooltip = "Changes how color get used for the other effects.\n"; - ui_items = "SD video\0HD video\0HDR video\0Intensity\0"; - ui_category = "HDR Adjustments"; + ui_items = "Timothy\0ACESFitted\0"; + ui_category = "Tonemapper Adjustments"; > = 0; -uniform bool Debug_View < +uniform float WP < + ui_type = "drag"; + ui_min = 0.00; ui_max = 2.00; + ui_label = "Linear White Point Value"; + ui_category = "Tonemapper Adjustments"; +> = 1.0; + +uniform float Exp < + ui_type = "drag"; + ui_min = -4.0; ui_max = 4.00; + ui_label = "Exposure"; + ui_category = "Tonemapper Adjustments"; +> = 0.0; + +uniform float GreyValue < + ui_type = "drag"; + ui_min = 0.0; ui_max = 0.5; + ui_label = "Exposure 50% Greyvalue"; + ui_tooltip = "Exposure 50% Greyvalue Set this Higher when using ACES Fitted and Lower when using Timoithy."; + ui_category = "Tonemapper Adjustments"; +> = 0.128; + +uniform float Gamma < + ui_type = "drag"; + ui_min = 1.0; ui_max = 4.0; + ui_label = "Gamma value"; + ui_tooltip = "Most monitors/images use a value of 2.2. Setting this to 1 disables the inital color space conversion from gamma to linear."; + ui_category = "Tonemapper Adjustments"; +> = 2.2; + +uniform float Contrast < + ui_type = "drag"; + ui_min = 0.0; ui_max = 3.0; + ui_tooltip = "Contrast Adjustment.\n" + "Number 1.0 is default."; + ui_category = "Tonemapper Adjustments"; +> = 1.0; + +uniform float Saturate < + ui_type = "drag"; + ui_min = 0.0; ui_max = 2.0; + ui_label = "Image Saturation"; + ui_tooltip = "Adjustment The amount to adjust the saturation of the color in the image.\n" + "Number 1.0 is default."; + ui_category = "Tonemapper Adjustments"; +> = 1.0; + +uniform int Inv_Tonemappers < + ui_type = "combo"; + ui_label = "Extract HDR Information"; + ui_tooltip = "Changes how color get used for the other effects.\n" + "Turn this Off when the game has a good HDR implementation."; + ui_items = "Off\0Luma\0Color\0Max Color Brightness\0"; + ui_category = "HDR"; +> = 2; + +uniform float HDR_BP < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "HDR Power"; + ui_tooltip = "Use adjsut the HDR Power, You can override this value and set it to like 1.5 or something.\n" + "Number 0.5 is default."; + ui_category = "HDR"; +> = 0.5; + +uniform bool Bloom_BA_iToneMapper < + ui_label = "HDR Bloom Application"; + ui_tooltip = "This will let you swap between Befor HDR ToneMapper and After."; + ui_category = "HDR"; +> = 0; + +uniform int Auto_Exposure < + ui_type = "combo"; + ui_label = "Auto Exposure Type"; + ui_items = "Off\0Auto Exposure & Eye Adaptation\0Auto Exposure & Eyelids Adaptation\0"; + ui_tooltip = "This will enable the shader to adjust Exposure automaticly.\n" + "This will also turn on Eye Adaptation for this shader.\n" + "This is based off Prod80's Port of an Auto-Expo Algo.\n" + "Padraic Hennessy, MJP and David Neubelt."; + ui_category = "Adaptation"; +> = 1; + +uniform float Adapt_Adjust < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Eye Adapt Speed"; + ui_tooltip = "Use this to Adjust Eye Adaptation Speed.\n" + "Set from Zero to One, Zero is the slowest.\n" + "Number 0.5 is default."; + ui_category = "Adaptation"; +> = 0.5; + +uniform float Adapt_Seek < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Eye Adapt Seeking"; + ui_tooltip = "Use this to Adjust Eye Seeking Radius for Average Brightness.\n" + "Set from 0 to 1, 1 is Full-Screen Average Brightness.\n" + "Number 0.5 is default."; + ui_category = "Adaptation"; +> = 0.5; + +uniform int Debug_View < + ui_type = "combo"; ui_label = "Debug View"; + ui_items = "Normal View\0Bloom View\0Heat Map\0"; ui_tooltip = "To view Shade & Blur effect on the game, movie piture & ect."; ui_category = "Debugging"; -> = false; +> = 0; /////////////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// #define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +//#define BloomSpread Bloom_Spread * rcp(Bloom_Max) +#define DBP lerp(0.0,1.0,NFCD.z) +#define Sat lerp(0,10,Saturation.x) +#define PHI 1.61803398874989484820459 * 00000.1 // Golden Ratio +#define PI 3.14159265358979323846264 * 00000.1 // PI +#define SQ2 1.41421356237309504880169 * 10000.0 // Square Root of Two +#define BloomSamples 8 + +uniform float timer < source = "timer"; >; texture DepthBufferTex : DEPTH; -sampler DepthBuffer - { - Texture = DepthBufferTex; +sampler DepthBuffer + { + Texture = DepthBufferTex; }; - + texture BackBufferTex : COLOR; -sampler BackBuffer - { +sampler BackBuffer + { Texture = BackBufferTex; + #if SRGB + SRGBTexture = true; + #endif }; -texture texBC { Width = BUFFER_WIDTH * 0.5; Height = BUFFER_HEIGHT * 0.5; Format = RGBA8; MipLevels = 4;}; -sampler SamplerBC +texture texCurrColor { Width = BUFFER_WIDTH * 0.5; Height = BUFFER_HEIGHT * 0.5; Format = RGBA8; MipLevels = 8;}; + +sampler SamplerCurrBB { - Texture = texBC; - MipLODBias = 2.0f; - MinFilter = LINEAR; - MagFilter = LINEAR; - MipFilter = LINEAR; + Texture = texCurrColor; }; - -texture texBlur { Width = BUFFER_WIDTH * 0.5; Height = BUFFER_HEIGHT * 0.5; Format = RGBA8; MipLevels = 3;}; -sampler SamplerBlur +//Bloom Passes +texture2D BloomTexH_A { Width = BUFFER_WIDTH / 2; Height = BUFFER_HEIGHT / 2; Format = RGBA16F;}; +sampler2D TextureBloomH_A { Texture = BloomTexH_A;}; + +texture2D BloomTexV_A { Width = BUFFER_WIDTH / 2; Height = BUFFER_HEIGHT / 2; Format = RGBA16F;}; +sampler2D TextureBloomV_A { Texture = BloomTexV_A;}; + +texture2D BloomTexH_B { Width = BUFFER_WIDTH / 4; Height = BUFFER_HEIGHT / 4; Format = RGBA16F;}; +sampler2D TextureBloomH_B { Texture = BloomTexH_B;}; + +texture2D BloomTexV_B { Width = BUFFER_WIDTH / 4; Height = BUFFER_HEIGHT / 4; Format = RGBA16F;}; +sampler2D TextureBloomV_B { Texture = BloomTexV_B;}; + +texture2D BloomTexH_C { Width = BUFFER_WIDTH / 8; Height = BUFFER_HEIGHT / 8; Format = RGBA16F;}; +sampler2D TextureBloomH_C { Texture = BloomTexH_C;}; + +texture2D BloomTexV_C { Width = BUFFER_WIDTH / 8; Height = BUFFER_HEIGHT / 8; Format = RGBA16F;}; +sampler2D TextureBloomV_C { Texture = BloomTexV_C;}; + +texture2D BloomTex { Width = BUFFER_WIDTH / 2; Height = BUFFER_HEIGHT / 2; Format = RGBA16F;}; +sampler2D TextureBloom { Texture = BloomTex;}; + + +#if Flare_A +texture TexFlareShared { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT; Format = RGBA16F;}; + +sampler SamplerFlare { - Texture = texBlur; - MinFilter = LINEAR; - MagFilter = LINEAR; - MipFilter = LINEAR; + Texture = TexFlareShared; }; - -texture PastSingle_BackBuffer { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;}; +#endif +#if Flare_B +texture TexLensFlareShared { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT; Format = RGBA16F;}; -sampler PSBackBuffer +sampler SamplerLensFlare { - Texture = PastSingle_BackBuffer; + Texture = TexLensFlareShared; }; - +#endif //Total amount of frames since the game started. -uniform uint framecount < source = "framecount"; >; uniform float frametime < source = "frametime";>; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#define Alternate framecount % 2 == 0 -#define MipLevelAdjust 2 //This is used for removing banding in the Bloom. -float3 Luma() +float Luma(float3 C) { - float3 Luma; - - if (Luma_Coefficient == 0) + if (HDR_Toggle == 0) { - Luma = float3(0.299, 0.587, 0.114); // (SD video) - } - else if (Luma_Coefficient == 1) - { - Luma = float3(0.2126, 0.7152, 0.0722); // (HD video) https://en.wikipedia.org/wiki/Luma_(video) - } - else if (Luma_Coefficient == 2) - { - Luma = float3(0.2627, 0.6780, 0.0593); // (HDR video) https://en.wikipedia.org/wiki/Rec._2100 + const float3 Luma = float3(0.2126, 0.7152, 0.0722); // (HD video) https://en.wikipedia.org/wiki/Luma_(video) + return dot(C,Luma); } else { - Luma = float3(0.3333, 0.3333, 0.3333); // Intensity + const float3 Luma = float3(0.2627, 0.6780, 0.0593); // (HDR video) https://en.wikipedia.org/wiki/Rec._2100 + return dot(C,Luma); } - return Luma; } +float3 ApplyPQ(float3 color) +{ + // Apply ST2084 curve + const float m1 = 2610.0 / 4096.0 / 4; + const float m2 = 2523.0 / 4096.0 * 128; + const float c1 = 3424.0 / 4096.0; + const float c2 = 2413.0 / 4096.0 * 32; + const float c3 = 2392.0 / 4096.0 * 32; + const float3 cp = pow(abs(color.xyz), m1); + color.xyz = pow((c1 + c2 * cp) / (1 + c3 * cp), m2); + return color; +} + +//float3 ApplyscRGBScale(float3 color, float minLuminancePerNits, float maxLuminancePerNits) +//{ +// color.xyz = (color.xyz * (maxLuminancePerNits - minLuminancePerNits)) + float3(minLuminancePerNits, minLuminancePerNits, minLuminancePerNits); +// return color; +//} + +float Log2Exposure( in float avgLuminance, in float GreyValue ) + { + float exposure = 0.0f; + avgLuminance = max(avgLuminance, 0.000001f); + // GreyValue should be 0.148 based on https://placeholderart.wordpress.com/2014/11/21/implementing-a-physically-based-camera-manual-exposure/ + const float linExp = GreyValue / avgLuminance; + exposure = log2( linExp ); + return exposure; + } + +float CalcExposedColor(in float avgLuminance, in float offset, in float GreyValue ) + { + const float exposure = Log2Exposure( avgLuminance, GreyValue * 2.2 ) + offset; //offset = exposure + return exp2( exposure ); + } + /////////////////////////////////////////////////////////////////////////////////Adapted Luminance///////////////////////////////////////////////////////////////////////////////// -//Something seems off in the new reshade. -texture texLumAvg {Width = 256; Height = 256; Format = RGBA8; MipLevels = 9;}; //Sample at 256x256 map only has nine mip levels; 0-1-2-3-4-5-6-7-8 : 256,128,64,32,16,8,4,2, and 1 (1x1). - -sampler SamplerLum +texture texDS {Width = 256; Height = 256; Format = RG16F; MipLevels = 9;}; //Sample at 256x256 map only has nine mip levels; 0-1-2-3-4-5-6-7-8 : 256,128,64,32,16,8,4,2, and 1 (1x1). + +sampler SamplerDS { - Texture = texLumAvg; - MipLODBias = 11; //Luminance adapted luminance value from 1x1 So you would only have to adjust the boxes from Image to 8. - MinFilter = LINEAR; - MagFilter = LINEAR; - MipFilter = LINEAR; - AddressU = Clamp; - AddressV = Clamp; + Texture = texDS; }; - -texture PStexLumAvg {Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; - -sampler SamplerPSLum + +texture texTA {Width = 64; Height = 64; Format = R16F; }; + +sampler SamplerTA { - Texture = PStexLumAvg; - MinFilter = LINEAR; - MagFilter = LINEAR; - MipFilter = LINEAR; - AddressU = Clamp; - AddressV = Clamp; + Texture = texTA; }; - -float Luminance(float4 pos : SV_Position, float2 texcoords : TEXCOORD) : SV_Target -{ - float GSBB = dot(tex2D(BackBuffer,texcoords).rgb, Luma()); - return GSBB; -} - -float Average_Luminance(float2 texcoords : TEXCOORD) -{ - const float2 tex_offset = 50 * pix; // gets texel offset - const float L = tex2D(SamplerLum, texcoords).x, PL = tex2D(PSBackBuffer, texcoords).w; - //L += tex2D(SamplerLum, texcoords + float2( 1, 0) * tex_offset ).x; - //L += tex2D(SamplerLum, texcoords + float2(-1, 0) * tex_offset ).x; - //L += tex2D(SamplerLum, texcoords + float2( 0, 1) * tex_offset ).x; - //L += tex2D(SamplerLum, texcoords + float2( 0,-1) * tex_offset ).x; - //PL += tex2D(PSBackBuffer, texcoords + float2( 1, 0) * tex_offset ).w; - //PL += tex2D(PSBackBuffer, texcoords + float2(-1, 0) * tex_offset ).w; - //PL += tex2D(PSBackBuffer, texcoords + float2( 0, 1) * tex_offset ).w; - //PL += tex2D(PSBackBuffer, texcoords + float2( 0,-1) * tex_offset ).w; - const float lum = L; - const float lumlast = PL; - //Temporal adaptation https://knarkowicz.wordpress.com/2016/01/09/automatic-exposure/ - return lumlast + (lum - lumlast) * (1.0 - exp2(-frametime)); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -float4 BrightColors(float4 position : SV_Position, float2 texcoords : TEXCOORD) : SV_Target //bright-pass filter is applied to dim-down the darkest areas of the scene. -{ - float4 BC, Color = tex2D(BackBuffer, texcoords); - // check whether fragment output is higher than threshold, if so output as brightness color. - const float brightness = dot(Color.rgb, Luma()); - - if(brightness > CBT_Adjust) - BC.rgb = Color.rgb; - else - BC.rgb = float3(0.0, 0.0, 0.0); - - const float3 intensity = dot(BC.rgb,Luma()); - BC.rgb = lerp(intensity,BC.rgb,Saturation); - // The result of the bright-pass filter is then downscaled. - return float4(BC.rgb,1.0); -} - -float4 Blur(float4 position : SV_Position, float2 texcoords : TEXCOORD) : SV_Target//Then blurred. -{ - float2 tex_offset = (Spread * 0.5f) * pix; // Gets texel offset - float4 result = tex2D(SamplerBC,texcoords); // Current fragment's contribution - if (Alternate) + +texture texStored {Width = 64; Height = 64; Format = R16F; }; + +sampler SamplerStored { - result += tex2D(SamplerBC,texcoords + float2( 1, 0) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2(-1, 0) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2( 0, 1) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2( 0,-1) * tex_offset ); - tex_offset *= 0.75; - result += tex2D(SamplerBC,texcoords + float2( 1, 1) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2(-1,-1) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2( 1,-1) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2(-1, 1) * tex_offset ); + Texture = texStored; + }; + +float3 Downsample(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + const float2 texXY = texcoord; + const float2 midHV = (Adapt_Seek-1) * float2(BUFFER_WIDTH * 0.5,BUFFER_HEIGHT * 0.5) * pix; + const float2 TC = float2((texXY.x*Adapt_Seek)-midHV.x,(texXY.y*Adapt_Seek)-midHV.y); + + return float3(Luma(tex2D(BackBuffer,TC).rgb),0,0); +} + +float PS_Temporal_Adaptation(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ //Temporal adaptation https://knarkowicz.wordpress.com/2016/01/09/automatic-exposure/ + float TT = 32500; + float EA = (1-Adapt_Adjust)*1250, L = tex2Dlod(SamplerDS,float4(texcoord,0,11)).x; + const float PL_A = tex2D(SamplerStored, float2(0.25,0.25)).x; + const float PL_B = tex2D(SamplerStored, float2(0.25,0.75)).x; + EA = Auto_Exposure >= 1 ? PL_A + (L - PL_A) * (1.0 - exp(-frametime/EA)) : L; + TT = Auto_Exposure >= 1 ? PL_B + (L - PL_B) * (1.0 - exp(-frametime/TT)) : L; + const float ITF= 1-(smoothstep(1,0,TT) < 0.85);// Is trigger Based on a Treshold... //smoothstep(1,0,tex2D(SamplerTA,0.0).y) < 0.85 + const float FT = 2500, PStoredfade = tex2D(SamplerStored, float2(0.75,0.25)).x;//Top Right + const float TF = PStoredfade + (ITF - PStoredfade) * (1.0 - exp2(-frametime/FT)); //Fade Time + //float3(EA,TT,TF) + //EA = 0;//Top Left float2(0.25,0.25).x + //TT = 0;//Bottom Left float2(0.25,0.75).y + //TF = 0;//Top Right float2(0.75,0.25).z + return texcoord.x > 0.5 ? (texcoord.y > 0.5 ? 0 : TF) : (texcoord.y > 0.5 ? TT : EA); +} +//----------------------------------Inverse ToneMappers-------------------------------------------- +float max3(float x, float y, float z) +{ + return max(x, max(y, z)); +} + +float3 inv_Tonemapper(float4 color, int TM) +{ + if(TM == 1)//Timothy Lottes fast_reversible + return color.rgb * rcp((1.0 + max(color.w,0.001)) - max3(color.r, color.g, color.b)); + else if(TM == 2)//Reinhard + return color.rgb * rcp(max((1.0 + color.w) - color.rgb,0.001)); + else//Luma Reinhard + return color.rgb * rcp(max((1.0 + lerp(-0.5,0,color.w) ) - Luma(color.rgb),0.001)); +} +//---------------------------------------ToneMappers----------------------------------------------- +// General tonemapping operator, build 'b' term. +float ColToneB(float hdrMax, float contrast, float shoulder, float midIn, float midOut) +{ + return + -((-pow(midIn, contrast) + (midOut*(pow(hdrMax, contrast*shoulder)*pow(midIn, contrast) - + pow(hdrMax, contrast)*pow(midIn, contrast*shoulder)*midOut)) / + (pow(hdrMax, contrast*shoulder)*midOut - pow(midIn, contrast*shoulder)*midOut)) / + (pow(midIn, contrast*shoulder)*midOut)); +} + +// General tonemapping operator, build 'c' term. +float ColToneC(float hdrMax, float contrast, float shoulder, float midIn, float midOut) +{ + return (pow(hdrMax, contrast*shoulder)*pow(midIn, contrast) - pow(hdrMax, contrast)*pow(midIn, contrast*shoulder)*midOut) / + (pow(hdrMax, contrast*shoulder)*midOut - pow(midIn, contrast*shoulder)*midOut); +} + +// General tonemapping operator, p := {contrast,shoulder,b,c}. +float ColTone(float x, float4 p) +{ + const float z = pow(x, p.r); + return z / (pow(z, p.g)*p.b + p.a); +} + +float3 TimothyTonemapper(float3 color, float EX) +{ + const float hdrMax = HDR_Toggle ? 25.0 : 16.0; // How much HDR range before clipping. HDR modes likely need this pushed up to say 25.0. + const float contrast = Contrast + 0.250; // Use as a baseline to tune the amount of contrast the tonemapper has. + static const float shoulder = 1.0; // Likely don't need to mess with this factor, unless matching existing tonemapper is not working well.. + static const float midIn = 0.11; // most games will have a {0.0 to 1.0} range for LDR so midIn should be 0.18.But,I settled around 0.11 + const float midOut = HDR_Toggle ? 0.18/25.0 : 0.18; // Use for LDR. For HDR10 10:10:10:2 use maybe 0.18/25.0 to start. For scRGB, I forget what a good starting point is, need to re-calculate. + + const float b = ColToneB(hdrMax, contrast, shoulder, midIn, midOut); + const float c = ColToneC(hdrMax, contrast, shoulder, midIn, midOut); + //Tone map all the things. But, first start with exposure. + color *= EX; + + #define EPS 1e-6f + float peak = max(color.r, max(color.g, color.b)); + peak = max(EPS, peak); + + float3 ratio = color / peak; + peak = ColTone(peak, float4(contrast, shoulder, b, c) ); + // then process ratio + + // probably want send these pre-computed (so send over saturation/crossSaturation as a constant) + const float crosstalk = 4.0; // controls amount of channel crosstalk + const float saturation = contrast * Saturate; // full tonal range saturation control + const float crossSaturation = contrast*16.0; // crosstalk saturation + + float white = WP; + + // wrap crosstalk in transform + ratio = pow(abs(ratio), saturation / crossSaturation); + ratio = lerp(ratio, white, pow(peak, crosstalk)); + ratio = pow(abs(ratio), crossSaturation); + + // then apply ratio to peak + color = peak * ratio; + return color; +} + +// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT +static const float3x3 ACESInputMat = +float3x3( float3(0.59719, 0.35458, 0.04823), + float3(0.07600, 0.90834, 0.01566), + float3(0.02840, 0.13383, 0.83777)); + +// ODT_SAT => XYZ => D60_2_D65 => sRGB +static const float3x3 ACESOutputMat = +float3x3( float3( 1.60475, -0.53108, -0.07367), + float3(-0.10208, 1.10813, -0.00605), + float3(-0.00327, -0.07276, 1.07602)); + +float3 RRTAndODTFit(float3 v) +{ + const float3 a = v * (v + 0.0245786f) - 0.000090537f; + const float3 b = v * (0.983729f * v + 0.4329510f) + 0.238081f; + return a / b; +} + +float3 ACESFitted( float3 color, float EX) +{ + color *= EX + 0.5; //Was told this need to be pre adjusted exposure. + color = mul(ACESInputMat,color); + color = RRTAndODTFit(color); + color = mul(ACESOutputMat,color); + + return color/WP; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float4 SimpleBlur(sampler2D InputTex, float2 Coord, float2 pixelsize) +{ + float4 Blur = 0.0; + + static const float2 Offsets[4]= + { + float2(1.0, 1.0), + float2(1.0, -1.0), + float2(-1.0, 1.0), + float2(-1.0, -1.0) + }; + + for (int i = 0; i < 4; i++) + { + Blur += tex2D(InputTex, Coord + Offsets[i] * pixelsize); } - else + + return Blur * 0.25; +} + +struct BloomData +{ + float4 Blur; + float2 Pixelsize; + float2 Coord; + float Offset; + float Weight; + float WeightSum; +}; + +float2 GetPixelSize(float texsize) +{ + return pix * texsize;//(1 / texsize) * float2(1, BUFFER_WIDTH / BUFFER_HEIGHT); +} + +float3 Auto_Luma() +{ + return float3(saturate(smoothstep(0,1,1-tex2D(SamplerTA,float2(0.25,0.25)).x)), //Top Left float2(0.25,0.25).x + tex2D(SamplerTA,float2(0.25,0.25)).x, //Top Left float2(0.25,0.25).x + saturate(smoothstep(0,1,tex2D(SamplerTA,float2(0.75,0.25)).x))); //Top Right float2(0.75,0.25).z +} + +float3 Color_GS(float4 BC) +{ // Luma Threshold Thank you Adyss + float GS = Luma(BC.rgb), Saturate_A = Sat, Saturate_B = saturate(Saturation.y), AL = Auto_Luma().x;//Luma and more + // Gamma Curve + BC.rgb = pow(abs(BC.rgb), BloomSensitivity); + BC.rgb /= max(GS, 0.001); + BC.a = max(0.0, GS - CBT_Adjust); + BC.rgb *= BC.a; + //Bloom Saturation + if(Auto_Bloom == 2 || Auto_Bloom == 4) //Desaturate + Saturate_A *= lerp(0.0 + Saturate_B,1,AL); + + if(Auto_Bloom == 3 || Auto_Bloom == 5) //Saturate + Saturate_A *= lerp(2.0 - Saturate_B,1,AL); + + BC.rgb = lerp(BC.a, BC.rgb, min(10,Saturate_A)); + + return saturate(BC.rgb); +} + +void PS_CurrentInfo(float4 pos : SV_Position, float2 texcoords : TEXCOORD, out float4 Color : SV_Target0) +{ //float2 D = Depth_Info(texcoords); + Color = float4(Color_GS(tex2D(BackBuffer, texcoords)), 0); +} +//Bloom Fuction from Adyss Bloom Wanted a version of your code to live on Miss you man. +float4 Bloom(float2 Coord, float texsize, sampler2D InputTex, int Dir) +{ + BloomData Bloom; + Bloom.Pixelsize = GetPixelSize(texsize); + Bloom.Offset = Bloom_Spread * 0.5 ; + + for (int i = 1; i < BloomSamples; i++) { - tex_offset *= 0.5; - result += tex2D(SamplerBC,texcoords + float2( 1, 0) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2(-1, 0) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2( 0, 1) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2( 0,-1) * tex_offset ); - tex_offset *= 0.75; - result += tex2D(SamplerBC,texcoords + float2( 1, 1) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2(-1,-1) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2( 1,-1) * tex_offset ); - result += tex2D(SamplerBC,texcoords + float2(-1, 1) * tex_offset ); - } - - return result / 9; + float2 D = Dir ? float2(Bloom.Offset * Bloom.Pixelsize.x, 0) : float2( 0, Bloom.Offset * Bloom.Pixelsize.y); + Bloom.Weight = pow(abs(BloomSamples - i), BloomCurve); + Bloom.Blur += tex2Dlod(InputTex, float4(Coord + D ,0,0)) * Bloom.Weight; + Bloom.Blur += tex2Dlod(InputTex, float4(Coord - D ,0,0)) * Bloom.Weight; + Bloom.Offset += Bloom_Spread ; + Bloom.WeightSum += Bloom.Weight; + } + + return Bloom.Blur /= Bloom.WeightSum * 2; +} + +float4 PS_BloomH_A(float4 pos : SV_Position, float2 Coord : TEXCOORD) : SV_Target +{ //Prepass + return Bloom(Coord, 2, SamplerCurrBB, 1); +} + +float4 PS_BloomV_A(float4 pos : SV_Position, float2 Coord : TEXCOORD) : SV_Target +{ + return Bloom(Coord, 2, TextureBloomH_A, 0); } -float3 LastBlur(float2 texcoord : TEXCOORD0) +float4 PS_BloomH_B(float4 pos : SV_Position, float2 Coord : TEXCOORD) : SV_Target { - float2 tex_offset = (Spread * 0.25f) * pix; // Gets texel offset - float3 result = tex2Dlod(SamplerBlur, float4(texcoord, 0,MipLevelAdjust)).rgb; - result += tex2Dlod(SamplerBlur, float4(texcoord + float2( 1, 0) * tex_offset, 0, MipLevelAdjust)).rgb; - result += tex2Dlod(SamplerBlur, float4(texcoord + float2(-1, 0) * tex_offset, 0, MipLevelAdjust)).rgb; - result += tex2Dlod(SamplerBlur, float4(texcoord + float2( 0, 1) * tex_offset, 0, MipLevelAdjust)).rgb; - result += tex2Dlod(SamplerBlur, float4(texcoord + float2( 0,-1) * tex_offset, 0, MipLevelAdjust)).rgb; - tex_offset *= 0.75; - result += tex2Dlod(SamplerBlur, float4(texcoord + float2( 1, 1) * tex_offset, 0, MipLevelAdjust)).rgb; - result += tex2Dlod(SamplerBlur, float4(texcoord + float2(-1,-1) * tex_offset, 0, MipLevelAdjust)).rgb; - result += tex2Dlod(SamplerBlur, float4(texcoord + float2( 1,-1) * tex_offset, 0, MipLevelAdjust)).rgb; - result += tex2Dlod(SamplerBlur, float4(texcoord + float2(-1, 1) * tex_offset, 0, MipLevelAdjust)).rgb; - return result / 9; + return Bloom(Coord, 8, TextureBloomV_A, 1); } -void Past_BackSingleBuffer(float4 position : SV_Position, float2 texcoords : TEXCOORD, out float4 PastSingle : SV_Target) -{ - PastSingle = float4(LastBlur(texcoords),Average_Luminance(texcoords).x); +float4 PS_BloomV_B(float4 pos : SV_Position, float2 Coord : TEXCOORD) : SV_Target +{ + return Bloom(Coord, 8, TextureBloomH_B, 0); } -float4 Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +float4 PS_BloomH_C(float4 pos : SV_Position, float2 Coord : TEXCOORD) : SV_Target +{ + return Bloom(Coord, 16, TextureBloomV_B, 1); +} + +float4 PS_BloomV_C(float4 pos : SV_Position, float2 Coord : TEXCOORD) : SV_Target { - float AL = Average_Luminance(texcoord).x, Ex = Exposure; + return Bloom(Coord, 16, TextureBloomH_C, 0); +} + +float4 Final_Bloom(float4 pos : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + const float3 LP = tex2D(BackBuffer, texcoords).rgb; + float4 Bloom = SimpleBlur(TextureBloomH_A, texcoords, GetPixelSize(2)).rgba; + Bloom += SimpleBlur(TextureBloomV_A, texcoords, GetPixelSize(2)).rgba; + Bloom += SimpleBlur(TextureBloomH_B, texcoords, GetPixelSize(4)).rgba; + Bloom += SimpleBlur(TextureBloomV_B, texcoords, GetPixelSize(4)).rgba; + Bloom += SimpleBlur(TextureBloomH_C, texcoords, GetPixelSize(8)).rgba; + Bloom += SimpleBlur(TextureBloomV_C, texcoords, GetPixelSize(8)).rgba; + Bloom *= lerp(0,10,Bloom_Intensity.x) / 6; // Luma Preserving Blending Not used........ + return float4(lerp(Bloom.rgb, max(Bloom.rgb - LP, 0.0), 0),0); +} - if(Auto_Exposure) - Ex = Ex * AL; +float3 Green_Blue( float interpolant ) +{ + if( interpolant < 0.5 ) + return float3(0.0, 1.0, 2.0 * interpolant); + else + return float3(0.0, 2.0 - 2.0 * interpolant, 1.0 ); +} - float4 Out; - float3 TM, Color = tex2D(BackBuffer, texcoord).rgb, HDR = tex2D(BackBuffer, texcoord).rgb; - float3 bloomColor = LastBlur(texcoord) + tex2D(PSBackBuffer, texcoord).rgb; // Merge Current and past frame. - //Tone Mapping done here. - TM = 1.0 - exp(-bloomColor * Ex ); - //HDR - HDR += TM; - Color = pow(abs(HDR),HDR_Adjust); +float3 Red_Green( float interpolant ) +{ + if( interpolant < 0.5 ) + return float3(1.0, 2.0 * interpolant, 0.0); + else + return float3(2.0 - 2.0 * interpolant, 1.0, 0.0 ); +} - if (!Debug_View) +float3 FHeat( float interpolant ) +{ + const float invertedInterpolant = interpolant; + if( invertedInterpolant < 0.5 ) + { + const float remappedFirstHalf = 1.0 - 2.0 * invertedInterpolant; + return Green_Blue( remappedFirstHalf ); + } + else + { + const float remappedSecondHalf = 2.0 - 2.0 * invertedInterpolant; + return Red_Green( remappedSecondHalf ); + } +} + +float3 HeatMap( float interpolant ) +{ + if( interpolant < 1.0 / 6.0 ) + { + const float firstSegmentInterpolant = 6.0 * interpolant; + return ( 1.0 - firstSegmentInterpolant ) * float3(0.0, 0.0, 0.0) + firstSegmentInterpolant * float3(0.0, 0.0, 1.0); + } + else if( interpolant < 5.0 / 6.0 ) { - Out = float4(Color, 1.0); + const float midInterpolant = 0.25 * ( 6.0 * interpolant - 1.0 ); + return FHeat( midInterpolant ); } else - { - Out = float4(bloomColor, 1.0); + { + const float lastSegmentInterpolant = 6.0 * interpolant - 5.0; + return ( 1.0 - lastSegmentInterpolant ) * float3(1.0, 0.0, 0.0) + lastSegmentInterpolant * float3(1.0, 1.0, 1.0); } +} -#if GSHADE_DITHER - return float4(Out.rgb + TriDither(Out.rgb, texcoord, BUFFER_COLOR_BIT_DEPTH), Out.a); -#else - return Out; -#endif +float Scale(float val,float max,float min) //Scale to 0 - 1 +{ + return (val - min) / (max - min); +} + +void GN(inout float Noise,float2 TC,float seed) +{ + Noise = frac(tan(distance(TC*((seed+10)+PHI), float2(PHI, PI)))*SQ2); +} + +float4 HDROut(float2 texcoords) +{ float4 Out, Bloom = SimpleBlur(TextureBloom, texcoords, GetPixelSize(1)).rgba; + const float2 TC = 10 * texcoords.xy - 5; + float AL = Auto_Luma().y, Ex; + + if(Auto_Exposure >= 1) + Ex = Exp; + else + Ex = lerp(0,2.5,Scale(Exp, 4, -4)); + + float NC = Bloom_Intensity.y;//BI_Brightness = lerp(1,0.01,Bloom_Intensity.y) + + if(Auto_Bloom == 1 || Auto_Bloom == 4 || Auto_Bloom == 5) + NC *= max(0.25,Auto_Luma().x); + + float3 Noise, iFast, iReinhard, iReinhardLuma, Color = tex2D(BackBuffer, texcoords).rgb; + // Goldern Noise RGB Dither + GN( Noise.r, TC, 1 ); + GN( Noise.g, TC, 2 ); + GN( Noise.b, TC, 3 ); + float3 SS = smoothstep( 0.0, 0.1, Bloom.rgb ); + SS *= lerp(0.0,0.1,saturate(Dither_Bloom)); + Bloom.rgb = saturate( Bloom.rgb + Noise * SS ); + + //Bloom should be applied before Tonemapping as otherwise all high ranges will be lost. Also can used as "resolve." But, I allow for both. + Bloom.rgb = lerp( 0.0, Bloom.rgb, saturate(NC)); + //Bloom_B = lerp( 0.0, (( Bloom.rgb - 0 ) / ( BI_Brightness - 0)), saturate(NC)); + //Bloom.rgb = lerp(Bloom_A,Bloom_B,Bloom.w); + + if(Tonemappers >= 1) + Color = lerp(Luma(Color),Color,Saturate); + // Do inital de-gamma of the game image to ensure we're operating in the correct colour range. + if( Gamma > 1. ) + Color = pow(abs(Color),Gamma); + //Bloom Befor Inverse ToneMapper + if(!Bloom_BA_iToneMapper) + Color += Bloom.rgb; + //Evil bad Negitive colors be gone by the wind of dev.... + Color = max(0,Color); + //HDR Map + if(Inv_Tonemappers == 1) + Color = inv_Tonemapper(float4(Color,1-HDR_BP), 0); + else if(Inv_Tonemappers == 2) + Color = inv_Tonemapper(float4(Color,1-HDR_BP), 2); + else if(Inv_Tonemappers == 3) + Color = inv_Tonemapper(float4(Color,1-HDR_BP), 1); + //Bloom After Inverse ToneMapper + if (Bloom_BA_iToneMapper) + Color += Bloom.rgb; + //Tone map all the things + if(Auto_Exposure >= 1) + Ex = CalcExposedColor(AL,Ex,GreyValue); + else //Using the optimized tonemapper by Jim Hejl and Richard Burgess-Dawson 0.148 for the GreyValue works for me. https://imgflip.com/i/oos2z But, I will alow for this to be adjusted. + Ex = Ex; + + if(Tonemappers == 0) + Color = TimothyTonemapper(Color,Ex); + else if (Tonemappers == 1) + Color = ACESFitted(Color,Ex); + //removed for now because of bug. + #if Flare_A + //Color += tex2D(SamplerFlare, texcoords).rgb; + #endif + + #if Flare_B + //Color += tex2D(SamplerLensFlare, texcoords).rgb; + #endif + + #if HDR_Toggle + // Do ST2084 curve + Color = ApplyPQ(Color); + #else + // Do the post-tonemapping gamma correction + if( Gamma > 1. ) + Color = pow(abs(Color),rcp(2.2)); + #endif + + //float2 D = Depth_Info(texcoords); + float MD = 0; + if(Tonemappers >= 1) + Color = (Color - 0.5) * (Contrast) + 0.5; + + if (Debug_View == 0) + Out = float4(Color, 1.); + else if(Debug_View == 1) + Out = Bloom; + else if(Debug_View == 2) + Out = texcoords.y < 0.975 ? HeatMap(Luma( Color )): HeatMap(texcoords.x); + //else + //Out = lerp(D.y,float3(D.y,0.5,D.y),MD) ; + //May need to dither....... + texcoords.x = texcoords.x * 0.75 + 0.125;//* 0.5 + 0.25; + texcoords *= 1.0 - float2(texcoords.x,texcoords.y); + float vignette = texcoords.x * texcoords.y * 15.0, Mfactor = pow(smoothstep(0,1,vignette), Auto_Luma().y * 2.0); + if(Auto_Exposure > 1) + vignette = lerp(1,lerp(0,1,saturate(Mfactor)),Auto_Luma().z); + else + vignette = 1; + + return float4(Out.rgb * vignette,1.0); +} + +float PS_StoreInfo(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + return tex2D(SamplerTA,texcoord).x; +} + +////////////////////////////////////////////////////////Logo///////////////////////////////////////////////////////////////////////// +float4 Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + const float PosX = 0.9525f*BUFFER_WIDTH*pix.x,PosY = 0.975f*BUFFER_HEIGHT*pix.y; + const float3 Color = HDROut(texcoord).rgb; + return float4(Color,1.0); } ///////////////////////////////////////////////////////////ReShade.fxh///////////////////////////////////////////////////////////// @@ -329,47 +904,87 @@ float4 Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Targe // Vertex shader generating a triangle covering the entire screen void PostProcessVS(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD) { - if (id == 2) - texcoord.x = 2.0; - else - texcoord.x = 0.0; - if (id == 1) - texcoord.y = 2.0; - else - texcoord.y = 0.0; + texcoord.x = (id == 2) ? 2.0 : 0.0; + texcoord.y = (id == 1) ? 2.0 : 0.0; position = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); } //*Rendering passes*// technique Blooming_HDR -{ - pass Bright_Filter +{ + pass Store_Info + { + VertexShader = PostProcessVS; + PixelShader = PS_StoreInfo; + RenderTarget = texStored; + } + pass Current_Info + { + VertexShader = PostProcessVS; + PixelShader = PS_CurrentInfo; + RenderTarget0 = texCurrColor; + } + pass BloomH_A { - VertexShader = PostProcessVS; - PixelShader = BrightColors; - RenderTarget = texBC; + VertexShader = PostProcessVS; + PixelShader = PS_BloomH_A; + RenderTarget = BloomTexH_A; } - pass Blur_Filter + pass BloomV_A { - VertexShader = PostProcessVS; - PixelShader = Blur; - RenderTarget = texBlur; + VertexShader = PostProcessVS; + PixelShader = PS_BloomV_A; + RenderTarget = BloomTexV_A; + } + pass BloomV_B + { + VertexShader = PostProcessVS; + PixelShader = PS_BloomH_B; + RenderTarget = BloomTexH_B; + } + pass BloomV_B + { + VertexShader = PostProcessVS; + PixelShader = PS_BloomV_B; + RenderTarget = BloomTexV_B; + } + pass BloomV_C + { + VertexShader = PostProcessVS; + PixelShader = PS_BloomH_C; + RenderTarget = BloomTexH_C; + } + pass BloomV_C + { + VertexShader = PostProcessVS; + PixelShader = PS_BloomV_C; + RenderTarget = BloomTexV_C; + } + pass Bloom + { + VertexShader = PostProcessVS; + PixelShader = Final_Bloom; + RenderTarget = BloomTex; } - pass Avg_Lum + pass Downsampler { VertexShader = PostProcessVS; - PixelShader = Luminance; - RenderTarget = texLumAvg; + PixelShader = Downsample; + RenderTarget = texDS; + } + pass Temporal_Adaptation + { + VertexShader = PostProcessVS; + PixelShader = PS_Temporal_Adaptation; + RenderTarget = texTA; } pass HDROut { VertexShader = PostProcessVS; - PixelShader = Out; - } - pass PSB - { - VertexShader = PostProcessVS; - PixelShader = Past_BackSingleBuffer; - RenderTarget = PastSingle_BackBuffer; + PixelShader = Out; + #if SRGB + SRGBWriteEnable = true; + #endif } + }