diff --git a/data_from_portwine/Reshade/ReShade.ini b/data_from_portwine/Reshade/ReShade.ini new file mode 100644 index 00000000..f09544b0 --- /dev/null +++ b/data_from_portwine/Reshade/ReShade.ini @@ -0,0 +1,88 @@ +[DEPTH] +DepthCopyAtClearIndex=0 +DepthCopyBeforeClears=0 +UseAspectRatioHeuristics=1 + +[GENERAL] +EffectSearchPaths=Z:\home\barry\.local\share\reshade\ReShade_shaders\Merged\Shaders +IntermediateCachePath=C:\users\steamuser\Temp +NoDebugInfo=1 +NoEffectCache=0 +NoReloadOnInit=0 +NoReloadOnInitForNonVR=0 +PerformanceMode=0 +PreprocessorDefinitions= +PresetPath=.\.\ReShadePreset.ini +PresetShortcutKeys= +PresetShortcutPaths= +PresetTransitionDelay=1000 +PresetTransitionDuration=1000 +SkipLoadingDisabledEffects=0 +StartupPresetPath= +TextureSearchPaths=Z:\home\barry\.local\share\reshade\ReShade_shaders\Merged\Textures + +[INPUT] +ForceShortcutModifiers=1 +InputProcessing=2 +KeyEffects=0,0,0,0 +KeyNextPreset=0,0,0,0 +KeyOverlay=36,0,0,0 +KeyPerformanceMode=0,0,0,0 +KeyPreviousPreset=0,0,0,0 +KeyReload=0,0,0,0 +KeyScreenshot=44,0,0,0 + +[OVERLAY] +AutoSavePreset=1 +ClockFormat=0 +Docking=[Docking][Data],DockSpace ID=0x7E010B79 Window=0x995B0CF8 Pos=8,,8 Size=1904,,1064 Split=X, DockNode ID=0x00000001 Parent=0x7E010B79 SizeRef=671,,1080 Selected=0xAF9E06C0, DockNode ID=0x00000002 Parent=0x7E010B79 SizeRef=1247,,1080 CentralNode=1 +FPSPosition=1 +NoFontScaling=1 +SaveWindowState=0 +ShowClock=0 +ShowForceLoadEffectsButton=1 +ShowFPS=0 +ShowFrameTime=0 +ShowPresetTransitionMessage=1 +ShowScreenshotMessage=1 +TutorialProgress=4 +VariableListHeight=300.000000 +VariableListUseTabs=0 +Window=[Window][Home],Pos=8,,8,Size=671,,1064,Collapsed=0,DockId=0x00000001,,0,[Window][Add-ons],Pos=8,,8,Size=671,,1064,Collapsed=0,DockId=0x00000001,,1,[Window][Settings],Pos=8,,8,Size=671,,1064,Collapsed=0,DockId=0x00000001,,2,[Window][Statistics],Pos=8,,8,Size=671,,1064,Collapsed=0,DockId=0x00000001,,3,[Window][Log],Pos=8,,8,Size=671,,1064,Collapsed=0,DockId=0x00000001,,4,[Window][About],Pos=8,,8,Size=671,,1064,Collapsed=0,DockId=0x00000001,,5,[Window][###editor],Collapsed=0,DockId=0x00000002,[Window][Viewport],Pos=0,,0,Size=1920,,1080,Collapsed=0,[Window][Debug##Default],Pos=60,,60,Size=400,,400,Collapsed=0 + +[SCREENSHOT] +ClearAlpha=1 +FileFormat=1 +FileNaming=%AppName% %Date% %Time% +FileNamingFormat=0 +JPEGQuality=90 +PostSaveCommand= +PostSaveCommandArguments="%TargetPath%" +PostSaveCommandNoWindow=0 +PostSaveCommandWorkingDirectory=.\ +SaveBeforeShot=0 +SaveOverlayShot=0 +SavePath= +SavePresetFile=0 +SoundPath= + +[STYLE] +Alpha=1.000000 +ChildRounding=0.000000 +ColFPSText=1.000000,1.000000,0.784314,1.000000 +EditorFont= +EditorFontSize=13 +EditorStyleIndex=0 +Font= +FontSize=13 +FPSScale=1.000000 +FrameRounding=0.000000 +GrabRounding=0.000000 +HdrOverlayBrightness=203.000000 +HdrOverlayOverwriteColorSpaceTo=0 +PopupRounding=0.000000 +ScrollbarRounding=0.000000 +StyleIndex=2 +TabRounding=4.000000 +WindowRounding=0.000000 + diff --git a/data_from_portwine/Reshade/ReShade32.dll b/data_from_portwine/Reshade/ReShade32.dll new file mode 100644 index 00000000..ece646e2 Binary files /dev/null and b/data_from_portwine/Reshade/ReShade32.dll differ diff --git a/data_from_portwine/Reshade/ReShade32.json b/data_from_portwine/Reshade/ReShade32.json new file mode 100644 index 00000000..b8e3f40e --- /dev/null +++ b/data_from_portwine/Reshade/ReShade32.json @@ -0,0 +1,21 @@ +{ + "file_format_version": "1.0.0", + "layer": { + "name": "VK_LAYER_reshade", + "type": "GLOBAL", + "library_path": ".\\ReShade32.dll", + "api_version": "1.3.204", + "implementation_version": "1", + "description": "crosire's ReShade post-processing injector for 32-bit", + "device_extensions": [ + { + "name": "VK_EXT_tooling_info", + "spec_version": "1", + "entrypoints": [ "vkGetPhysicalDeviceToolPropertiesEXT" ] + } + ], + "disable_environment": { + "DISABLE_VK_LAYER_reshade_1": "1" + } + } +} diff --git a/data_from_portwine/Reshade/ReShade64.dll b/data_from_portwine/Reshade/ReShade64.dll new file mode 100644 index 00000000..46b854e9 Binary files /dev/null and b/data_from_portwine/Reshade/ReShade64.dll differ diff --git a/data_from_portwine/Reshade/ReShade64.json b/data_from_portwine/Reshade/ReShade64.json new file mode 100644 index 00000000..da7241fc --- /dev/null +++ b/data_from_portwine/Reshade/ReShade64.json @@ -0,0 +1,21 @@ +{ + "file_format_version": "1.0.0", + "layer": { + "name": "VK_LAYER_reshade", + "type": "GLOBAL", + "library_path": ".\\ReShade64.dll", + "api_version": "1.3.204", + "implementation_version": "1", + "description": "crosire's ReShade post-processing injector for 64-bit", + "device_extensions": [ + { + "name": "VK_EXT_tooling_info", + "spec_version": "1", + "entrypoints": [ "vkGetPhysicalDeviceToolPropertiesEXT" ] + } + ], + "disable_environment": { + "DISABLE_VK_LAYER_reshade_1": "1" + } + } +} diff --git a/data_from_portwine/Reshade/Shaders/ASCII.fx b/data_from_portwine/Reshade/Shaders/ASCII.fx new file mode 100644 index 00000000..45877d1e --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/ASCII.fx @@ -0,0 +1,530 @@ +/*------------------. +| :: Description :: | +'-------------------/ + + Ascii (Version 0.9) + + Author: CeeJay.dk + License: MIT + + About: + Converts the image to ASCII characters using a greyscale algoritm, + cherrypicked characters and a custom bitmap font stored in a set of floats. + + It has 17 gray levels but uses dithering to greatly increase that number. + + Ideas for future improvement: + * Cleanup code + * Maybe find a better/faster pattern - possibly blur the pixels first with a 2 pass aproach + * Try using a font atlas for more fonts or perhaps more performance + * Try making an ordered dither rather than the random one. I think the random looks a bit too noisy. + * Calculate luma from linear colorspace + + History: + (*) Feature (+) Improvement (x) Bugfix (-) Information (!) Compatibility + + Version 0.7 by CeeJay.dk + * Added the 3x5 font + + Version 0.8 by CeeJay.dk + + Cleaned up settings UI for Reshade 3.x + + Version 0.9 by CeeJay.dk + x Fixed an issue with the settings where the 3x5 could not be selected. + - Cleaned up and commented the code. More cleanup is still needed. + * Added the ability to toggle dithering on/off + x Removed temporal dither code due to incompatibility with humans - it was giving me headaches and I didn't want to cause anyones seizure + x Fixed an uneven distribution of the greyscale shades +*/ + + +/*---------------. +| :: Includes :: | +'---------------*/ + +#include "ReShade.fxh" + + +/*------------------. +| :: UI Settings :: | +'------------------*/ + +#include "ReShadeUI.fxh" + +/* +uniform float Version < + ui_label = "Version"; + ui_min = 0.8; + ui_max = 0.8; + ui_step = 1.0; + ui_category = "Author : CeeJay.dk\n\n" + "To increase the size of the characters on screen simply lower your resolution in-game\n\n" + "Try using this together with Nostagia. It also looks best if you first increase the contrast with Curves.\n\n"; +> = float(0.8); +*/ + +uniform int Ascii_spacing < __UNIFORM_SLIDER_INT1 + ui_min = 0; + ui_max = 5; + ui_label = "Character Spacing"; + ui_tooltip = "Determines the spacing between characters. I feel 1 to 3 looks best."; + ui_category = "Font style"; +> = 1; + +/* +uniform int Ascii_font < + ui_type = "drag"; + ui_min = 1; + ui_max = 2; + ui_label = "Font Size"; + ui_tooltip = "1 = 5x5 font, 2 = 3x5 font"; + ui_category = "Font style"; +> = 1; +*/ + +uniform int Ascii_font < + ui_type = "combo"; + ui_label = "Font Size"; + ui_tooltip = "Choose font size"; + ui_category = "Font style"; + ui_items = + "Smaller 3x5 font\0" + "Normal 5x5 font\0" + ; +> = 1; + + +uniform int Ascii_font_color_mode < __UNIFORM_SLIDER_INT1 + ui_min = 0; + ui_max = 2; + ui_label = "Font Color Mode"; + ui_tooltip = "0 = Foreground color on background color, 1 = Colorized grayscale, 2 = Full color"; + ui_category = "Color options"; +> = 1; + +uniform float3 Ascii_font_color < __UNIFORM_COLOR_FLOAT3 + ui_label = "Font Color"; + ui_tooltip = "Choose a font color"; + ui_category = "Color options"; +> = float3(1.0, 1.0, 1.0); + +uniform float3 Ascii_background_color < __UNIFORM_COLOR_FLOAT3 + ui_label = "Background Color"; + ui_tooltip = "Choose a background color"; + ui_category = "Color options"; +> = float3(0.0, 0.0, 0.0); + +uniform bool Ascii_swap_colors < + ui_label = "Swap Colors"; + ui_tooltip = "Swaps the font and background color when you are too lazy to edit the settings above (I know I am)"; + ui_category = "Color options"; +> = 0; + +uniform bool Ascii_invert_brightness < + ui_label = "Invert Brightness"; + ui_category = "Color options"; +> = 0; + +uniform bool Ascii_dithering < + ui_label = "Dithering"; + ui_category = "Dithering"; +> = 1; + +uniform float Ascii_dithering_intensity < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; + ui_max = 4.0; + ui_label = "Dither shift intensity"; + ui_tooltip = "For debugging purposes"; + ui_category = "Debugging"; +> = 2.0; + +uniform bool Ascii_dithering_debug_gradient < + ui_label = "Dither debug gradient"; + ui_category = "Debugging"; +> = 0; + +/*-------------------------. +| :: Sampler and timers :: | +'-------------------------*/ + +#define asciiSampler ReShade::BackBuffer + +uniform float timer < source = "timer"; >; +uniform float framecount < source = "framecount"; >; + +/*-------------. +| :: Effect :: | +'-------------*/ + +float3 AsciiPass( float2 tex ) +{ + +/*-------------------------. +| :: Sample and average :: | +'-------------------------*/ + +//if (Ascii_font != 1) +float2 Ascii_font_size = float2(3.0,5.0); //3x5 +float num_of_chars = 14. ; + +if (Ascii_font == 1) +{ + Ascii_font_size = float2(5.0,5.0); //5x5 + num_of_chars = 17.; +} + +float quant = 1.0/(num_of_chars-1.0); //value used for quantization + +float2 Ascii_block = Ascii_font_size + float(Ascii_spacing); +float2 cursor_position = trunc((BUFFER_SCREEN_SIZE / Ascii_block) * tex) * (Ascii_block / BUFFER_SCREEN_SIZE); + + +//TODO Cleanup - and maybe find a better/faster pattern - possibly blur the pixels first with a 2 pass aproach +//-- Pattern 2 - Sample ALL the pixels! -- +float3 color = tex2D(asciiSampler, cursor_position + float2( 1.5, 1.5) * BUFFER_PIXEL_SIZE).rgb; +color += tex2D(asciiSampler, cursor_position + float2( 1.5, 3.5) * BUFFER_PIXEL_SIZE).rgb; +color += tex2D(asciiSampler, cursor_position + float2( 1.5, 5.5) * BUFFER_PIXEL_SIZE).rgb; +//color += tex2D(asciiSampler, cursor_position + float2( 0.5, 6.5) * BUFFER_PIXEL_SIZE).rgb; +color += tex2D(asciiSampler, cursor_position + float2( 3.5, 1.5) * BUFFER_PIXEL_SIZE).rgb; +color += tex2D(asciiSampler, cursor_position + float2( 3.5, 3.5) * BUFFER_PIXEL_SIZE).rgb; +color += tex2D(asciiSampler, cursor_position + float2( 3.5, 5.5) * BUFFER_PIXEL_SIZE).rgb; +//color += tex2D(asciiSampler, cursor_position + float2( 2.5, 6.5) * BUFFER_PIXEL_SIZE).rgb; +color += tex2D(asciiSampler, cursor_position + float2( 5.5, 1.5) * BUFFER_PIXEL_SIZE).rgb; +color += tex2D(asciiSampler, cursor_position + float2( 5.5, 3.5) * BUFFER_PIXEL_SIZE).rgb; +color += tex2D(asciiSampler, cursor_position + float2( 5.5, 5.5) * BUFFER_PIXEL_SIZE).rgb; +//color += tex2D(asciiSampler, cursor_position + float2( 4.5, 6.5) * BUFFER_PIXEL_SIZE).rgb; +//color += tex2D(asciiSampler, cursor_position + float2( 6.5, 0.5) * BUFFER_PIXEL_SIZE).rgb; +//color += tex2D(asciiSampler, cursor_position + float2( 6.5, 2.5) * BUFFER_PIXEL_SIZE).rgb; +//color += tex2D(asciiSampler, cursor_position + float2( 6.5, 4.5) * BUFFER_PIXEL_SIZE).rgb; +//color += tex2D(asciiSampler, cursor_position + float2( 6.5, 6.5) * BUFFER_PIXEL_SIZE).rgb; + +color /= 9.0; + +/* +//-- Pattern 3 - Just one -- +float3 color = tex2D(asciiSampler, cursor_position + float2(4.0,4.0) * BUFFER_PIXEL_SIZE) .rgb; //this may be fast but it's not very temporally stable +*/ + +/*------------------------. +| :: Make it grayscale :: | +'------------------------*/ + +float luma = dot(color,float3(0.2126, 0.7152, 0.0722)); + +float gray = luma; + +if (Ascii_invert_brightness) + gray = 1.0 - gray; + + +/*----------------. +| :: Debugging :: | +'----------------*/ + +if (Ascii_dithering_debug_gradient) +{ + //gray = sqrt(dot(float2((cursor_position.x - 0.5)*1.778,cursor_position.y - 0.5),float2((cursor_position.x - 0.5)*1.778,cursor_position.y - 0.5))) * 1.1; + //gray = (cursor_position.x + cursor_position.y) * 0.5; //diagonal test gradient + //gray = smoothstep(0.0,1.0,gray); //increase contrast + gray = cursor_position.x; //horizontal test gradient + //gray = cursor_position.y; //vertical test gradient +} +/*-------------------. +| :: Get position :: | +'-------------------*/ + +float2 p = frac((BUFFER_SCREEN_SIZE / Ascii_block) * tex); //p is the position of the current pixel inside the character + +p = trunc(p * Ascii_block); +//p = trunc(p * Ascii_block - float2(1.5,1.5)) ; + +float x = (Ascii_font_size.x * p.y + p.x); //x is the number of the position in the bitfield + +/*----------------. +| :: Dithering :: | +'----------------*/ + +//TODO : Try make an ordered dither rather than the random dither. Random looks a bit too noisy for my taste. + +if (Ascii_dithering != 0) +{ +//Pseudo Random Number Generator +// -- PRNG 1 - Reference -- +float seed = dot(cursor_position, float2(12.9898,78.233)); //I could add more salt here if I wanted to +float sine = sin(seed); //cos also works well. Sincos too if you want 2D noise. +float noise = frac(sine * 43758.5453 + cursor_position.y); + +float dither_shift = (quant * Ascii_dithering_intensity); // Using noise to determine shift. + +float dither_shift_half = (dither_shift * 0.5); // The noise should vary between +- 0.5 +dither_shift = dither_shift * noise - dither_shift_half; // MAD + +//shift the color by dither_shift +gray += dither_shift; //apply dithering +} + +/*---------------------------. +| :: Convert to character :: | +'---------------------------*/ + +float n = 0; + +if (Ascii_font == 1) +{ + // -- 5x5 bitmap font by CeeJay.dk -- + // .:^"~cvo*wSO8Q0# + + //17 characters including space which is handled as a special case + + //The serial aproach to this would take 16 cycles, so I instead used an upside down binary tree to parallelize this to only 5 cycles + + float n12 = (gray < (2. * quant)) ? 4194304. : 131200. ; // . or : + float n34 = (gray < (4. * quant)) ? 324. : 330. ; // ^ or " + float n56 = (gray < (6. * quant)) ? 283712. : 12650880.; // ~ or c + float n78 = (gray < (8. * quant)) ? 4532768. : 13191552.; // v or o + float n910 = (gray < (10. * quant)) ? 10648704. : 11195936.; // * or w + float n1112 = (gray < (12. * quant)) ? 15218734. : 15255086.; // S or O + float n1314 = (gray < (14. * quant)) ? 15252014. : 32294446.; // 8 or Q + float n1516 = (gray < (16. * quant)) ? 15324974. : 11512810.; // 0 or # + + float n1234 = (gray < (3. * quant)) ? n12 : n34; + float n5678 = (gray < (7. * quant)) ? n56 : n78; + float n9101112 = (gray < (11. * quant)) ? n910 : n1112; + float n13141516 = (gray < (15. * quant)) ? n1314 : n1516; + + float n12345678 = (gray < (5. * quant)) ? n1234 : n5678; + float n910111213141516 = (gray < (13. * quant)) ? n9101112 : n13141516; + + n = (gray < (9. * quant)) ? n12345678 : n910111213141516; +} +else // Ascii_font == 0 , the 3x5 font +{ + // -- 3x5 bitmap font by CeeJay.dk -- + // .:;s*oSOXH0 + + //14 characters including space which is handled as a special case + + /* Font reference : + + //The plusses are "likes". I was rating how much I liked that character over other alternatives. + + 3 ^ 42. + 3 - 448. + 3 i (short) 9232. + 3 ; 5136. ++ + 4 " 45. + 4 i 9346. + 4 s 5200. ++ + 5 + 1488. + 5 * 2728. ++ + 6 c 25200. + 6 o 11088. ++ + 7 v 11112. + 7 S 14478. ++ + 8 O 11114. ++ + 9 F 5071. + 9 5 (rounded) 14543. + 9 X 23213. ++ + 10 A 23530. + 10 D 15211. + + 11 H 23533. + + 11 5 (square) 31183. + 11 2 (square) 29671. ++ + + 5 (rounded) 14543. + */ + + float n12 = (gray < (2. * quant)) ? 4096. : 1040. ; // . or : + float n34 = (gray < (4. * quant)) ? 5136. : 5200. ; // ; or s + float n56 = (gray < (6. * quant)) ? 2728. : 11088.; // * or o + float n78 = (gray < (8. * quant)) ? 14478. : 11114.; // S or O + float n910 = (gray < (10. * quant)) ? 23213. : 15211.; // X or D + float n1112 = (gray < (12. * quant)) ? 23533. : 31599.; // H or 0 + float n13 = 31727.; // 8 + + float n1234 = (gray < (3. * quant)) ? n12 : n34; + float n5678 = (gray < (7. * quant)) ? n56 : n78; + float n9101112 = (gray < (11. * quant)) ? n910 : n1112; + + float n12345678 = (gray < (5. * quant)) ? n1234 : n5678; + float n910111213 = (gray < (13. * quant)) ? n9101112 : n13; + + n = (gray < (9. * quant)) ? n12345678 : n910111213; +} + + +/*--------------------------------. +| :: Decode character bitfield :: | +'--------------------------------*/ + +float character = 0.0; + +//Test values +//n = -(exp2(24.)-1.0); //-(2^24-1) All bits set - a white 5x5 box + +float lit = (gray <= (1. * quant)) //If black then set all pixels to black (the space character) + ? 0.0 //That way I don't have to use a character bitfield for space + : 1.0 ; //I simply let it to decode to the second darkest "." and turn its pixels off + +float signbit = (n < 0.0) //is n negative? (I would like to test for negative 0 here too but can't) + ? lit + : 0.0 ; + +signbit = (x > 23.5) //is this the first pixel in the character? + ? signbit //if so set to the signbit (which may be on or off depending on if the number was negative) + : 0.0 ; //else make it black + +//Tenary Multiply exp2 +character = ( frac( abs( n*exp2(-x-1.0))) >= 0.5) ? lit : signbit; //If the bit for the right position is set, then light up the pixel + //UNLESS gray was dark enough, then keep the pixel dark to make a space + //If the bit for the right position was not set, then turn off the pixel + //UNLESS it's the first pixel in the character AND n is negative - if so light up the pixel. + //This way I can use all 24 bits in the mantissa as well as the signbit for characters. + +if (clamp(p.x, 0.0, Ascii_font_size.x - 1.0) != p.x || clamp(p.y, 0.0, Ascii_font_size.y - 1.0) != p.y) //Is this the space around the character? + character = 0.0; //If so make the pixel black. + + +/*---------------. +| :: Colorize :: | +'---------------*/ + +if (Ascii_swap_colors) +{ + if (Ascii_font_color_mode == 2) + { + color = (character) ? character * color : Ascii_font_color; + } + else if (Ascii_font_color_mode == 1) + { + color = (character) ? Ascii_background_color * gray : Ascii_font_color; + } + else // Ascii_font_color_mode == 0 + { + color = (character) ? Ascii_background_color : Ascii_font_color; + } +} +else +{ + if (Ascii_font_color_mode == 2) + { + color = (character) ? character * color : Ascii_background_color; + } + else if (Ascii_font_color_mode == 1) + { + color = (character) ? Ascii_font_color * gray : Ascii_background_color; + } + else // Ascii_font_color_mode == 0 + { + color = (character) ? Ascii_font_color : Ascii_background_color; + } +} + +/*-------------. +| :: Return :: | +'-------------*/ + +//color = gray; +return saturate(color); +} + + +float3 PS_Ascii(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float3 color = AsciiPass(texcoord); + return color.rgb; +} + + +technique ASCII +{ + pass ASCII + { + VertexShader=PostProcessVS; + PixelShader=PS_Ascii; + } +} + + +/* +.---------------------. +| :: Character set :: | +'---------------------' + +Here are some various chacters and gradients I created in my quest to get the best look + +.'~:;!>+=icjtJY56SXDQKHNWM +.':!+ijY6XbKHNM +.:%oO$8@#M +.:+j6bHM +.:coCO8@ +.:oO8@ +.:oO8 +:+# + +.:^"~cso*wSO8Q0# +.:^"~csoCwSO8Q0# +.:^"~c?o*wSO8Q0# + +n value // # of pixels // character +------------//----//------------------- +4194304. // 1 // . (bottom aligned) * +131200. // 2 // : (middle aligned) * +4198400. // 2 // : (bottom aligned) +132. // 2 // ' +2228352. // 3 // ; +4325504. // 3 // i (short) +14336. // 3 // - (small) +324. // 3 // ^ +4329476. // 4 // i (tall) +330. // 4 // " +31744. // 5 // - (larger) +283712. // 5 // ~ +10627072. // 5 // x +145536. // 5 // * or + (small and centered) +6325440. // 6 // c (narrow - left aligned) +12650880. // 6 // c (narrow - center aligned) +9738240. // 6 // n (left aligned) +6557772. // 7 // s (tall) +8679696. // 7 // f +4532768. // 7 // v (1st) +4539936. // 7 // v (2nd) +4207118. // 7 // ? +-17895696. // 7 // % +6557958. // 7 // 3 +6595776. // 8 // o (left aligned) +13191552. // 8 // o (right aligned) +14714304. // 8 // c (wide) +12806528. // 9 // e (right aligned) +332772. // 9 // * (top aligned) +10648704. // 9 // * (bottom aligned) +4357252. // 9 // + +-18157904. // 9 // X +11195936. // 10 // w +483548. // 10 // s (thick) +15218734. // 11 // S +31491134. // 11 // C +15238702. // 11 // C (rounded) +22730410. // 11 // M (more like a large m) +10648714. // 11 // * (larger) +4897444. // 11 // * (2nd larger) +14726438. // 11 // @ (also looks like a large e) +23385164. // 11 // & +15255086. // 12 // O +16267326. // 13 // S (slightly larger) +15252014. // 13 // 8 +15259182. // 13 // 0 (O with dot in the middle) +15517230. // 13 // Q (1st) +-18405232. // 13 // M +-11196080. // 13 // W +32294446. // 14 // Q (2nd) +15521326. // 14 // Q (3rd) +32298542. // 15 // Q (4th) +15324974. // 15 // 0 or Ø +16398526. // 15 // $ +11512810. // 16 // # +-33061950. // 17 // 5 or S (stylized) +-33193150. // 19 // $ (stylized) +-33150782. // 19 // 0 (stylized) + +*/ diff --git a/data_from_portwine/Reshade/Shaders/Blending.fxh b/data_from_portwine/Reshade/Shaders/Blending.fxh new file mode 100644 index 00000000..e881ced0 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Blending.fxh @@ -0,0 +1,589 @@ +/*------------------. +| :: Description :: | +'-------------------/ + + Blending Header (version 0.8) + + Blending Algorithm Sources: + https://www.khronos.org/registry/OpenGL/extensions/NV/NV_blend_equation_advanced.txt + + http://www.nathanm.com/photoshop-blending-math/ + (Alt) https://github.com/cplotts/WPFSLBlendModeFx/blob/master/PhotoshopMathFP.hlsl + + Header Authors: originalnicodr, prod80, uchu suzume, Marot Satil + + About: + Provides a variety of blending methods for you to use as you wish. Just include this header. + + History: + (*) Feature (+) Improvement (x) Bugfix (-) Information (!) Compatibility + + Version 0.1 by Marot Satil & uchu suzume + * Added and improved upon multiple blending modes thanks to the work of uchu suzume, prod80, and originalnicodr. + + Version 0.2 by uchu suzume & Marot Satil + * Added Addition, Subtract, Divide blending modes and improved code readability. + + Version 0.3 by uchu suzume & Marot Satil + * Sorted blending modes in a more logical fashion, grouping by type. + + Version 0.4 by uchu suzume + x Corrected Color Dodge blending behavior. + + Version 0.5 by Marot Satil & uchu suzume + * Added preprocessor macros for uniform variable combo UI element & lerp. + + Version 0.6 by Marot Satil & uchu suzume + * Added Divide (Alternative) and Divide (Photoshop) blending modes. + + Version 0.7 by prod80 + - Added original sources for blending algorithms. + x Corrected average luminosity values. + + Version 0.8 by Marot Satil + * Added a new funciton to output blended data. + + Moved all code into the BlendingH namespace, which is part of the ComHeaders common namespace meant to be used by other headers. + ! Removed old preprocessor macro blending output. + +.------------------. +| :: How To Use :: | +'------------------/ + + Blending two variables using this header in your own shaders is very straightforward. + Very basic example code using the "Darken" blending mode follows: + + // First, include the header. + #include "Blending.fxh" + + // You can use this preprocessor macro to generate an attractive and functional uniform int UI combo element containing the list of blending techniques: + // BLENDING_COMBO(variable_name, label, tooltip, category, category_closed, spacing, default_value) + BLENDING_COMBO(_BlendMode, "Blending Mode", "Select the blending mode applied to the layer.", "Blending Options", false, 0, 0) + + // Inside of your function you can call this function to apply the blending option specified by an int (variable) to your float3 (input) via + // a lerp between your float3 (input), float3 (output), and a float (blending) for the alpha channel. + // ComHeaders::Blending::Blend(int variable, float3 input, float3 output, float blending) + outColor.rgb = ComHeaders::Blending::Blend(_BlendMode, inColor, outColor, outColor.a); +*/ + + +// ------------------------------------- +// Preprocessor Macros +// ------------------------------------- + +#undef BLENDING_COMBO +#define BLENDING_COMBO(variable, name_label, description, group, grp_closed, space, default_value) \ +uniform int variable \ +< \ + ui_category = group; \ + ui_category_closed = grp_closed; \ + ui_items = \ + "Normal\0" \ +/* "Darken" */ \ + "Darken\0" \ + " Multiply\0" \ + " Color Burn\0" \ + " Linear Burn\0" \ +/* "Lighten" */ \ + "Lighten\0" \ + " Screen\0" \ + " Color Dodge\0" \ + " Linear Dodge\0" \ + " Addition\0" \ + " Glow\0" \ +/* "Contrast" */ \ + "Overlay\0" \ + " Soft Light\0" \ + " Hard Light\0" \ + " Vivid Light\0" \ + " Linear Light\0" \ + " Pin Light\0" \ + " Hard Mix\0" \ +/* "Inversion" */ \ + "Difference\0" \ + " Exclusion\0" \ +/* "Cancelation" */ \ + "Subtract\0" \ + " Divide\0" \ + " Divide (Alternative)\0" \ + " Divide (Photoshop)\0" \ + " Reflect\0" \ + " Grain Extract\0" \ + " Grain Merge\0" \ +/* "Component" */ \ + "Hue\0" \ + " Saturation\0" \ + " Color\0" \ + " Luminosity\0"; \ + ui_label = name_label; \ + ui_tooltip = description; \ + ui_type = "combo"; \ + ui_spacing = space; \ +> = default_value; + +namespace ComHeaders +{ + namespace Blending + { + +// ------------------------------------- +// Helper Functions +// ------------------------------------- + + float3 Aux(float3 a) + { + if (a.r <= 0.25 && a.g <= 0.25 && a.b <= 0.25) + return ((16.0 * a - 12.0) * a + 4) * a; + else + return sqrt(a); + } + + float Lum(float3 a) + { + return (0.33333 * a.r + 0.33334 * a.g + 0.33333 * a.b); + } + + float3 SetLum (float3 a, float b){ + const float c = b - Lum(a); + return float3(a.r + c, a.g + c, a.b + c); + } + + float min3 (float a, float b, float c) + { + return min(a, (min(b, c))); + } + + float max3 (float a, float b, float c) + { + return max(a, max(b, c)); + } + + float3 SetSat(float3 a, float b){ + float ar = a.r; + float ag = a.g; + float ab = a.b; + if (ar == max3(ar, ag, ab) && ab == min3(ar, ag, ab)) + { + //caso r->max g->mid b->min + if (ar > ab) + { + ag = (((ag - ab) * b) / (ar - ab)); + ar = b; + } + else + { + ag = 0.0; + ar = 0.0; + } + ab = 0.0; + } + else + { + if (ar == max3(ar, ag, ab) && ag == min3(ar, ag, ab)) + { + //caso r->max b->mid g->min + if (ar > ag) + { + ab = (((ab - ag) * b) / (ar - ag)); + ar = b; + } + else + { + ab = 0.0; + ar = 0.0; + } + ag = 0.0; + } + else + { + if (ag == max3(ar, ag, ab) && ab == min3(ar, ag, ab)) + { + //caso g->max r->mid b->min + if (ag > ab) + { + ar = (((ar - ab) * b) / (ag - ab)); + ag = b; + } + else + { + ar = 0.0; + ag = 0.0; + } + ab = 0.0; + } + else + { + if (ag == max3(ar, ag, ab) && ar == min3(ar, ag, ab)) + { + //caso g->max b->mid r->min + if (ag > ar) + { + ab = (((ab - ar) * b) / (ag - ar)); + ag = b; + } + else + { + ab = 0.0; + ag = 0.0; + } + ar = 0.0; + } + else + { + if (ab == max3(ar, ag, ab) && ag == min3(ar, ag, ab)) + { + //caso b->max r->mid g->min + if (ab > ag) + { + ar = (((ar - ag) * b) / (ab - ag)); + ab = b; + } + else + { + ar = 0.0; + ab = 0.0; + } + ag = 0.0; + } + else + { + if (ab == max3(ar, ag, ab) && ar == min3(ar, ag, ab)) + { + //caso b->max g->mid r->min + if (ab > ar) + { + ag = (((ag - ar) * b) / (ab - ar)); + ab = b; + } + else + { + ag = 0.0; + ab = 0.0; + } + ar = 0.0; + } + } + } + } + } + } + return float3(ar, ag, ab); + } + + float Sat(float3 a) + { + return max3(a.r, a.g, a.b) - min3(a.r, a.g, a.b); + } + + +// ------------------------------------- +// Blending Modes +// ------------------------------------- + + // Darken + float3 Darken(float3 a, float3 b) + { + return min(a, b); + } + + // Multiply + float3 Multiply(float3 a, float3 b) + { + return a * b; + } + + // Color Burn + float3 ColorBurn(float3 a, float3 b) + { + if (b.r > 0 && b.g > 0 && b.b > 0) + return 1.0 - min(1.0, (0.5 - a) / b); + else + return 0.0; + } + + // Linear Burn + float3 LinearBurn(float3 a, float3 b) + { + return max(a + b - 1.0f, 0.0f); + } + + // Lighten + float3 Lighten(float3 a, float3 b) + { + return max(a, b); + } + + // Screen + float3 Screen(float3 a, float3 b) + { + return 1.0 - (1.0 - a) * (1.0 - b); + } + + // Color Dodge + float3 ColorDodge(float3 a, float3 b) + { + if (b.r < 1 && b.g < 1 && b.b < 1) + return min(1.0, a / (1.0 - b)); + else + return 1.0; + } + + // Linear Dodge + float3 LinearDodge(float3 a, float3 b) + { + return min(a + b, 1.0f); + } + + // Addition + float3 Addition(float3 a, float3 b) + { + return min((a + b), 1); + } + + // Reflect + float3 Reflect(float3 a, float3 b) + { + if (b.r >= 0.999999 || b.g >= 0.999999 || b.b >= 0.999999) + return b; + else + return saturate(a * a / (1.0f - b)); + } + + // Glow + float3 Glow(float3 a, float3 b) + { + return Reflect(b, a); + } + + // Overlay + float3 Overlay(float3 a, float3 b) + { + return lerp(2 * a * b, 1.0 - 2 * (1.0 - a) * (1.0 - b), step(0.5, a)); + } + + // Soft Light + float3 SoftLight(float3 a, float3 b) + { + if (b.r <= 0.5 && b.g <= 0.5 && b.b <= 0.5) + return clamp(a - (1.0 - 2 * b) * a * (1 - a), 0,1); + else + return clamp(a + (2 * b - 1.0) * (Aux(a) - a), 0, 1); + } + + // Hard Light + float3 HardLight(float3 a, float3 b) + { + return lerp(2 * a * b, 1.0 - 2 * (1.0 - b) * (1.0 - a), step(0.5, b)); + } + + // Vivid Light + float3 VividLight(float3 a, float3 b) + { + return lerp(2 * a * b, b / (2 * (1.01 - a)), step(0.50, a)); + } + + // Linear Light + float3 LinearLight(float3 a, float3 b) + { + if (b.r < 0.5 || b.g < 0.5 || b.b < 0.5) + return LinearBurn(a, (2.0 * b)); + else + return LinearDodge(a, (2.0 * (b - 0.5))); + } + + // Pin Light + float3 PinLight(float3 a, float3 b) + { + if (b.r < 0.5 || b.g < 0.5 || b.b < 0.5) + return Darken(a, (2.0 * b)); + else + return Lighten(a, (2.0 * (b - 0.5))); + } + + // Hard Mix + float3 HardMix(float3 a, float3 b) + { + const float3 vl = VividLight(a, b); + if (vl.r < 0.5 || vl.g < 0.5 || vl.b < 0.5) + return 0.0; + else + return 1.0; + } + + // Difference + float3 Difference(float3 a, float3 b) + { + return max(a - b, b - a); + } + + // Exclusion + float3 Exclusion(float3 a, float3 b) + { + return a + b - 2 * a * b; + } + + // Subtract + float3 Subtract(float3 a, float3 b) + { + return max((a - b), 0); + } + + // Divide + float3 Divide(float3 a, float3 b) + { + return (saturate(a / (b + 0.01))); + } + + // Divide (Alternative) + float3 DivideAlt(float3 a, float3 b) + { + return (saturate(1.0 / (a / b))); + } + + // Divide (Photoshop) + float3 DividePS(float3 a, float3 b) + { + return (saturate(a / b)); + } + + // Grain Merge + float3 GrainMerge(float3 a, float3 b) + { + return saturate(b + a - 0.5); + } + + // Grain Extract + float3 GrainExtract(float3 a, float3 b) + { + return saturate(a - b + 0.5); + } + + // Hue + float3 Hue(float3 a, float3 b) + { + return SetLum(SetSat(b, Sat(a)), Lum(a)); + } + + // Saturation + float3 Saturation(float3 a, float3 b) + { + return SetLum(SetSat(a, Sat(b)), Lum(a)); + } + + // Color + float3 ColorB(float3 a, float3 b) + { + return SetLum(b, Lum(a)); + } + + // Luminousity + float3 Luminosity(float3 a, float3 b) + { + return SetLum(a, Lum(b)); + } + + +// ------------------------------------- +// Output Functions +// ------------------------------------- + + float3 Blend(int mode, float3 input, float3 output, float blending) + { + switch (mode) + { + // Normal + default: + return lerp(input.rgb, output.rgb, blending); + // Darken + case 1: + return lerp(input.rgb, Darken(input.rgb, output.rgb), blending); + // Multiply + case 2: + return lerp(input.rgb, Multiply(input.rgb, output.rgb), blending); + // Color Burn + case 3: + return lerp(input.rgb, ColorBurn(input.rgb, output.rgb), blending); + // Linear Burn + case 4: + return lerp(input.rgb, LinearBurn(input.rgb, output.rgb), blending); + // Lighten + case 5: + return lerp(input.rgb, Lighten(input.rgb, output.rgb), blending); + // Screen + case 6: + return lerp(input.rgb, Screen(input.rgb, output.rgb), blending); + // Color Dodge + case 7: + return lerp(input.rgb, ColorDodge(input.rgb, output.rgb), blending); + // Linear Dodge + case 8: + return lerp(input.rgb, LinearDodge(input.rgb, output.rgb), blending); + // Addition + case 9: + return lerp(input.rgb, Addition(input.rgb, output.rgb), blending); + // Glow + case 10: + return lerp(input.rgb, Glow(input.rgb, output.rgb), blending); + // Overlay + case 11: + return lerp(input.rgb, Overlay(input.rgb, output.rgb), blending); + // Soft Light + case 12: + return lerp(input.rgb, SoftLight(input.rgb, output.rgb), blending); + // Hard Light + case 13: + return lerp(input.rgb, HardLight(input.rgb, output.rgb), blending); + // Vivid Light + case 14: + return lerp(input.rgb, VividLight(input.rgb, output.rgb), blending); + // Linear Light + case 15: + return lerp(input.rgb, LinearLight(input.rgb, output.rgb), blending); + // Pin Light + case 16: + return lerp(input.rgb, PinLight(input.rgb, output.rgb), blending); + // Hard Mix + case 17: + return lerp(input.rgb, HardMix(input.rgb, output.rgb), blending); + // Difference + case 18: + return lerp(input.rgb, Difference(input.rgb, output.rgb), blending); + // Exclusion + case 19: + return lerp(input.rgb, Exclusion(input.rgb, output.rgb), blending); + // Subtract + case 20: + return lerp(input.rgb, Subtract(input.rgb, output.rgb), blending); + // Divide + case 21: + return lerp(input.rgb, Divide(input.rgb, output.rgb), blending); + // Divide (Alternative) + case 22: + return lerp(input.rgb, DivideAlt(input.rgb, output.rgb), blending); + // Divide (Photoshop) + case 23: + return lerp(input.rgb, DividePS(input.rgb, output.rgb), blending); + // Reflect + case 24: + return lerp(input.rgb, Reflect(input.rgb, output.rgb), blending); + // Grain Merge + case 25: + return lerp(input.rgb, GrainMerge(input.rgb, output.rgb), blending); + // Grain Extract + case 26: + return lerp(input.rgb, GrainExtract(input.rgb, output.rgb), blending); + // Hue + case 27: + return lerp(input.rgb, Hue(input.rgb, output.rgb), blending); + // Saturation + case 28: + return lerp(input.rgb, Saturation(input.rgb, output.rgb), blending); + // Color + case 29: + return lerp(input.rgb, ColorB(input.rgb, output.rgb), blending); + // Luminosity + case 30: + return lerp(input.rgb, Luminosity(input.rgb, output.rgb), blending); + } + } + } +} diff --git a/data_from_portwine/Reshade/Shaders/BloomingHDR.fx b/data_from_portwine/Reshade/Shaders/BloomingHDR.fx new file mode 100644 index 00000000..3ee5a19d --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/BloomingHDR.fx @@ -0,0 +1,990 @@ + ////----------------// + ///**Blooming HDR**/// + //----------------//// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// *// +//*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" + "Default Number is 0.5."; + ui_category = "Bloom Adjustments"; +> = 0.5; + +uniform float2 Bloom_Intensity< + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 0.0; ui_max = 1.0; + 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"; + #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 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"; + #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 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 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 = "Tonemappers"; + ui_tooltip = "Changes how color get used for the other effects.\n"; + ui_items = "Timothy\0ACESFitted\0"; + ui_category = "Tonemapper Adjustments"; +> = 0; + +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"; +> = 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; + }; + +texture BackBufferTex : COLOR; + +sampler BackBuffer + { + Texture = BackBufferTex; + #if SRGB + SRGBTexture = true; + #endif + }; + +texture texCurrColor { Width = BUFFER_WIDTH * 0.5; Height = BUFFER_HEIGHT * 0.5; Format = RGBA8; MipLevels = 8;}; + +sampler SamplerCurrBB + { + Texture = texCurrColor; + }; + +//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 = TexFlareShared; + }; +#endif +#if Flare_B +texture TexLensFlareShared { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT; Format = RGBA16F;}; + +sampler SamplerLensFlare + { + Texture = TexLensFlareShared; + }; +#endif +//Total amount of frames since the game started. +uniform float frametime < source = "frametime";>; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +float Luma(float3 C) +{ + float3 Luma; + + if (HDR_Toggle == 0) + { + Luma = float3(0.2126, 0.7152, 0.0722); // (HD video) https://en.wikipedia.org/wiki/Luma_(video) + } + else + { + Luma = float3(0.2627, 0.6780, 0.0593); // (HDR video) https://en.wikipedia.org/wiki/Rec._2100 + } + + return dot(C,Luma); +} + +float3 ApplyPQ(float3 color) +{ + // Apply ST2084 curve + float m1 = 2610.0 / 4096.0 / 4; + float m2 = 2523.0 / 4096.0 * 128; + float c1 = 3424.0 / 4096.0; + float c2 = 2413.0 / 4096.0 * 32; + float c3 = 2392.0 / 4096.0 * 32; + 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/ + float linExp = GreyValue / avgLuminance; + exposure = log2( linExp ); + return exposure; + } + +float CalcExposedColor(in float avgLuminance, in float offset, in float GreyValue ) + { + float exposure = Log2Exposure( avgLuminance, GreyValue * 2.2 ); + exposure += offset; //offset = exposure + return exp2( exposure ); + } + +/////////////////////////////////////////////////////////////////////////////////Adapted Luminance///////////////////////////////////////////////////////////////////////////////// +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 = texDS; + }; + +texture texTA {Width = 64; Height = 64; Format = R16F; }; + +sampler SamplerTA + { + Texture = texTA; + }; + +texture texStored {Width = 64; Height = 64; Format = R16F; }; + +sampler SamplerStored + { + Texture = texStored; + }; + +float3 Downsample(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float2 texXY = texcoord; + float2 midHV = (Adapt_Seek-1) * float2(BUFFER_WIDTH * 0.5,BUFFER_HEIGHT * 0.5) * pix; + 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,EA = (1-Adapt_Adjust)*1250, L = tex2Dlod(SamplerDS,float4(texcoord,0,11)).x, PL_A = tex2D(SamplerStored, float2(0.25,0.25)).x, 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; + 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 + float FT = 2500, PStoredfade = tex2D(SamplerStored, float2(0.75,0.25)).x;//Top Right + 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) +{ + float z = pow(x, p.r); + return z / (pow(z, p.g)*p.b + p.a); +} + +float3 TimothyTonemapper(float3 color, float EX) +{ + 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. + float contrast = Contrast + 0.250; // Use as a baseline to tune the amount of contrast the tonemapper has. + static float shoulder = 1.0; // Likely don't need to mess with this factor, unless matching existing tonemapper is not working well.. + static 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 + 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. + + float b = ColToneB(hdrMax, contrast, shoulder, midIn, midOut); + 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) + float crosstalk = 4.0; // controls amount of channel crosstalk + float saturation = contrast * Saturate; // full tonal range saturation control + 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) +{ + float3 a = v * (v + 0.0245786f) - 0.000090537f; + 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); + } + + 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++) + { + 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); +} + +float4 PS_BloomH_B(float4 pos : SV_Position, float2 Coord : TEXCOORD) : SV_Target +{ + return Bloom(Coord, 8, TextureBloomV_A, 1); +} + +float4 PS_BloomV_B(float4 pos : SV_Position, float2 Coord : TEXCOORD) : SV_Target +{ + return Bloom(Coord, 8, TextureBloomH_B, 0); +} + +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 +{ + return Bloom(Coord, 16, TextureBloomH_C, 0); +} + +float4 Final_Bloom(float4 pos : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + 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); +} + +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 ); +} + +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 ); +} + +float3 FHeat( float interpolant ) +{ + float invertedInterpolant = interpolant; + if( invertedInterpolant < 0.5 ) + { + float remappedFirstHalf = 1.0 - 2.0 * invertedInterpolant; + return Green_Blue( remappedFirstHalf ); + } + else + { + float remappedSecondHalf = 2.0 - 2.0 * invertedInterpolant; + return Red_Green( remappedSecondHalf ); + } +} + +float3 HeatMap( float interpolant ) +{ + if( interpolant < 1.0 / 6.0 ) + { + 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 ) + { + float midInterpolant = 0.25 * ( 6.0 * interpolant - 1.0 ); + return FHeat( midInterpolant ); + } + else + { + 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); + } +} + +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; + 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 +{ + float PosX = 0.9525f*BUFFER_WIDTH*pix.x,PosY = 0.975f*BUFFER_HEIGHT*pix.y; + float3 Color = HDROut(texcoord).rgb; + return float4(Color,1.0); +} + +///////////////////////////////////////////////////////////ReShade.fxh///////////////////////////////////////////////////////////// + +// 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) +{ + 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 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 = PS_BloomH_A; + RenderTarget = BloomTexH_A; + } + pass BloomV_A + { + 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 Downsampler + { + VertexShader = PostProcessVS; + PixelShader = Downsample; + RenderTarget = texDS; + } + pass Temporal_Adaptation + { + VertexShader = PostProcessVS; + PixelShader = PS_Temporal_Adaptation; + RenderTarget = texTA; + } + pass HDROut + { + VertexShader = PostProcessVS; + PixelShader = Out; + #if SRGB + SRGBWriteEnable = true; + #endif + } + +} diff --git a/data_from_portwine/Reshade/Shaders/Border.fx b/data_from_portwine/Reshade/Shaders/Border.fx new file mode 100644 index 00000000..6e863c46 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Border.fx @@ -0,0 +1,73 @@ +/** + * Border version 1.4.1 + * + * -- Version 1.0 by Oomek -- + * Fixes light, one pixel thick border in some games when forcing MSAA like i.e. Dishonored + * -- Version 1.1 by CeeJay.dk -- + * Optimized the shader. It still does the same but now it runs faster. + * -- Version 1.2 by CeeJay.dk -- + * Added border_width and border_color features + * -- Version 1.3 by CeeJay.dk -- + * Optimized the performance further + * -- Version 1.4 by CeeJay.dk -- + * Added the border_ratio feature + * -- Version 1.4.1 by CeeJay.dk -- + * Cleaned up setting for Reshade 3.x + */ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +/* +uniform float2 border_width < + ui_type = "input"; + ui_label = "Size"; + ui_tooltip = "Measured in pixels. If this is set to zero then the ratio will be used instead."; +> = float2(0.0, 0.0); +*/ + +uniform float2 border_width < + ui_type = "drag"; + ui_label = "Size"; + ui_tooltip = "Measured in pixels. If this is set to zero then the ratio will be used instead."; + ui_min = 0.0; ui_max = (BUFFER_WIDTH * 0.5); + ui_step = 1.0; + > = float2(0.0, 0.0); + +uniform float border_ratio < + ui_type = "input"; + ui_label = "Size Ratio"; + ui_tooltip = "Set the desired ratio for the visible area."; +> = 2.35; + +uniform float3 border_color < + ui_type = "color"; + ui_label = "Border Color"; +> = float3(0.0, 0.0, 0.0); + +float3 BorderPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + + // -- calculate the right border_width for a given border_ratio -- + float2 border_width_variable = border_width; + if (border_width.x == -border_width.y) // If width is not used + if (BUFFER_ASPECT_RATIO < border_ratio) + border_width_variable = float2(0.0, (BUFFER_HEIGHT - (BUFFER_WIDTH / border_ratio)) * 0.5); + else + border_width_variable = float2((BUFFER_WIDTH - (BUFFER_HEIGHT * border_ratio)) * 0.5, 0.0); + + float2 border = (BUFFER_PIXEL_SIZE * border_width_variable); // Translate integer pixel width to floating point + float2 within_border = saturate((-texcoord * texcoord + texcoord) - (-border * border + border)); // Becomes positive when inside the border and zero when outside + + return all(within_border) ? color : border_color; +} + +technique Border +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = BorderPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/CAS.fx b/data_from_portwine/Reshade/Shaders/CAS.fx new file mode 100644 index 00000000..fcf7aeee --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/CAS.fx @@ -0,0 +1,178 @@ +// LICENSE +// ======= +// Copyright (c) 2017-2019 Advanced Micro Devices, Inc. All rights reserved. +// ------- +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// ------- +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +// Software. +// ------- +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE + +//Initial port to ReShade: SLSNe https://gist.github.com/SLSNe/bbaf2d77db0b2a2a0755df581b3cf00c + +//Optimizations by Marty McFly: +// vectorized math, even with scalar gcn hardware this should work +// out the same, order of operations has not changed +// For some reason, it went from 64 to 48 instructions, a lot of MOV gone +// Also modified the way the final window is calculated +// +// reordered min() and max() operations, from 11 down to 9 registers +// +// restructured final weighting, 49 -> 48 instructions +// +// delayed RCP to replace SQRT with RSQRT +// +// removed the saturate() from the control var as it is clamped +// by UI manager already, 48 -> 47 instructions +// +// replaced tex2D with tex2Doffset intrinsic (address offset by immediate integer) +// 47 -> 43 instructions +// 9 -> 8 registers + +//Further modified by OopyDoopy and Lord of Lunacy: +// Changed wording in the UI for the existing variable and added a new variable and relevant code to adjust sharpening strength. + +//Fix by Lord of Lunacy: +// Made the shader use a linear colorspace rather than sRGB, as recommended by the original AMD documentation from FidelityFX. + +//Modified by CeeJay.dk: +// Included a label and tooltip description. I followed AMDs official naming guidelines for FidelityFX. +// +// Used gather trick to reduce the number of texture operations by one (9 -> 8). It's now 42 -> 51 instructions but still faster +// because of the texture operation that was optimized away. + +//Fix by CeeJay.dk +// Fixed precision issues with the gather at super high resolutions +// Also tried to refactor the samples so more work can be done while they are being sampled, but it's not so easy and the gains +// I'm seeing are so small they might be statistical noise. So it MIGHT be faster - no promises. + +uniform float Contrast < + ui_type = "drag"; + ui_label = "Contrast Adaptation"; + ui_tooltip = "Adjusts the range the shader adapts to high contrast (0 is not all the way off). Higher values = more high contrast sharpening."; + ui_min = 0.0; ui_max = 1.0; +> = 0.0; + +uniform float Sharpening < + ui_type = "drag"; + ui_label = "Sharpening intensity"; + ui_tooltip = "Adjusts sharpening intensity by averaging the original pixels to the sharpened result. 1.0 is the unmodified default."; + ui_min = 0.0; ui_max = 1.0; +> = 1.0; + +#include "ReShade.fxh" +#define pixel float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) + +texture TexColor : COLOR; +sampler sTexColor {Texture = TexColor; SRGBTexture = true;}; + +float3 CASPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + // fetch a 3x3 neighborhood around the pixel 'e', + // a b c + // d(e)f + // g h i + + + float3 b = tex2Doffset(sTexColor, texcoord, int2(0, -1)).rgb; + float3 d = tex2Doffset(sTexColor, texcoord, int2(-1, 0)).rgb; + + +#if __RENDERER__ >= 0xa000 // If DX10 or higher + float4 red_efhi = tex2DgatherR(sTexColor, texcoord + 0.5 * pixel); + + float3 e = float3( red_efhi.w, red_efhi.w, red_efhi.w); + float3 f = float3( red_efhi.z, red_efhi.z, red_efhi.z); + float3 h = float3( red_efhi.x, red_efhi.x, red_efhi.x); + float3 i = float3( red_efhi.y, red_efhi.y, red_efhi.y); + + float4 green_efhi = tex2DgatherG(sTexColor, texcoord + 0.5 * pixel); + + e.g = green_efhi.w; + f.g = green_efhi.z; + h.g = green_efhi.x; + i.g = green_efhi.y; + + float4 blue_efhi = tex2DgatherB(sTexColor, texcoord + 0.5 * pixel); + + e.b = blue_efhi.w; + f.b = blue_efhi.z; + h.b = blue_efhi.x; + i.b = blue_efhi.y; + + +#else // If DX9 + float3 e = tex2D(sTexColor, texcoord).rgb; + float3 f = tex2Doffset(sTexColor, texcoord, int2(1, 0)).rgb; + + float3 h = tex2Doffset(sTexColor, texcoord, int2(0, 1)).rgb; + float3 i = tex2Doffset(sTexColor, texcoord, int2(1, 1)).rgb; + +#endif + + float3 g = tex2Doffset(sTexColor, texcoord, int2(-1, 1)).rgb; + float3 a = tex2Doffset(sTexColor, texcoord, int2(-1, -1)).rgb; + float3 c = tex2Doffset(sTexColor, texcoord, int2(1, -1)).rgb; + + + // Soft min and max. + // a b c b + // d e f * 0.5 + d e f * 0.5 + // g h i h + // These are 2.0x bigger (factored out the extra multiply). + float3 mnRGB = min(min(min(d, e), min(f, b)), h); + float3 mnRGB2 = min(mnRGB, min(min(a, c), min(g, i))); + mnRGB += mnRGB2; + + float3 mxRGB = max(max(max(d, e), max(f, b)), h); + float3 mxRGB2 = max(mxRGB, max(max(a, c), max(g, i))); + mxRGB += mxRGB2; + + // Smooth minimum distance to signal limit divided by smooth max. + float3 rcpMRGB = rcp(mxRGB); + float3 ampRGB = saturate(min(mnRGB, 2.0 - mxRGB) * rcpMRGB); + + // Shaping amount of sharpening. + ampRGB = rsqrt(ampRGB); + + float peak = -3.0 * Contrast + 8.0; + float3 wRGB = -rcp(ampRGB * peak); + + float3 rcpWeightRGB = rcp(4.0 * wRGB + 1.0); + + // 0 w 0 + // Filter shape: w 1 w + // 0 w 0 + float3 window = (b + d) + (f + h); + float3 outColor = saturate((window * wRGB + e) * rcpWeightRGB); + + return lerp(e, outColor, Sharpening); +} + +technique ContrastAdaptiveSharpen + < + ui_label = "AMD FidelityFX Contrast Adaptive Sharpening"; + ui_tooltip = + "CAS is a low overhead adaptive sharpening algorithm that AMD includes with their drivers.\n" + "This port to Reshade works with all cards from all vendors,\n" + "but cannot do the optional scaling that CAS is normally also capable of when activated in the AMD drivers.\n" + "\n" + "The algorithm adjusts the amount of sharpening per pixel to target an even level of sharpness across the image.\n" + "Areas of the input image that are already sharp are sharpened less, while areas that lack detail are sharpened more.\n" + "This allows for higher overall natural visual sharpness with fewer artifacts."; + > +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = CASPass; + SRGBWriteEnable = true; + } +} diff --git a/data_from_portwine/Reshade/Shaders/CRT.fx b/data_from_portwine/Reshade/Shaders/CRT.fx new file mode 100644 index 00000000..6c0930de --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/CRT.fx @@ -0,0 +1,312 @@ +// CRT shader +// +// Copyright (C) 2010-2012 cgwg, Themaister and DOLLS +// +// 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. + +// Comment the next line to disable interpolation in linear gamma (and gain speed). +//#define LINEAR_PROCESSING + +#include "ReShadeUI.fxh" + +uniform float Amount < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Amount of CRT effect you want"; +> = 1.00; +uniform float Resolution < __UNIFORM_SLIDER_FLOAT1 + ui_min = 1.0; ui_max = 8.0; + ui_tooltip = "Input size coefficient (low values gives the 'low - res retro look')."; +> = 1.15; +uniform float Gamma < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 4.0; + ui_tooltip = "Gamma of simulated CRT"; +> = 2.4; +uniform float MonitorGamma < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 4.0; + ui_tooltip = "Gamma of display monitor"; +> = 2.2; +uniform float Brightness < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 3.0; + ui_tooltip = "Used to boost brightness a little."; +> = 0.9; + +uniform int ScanlineIntensity < __UNIFORM_SLIDER_INT1 + ui_min = 2; ui_max = 4; + ui_label = "Scanline Intensity"; +> = 2; +uniform bool ScanlineGaussian < + ui_label = "Scanline Bloom Effect"; + ui_tooltip = "Use the new nongaussian scanlines bloom effect."; +> = true; + +uniform bool Curvature < + ui_tooltip = "Barrel effect"; +> = false; +uniform float CurvatureRadius < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 2.0; + ui_label = "Curvature Radius"; +> = 1.5; +uniform float CornerSize < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.00; ui_max = 0.02; ui_step = 0.001; + ui_label = "Corner Size"; + ui_tooltip = "Higher values => more rounded corner"; +> = 0.0100; +uniform float ViewerDistance < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 4.0; + ui_Label = "Viewer Distance"; + ui_tooltip = "Simulated distance from viewer to monitor"; +> = 2.00; +uniform float2 Angle < __UNIFORM_SLIDER_FLOAT2 + ui_min = -0.2; ui_max = 0.2; + ui_tooltip = "Tilt angle in radians"; +> = 0.00; + +uniform float Overscan < __UNIFORM_SLIDER_FLOAT1 + ui_min = 1.0; ui_max = 1.10; ui_step = 0.01; + ui_tooltip = "Overscan (e.g. 1.02 for 2% overscan)."; +> = 1.01; +uniform bool Oversample < + ui_tooltip = "Enable 3x oversampling of the beam profile (warning : performance hit)"; +> = true; + +#include "ReShade.fxh" + +#define CeeJay_aspect float2(1.0, 0.75) + +// A bunch of useful values we'll need in the fragment shader. +#define sinangle sin(Angle) +#define cosangle cos(Angle) +#define stretch maxscale() + +// Macros. +#define FIX(c) max(abs(c), 1e-5); + +#ifndef PI + #define PI 3.1415927 +#endif + +// The size of one texel, in texture-coordinates. +#define coone 1.0 / rubyTextureSize + +#define mod_factor tex.x * rubyTextureSize.x * rubyOutputSize.x / rubyInputSize.x + +#ifdef LINEAR_PROCESSING + #define TEX2D(c) pow(tex2D(ReShade::BackBuffer, (c)), Gamma) +#else + #define TEX2D(c) tex2D(ReShade::BackBuffer, (c)) +#endif + +float intersect(float2 xy) +{ + float A = dot(xy,xy) + (ViewerDistance * ViewerDistance); + float B = 2.0 * (CurvatureRadius * (dot(xy, sinangle) - ViewerDistance * cosangle.x * cosangle.y) - ViewerDistance * ViewerDistance); + float C = ViewerDistance * ViewerDistance + 2.0 * CurvatureRadius * ViewerDistance * cosangle.x * cosangle.y; //all constants + return (-B - sqrt(B * B -4.0 * A * C)) / (2.0 * A); +} + +float2 bkwtrans(float2 xy) +{ + float c = intersect(xy); + float2 _point = float2(c, c) * xy; + _point -= float2(-CurvatureRadius, -CurvatureRadius) * sinangle; + _point /= float2(CurvatureRadius, CurvatureRadius); + float2 tang = sinangle / cosangle; + float2 poc = _point / cosangle; + float A = dot(tang, tang) + 1.0; + float B = -2.0 * dot(poc, tang); + float C = dot(poc, poc) - 1.0; + float a = (-B + sqrt(B * B -4.0 * A * C)) / (2.0 * A); + float2 uv = (_point - a * sinangle) / cosangle; + float r = CurvatureRadius * acos(a); + return uv * r / sin(r / CurvatureRadius); +} +float2 fwtrans(float2 uv) +{ + float r = FIX(sqrt(dot(uv, uv))); + uv *= sin(r / CurvatureRadius) / r; + float x = 1.0 - cos(r / CurvatureRadius); + float D = ViewerDistance / CurvatureRadius + x * cosangle.x * cosangle.y + dot(uv, sinangle); + return ViewerDistance * (uv * cosangle - x * sinangle) / D; +} + +float3 maxscale() +{ + float2 c = bkwtrans(-CurvatureRadius * sinangle / (1.0 + CurvatureRadius / ViewerDistance * cosangle.x * cosangle.y)); + float2 a = float2(0.5, 0.5) * CeeJay_aspect; + float2 lo = float2(fwtrans(float2(-a.x, c.y)).x, fwtrans(float2(c.x,-a.y)).y) / CeeJay_aspect; + float2 hi = float2(fwtrans(float2(+a.x, c.y)).x, fwtrans(float2(c.x, +a.y)).y) / CeeJay_aspect; + return float3((hi + lo) * CeeJay_aspect * 0.5, max(hi.x - lo.x, hi.y - lo.y)); +} + +float2 transform(float2 coord, float2 textureSize, float2 inputSize) +{ + coord *= textureSize / inputSize; + coord = (coord - 0.5) * CeeJay_aspect * stretch.z + stretch.xy; + return (bkwtrans(coord) / float2(Overscan, Overscan) / CeeJay_aspect + 0.5) * inputSize / textureSize; +} + +float corner(float2 coord, float2 textureSize, float2 inputSize) +{ + coord *= textureSize / inputSize; + coord = (coord - 0.5) * float2(Overscan, Overscan) + 0.5; + coord = min(coord, 1.0 - coord) * CeeJay_aspect; + float2 cdist = float2(CornerSize, CornerSize); + coord = (cdist - min(coord, cdist)); + float dist = sqrt(dot(coord, coord)); + return clamp((cdist.x-dist) * 1000.0, 0.0, 1.0); +} + +// Calculate the influence of a scanline on the current pixel. +// +// 'distance' is the distance in texture coordinates from the current +// pixel to the scanline in question. +// 'color' is the colour of the scanline at the horizontal location of +// the current pixel. +float4 scanlineWeights(float distance, float4 color) +{ + // "wid" controls the width of the scanline beam, for each RGB channel + // The "weights" lines basically specify the formula that gives + // you the profile of the beam, i.e. the intensity as + // a function of distance from the vertical center of the + // scanline. In this case, it is gaussian if width=2, and + // becomes nongaussian for larger widths. Ideally this should + // be normalized so that the integral across the beam is + // independent of its width. That is, for a narrower beam + // "weights" should have a higher peak at the center of the + // scanline than for a wider beam. + if (!ScanlineGaussian) + { + float4 wid = 0.3 + 0.1 * pow(abs(color), 3.0); + float4 weights = float4(distance / wid); + return 0.4 * exp(-weights * weights) / wid; + } + else + { + float4 wid = 2.0 * pow(abs(color), 4.0) + 2.0; + float4 weights = (distance / 0.3).xxxx; + return 1.4 * exp(-pow(abs(weights * rsqrt(0.5 * wid)), abs(wid))) / (0.2 * wid + 0.6); + } +} + +float3 AdvancedCRTPass(float4 position : SV_Position, float2 tex : TEXCOORD) : SV_Target +{ + // Here's a helpful diagram to keep in mind while trying to + // understand the code: + // + // | | | | | + // ------------------------------- + // | | | | | + // | 01 | 11 | 21 | 31 | <-- current scanline + // | | @ | | | + // ------------------------------- + // | | | | | + // | 02 | 12 | 22 | 32 | <-- next scanline + // | | | | | + // ------------------------------- + // | | | | | + // + // Each character-cell represents a pixel on the output + // surface, "@" represents the current pixel (always somewhere + // in the bottom half of the current scan-line, or the top-half + // of the next scanline). The grid of lines represents the + // edges of the texels of the underlying texture. + + float Input_ratio = ceil(256 * Resolution); + float2 Resolution = float2(Input_ratio, Input_ratio); + float2 rubyTextureSize = Resolution; + float2 rubyInputSize = Resolution; + float2 rubyOutputSize = BUFFER_SCREEN_SIZE; + + float2 orig_xy = Curvature ? transform(tex, rubyTextureSize, rubyInputSize) : tex; + float cval = corner(orig_xy, rubyTextureSize, rubyInputSize); + + // Of all the pixels that are mapped onto the texel we are + // currently rendering, which pixel are we currently rendering? + float2 ratio_scale = orig_xy * rubyTextureSize - 0.5; + + float filter = fwidth(ratio_scale.y); + float2 uv_ratio = frac(ratio_scale); + + // Snap to the center of the underlying texel. + float2 xy = (floor(ratio_scale) + 0.5) / rubyTextureSize; + + // Calculate Lanczos scaling coefficients describing the effect + // of various neighbour texels in a scanline on the current + // pixel. + float4 coeffs = PI * float4(1.0 + uv_ratio.x, uv_ratio.x, 1.0 - uv_ratio.x, 2.0 - uv_ratio.x); + + // Prevent division by zero. + coeffs = FIX(coeffs); + + // Lanczos2 kernel. + coeffs = 2.0 * sin(coeffs) * sin(coeffs / 2.0) / (coeffs * coeffs); + + // Normalize. + coeffs /= dot(coeffs, 1.0); + + // Calculate the effective colour of the current and next + // scanlines at the horizontal location of the current pixel, + // using the Lanczos coefficients above. + float4 col = clamp(mul(coeffs, float4x4( + TEX2D(xy + float2(-coone.x, 0.0)), + TEX2D(xy), + TEX2D(xy + float2(coone.x, 0.0)), + TEX2D(xy + float2(2.0 * coone.x, 0.0)))), + 0.0, 1.0); + float4 col2 = clamp(mul(coeffs, float4x4( + TEX2D(xy + float2(-coone.x, coone.y)), + TEX2D(xy + float2(0.0, coone.y)), + TEX2D(xy + coone), + TEX2D(xy + float2(2.0 * coone.x, coone.y)))), + 0.0, 1.0); + +#ifndef LINEAR_PROCESSING + col = pow(abs(col) , Gamma); + col2 = pow(abs(col2), Gamma); +#endif + + // Calculate the influence of the current and next scanlines on + // the current pixel. + float4 weights = scanlineWeights(uv_ratio.y, col); + float4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2); + +#if __RENDERER__ < 0xa000 && !__RESHADE_PERFORMANCE_MODE__ + [flatten] +#endif + if (Oversample) + { + uv_ratio.y = uv_ratio.y + 1.0 / 3.0 * filter; + weights = (weights + scanlineWeights(uv_ratio.y, col)) / 3.0; + weights2 = (weights2 + scanlineWeights(abs(1.0 - uv_ratio.y), col2)) / 3.0; + uv_ratio.y = uv_ratio.y - 2.0 / 3.0 * filter; + weights = weights + scanlineWeights(abs(uv_ratio.y), col) / 3.0; + weights2 = weights2 + scanlineWeights(abs(1.0 - uv_ratio.y), col2) / 3.0; + } + + float3 mul_res = (col * weights + col2 * weights2).rgb * cval.xxx; + + // dot-mask emulation: + // Output pixels are alternately tinted green and magenta. + float3 dotMaskWeights = lerp(float3(1.0, 0.7, 1.0), float3(0.7, 1.0, 0.7), floor(mod_factor % ScanlineIntensity)); + mul_res *= dotMaskWeights * float3(0.83, 0.83, 1.0) * Brightness; + + // Convert the image gamma for display on our output device. + mul_res = pow(abs(mul_res), 1.0 / MonitorGamma); + + float3 color = TEX2D(orig_xy).rgb * cval.xxx; + color = lerp(color, mul_res, Amount); + + return saturate(color); +} + +technique AdvancedCRT +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = AdvancedCRTPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Cartoon.fx b/data_from_portwine/Reshade/Shaders/Cartoon.fx new file mode 100644 index 00000000..25acc4c7 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Cartoon.fx @@ -0,0 +1,42 @@ +/** + * Cartoon + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + */ + +#include "ReShadeUI.fxh" + +uniform float Power < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.1; ui_max = 10.0; + ui_tooltip = "Amount of effect you want."; +> = 1.5; +uniform float EdgeSlope < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.1; ui_max = 6.0; + ui_label = "Edge Slope"; + ui_tooltip = "Raise this to filter out fainter edges. You might need to increase the power to compensate. Whole numbers are faster."; +> = 1.5; + +#include "ReShade.fxh" + +float3 CartoonPass(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + const float3 coefLuma = float3(0.2126, 0.7152, 0.0722); + + float diff1 = dot(coefLuma, tex2D(ReShade::BackBuffer, texcoord + BUFFER_PIXEL_SIZE).rgb); + diff1 = dot(float4(coefLuma, -1.0), float4(tex2D(ReShade::BackBuffer, texcoord - BUFFER_PIXEL_SIZE).rgb , diff1)); + float diff2 = dot(coefLuma, tex2D(ReShade::BackBuffer, texcoord + BUFFER_PIXEL_SIZE * float2(1, -1)).rgb); + diff2 = dot(float4(coefLuma, -1.0), float4(tex2D(ReShade::BackBuffer, texcoord + BUFFER_PIXEL_SIZE * float2(-1, 1)).rgb , diff2)); + + float edge = dot(float2(diff1, diff2), float2(diff1, diff2)); + + return saturate(pow(abs(edge), EdgeSlope) * -Power + color); +} + +technique Cartoon +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = CartoonPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/ChromaticAberration.fx b/data_from_portwine/Reshade/Shaders/ChromaticAberration.fx new file mode 100644 index 00000000..ecd1d73c --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/ChromaticAberration.fx @@ -0,0 +1,39 @@ +/** + * Chromatic Aberration + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + * + * Distorts the image by shifting each color component, which creates color artifacts similar to those in a very cheap lens or a cheap sensor. + */ + +#include "ReShadeUI.fxh" + +uniform float2 Shift < __UNIFORM_SLIDER_FLOAT2 + ui_min = -10; ui_max = 10; + ui_tooltip = "Distance (X,Y) in pixels to shift the color components. For a slightly blurred look try fractional values (.5) between two pixels."; +> = float2(2.5, -0.5); +uniform float Strength < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; +> = 0.5; + +#include "ReShade.fxh" + +float3 ChromaticAberrationPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color, colorInput = tex2D(ReShade::BackBuffer, texcoord).rgb; + // Sample the color components + color.r = tex2D(ReShade::BackBuffer, texcoord + (BUFFER_PIXEL_SIZE * Shift)).r; + color.g = colorInput.g; + color.b = tex2D(ReShade::BackBuffer, texcoord - (BUFFER_PIXEL_SIZE * Shift)).b; + + // Adjust the strength of the effect + return lerp(colorInput, color, Strength); +} + +technique CA +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = ChromaticAberrationPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Clarity.fx b/data_from_portwine/Reshade/Shaders/Clarity.fx new file mode 100644 index 00000000..e61ebd5d --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Clarity.fx @@ -0,0 +1,553 @@ + +//Clarity by Ioxa +//Version 1.5 for ReShade 3.0 + +//>Clarity Settings<\\ + +//#include "ReShadeUI.fxh" Removed when porting over to Astray.fx Repo. +//Notes: + +//The goal here is port and store this shader since the main repo is going away. +//I am taking over a few shaders I feel should be saved and don't have textures. +//The rest of the shaders will be moved to a other repo. That Ceejay.dk tells me. +//Any changes done to the shaders for now will be for compatablity. Other then that, +//I don't see any licenceing so I am worried about this since here is no due diligence. +//Anyways I think it should be fine and thank you Ioxa for a shader staple in ReShade. +//Also to anyone else if you see issues in the shader please report them to the AtrayFX repo. +//Thank you. + +uniform int ClarityRadius +< ui_type = "slider"; + ui_min = 0; ui_max = 4; + ui_tooltip = "[0|1|2|3|4] Higher values will increase the radius of the effect."; + ui_step = 1.00; +> = 3; + +uniform float ClarityOffset +< ui_type = "slider"; + ui_min = 1.00; ui_max = 5.00; + ui_tooltip = "Additional adjustment for the blur radius. Increasing the value will increase the radius."; + ui_step = 1.00; +> = 2.00; + +uniform int ClarityBlendMode +< + ui_type = "combo"; + ui_items = "\Soft Light\0Overlay\0Hard Light\0Multiply\0Vivid Light\0Linear Light\0Addition"; + ui_tooltip = "Blend modes determine how the clarity mask is applied to the original image"; +> = 2; + +uniform int ClarityBlendIfDark +< ui_type = "slider"; + ui_min = 0; ui_max = 255; + ui_tooltip = "Any pixels below this value will be excluded from the effect. Set to 50 to target mid-tones."; + ui_step = 5; +> = 50; + +uniform int ClarityBlendIfLight +< ui_type = "slider"; + ui_min = 0; ui_max = 255; + ui_tooltip = "Any pixels above this value will be excluded from the effect. Set to 205 to target mid-tones."; + ui_step = 5; +> = 205; + +uniform bool ClarityViewBlendIfMask +< + ui_tooltip = "The mask used for BlendIf settings. The effect will not be applied to areas covered in black"; +> = false; + +uniform float ClarityStrength +< ui_type = "slider"; + ui_min = 0.00; ui_max = 1.00; + ui_tooltip = "Adjusts the strength of the effect"; +> = 0.400; + +uniform float ClarityDarkIntensity +< ui_type = "slider"; + ui_min = 0.00; ui_max = 1.00; + ui_tooltip = "Adjusts the strength of dark halos."; +> = 0.400; + +uniform float ClarityLightIntensity +< ui_type = "slider"; + ui_min = 0.00; ui_max = 1.00; + ui_tooltip = "Adjusts the strength of light halos."; +> = 0.000; + +uniform bool ClarityViewMask +< + ui_tooltip = "The mask is what creates the effect. View it when making adjustments to get a better idea of how your changes will affect the image."; +> = false; + +//#include "ReShade.fxh" //Devorced from this header file. +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +texture BackBufferTex : COLOR; +sampler BackBuffer { Texture = BackBufferTex; }; +texture ClarityTex < pooled = true; > { Width = BUFFER_WIDTH * 0.5; Height = BUFFER_HEIGHT * 0.5; Format = R8; }; +texture ClarityTex2 { Width = BUFFER_WIDTH * 0.5; Height = BUFFER_HEIGHT * 0.5; Format = R8; }; +texture ClarityTex3 < pooled = true; > { Width = BUFFER_WIDTH * 0.25; Height = BUFFER_HEIGHT * 0.25; Format = R8; }; + +sampler ClaritySampler { Texture = ClarityTex;}; +sampler ClaritySampler2 { Texture = ClarityTex2;}; +sampler ClaritySampler3 { Texture = ClarityTex3;}; + +float3 ClarityFinal(in float4 pos : SV_Position, in float2 texcoord : TEXCOORD) : COLOR +{ + + float color = tex2Dlod(ClaritySampler3, float4(texcoord,0,1)).r; + +if(ClarityRadius == 0) +{ + float offset[4] = { 0.0, 1.1824255238, 3.0293122308, 5.0040701377 }; + float weight[4] = { 0.39894, 0.2959599993, 0.0045656525, 0.00000149278686458842 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 4; ++i) + { + color += tex2Dlod(ClaritySampler3, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + color += tex2Dlod(ClaritySampler3, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + } +} + +if(ClarityRadius == 1) +{ + float offset[6] = { 0.0, 1.4584295168, 3.40398480678, 5.3518057801, 7.302940716, 9.2581597095 }; + float weight[6] = { 0.13298, 0.23227575, 0.1353261595, 0.0511557427, 0.01253922, 0.0019913644 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 6; ++i) + { + color += tex2Dlod(ClaritySampler3, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + color += tex2Dlod(ClaritySampler3, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + } +} + +if(ClarityRadius == 2) +{ + float offset[11] = { 0.0, 1.4895848401, 3.4757135714, 5.4618796741, 7.4481042327, 9.4344079746, 11.420811147, 13.4073334, 15.3939936778, 17.3808101174, 19.3677999584 }; + float weight[11] = { 0.06649, 0.1284697563, 0.111918249, 0.0873132676, 0.0610011113, 0.0381655709, 0.0213835661, 0.0107290241, 0.0048206869, 0.0019396469, 0.0006988718 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 11; ++i) + { + color += tex2Dlod(ClaritySampler3, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + color += tex2Dlod(ClaritySampler3, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + } +} + +if(ClarityRadius == 3) +{ + float offset[15] = { 0.0, 1.4953705027, 3.4891992113, 5.4830312105, 7.4768683759, 9.4707125766, 11.4645656736, 13.4584295168, 15.4523059431, 17.4461967743, 19.4401038149, 21.43402885, 23.4279736431, 25.4219399344, 27.4159294386 }; + float weight[15] = { 0.0443266667, 0.0872994708, 0.0820892038, 0.0734818355, 0.0626171681, 0.0507956191, 0.0392263968, 0.0288369812, 0.0201808877, 0.0134446557, 0.0085266392, 0.0051478359, 0.0029586248, 0.0016187257, 0.0008430913 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 15; ++i) + { + color += tex2Dlod(ClaritySampler3, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + color += tex2Dlod(ClaritySampler3, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + } +} + +if(ClarityRadius == 4) +{ + float offset[18] = { 0.0, 1.4953705027, 3.4891992113, 5.4830312105, 7.4768683759, 9.4707125766, 11.4645656736, 13.4584295168, 15.4523059431, 17.4461967743, 19.4661974725, 21.4627427973, 23.4592916956, 25.455844494, 27.4524015179, 29.4489630909, 31.445529535, 33.4421011704 }; + float weight[18] = { 0.033245, 0.0659162217, 0.0636705814, 0.0598194658, 0.0546642566, 0.0485871646, 0.0420045997, 0.0353207015, 0.0288880982, 0.0229808311, 0.0177815511, 0.013382297, 0.0097960001, 0.0069746748, 0.0048301008, 0.0032534598, 0.0021315311, 0.0013582974 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 18; ++i) + { + color += tex2Dlod(ClaritySampler3, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + color += tex2Dlod(ClaritySampler3, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r * weight[i]; + } +} + + float3 orig = tex2Dlod(BackBuffer, float4(texcoord,0,0)).rgb; //Original Image + float luma = dot(orig.rgb,float3(0.32786885,0.655737705,0.0163934436)); + float3 chroma = orig.rgb/luma; + + float sharp = 1-color; + sharp = (luma+sharp)*0.5; + + float sharpMin = lerp(0.0,1.0,smoothstep(0.0,1.0,sharp)); + float sharpMax = sharpMin; + sharpMin = lerp(sharp,sharpMin,ClarityDarkIntensity); + sharpMax = lerp(sharp,sharpMax,ClarityLightIntensity); + sharp = lerp(sharpMin,sharpMax,step(0.5,sharp)); + + if(ClarityViewMask) + { + orig.rgb = sharp; + luma = sharp; + chroma = 1.0; + } + else + { + if(ClarityBlendMode == 0) + { + //softlight + sharp = lerp(2*luma*sharp + luma*luma*(1.0-2*sharp), 2*luma*(1.0-sharp)+pow(luma,0.5)*(2*sharp-1.0), step(0.49,sharp)); + } + + if(ClarityBlendMode == 1) + { + //overlay + sharp = lerp(2*luma*sharp, 1.0 - 2*(1.0-luma)*(1.0-sharp), step(0.50,luma)); + } + + if(ClarityBlendMode == 2) + { + //Hardlight + sharp = lerp(2*luma*sharp, 1.0 - 2*(1.0-luma)*(1.0-sharp), step(0.50,sharp)); + } + + if(ClarityBlendMode == 3) + { + //Multiply + sharp = saturate(2 * luma * sharp); + } + + if(ClarityBlendMode == 4) + { + //vivid light + sharp = lerp(2*luma*sharp, luma/(2*(1-sharp)), step(0.5,sharp)); + } + + if(ClarityBlendMode == 5) + { + //Linear Light + sharp = luma + 2.0*sharp-1.0; + } + + if(ClarityBlendMode == 6) + { + //Addition + sharp = saturate(luma + (sharp - 0.5)); + } + } + + if( ClarityBlendIfDark > 0 || ClarityBlendIfLight < 255 || ClarityViewBlendIfMask) + { + float ClarityBlendIfD = (ClarityBlendIfDark/255.0)+0.0001; + float ClarityBlendIfL = (ClarityBlendIfLight/255.0)-0.0001; + float mix = dot(orig.rgb, 0.333333); + float mask = 1.0; + + if(ClarityBlendIfDark > 0) + { + mask = lerp(0.0,1.0,smoothstep(ClarityBlendIfD-(ClarityBlendIfD*0.2),ClarityBlendIfD+(ClarityBlendIfD*0.2),mix)); + } + + if(ClarityBlendIfLight < 255) + { + mask = lerp(mask,0.0,smoothstep(ClarityBlendIfL-(ClarityBlendIfL*0.2),ClarityBlendIfL+(ClarityBlendIfL*0.2),mix)); + } + + sharp = lerp(luma,sharp,mask); + + if (ClarityViewBlendIfMask) + { + sharp = mask; + luma = mask; + chroma = 1.0; + } + } + + orig.rgb = lerp(luma, sharp, ClarityStrength); + orig.rgb *= chroma; + + return saturate(orig); +} + +float Clarity1(in float4 pos : SV_Position, in float2 texcoord : TEXCOORD) : COLOR +{ + float3 color = tex2Dlod(BackBuffer, float4(texcoord,0,0)).rgb; + +if(ClarityRadius == 0) +{ + float offset[4] = { 0.0, 1.1824255238, 3.0293122308, 5.0040701377 }; + float weight[4] = { 0.39894, 0.2959599993, 0.0045656525, 0.00000149278686458842 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 4; ++i) + { + color += tex2Dlod(BackBuffer, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + color += tex2Dlod(BackBuffer, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + } +} + +if(ClarityRadius == 1) +{ + float offset[6] = { 0.0, 1.4584295168, 3.40398480678, 5.3518057801, 7.302940716, 9.2581597095 }; + float weight[6] = { 0.13298, 0.23227575, 0.1353261595, 0.0511557427, 0.01253922, 0.0019913644 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 6; ++i) + { + color += tex2Dlod(BackBuffer, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + color += tex2Dlod(BackBuffer, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + } +} + +if(ClarityRadius == 2) +{ + float offset[11] = { 0.0, 1.4895848401, 3.4757135714, 5.4618796741, 7.4481042327, 9.4344079746, 11.420811147, 13.4073334, 15.3939936778, 17.3808101174, 19.3677999584 }; + float weight[11] = { 0.06649, 0.1284697563, 0.111918249, 0.0873132676, 0.0610011113, 0.0381655709, 0.0213835661, 0.0107290241, 0.0048206869, 0.0019396469, 0.0006988718 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 11; ++i) + { + color += tex2Dlod(BackBuffer, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + color += tex2Dlod(BackBuffer, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + } +} + +if(ClarityRadius == 3) +{ + float offset[15] = { 0.0, 1.4953705027, 3.4891992113, 5.4830312105, 7.4768683759, 9.4707125766, 11.4645656736, 13.4584295168, 15.4523059431, 17.4461967743, 19.4401038149, 21.43402885, 23.4279736431, 25.4219399344, 27.4159294386 }; + float weight[15] = { 0.0443266667, 0.0872994708, 0.0820892038, 0.0734818355, 0.0626171681, 0.0507956191, 0.0392263968, 0.0288369812, 0.0201808877, 0.0134446557, 0.0085266392, 0.0051478359, 0.0029586248, 0.0016187257, 0.0008430913 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 15; ++i) + { + color += tex2Dlod(BackBuffer, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + color += tex2Dlod(BackBuffer, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + } +} + +if(ClarityRadius == 4) +{ + float offset[18] = { 0.0, 1.4953705027, 3.4891992113, 5.4830312105, 7.4768683759, 9.4707125766, 11.4645656736, 13.4584295168, 15.4523059431, 17.4461967743, 19.4661974725, 21.4627427973, 23.4592916956, 25.455844494, 27.4524015179, 29.4489630909, 31.445529535, 33.4421011704 }; + float weight[18] = { 0.033245, 0.0659162217, 0.0636705814, 0.0598194658, 0.0546642566, 0.0485871646, 0.0420045997, 0.0353207015, 0.0288880982, 0.0229808311, 0.0177815511, 0.013382297, 0.0097960001, 0.0069746748, 0.0048301008, 0.0032534598, 0.0021315311, 0.0013582974 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 18; ++i) + { + color += tex2Dlod(BackBuffer, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + color += tex2Dlod(BackBuffer, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).rgb * weight[i]; + } +} + + return dot(color.rgb,float3(0.32786885,0.655737705,0.0163934436)); +} + +float Clarity2(in float4 pos : SV_Position, in float2 texcoord : TEXCOORD) : COLOR +{ + float color = tex2Dlod(ClaritySampler, float4(texcoord,0,0)).r; + +if(ClarityRadius == 0) +{ + float offset[4] = { 0.0, 1.1824255238, 3.0293122308, 5.0040701377 }; + float weight[4] = { 0.39894, 0.2959599993, 0.0045656525, 0.00000149278686458842 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 4; ++i) + { + color += tex2Dlod(ClaritySampler, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + } +} + +if(ClarityRadius == 1) +{ + float offset[6] = { 0.0, 1.4584295168, 3.40398480678, 5.3518057801, 7.302940716, 9.2581597095 }; + float weight[6] = { 0.13298, 0.23227575, 0.1353261595, 0.0511557427, 0.01253922, 0.0019913644 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 6; ++i) + { + color += tex2Dlod(ClaritySampler, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + } +} + +if(ClarityRadius == 2) +{ + float offset[11] = { 0.0, 1.4895848401, 3.4757135714, 5.4618796741, 7.4481042327, 9.4344079746, 11.420811147, 13.4073334, 15.3939936778, 17.3808101174, 19.3677999584 }; + float weight[11] = { 0.06649, 0.1284697563, 0.111918249, 0.0873132676, 0.0610011113, 0.0381655709, 0.0213835661, 0.0107290241, 0.0048206869, 0.0019396469, 0.0006988718 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 11; ++i) + { + color += tex2Dlod(ClaritySampler, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + } +} + +if(ClarityRadius == 3) +{ + float offset[15] = { 0.0, 1.4953705027, 3.4891992113, 5.4830312105, 7.4768683759, 9.4707125766, 11.4645656736, 13.4584295168, 15.4523059431, 17.4461967743, 19.4401038149, 21.43402885, 23.4279736431, 25.4219399344, 27.4159294386 }; + float weight[15] = { 0.0443266667, 0.0872994708, 0.0820892038, 0.0734818355, 0.0626171681, 0.0507956191, 0.0392263968, 0.0288369812, 0.0201808877, 0.0134446557, 0.0085266392, 0.0051478359, 0.0029586248, 0.0016187257, 0.0008430913 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 15; ++i) + { + color += tex2Dlod(ClaritySampler, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + } +} + +if(ClarityRadius == 4) +{ + float offset[18] = { 0.0, 1.4953705027, 3.4891992113, 5.4830312105, 7.4768683759, 9.4707125766, 11.4645656736, 13.4584295168, 15.4523059431, 17.4461967743, 19.4661974725, 21.4627427973, 23.4592916956, 25.455844494, 27.4524015179, 29.4489630909, 31.445529535, 33.4421011704 }; + float weight[18] = { 0.033245, 0.0659162217, 0.0636705814, 0.0598194658, 0.0546642566, 0.0485871646, 0.0420045997, 0.0353207015, 0.0288880982, 0.0229808311, 0.0177815511, 0.013382297, 0.0097960001, 0.0069746748, 0.0048301008, 0.0032534598, 0.0021315311, 0.0013582974 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 18; ++i) + { + color += tex2Dlod(ClaritySampler, float4(texcoord + float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler, float4(texcoord - float2(0.0, offset[i] * pix.y) * ClarityOffset,0,0)).r* weight[i]; + } +} + + return color; +} + +float Clarity3(in float4 pos : SV_Position, in float2 texcoord : TEXCOORD) : COLOR +{ + float color = tex2Dlod(ClaritySampler2, float4(texcoord,0,0)).r; + +if(ClarityRadius == 0) +{ + float offset[4] = { 0.0, 1.1824255238, 3.0293122308, 5.0040701377 }; + float weight[4] = { 0.39894, 0.2959599993, 0.0045656525, 0.00000149278686458842 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 4; ++i) + { + color += tex2Dlod(ClaritySampler2, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler2, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + } +} + +if(ClarityRadius == 1) +{ + float offset[6] = { 0.0, 1.4584295168, 3.40398480678, 5.3518057801, 7.302940716, 9.2581597095 }; + float weight[6] = { 0.13298, 0.23227575, 0.1353261595, 0.0511557427, 0.01253922, 0.0019913644 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 6; ++i) + { + color += tex2Dlod(ClaritySampler2, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler2, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + } +} + +if(ClarityRadius == 2) +{ + float offset[11] = { 0.0, 1.4895848401, 3.4757135714, 5.4618796741, 7.4481042327, 9.4344079746, 11.420811147, 13.4073334, 15.3939936778, 17.3808101174, 19.3677999584 }; + float weight[11] = { 0.06649, 0.1284697563, 0.111918249, 0.0873132676, 0.0610011113, 0.0381655709, 0.0213835661, 0.0107290241, 0.0048206869, 0.0019396469, 0.0006988718 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 11; ++i) + { + color += tex2Dlod(ClaritySampler2, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler2, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + } +} + +if(ClarityRadius == 3) +{ + float offset[15] = { 0.0, 1.4953705027, 3.4891992113, 5.4830312105, 7.4768683759, 9.4707125766, 11.4645656736, 13.4584295168, 15.4523059431, 17.4461967743, 19.4401038149, 21.43402885, 23.4279736431, 25.4219399344, 27.4159294386 }; + float weight[15] = { 0.0443266667, 0.0872994708, 0.0820892038, 0.0734818355, 0.0626171681, 0.0507956191, 0.0392263968, 0.0288369812, 0.0201808877, 0.0134446557, 0.0085266392, 0.0051478359, 0.0029586248, 0.0016187257, 0.0008430913 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 15; ++i) + { + color += tex2Dlod(ClaritySampler2, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler2, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + } +} + +if(ClarityRadius == 4) +{ + float offset[18] = { 0.0, 1.4953705027, 3.4891992113, 5.4830312105, 7.4768683759, 9.4707125766, 11.4645656736, 13.4584295168, 15.4523059431, 17.4461967743, 19.4661974725, 21.4627427973, 23.4592916956, 25.455844494, 27.4524015179, 29.4489630909, 31.445529535, 33.4421011704 }; + float weight[18] = { 0.033245, 0.0659162217, 0.0636705814, 0.0598194658, 0.0546642566, 0.0485871646, 0.0420045997, 0.0353207015, 0.0288880982, 0.0229808311, 0.0177815511, 0.013382297, 0.0097960001, 0.0069746748, 0.0048301008, 0.0032534598, 0.0021315311, 0.0013582974 }; + + color *= weight[0]; + + [loop] + for(int i = 1; i < 18; ++i) + { + color += tex2Dlod(ClaritySampler2, float4(texcoord + float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + color += tex2Dlod(ClaritySampler2, float4(texcoord - float2(offset[i] * pix.x, 0.0) * ClarityOffset,0,0)).r* weight[i]; + } +} + + return color; +} + +// 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) +{ + 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); +} + +technique Clarity +{ + pass Clarity1 + { + VertexShader = PostProcessVS; + PixelShader = Clarity1; + RenderTarget = ClarityTex; + } + + pass Clarity2 + { + VertexShader = PostProcessVS; + PixelShader = Clarity2; + RenderTarget = ClarityTex2; + } + + pass Clarity3 + { + VertexShader = PostProcessVS; + PixelShader = Clarity3; + RenderTarget = ClarityTex3; + } + + pass ClarityFinal + { + VertexShader = PostProcessVS; + PixelShader = ClarityFinal; + } +} diff --git a/data_from_portwine/Reshade/Shaders/ColorMatrix.fx b/data_from_portwine/Reshade/Shaders/ColorMatrix.fx new file mode 100644 index 00000000..2613d55b --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/ColorMatrix.fx @@ -0,0 +1,50 @@ +/** + * Color Matrix version 1.0 + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + * + * ColorMatrix allow the user to transform the colors using a color matrix + */ + +#include "ReShadeUI.fxh" + +uniform float3 ColorMatrix_Red < __UNIFORM_SLIDER_FLOAT3 + ui_min = 0.0; ui_max = 1.0; + ui_label = "Matrix Red"; + ui_tooltip = "How much of a red, green and blue tint the new red value should contain. Should sum to 1.0 if you don't wish to change the brightness."; +> = float3(0.817, 0.183, 0.000); +uniform float3 ColorMatrix_Green < __UNIFORM_SLIDER_FLOAT3 + ui_min = 0.0; ui_max = 1.0; + ui_label = "Matrix Green"; + ui_tooltip = "How much of a red, green and blue tint the new green value should contain. Should sum to 1.0 if you don't wish to change the brightness."; +> = float3(0.333, 0.667, 0.000); +uniform float3 ColorMatrix_Blue < __UNIFORM_SLIDER_FLOAT3 + ui_min = 0.0; ui_max = 1.0; + ui_label = "Matrix Blue"; + ui_tooltip = "How much of a red, green and blue tint the new blue value should contain. Should sum to 1.0 if you don't wish to change the brightness."; +> = float3(0.000, 0.125, 0.875); + +uniform float Strength < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Adjust the strength of the effect."; +> = 1.0; + +#include "ReShade.fxh" + +float3 ColorMatrixPass(float4 position : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + + const float3x3 ColorMatrix = float3x3(ColorMatrix_Red, ColorMatrix_Green, ColorMatrix_Blue); + color = lerp(color, mul(ColorMatrix, color), Strength); + + return saturate(color); +} + +technique ColorMatrix +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = ColorMatrixPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Curves.fx b/data_from_portwine/Reshade/Shaders/Curves.fx new file mode 100644 index 00000000..e2c5abe7 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Curves.fx @@ -0,0 +1,199 @@ +/** + * Curves + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + * + * Curves, uses S-curves to increase contrast, without clipping highlights and shadows. + */ + +#include "ReShadeUI.fxh" + +uniform int Mode < + ui_type = "combo"; + ui_items = "Luma\0Chroma\0Both Luma and Chroma\0"; + ui_tooltip = "Choose what to apply contrast to."; +> = 0; +uniform int Formula < + ui_type = "combo"; + ui_items = "Sine\0Abs split\0Smoothstep\0Exp formula\0Simplified Catmull-Rom (0,0,1,1)\0Perlins Smootherstep\0Abs add\0Techicolor Cinestyle\0Parabola\0Half-circles\0Polynomial split\0"; + ui_tooltip = "The contrast s-curve you want to use. Note that Technicolor Cinestyle is practically identical to Sine, but runs slower. In fact I think the difference might only be due to rounding errors. I prefer 2 myself, but 3 is a nice alternative with a little more effect (but harsher on the highlight and shadows) and it's the fastest formula."; +> = 4; + +uniform float Contrast < __UNIFORM_SLIDER_FLOAT1 + ui_min = -1.0; ui_max = 1.0; + ui_tooltip = "The amount of contrast you want."; +> = 0.65; + +#include "ReShade.fxh" + +float4 CurvesPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float4 colorInput = tex2D(ReShade::BackBuffer, texcoord); + float3 lumCoeff = float3(0.2126, 0.7152, 0.0722); //Values to calculate luma with + float Contrast_blend = Contrast; + const float PI = 3.1415927; + + /*-----------------------------------------------------------. + / Separation of Luma and Chroma / + '-----------------------------------------------------------*/ + + // -- Calculate Luma and Chroma if needed -- + //calculate luma (grey) + float luma = dot(lumCoeff, colorInput.rgb); + //calculate chroma + float3 chroma = colorInput.rgb - luma; + + // -- Which value to put through the contrast formula? -- + // I name it x because makes it easier to copy-paste to Graphtoy or Wolfram Alpha or another graphing program + float3 x; + if (Mode == 0) + x = luma; //if the curve should be applied to Luma + else if (Mode == 1) + x = chroma, //if the curve should be applied to Chroma + x = x * 0.5 + 0.5; //adjust range of Chroma from -1 -> 1 to 0 -> 1 + else + x = colorInput.rgb; //if the curve should be applied to both Luma and Chroma + + /*-----------------------------------------------------------. + / Contrast formulas / + '-----------------------------------------------------------*/ + + // -- Curve 1 -- + if (Formula == 0) + { + x = sin(PI * 0.5 * x); // Sin - 721 amd fps, +vign 536 nv + x *= x; + + //x = 0.5 - 0.5*cos(PI*x); + //x = 0.5 * -sin(PI * -x + (PI*0.5)) + 0.5; + } + + // -- Curve 2 -- + if (Formula == 1) + { + x = x - 0.5; + x = (x / (0.5 + abs(x))) + 0.5; + + //x = ( (x - 0.5) / (0.5 + abs(x-0.5)) ) + 0.5; + } + + // -- Curve 3 -- + if (Formula == 2) + { + //x = smoothstep(0.0,1.0,x); //smoothstep + x = x*x*(3.0 - 2.0*x); //faster smoothstep alternative - 776 amd fps, +vign 536 nv + //x = x - 2.0 * (x - 1.0) * x* (x- 0.5); //2.0 is contrast. Range is 0.0 to 2.0 + } + + // -- Curve 4 -- + if (Formula == 3) + { + x = (1.0524 * exp(6.0 * x) - 1.05248) / (exp(6.0 * x) + 20.0855); //exp formula + } + + // -- Curve 5 -- + if (Formula == 4) + { + //x = 0.5 * (x + 3.0 * x * x - 2.0 * x * x * x); //a simplified catmull-rom (0,0,1,1) - btw smoothstep can also be expressed as a simplified catmull-rom using (1,0,1,0) + //x = (0.5 * x) + (1.5 -x) * x*x; //estrin form - faster version + x = x * (x * (1.5 - x) + 0.5); //horner form - fastest version + + Contrast_blend = Contrast * 2.0; //I multiply by two to give it a strength closer to the other curves. + } + + // -- Curve 6 -- + if (Formula == 5) + { + x = x*x*x*(x*(x*6.0 - 15.0) + 10.0); //Perlins smootherstep + } + + // -- Curve 7 -- + if (Formula == 6) + { + //x = ((x-0.5) / ((0.5/(4.0/3.0)) + abs((x-0.5)*1.25))) + 0.5; + x = x - 0.5; + x = x / ((abs(x)*1.25) + 0.375) + 0.5; + //x = ( (x-0.5) / ((abs(x-0.5)*1.25) + (0.5/(4.0/3.0))) ) + 0.5; + } + + // -- Curve 8 -- + if (Formula == 7) + { + x = (x * (x * (x * (x * (x * (x * (1.6 * x - 7.2) + 10.8) - 4.2) - 3.6) + 2.7) - 1.8) + 2.7) * x * x; //Techicolor Cinestyle - almost identical to curve 1 + } + + // -- Curve 9 -- + if (Formula == 8) + { + x = -0.5 * (x*2.0 - 1.0) * (abs(x*2.0 - 1.0) - 2.0) + 0.5; //parabola + } + + // -- Curve 10 -- + if (Formula == 9) + { + float3 xstep = step(x, 0.5); //tenary might be faster here + float3 xstep_shift = (xstep - 0.5); + float3 shifted_x = x + xstep_shift; + + x = abs(xstep - sqrt(-shifted_x * shifted_x + shifted_x)) - xstep_shift; + + //x = abs(step(x,0.5)-sqrt(-(x+step(x,0.5)-0.5)*(x+step(x,0.5)-0.5)+(x+step(x,0.5)-0.5)))-(step(x,0.5)-0.5); //single line version of the above + + //x = 0.5 + (sign(x-0.5)) * sqrt(0.25-(x-trunc(x*2))*(x-trunc(x*2))); //worse + + /* // if/else - even worse + if (x-0.5) + x = 0.5-sqrt(0.25-x*x); + else + x = 0.5+sqrt(0.25-(x-1)*(x-1)); + */ + + //x = (abs(step(0.5,x)-clamp( 1-sqrt(1-abs(step(0.5,x)- frac(x*2%1)) * abs(step(0.5,x)- frac(x*2%1))),0 ,1))+ step(0.5,x) )*0.5; //worst so far + + //TODO: Check if I could use an abs split instead of step. It might be more efficient + + Contrast_blend = Contrast * 0.5; //I divide by two to give it a strength closer to the other curves. + } + + // -- Curve 11 -- + if (Formula == 10) + { + float3 a = float3(0.0, 0.0, 0.0); + float3 b = float3(0.0, 0.0, 0.0); + + a = x * x * 2.0; + b = (2.0 * -x + 4.0) * x - 1.0; + x = (x < 0.5) ? a : b; + } + + /*-----------------------------------------------------------. + / Joining of Luma and Chroma / + '-----------------------------------------------------------*/ + + if (Mode == 0) // Only Luma + { + x = lerp(luma, x, Contrast_blend); //Blend by Contrast + colorInput.rgb = x + chroma; //Luma + Chroma + } + else if (Mode == 1) // Only Chroma + { + x = x * 2.0 - 1.0; //adjust the Chroma range back to -1 -> 1 + float3 color = luma + x; //Luma + Chroma + colorInput.rgb = lerp(colorInput.rgb, color, Contrast_blend); //Blend by Contrast + } + else // Both Luma and Chroma + { + float3 color = x; //if the curve should be applied to both Luma and Chroma + colorInput.rgb = lerp(colorInput.rgb, color, Contrast_blend); //Blend by Contrast + } + + return colorInput; +} + +technique Curves +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = CurvesPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/DLAA_Plus.fx b/data_from_portwine/Reshade/Shaders/DLAA_Plus.fx new file mode 100644 index 00000000..48707040 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/DLAA_Plus.fx @@ -0,0 +1,643 @@ + ////-------------// + ///**DLAA Plus**/// + //-------------//// + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //* Directionally Localized Antialiasing Plus. + //* For ReShade 3.0+ + //* --------------------------------- + //* DLAA+ + //* Due Diligence + //* Directionally Localized Anti-Aliasing (DLAA) + //* Original method by Dmitry Andreev + //* http://and.intercon.ru/releases/talks/dlaagdc2011/ + //* + //* LICENSE + //* ============ + //* Directionally Localized Anti-Aliasing Plus is licenses under: Attribution-NoDerivatives 4.0 International + //* + //* 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. + //* + //* NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + //* + //* 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-nd/4.0/ + //* + //* Have fun, + //* Jose Negrete AKA BlueSkyDefender + //* + //* https://github.com/BlueSkyDefender/Depth3D + //* + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +uniform float Short_Edge_Mask < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Short Edge AA"; + ui_tooltip = "Use this to adjust the Short Edge AA.\n" + "Default is 0.25"; + ui_category = "DLAA"; + > = 0.25; +/* + uniform float Long_Edge_Mask < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Long Edge AA"; + ui_tooltip = "Use this to adjust the Long Edge AA.\n" + "Default is 0.5"; + ui_category = "DLAA"; + > = 0.5; +*/ +uniform float Long_Edge_Mask_H < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Long Edge H+"; + ui_tooltip = "Use this to adjust the Super Long Edge AA.\n" + "Default is 1.0"; + ui_category = "DLAA Expanded"; +> = 0.0; + +uniform float Long_Edge_Mask_V < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Long Edge V+"; + ui_tooltip = "Use this to adjust the Super Long Edge AA.\n" + "Default is 1.0"; + ui_category = "DLAA Expanded"; +> = 0.0; + +uniform float De_Artifact < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "De-Artifacting"; + ui_tooltip = "Use this to adjust de-artifacting power.\n" + "Default is 0.5"; + ui_category = "DLAA Debuging"; + > = 0.5; + +uniform float Text_Preservation < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Text Preservation"; + ui_tooltip = "Use this to adjust Text Preservation Power.\n" + "Default is 0.5"; + ui_category = "DLAA Debuging"; + > = 0.5; + +uniform int View_Mode < + ui_type = "combo"; + ui_items = "DLAA\0DLAA Text Preservation\0Blue Short H/V AA Mask\0Red H & Green V Long Edge Mask\0Text Preservation Mask\0"; + ui_label = "View Mode"; + ui_tooltip = "This is used to select the normal view output or debug view."; + ui_category = "DLAA Debuging"; +> = 0; + +//Total amount of frames since the game started. +uniform uint framecount < source = "framecount"; >; +////////////////////////////////////////////////////////////DLAA//////////////////////////////////////////////////////////////////// +#define Alternate framecount % 2 == 0 +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +#define lambda lerp(0,10,Short_Edge_Mask) +#define epsilon 0.0 //lerp(0,0.5,Error_Clamping) +#define DA lerp(0,16,De_Artifact) +#define Hoiz lerp(1,10,Long_Edge_Mask_H) +#define Vert lerp(1,10,Long_Edge_Mask_V) +texture BackBufferTex : COLOR; + +sampler BackBuffer + { + Texture = BackBufferTex; + }; + +texture DLAAtex_S {Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; + +sampler SamplerDLAA_S + { + Texture = DLAAtex_S; + }; + +texture SLPtex_H {Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; + +sampler SamplerLoadedPixel_H + { + Texture = SLPtex_H; + }; + + texture TexDLAA_H {Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; + + sampler SamplerDLAA_H + { + Texture = TexDLAA_H; + }; + + texture SLPtex_V {Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; + + sampler SamplerLoadedPixel_V + { + Texture = SLPtex_V; + }; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Luminosity Intensity +float LI(in float3 value) +{ + //Luminosity Controll from 0.1 to 1.0 + //If GGG value of 0.333, 0.333, 0.333 is about right for Green channel. + //Slide 51 talk more about this. + return dot(value.rgb,float3(0.299, 0.587, 0.114)); +} +//WIP +float Text_Detection(float2 texcoord) +{ + float4 BC = tex2D(BackBuffer, texcoord); + //BC += tex2D(BackBuffer, texcoord + float2( TEST, TEST) * pix.xy); + //BC += tex2D(BackBuffer, texcoord + float2( TEST,-TEST) * pix.xy); + //BC += tex2D(BackBuffer, texcoord + float2(-TEST, TEST) * pix.xy); + //BC += tex2D(BackBuffer, texcoord + float2(-TEST, -TEST) * pix.xy); + //BC /= 4; + // Luma Threshold Thank you Adyss + BC.a = LI(BC.rgb);//Luma + BC.rgb /= max(BC.a, 0.001); + BC.a = max(0.0, BC.a - Text_Preservation); + BC.rgb *= BC.a; + + return 1-dot(BC.rgb,BC.rgb); +} + +float4 SLP(float2 tc,float dx, float dy) //Load Pixel +{ + float4 BB = tex2D(BackBuffer, tc + float2(dx, dy) * pix.xy); + return BB; +} + +float4 DLAA_Short( float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float t, l, r, d, n, MA = 1; + + float2 UV = texcoord.xy, SW = MA; // But, I don't think it's really needed. + float4 NFAA; // The Edge Seeking code can be adjusted to look for longer edges. + // Find Edges + t = LI(SLP(texcoord, 0 ,-1).rgb); + d = LI(SLP(texcoord, 0 , 1).rgb); + l = LI(SLP(texcoord,-1 , 0).rgb); + r = LI(SLP(texcoord, 1 , 0).rgb); + n = length(float2(t - d,-(r - l))); + + //Short Edge Filter http://and.intercon.ru/releases/talks/dlaagdc2011/slides/#slide43 + float4 DLAA; //DLAA is the completed AA Result. + + //5 bi-linear samples cross + float4 Center = SLP(texcoord, 0 , 0); + float4 Left = SLP(texcoord,-1.25 , 0.0); + float4 Right = SLP(texcoord, 1.25 , 0.0); + float4 Up = SLP(texcoord, 0.0 ,-1.25); + float4 Down = SLP(texcoord, 0.0 , 1.25); + + //Combine horizontal and vertical blurs together + float4 combH = 2.0 * ( Up + Down ); + float4 combV = 2.0 * ( Left + Right ); + + //Bi-directional anti-aliasing using HORIZONTAL & VERTICAL blur and horizontal edge detection + //Slide information triped me up here. Read slide 43. + //Edge detection + float4 CenterDiffH = abs( combH - 4.0 * Center ) / 4.0; + float4 CenterDiffV = abs( combV - 4.0 * Center ) / 4.0; + + //Blur + float4 blurredH = (combH + 2.0 * Center) / 6.0; + float4 blurredV = (combV + 2.0 * Center) / 6.0; + + //Edge detection + float LumH = LI( CenterDiffH.rgb ); + float LumV = LI( CenterDiffV.rgb ); + + float LumHB = LI(blurredH.xyz); + float LumVB = LI(blurredV.xyz); + + //t + float satAmountH = saturate( ( lambda * LumH - epsilon ) / LumVB ); + float satAmountV = saturate( ( lambda * LumV - epsilon ) / LumHB ); + + //color = lerp(color,blur,sat(Edge/blur) + //Re-blend Short Edge Done + DLAA = lerp( Center, blurredH, saturate(lerp(satAmountV ,1,-1)) );//* 1.1 + DLAA = lerp( DLAA, blurredV, saturate(lerp(satAmountH ,1,-1)) );// * 0.5 + + // Lets make that mask for a sharper image. + float Mask = n * 5.0; + if (Mask > 0) + Mask = 1-Mask; + else + Mask = 1; + // Super Evil Magic Number. + Mask = saturate(lerp(Mask,1,-1)); + + Mask += 1-saturate(lerp(satAmountV + satAmountH,1,-1)); + + return float4(DLAA.rgb,(satAmountV + satAmountH) * 0.5); +} + +float4 LP_H(float2 tc,float dx, float dy) //Load Pixel +{ + float4 BB = tex2D(BackBuffer, tc + float2(dx, dy) * pix.xy); + return BB; +} + +float4 PreFilter_H(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target //Loaded Pixel +{ + + float4 center = LP_H(texcoord, 0, 0); + float4 left = LP_H(texcoord,-1.0, 0); + float4 right = LP_H(texcoord, 1.0, 0); + float4 top = LP_H(texcoord, 0,-1.0); + float4 bottom = LP_H(texcoord, 0, 1.0); + + float4 edges = 4.0 * abs((left + right + top + bottom) - 4.0 * center); + float edgesLum = LI(edges.rgb); + + return float4(center.rgb, edgesLum); +} + +float4 SLP_H(float2 tc,float dx, float dy) //Load Pixel +{ + float4 BB = tex2D(SamplerLoadedPixel_H, tc + float2(dx, dy) * pix.xy); + return BB; +} + +//Information on Slide 44 says to run the edge processing jointly short and Large. +float4 DLAA_H(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target //Loaded Pixel +{ + //Short Edge Filter http://and.intercon.ru/releases/talks/dlaagdc2011/slides/#slide43 + float4 DLAA, H, V, UDLR; //DLAA is the completed AA Result. + float SLE_H = 2 * Hoiz; + //Center sample + float4 Center = SLP_H(texcoord, 0 , 0); + + DLAA = tex2D(SamplerDLAA_S,texcoord); + float4 HNeg, HNegA, HNegB, HNegC, HNegD, HNegE, + HPos, HPosA, HPosB, HPosC, HPosD, HPosE, + VNeg, VNegA, VNegB, VNegC, + VPos, VPosA, VPosB, VPosC; + + // Long Edges + //16 bi-linear samples cross, added extra bi-linear samples in each direction. + HNeg = SLP_H( texcoord, -1.5 , 0.0 ); + HNegA = SLP_H( texcoord, -3.5 , 0.0 ); + HNegB = SLP_H( texcoord, -5.5 , 0.0 ); + HNegC = SLP_H( texcoord, -7.0 , 0.0 ); + + HPos = SLP_H( texcoord, 1.5 , 0.0 ); + HPosA = SLP_H( texcoord, 3.5 , 0.0 ); + HPosB = SLP_H( texcoord, 5.5 , 0.0 ); + HPosC = SLP_H( texcoord, 7.0 , 0.0 ); + + VNeg = SLP_H( texcoord, 0.0,-1.5 ); + VNegA = SLP_H( texcoord, 0.0,-3.5 ); + VNegB = SLP_H( texcoord, 0.0,-5.5 ); + VNegC = SLP_H( texcoord, 0.0,-7.0 ); + + VPos = SLP_H( texcoord, 0.0, 1.5 ); + VPosA = SLP_H( texcoord, 0.0, 3.5 ); + VPosB = SLP_H( texcoord, 0.0, 5.5 ); + VPosC = SLP_H( texcoord, 0.0, 7.0 ); + + //Long Edge detection H & V + float4 AvgBlurH = ( HNeg + HNegA + HNegB + HNegC + HPos + HPosA + HPosB + HPosC ) / 8; + float4 AvgBlurV = ( VNeg + VNegA + VNegB + VNegC + VPos + VPosA + VPosB + VPosC ) / 8; + float EAH = saturate( AvgBlurH.a * SLE_H - 1.0 ); + float EAV = saturate( AvgBlurV.a * 2.0 - 1.0 ); + + float longEdge_H = abs( EAH - EAV ); + + float Mask_H = longEdge_H > 0; + + if ( Mask_H ) + { + float4 up = LP_H(texcoord, 0 ,-1); + float4 down = LP_H(texcoord, 0 , 1); + //Merge for BlurSamples. + //Long Blur H + float LongBlurLumH = LI( AvgBlurH.rgb);//8 samples + + float centerLI = LI( Center.rgb); + float upLI = LI( up.rgb ); + float downLI = LI( down.rgb ); + + float blurUp = saturate( 0.0 + ( LongBlurLumH - upLI ) / (centerLI - upLI ) ); + float blurDown = saturate( 1.0 + ( LongBlurLumH - centerLI) / (centerLI - downLI) ); + + UDLR = float4( 1, 1, blurUp, blurDown ); + + UDLR = UDLR == float4(0.0, 0.0, 0.0, 0.0) ? float4(1.0, 1.0, 1.0, 1.0) : UDLR; + + H = lerp( up , Center, UDLR.z ); + H = lerp( down , H , UDLR.w ); + + DLAA = lerp( DLAA , H , EAH); + } + + return float4(DLAA.rgb,EAH); +} + +float4 LP_V(float2 tc,float dx, float dy) //Load Pixel +{ + float4 BB = tex2D(SamplerDLAA_H, tc + float2(dx, dy) * pix.xy); + return BB; +} + +float4 PreFilter_V(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target //Loaded Pixel +{ + + float4 center = LP_V(texcoord, 0, 0); + float4 left = LP_V(texcoord, -1.0, 0); + float4 right = LP_V(texcoord, 1.0, 0); + float4 top = LP_V(texcoord, 0, -1.0); + float4 bottom = LP_V(texcoord, 0, 1.0); + + float4 edges = 4.0 * abs((left + right + top + bottom) - 4.0 * center); + float edgesLum = LI(edges.rgb); + + return float4(center.rgb, edgesLum); +} + +float4 SLP_V(float2 tc,float dx, float dy) //Load Pixel +{ + float4 BB = tex2D(SamplerLoadedPixel_V, tc + float2(dx, dy) * pix.xy); + return BB; +} + +float4 DLAA_V(float2 texcoord) +{ + //Short Edge Filter http://and.intercon.ru/releases/talks/dlaagdc2011/slides/#slide43 + float4 DLAA, H, V, UDLR; //DLAA is the completed AA Result. + float SLE_V = 2 * Vert; + //Center sample + float4 Center = SLP_V(texcoord, 0 , 0); + + //Reuse Long Horizontal AA + DLAA = Center; + float4 HNeg, HNegA, HNegB, HNegC, HNegD, HNegE, + HPos, HPosA, HPosB, HPosC, HPosD, HPosE, + VNeg, VNegA, VNegB, VNegC, + VPos, VPosA, VPosB, VPosC; + + // Long Edges + //16 bi-linear samples cross, added extra bi-linear samples in each direction. + HNeg = SLP_V( texcoord, -1.5 , 0.0 ); + HNegA = SLP_V( texcoord, -3.5 , 0.0 ); + HNegB = SLP_V( texcoord, -5.5 , 0.0 ); + HNegC = SLP_V( texcoord, -7.0 , 0.0 ); + + HPos = SLP_V( texcoord, 1.5 , 0.0 ); + HPosA = SLP_V( texcoord, 3.5 , 0.0 ); + HPosB = SLP_V( texcoord, 5.5 , 0.0 ); + HPosC = SLP_V( texcoord, 7.0 , 0.0 ); + + VNeg = SLP_V( texcoord, 0.0,-1.5 ); + VNegA = SLP_V( texcoord, 0.0,-3.5 ); + VNegB = SLP_V( texcoord, 0.0,-5.5 ); + VNegC = SLP_V( texcoord, 0.0,-7.0 ); + + VPos = SLP_V( texcoord, 0.0, 1.5 ); + VPosA = SLP_V( texcoord, 0.0, 3.5 ); + VPosB = SLP_V( texcoord, 0.0, 5.5 ); + VPosC = SLP_V( texcoord, 0.0, 7.0 ); + + //Long Edge detection H & V + float4 AvgBlurH = ( HNeg + HNegA + HNegB + HNegC + HPos + HPosA + HPosB + HPosC ) / 8; + float4 AvgBlurV = ( VNeg + VNegA + VNegB + VNegC + VPos + VPosA + VPosB + VPosC ) / 8; + float EAH = saturate( AvgBlurH.a * 2.0 - 1.0 ); + float EAV = saturate( AvgBlurV.a * SLE_V - 1.0 ); + + float longEdge_V = abs( EAV - EAH ); + + float Mask_V = longEdge_V > 0; + + if ( Mask_V ) + { + float4 left = LP_V(texcoord,-1 , 0); + float4 right = LP_V(texcoord, 1 , 0); + //Merge for BlurSamples. + + //Long Blur V + float LongBlurLumV = LI( AvgBlurV.rgb );//8 samples + + float centerLI = LI( Center.rgb); + float leftLI = LI( left.rgb ); + float rightLI = LI( right.rgb ); + + float blurLeft = saturate( 0.0 + ( LongBlurLumV - leftLI ) / (centerLI - leftLI ) ); + float blurRight = saturate( 1.0 + ( LongBlurLumV - centerLI) / (centerLI - rightLI) ); + + UDLR = float4( blurLeft, blurRight, 1, 1 ); + + UDLR = UDLR == float4(0.0, 0.0, 0.0, 0.0) ? float4(1.0, 1.0, 1.0, 1.0) : UDLR; + + V = lerp( left , Center, UDLR.x ); + V = lerp( right, V , UDLR.y ); + + //Reuse short samples and DLAA Long Edge Out. + DLAA = lerp( DLAA , V , EAV); + } + + return float4(DLAA.rgb,EAV); +} + + +float4 DLAA(float2 texcoord) +{ + float t, l, r, d; + + float2 UV = texcoord.xy, SW = pix, n; // But, I don't think it's really needed. + float4 D_A; + // Find Edges + t = LI(DLAA_V( float2( UV.x , UV.y - SW.y ) ).rgb); + d = LI(DLAA_V( float2( UV.x , UV.y + SW.y ) ).rgb); + l = LI(DLAA_V( float2( UV.x - SW.x , UV.y ) ).rgb); + r = LI(DLAA_V( float2( UV.x + SW.x , UV.y ) ).rgb); + n = float2(t - d,-(r - l)); + + float nl = length(n), Rep = rcp(DA); + + if (nl < Rep) + D_A = DLAA_V(UV); + else + { + n *= pix / nl; + + float4 o = DLAA_V( UV ), + t0 = DLAA_V( UV + float2(n.x, -n.y) * 0.5) * 0.9, + t1 = DLAA_V( UV - float2(n.x, -n.y) * 0.5) * 0.9, + t2 = DLAA_V( UV + n * 0.9) * 0.75, + t3 = DLAA_V( UV - n * 0.9) * 0.75; + + D_A = (o + t0 + t1 + t2 + t3) / 4.3; + } + + //NFAA = tex2D(SamplerDLAA_S,UV); + + float4 DLAA = D_A; + + if(View_Mode == 1) + { + DLAA = lerp(tex2D(BackBuffer, texcoord),DLAA,Text_Detection(texcoord)); + } + else if (View_Mode == 2) + { + DLAA = lerp(DLAA,1,float4(0,0,tex2D(SamplerDLAA_S,UV).w,1)); + } + else if (View_Mode == 3) + { + DLAA = lerp(DLAA,1,float4(tex2D(SamplerDLAA_H,texcoord).w,DLAA_V(texcoord).w,0,1)); + } + else if (View_Mode == 4) + { + DLAA = lerp(float4(1,1,0,1),DLAA,Text_Detection(texcoord)); + } + + return DLAA; +} + +uniform float timer < source = "timer"; >; //Please do not remove. +////////////////////////////////////////////////////////Logo///////////////////////////////////////////////////////////////////////// +float4 Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float PosX = 0.9525f*BUFFER_WIDTH*pix.x,PosY = 0.975f*BUFFER_HEIGHT*pix.y; + float3 Color = DLAA(texcoord).rgb,D,E,P,T,H,Three,DD,Dot,I,N,F,O; + + [branch] if(timer <= 12500) + { + //DEPTH + //D + float PosXD = -0.035+PosX, offsetD = 0.001; + float3 OneD = all( abs(float2( texcoord.x -PosXD, texcoord.y-PosY)) < float2(0.0025,0.009)); + float3 TwoD = all( abs(float2( texcoord.x -PosXD-offsetD, texcoord.y-PosY)) < float2(0.0025,0.007)); + D = OneD-TwoD; + + //E + float PosXE = -0.028+PosX, offsetE = 0.0005; + float3 OneE = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.009)); + float3 TwoE = all( abs(float2( texcoord.x -PosXE-offsetE, texcoord.y-PosY)) < float2(0.0025,0.007)); + float3 ThreeE = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.001)); + E = (OneE-TwoE)+ThreeE; + + //P + float PosXP = -0.0215+PosX, PosYP = -0.0025+PosY, offsetP = 0.001, offsetP1 = 0.002; + float3 OneP = all( abs(float2( texcoord.x -PosXP, texcoord.y-PosYP)) < float2(0.0025,0.009*0.775)); + float3 TwoP = all( abs(float2( texcoord.x -PosXP-offsetP, texcoord.y-PosYP)) < float2(0.0025,0.007*0.680)); + float3 ThreeP = all( abs(float2( texcoord.x -PosXP+offsetP1, texcoord.y-PosY)) < float2(0.0005,0.009)); + P = (OneP-TwoP) + ThreeP; + + //T + float PosXT = -0.014+PosX, PosYT = -0.008+PosY; + float3 OneT = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosYT)) < float2(0.003,0.001)); + float3 TwoT = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosY)) < float2(0.000625,0.009)); + T = OneT+TwoT; + + //H + float PosXH = -0.0072+PosX; + float3 OneH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.001)); + float3 TwoH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.009)); + float3 ThreeH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.00325,0.009)); + H = (OneH-TwoH)+ThreeH; + + //Three + float offsetFive = 0.001, PosX3 = -0.001+PosX; + float3 OneThree = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.009)); + float3 TwoThree = all( abs(float2( texcoord.x -PosX3 - offsetFive, texcoord.y-PosY)) < float2(0.003,0.007)); + float3 ThreeThree = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.001)); + Three = (OneThree-TwoThree)+ThreeThree; + + //DD + float PosXDD = 0.006+PosX, offsetDD = 0.001; + float3 OneDD = all( abs(float2( texcoord.x -PosXDD, texcoord.y-PosY)) < float2(0.0025,0.009)); + float3 TwoDD = all( abs(float2( texcoord.x -PosXDD-offsetDD, texcoord.y-PosY)) < float2(0.0025,0.007)); + DD = OneDD-TwoDD; + + //Dot + float PosXDot = 0.011+PosX, PosYDot = 0.008+PosY; + float3 OneDot = all( abs(float2( texcoord.x -PosXDot, texcoord.y-PosYDot)) < float2(0.00075,0.0015)); + Dot = OneDot; + + //INFO + //I + float PosXI = 0.0155+PosX, PosYI = 0.004+PosY, PosYII = 0.008+PosY; + float3 OneI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosY)) < float2(0.003,0.001)); + float3 TwoI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYI)) < float2(0.000625,0.005)); + float3 ThreeI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYII)) < float2(0.003,0.001)); + I = OneI+TwoI+ThreeI; + + //N + float PosXN = 0.0225+PosX, PosYN = 0.005+PosY,offsetN = -0.001; + float3 OneN = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN)) < float2(0.002,0.004)); + float3 TwoN = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN - offsetN)) < float2(0.003,0.005)); + N = OneN-TwoN; + + //F + float PosXF = 0.029+PosX, PosYF = 0.004+PosY, offsetF = 0.0005, offsetF1 = 0.001; + float3 OneF = all( abs(float2( texcoord.x -PosXF-offsetF, texcoord.y-PosYF-offsetF1)) < float2(0.002,0.004)); + float3 TwoF = all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0025,0.005)); + float3 ThreeF = all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0015,0.00075)); + F = (OneF-TwoF)+ThreeF; + + //O + float PosXO = 0.035+PosX, PosYO = 0.004+PosY; + float3 OneO = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.003,0.005)); + float3 TwoO = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.002,0.003)); + O = OneO-TwoO; + //Website + return float4(D+E+P+T+H+Three+DD+Dot+I+N+F+O,1.) ? 1-texcoord.y*50.0+48.35f : float4(Color,1.); + } + else + return float4(Color,1.); +} + +///////////////ReShade.fxh///////////////////////////////////////////////////////////// + +// 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) +{ + 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 Directionally_Localized_Anti_Aliasing_Plus +{ + pass Short_Edge_AA + { + VertexShader = PostProcessVS; + PixelShader = DLAA_Short; + RenderTarget = DLAAtex_S; + } + pass Pre_Filter_Hoizontal + { + VertexShader = PostProcessVS; + PixelShader = PreFilter_H; + RenderTarget = SLPtex_H; + } + pass Pre_Filter_Vertical + { + VertexShader = PostProcessVS; + PixelShader = DLAA_H; + RenderTarget = TexDLAA_H; + } + pass Pre_Filter_Vertical + { + VertexShader = PostProcessVS; + PixelShader = PreFilter_V; + RenderTarget = SLPtex_V; + } + pass DLAA + { + VertexShader = PostProcessVS; + PixelShader = Out; + } +} diff --git a/data_from_portwine/Reshade/Shaders/DPX.fx b/data_from_portwine/Reshade/Shaders/DPX.fx new file mode 100644 index 00000000..76754933 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/DPX.fx @@ -0,0 +1,73 @@ +/** + * DPX/Cineon shader by Loadus + */ + +#include "ReShadeUI.fxh" + +uniform float3 RGB_Curve < __UNIFORM_SLIDER_FLOAT3 + ui_min = 1.0; ui_max = 15.0; + ui_label = "RGB Curve"; +> = float3(8.0, 8.0, 8.0); +uniform float3 RGB_C < __UNIFORM_SLIDER_FLOAT3 + ui_min = 0.2; ui_max = 0.5; + ui_label = "RGB C"; +> = float3(0.36, 0.36, 0.34); + +uniform float Contrast < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; +> = 0.1; +uniform float Saturation < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 8.0; +> = 3.0; +uniform float Colorfulness < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.1; ui_max = 2.5; +> = 2.5; + +uniform float Strength < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Adjust the strength of the effect."; +> = 0.20; + +#include "ReShade.fxh" + +static const float3x3 RGB = float3x3( + 2.6714711726599600, -1.2672360578624100, -0.4109956021722270, + -1.0251070293466400, 1.9840911624108900, 0.0439502493584124, + 0.0610009456429445, -0.2236707508128630, 1.1590210416706100 +); +static const float3x3 XYZ = float3x3( + 0.5003033835433160, 0.3380975732227390, 0.1645897795458570, + 0.2579688942747580, 0.6761952591447060, 0.0658358459823868, + 0.0234517888692628, 0.1126992737203000, 0.8668396731242010 +); + +float3 DPXPass(float4 vois : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 input = tex2D(ReShade::BackBuffer, texcoord).rgb; + + float3 B = input; + B = B * (1.0 - Contrast) + (0.5 * Contrast); + float3 Btemp = (1.0 / (1.0 + exp(RGB_Curve / 2.0))); + B = ((1.0 / (1.0 + exp(-RGB_Curve * (B - RGB_C)))) / (-2.0 * Btemp + 1.0)) + (-Btemp / (-2.0 * Btemp + 1.0)); + + float value = max(max(B.r, B.g), B.b); + float3 color = B / value; + color = pow(abs(color), 1.0 / Colorfulness); + + float3 c0 = color * value; + c0 = mul(XYZ, c0); + float luma = dot(c0, float3(0.30, 0.59, 0.11)); + c0 = (1.0 - Saturation) * luma + Saturation * c0; + c0 = mul(RGB, c0); + + return lerp(input, c0, Strength); +} + +technique DPX +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = DPXPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Daltonize.fx b/data_from_portwine/Reshade/Shaders/Daltonize.fx new file mode 100644 index 00000000..1af4473e --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Daltonize.fx @@ -0,0 +1,73 @@ +/** + * Daltonization algorithm by daltonize.org + * http://www.daltonize.org/2010/05/lms-daltonization-algorithm.html + * Originally ported to ReShade by IDDQD, modified for ReShade 3.0 by crosire + */ + +uniform int Type < + ui_type = "combo"; + ui_items = "Protanopia\0Deuteranopia\0Tritanopia\0"; +> = 0; + +#include "ReShade.fxh" + +float3 PS_DaltonizeFXmain(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 input = tex2D(ReShade::BackBuffer, texcoord).rgb; + + // RGB to LMS matrix conversion + float OnizeL = (17.8824f * input.r) + (43.5161f * input.g) + (4.11935f * input.b); + float OnizeM = (3.45565f * input.r) + (27.1554f * input.g) + (3.86714f * input.b); + float OnizeS = (0.0299566f * input.r) + (0.184309f * input.g) + (1.46709f * input.b); + + // Simulate color blindness + float Daltl, Daltm, Dalts; + + if (Type == 0) // Protanopia - reds are greatly reduced (1% men) + { + Daltl = 0.0f * OnizeL + 2.02344f * OnizeM + -2.52581f * OnizeS; + Daltm = 0.0f * OnizeL + 1.0f * OnizeM + 0.0f * OnizeS; + Dalts = 0.0f * OnizeL + 0.0f * OnizeM + 1.0f * OnizeS; + } + else if (Type == 1) // Deuteranopia - greens are greatly reduced (1% men) + { + Daltl = 1.0f * OnizeL + 0.0f * OnizeM + 0.0f * OnizeS; + Daltm = 0.494207f * OnizeL + 0.0f * OnizeM + 1.24827f * OnizeS; + Dalts = 0.0f * OnizeL + 0.0f * OnizeM + 1.0f * OnizeS; + } + else if (Type == 2) // Tritanopia - blues are greatly reduced (0.003% population) + { + Daltl = 1.0f * OnizeL + 0.0f * OnizeM + 0.0f * OnizeS; + Daltm = 0.0f * OnizeL + 1.0f * OnizeM + 0.0f * OnizeS; + Dalts = -0.395913f * OnizeL + 0.801109f * OnizeM + 0.0f * OnizeS; + } + + // LMS to RGB matrix conversion + float3 error; + error.r = (0.0809444479f * Daltl) + (-0.130504409f * Daltm) + (0.116721066f * Dalts); + error.g = (-0.0102485335f * Daltl) + (0.0540193266f * Daltm) + (-0.113614708f * Dalts); + error.b = (-0.000365296938f * Daltl) + (-0.00412161469f * Daltm) + (0.693511405f * Dalts); + + // Isolate invisible colors to color vision deficiency (calculate error matrix) + error = (input - error); + + // Shift colors towards visible spectrum (apply error modifications) + float3 correction; + correction.r = 0; // (error.r * 0.0) + (error.g * 0.0) + (error.b * 0.0); + correction.g = (error.r * 0.7) + (error.g * 1.0); // + (error.b * 0.0); + correction.b = (error.r * 0.7) + (error.b * 1.0); // + (error.g * 0.0); + + // Add compensation to original values + correction = input + correction; + + return correction; +} + +technique Daltonize +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_DaltonizeFXmain; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Deband.fx b/data_from_portwine/Reshade/Shaders/Deband.fx new file mode 100644 index 00000000..cc2eaeab --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Deband.fx @@ -0,0 +1,252 @@ +/** + * Deband shader by haasn + * https://github.com/haasn/gentoo-conf/blob/xor/home/nand/.mpv/shaders/deband-pre.glsl + * + * Copyright (c) 2015 Niklas Haas + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Modified and optimized for ReShade by JPulowski + * https://reshade.me/forum/shader-presentation/768-deband + * + * Do not distribute without giving credit to the original author(s). + * + * 1.0 - Initial release + * 1.1 - Replaced the algorithm with the one from MPV + * 1.1a - Minor optimizations + * - Removed unnecessary lines and replaced them with ReShadeFX intrinsic counterparts + * 2.0 - Replaced "grain" with CeeJay.dk's ordered dithering algorithm and enabled it by default + * - The configuration is now more simpler and straightforward + * - Some minor code changes and optimizations + * - Improved the algorithm and made it more robust by adding some of the madshi's + * improvements to flash3kyuu_deband which should cause an increase in quality. Higher + * iterations/ranges should now yield higher quality debanding without too much decrease + * in quality. + * - Changed licensing text and original source code URL + * 3.0 - Replaced the entire banding detection algorithm with modified standard deviation and + * Weber ratio analyses which give more accurate and error-free results compared to the + * previous algorithm + * - Added banding map debug view + * - Added and redefined UI categories + * - Added depth detection (credits to spiro) which should be useful when banding only + * occurs in the sky texture for example + * - Fixed a bug in random number generation which was causing artifacts on the upper left + * side of the screen + * - Dithering is now applied only when debanding a pixel as it should be which should + * reduce the overall noise in the final texture + * - Minor code optimizations + * 3.1 - Switched to chroma-based analysis from luma-based analysis which was causing artifacts + * under some scenarios + * - Changed parts of the code which was causing compatibility issues on some renderers + */ + +#include "ReShadeUI.fxh" +#include "ReShade.fxh" + +uniform bool enable_weber < + ui_category = "Banding analysis"; + ui_label = "Weber ratio"; + ui_tooltip = "Weber ratio analysis that calculates the ratio of the each local pixel's intensity to average background intensity of all the local pixels."; + ui_type = "radio"; +> = true; + +uniform bool enable_sdeviation < + ui_category = "Banding analysis"; + ui_label = "Standard deviation"; + ui_tooltip = "Modified standard deviation analysis that calculates nearby pixels' intensity deviation from the current pixel instead of the mean."; + ui_type = "radio"; +> = true; + +uniform bool enable_depthbuffer < + ui_category = "Banding analysis"; + ui_label = "Depth detection"; + ui_tooltip = "Allows depth information to be used when analysing banding, pixels will only be analysed if they are in a certain depth. (e.g. debanding only the sky)"; + ui_type = "radio"; +> = false; + +uniform float t1 < + ui_category = "Banding analysis"; + ui_label = "Standard deviation threshold"; + ui_max = 0.5; + ui_min = 0.0; + ui_step = 0.001; + ui_tooltip = "Standard deviations lower than this threshold will be flagged as flat regions with potential banding."; + ui_type = "slider"; +> = 0.007; + +uniform float t2 < + ui_category = "Banding analysis"; + ui_label = "Weber ratio threshold"; + ui_max = 2.0; + ui_min = 0.0; + ui_step = 0.01; + ui_tooltip = "Weber ratios lower than this threshold will be flagged as flat regions with potential banding."; + ui_type = "slider"; +> = 0.04; + +uniform float banding_depth < + ui_category = "Banding analysis"; + ui_label = "Banding depth"; + ui_max = 1.0; + ui_min = 0.0; + ui_step = 0.001; + ui_tooltip = "Pixels under this depth threshold will not be processed and returned as they are."; + ui_type = "slider"; +> = 1.0; + +uniform float range < + ui_category = "Banding detection & removal"; + ui_label = "Radius"; + ui_max = 32.0; + ui_min = 1.0; + ui_step = 1.0; + ui_tooltip = "The radius increases linearly for each iteration. A higher radius will find more gradients, but a lower radius will smooth more aggressively."; + ui_type = "slider"; +> = 24.0; + +uniform int iterations < + ui_category = "Banding detection & removal"; + ui_label = "Iterations"; + ui_max = 4; + ui_min = 1; + ui_tooltip = "The number of debanding steps to perform per sample. Each step reduces a bit more banding, but takes time to compute."; + ui_type = "slider"; +> = 1; + +uniform int debug_output < + ui_category = "Debug"; + ui_items = "None\0Blurred (LPF) image\0Banding map\0"; + ui_label = "Debug view"; + ui_tooltip = "Blurred (LPF) image: Useful when tweaking radius and iterations to make sure all banding regions are blurred enough.\nBanding map: Useful when tweaking analysis parameters, continuous green regions indicate flat (i.e. banding) regions."; + ui_type = "combo"; +> = 0; + +// Reshade uses C rand for random, max cannot be larger than 2^15-1 +uniform int drandom < source = "random"; min = 0; max = 32767; >; + +float rand(float x) +{ + return frac(x / 41.0); +} + +float permute(float x) +{ + return ((34.0 * x + 1.0) * x) % 289.0; +} + +float3 PS_Deband(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 ori = tex2Dlod(ReShade::BackBuffer, float4(texcoord, 0.0, 0.0)).rgb; + + if (enable_depthbuffer && (ReShade::GetLinearizedDepth(texcoord) < banding_depth)) + return ori; + + // Initialize the PRNG by hashing the position + a random uniform + float3 m = float3(texcoord + 1.0, (drandom / 32767.0) + 1.0); + float h = permute(permute(permute(m.x) + m.y) + m.z); + + // Compute a random angle + float dir = rand(permute(h)) * 6.2831853; + float2 o; + sincos(dir, o.y, o.x); + + // Distance calculations + float2 pt; + float dist; + + for (int i = 1; i <= iterations; ++i) { + dist = rand(h) * range * i; + pt = dist * BUFFER_PIXEL_SIZE; + + h = permute(h); + } + + // Sample at quarter-turn intervals around the source pixel + float3 ref[4] = { + tex2Dlod(ReShade::BackBuffer, float4(mad(pt, o, texcoord), 0.0, 0.0)).rgb, // SE + tex2Dlod(ReShade::BackBuffer, float4(mad(pt, -o, texcoord), 0.0, 0.0)).rgb, // NW + tex2Dlod(ReShade::BackBuffer, float4(mad(pt, float2(-o.y, o.x), texcoord), 0.0, 0.0)).rgb, // NE + tex2Dlod(ReShade::BackBuffer, float4(mad(pt, float2( o.y, -o.x), texcoord), 0.0, 0.0)).rgb // SW + }; + + // Calculate weber ratio + float3 mean = (ori + ref[0] + ref[1] + ref[2] + ref[3]) * 0.2; + float3 k = abs(ori - mean); + for (int j = 0; j < 4; ++j) { + k += abs(ref[j] - mean); + } + + k = k * 0.2 / mean; + + // Calculate std. deviation + float3 sd = 0.0; + + for (int j = 0; j < 4; ++j) { + sd += pow(ref[j] - ori, 2); + } + + sd = sqrt(sd * 0.25); + + // Generate final output + float3 output; + + if (debug_output == 2) + output = float3(0.0, 1.0, 0.0); + else + output = (ref[0] + ref[1] + ref[2] + ref[3]) * 0.25; + + // Generate a binary banding map + bool3 banding_map = true; + + if (debug_output != 1) { + if (enable_weber) + banding_map = banding_map && k <= t2 * iterations; + + if (enable_sdeviation) + banding_map = banding_map && sd <= t1 * iterations; + } + + /*------------------------. + | :: Ordered Dithering :: | + '------------------------*/ + //Calculate grid position + float grid_position = frac(dot(texcoord, (BUFFER_SCREEN_SIZE * float2(1.0 / 16.0, 10.0 / 36.0)) + 0.25)); + + //Calculate how big the shift should be + float dither_shift = 0.25 * (1.0 / (pow(2, BUFFER_COLOR_BIT_DEPTH) - 1.0)); + + //Shift the individual colors differently, thus making it even harder to see the dithering pattern + float3 dither_shift_RGB = float3(dither_shift, -dither_shift, dither_shift); //subpixel dithering + + //modify shift acording to grid position. + dither_shift_RGB = lerp(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position); //shift acording to grid position. + + return banding_map ? output + dither_shift_RGB : ori; +} + +technique Deband < +ui_tooltip = "Alleviates color banding by trying to approximate original color values."; +> +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_Deband; + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/Depth_Cues.fx b/data_from_portwine/Reshade/Shaders/Depth_Cues.fx new file mode 100644 index 00000000..a6f02ef1 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Depth_Cues.fx @@ -0,0 +1,425 @@ + ////---------------// + ///**Depth Cues**/// + //---------------//// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Depth Based Unsharp Mask haloing +// For Reshade 3.0+ +// --------------------------------- +// Depth Cues +// Extra Information for where I got the Idea for Depth Cues. +// https://www.uni-konstanz.de/mmsp/pubsys/publishedFiles/LuCoDe06.pdf +// +// LICENSE +// ============ +// Overwatch & Depth Cues is licenses under: Attribution-NoDerivatives 4.0 International +// +// 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. +// +// NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. +// +// 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-nd/4.0/ +// +// Have fun, +// Jose Negrete AKA BlueSkyDefender +// +// https://github.com/BlueSkyDefender/Depth3D +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if exists "Overwatch.fxh" //Overwatch Intercepter// + #include "Overwatch.fxh" +#else //DA_W Depth_Linearization | DB_X Depth_Flip + static const float DA_W = 0.0, DB_X = 0; + #define NC 0 + #define NP 0 +#endif + +//Automatic Blur Adjustment based on Resolutionsup to 8k considered. +#if (BUFFER_HEIGHT <= 720) + #define Multi 0.5 +#elif (BUFFER_HEIGHT <= 1080) + #define Multi 1.0 +#elif (BUFFER_HEIGHT <= 1440) + #define Multi 1.5 +#elif (BUFFER_HEIGHT <= 2160) + #define Multi 2 +#else + #define Quality 2.5 +#endif + +// It is best to run Smart Sharp after tonemapping. + +#if !defined(__RESHADE__) || __RESHADE__ < 40000 + #define Compatibility 1 +#else + #define Compatibility 0 +#endif + +uniform int Depth_Map < + ui_type = "combo"; + ui_items = "Normal\0Reverse\0"; + ui_label = "Custom Depth Map"; + ui_tooltip = "Pick your Depth Map."; + ui_category = "Depth Buffer"; +> = DA_W; + +uniform float Depth_Map_Adjust < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 1.0; ui_max = 1000.0; ui_step = 0.125; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "Adjust the depth map and sharpness distance."; + ui_category = "Depth Buffer"; +> = 250.0; + +uniform bool Depth_Map_Flip < + ui_label = "Depth Map Flip"; + ui_tooltip = "Flip the depth map if it is upside down."; + ui_category = "Depth Buffer"; +> = DB_X; + +uniform bool DEPTH_DEBUG < + ui_label = "View Depth"; + ui_tooltip = "Shows depth, you want close objects to be black and far objects to be white for things to work properly."; + ui_category = "Depth Buffer"; +> = false; + +uniform bool No_Depth_Map < + ui_label = "No Depth Map"; + ui_tooltip = "If you have No Depth Buffer turn this On."; + ui_category = "Depth Buffer"; +> = true; + +uniform float Shade_Power < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 0.25; ui_max = 1.0; + ui_label = "Shade Power"; + ui_tooltip = "Adjust the Shade Power This improves AO, Shadows, & Darker Areas in game.\n" + "Number 0.5 is default."; + ui_category = "Depth Cues"; +> = 0.5; + +uniform float Blur_Cues < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 0.0; ui_max = 1.0; + ui_label = "Blur Shade"; + ui_tooltip = "Adjust the to make Shade Softer in the Image.\n" + "Number 0.5 is default."; + ui_category = "Depth Cues"; +> = 0.5; + +uniform float Spread < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 1.0; ui_max = 25.0; ui_step = 0.25; + ui_label = "Shade Fill"; + ui_tooltip = "Adjust This to have the shade effect to fill in areas gives fakeAO effect.\n" + "This is used for gap filling.\n" + "Number 10.0 is default."; + ui_category = "Depth Cues"; +> = 10.0; + +uniform bool Debug_View < + ui_label = "Depth Cues Debug"; + ui_tooltip = "Depth Cues Debug output the shadeded output."; + ui_category = "Depth Cues"; +> = false; + +//uniform bool Fake_AO < +// ui_label = "Fake AO"; +// ui_tooltip = "Fake AO only works when you Have Depth Buffer Access."; +// ui_category = "Fake AO"; +//> = false; + +/////////////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +#define BlurSamples 10 //BlurSamples = # * 2 +//#define Fake_AO_Adjust 0.001 +#define S_Power Spread * Multi +#define M_Power Blur_Cues * Multi +uniform float timer < source = "timer"; >; + +texture DepthBufferTex : DEPTH; + +sampler DepthBuffer_DC + { + Texture = DepthBufferTex; + }; + +texture BackBufferTex : COLOR; + +sampler BackBuffer_DC + { + Texture = BackBufferTex; + }; + +texture texHB_DC { Width = BUFFER_WIDTH * 0.5 ; Height = BUFFER_HEIGHT * 0.5 ; Format = R8; MipLevels = 1;}; + +sampler SamplerHB_DC + { + Texture = texHB_DC; + }; + +texture texDC { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R8; MipLevels = 3;}; + +sampler SamplerDC + { + Texture = texDC; + }; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Depth_DC(in float2 texcoord : TEXCOORD0) +{ + if (Depth_Map_Flip) + texcoord.y = 1 - texcoord.y; + + float zBuffer = tex2D(DepthBuffer_DC, texcoord).x; //Depth Buffer + + //Conversions to linear space..... + //Near & Far Adjustment + float Far = 1.0, Near = 0.125/Depth_Map_Adjust; //Division Depth Map Adjust - Near + + float2 Z = float2( zBuffer, 1-zBuffer ); + + if (Depth_Map == 0)//DM0. Normal + zBuffer = Far * Near / (Far + Z.x * (Near - Far)); + else if (Depth_Map == 1)//DM1. Reverse + zBuffer = Far * Near / (Far + Z.y * (Near - Far)); + + return saturate(zBuffer); +} + +float lum(float3 RGB) +{ + return dot(RGB, float3(0.2126, 0.7152, 0.0722) ); +} + +float BB(in float2 texcoord, float2 AD) +{ + + //if(Fake_AO) + // return lerp(1-(1 - Fake_AO_Adjust/Depth_DC(texcoord + AD).x) , lum(tex2Dlod(BackBuffer_DC, float4(texcoord + AD,0,0)).rgb) , 0.125); + //else + return lum(tex2Dlod(BackBuffer_DC, float4(texcoord + AD,0,0)).rgb); + +} + +float H_Blur_DC(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float S = S_Power * 0.125; + + float sum = BB(texcoord,0) * BlurSamples; + + float total = BlurSamples; + + for ( int j = -BlurSamples; j <= BlurSamples; ++j) + { + float W = BlurSamples; + + sum += BB(texcoord , + float2(pix.x * S,0) * j ) * W; + + total += W; + } + return saturate(sum / total); // Get it Total sum..... :D +} + +// Spread the blur a bit more. +float DepthCues(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float2 S = S_Power * 0.75f * pix; + + float M_Cues = 1, result = tex2Dlod(SamplerHB_DC,float4(texcoord,0,M_Cues)).x; + result += tex2Dlod(SamplerHB_DC,float4(texcoord + float2( 1, 0) * S ,0,M_Cues)).x; + result += tex2Dlod(SamplerHB_DC,float4(texcoord + float2( 0, 1) * S ,0,M_Cues)).x; + result += tex2Dlod(SamplerHB_DC,float4(texcoord + float2(-1, 0) * S ,0,M_Cues)).x; + result += tex2Dlod(SamplerHB_DC,float4(texcoord + float2( 0,-1) * S ,0,M_Cues)).x; + S *= 0.5; + result += tex2Dlod(SamplerHB_DC,float4(texcoord + float2( 1, 0) * S ,0,M_Cues)).x; + result += tex2Dlod(SamplerHB_DC,float4(texcoord + float2( 0, 1) * S ,0,M_Cues)).x; + result += tex2Dlod(SamplerHB_DC,float4(texcoord + float2(-1, 0) * S ,0,M_Cues)).x; + result += tex2Dlod(SamplerHB_DC,float4(texcoord + float2( 0,-1) * S ,0,M_Cues)).x; + result *= rcp(9); + + // Formula for Image Pop = Original + (Original / Blurred). + //float DC = BB(texcoord,0) / result; +return saturate(lerp(1.0f,BB(texcoord,0) / result,Shade_Power)); +} + +float3 ShaderOut_DC(float2 texcoord : TEXCOORD0) +{ + float DCB = tex2Dlod(SamplerDC,float4(texcoord,0,M_Power)).x,DB = Depth_DC(texcoord).x; + float3 Out, BBN = tex2D(BackBuffer_DC,texcoord).rgb; + + if(No_Depth_Map) + DB = 0.0; + + Out.rgb = BBN * lerp(DCB,1., DB); + + if (Debug_View) + Out = lerp(DCB,1., DB); + + if (DEPTH_DEBUG) + Out = DB; + + return Out; +} +////////////////////////////////////////////////////////Logo///////////////////////////////////////////////////////////////////////// +float3 Out_DC(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ //Overwatch integration + float PosX = 0.9525f*BUFFER_WIDTH*pix.x,PosY = 0.975f*BUFFER_HEIGHT*pix.y, Text_Timer = 12500, BT = smoothstep(0,1,sin(timer*(3.75/1000))); + float D,E,P,T,H,Three,DD,Dot,I,N,F,O,R,EE,A,DDD,HH,EEE,L,PP,NN,PPP,C,Not,No; + float3 Color = ShaderOut_DC(texcoord).rgb; + + if(NC || NP) + Text_Timer = 18750; + + [branch] if(timer <= Text_Timer) + { + //DEPTH + //D + float PosXD = -0.035+PosX, offsetD = 0.001; + float OneD = all( abs(float2( texcoord.x -PosXD, texcoord.y-PosY)) < float2(0.0025,0.009)); + float TwoD = all( abs(float2( texcoord.x -PosXD-offsetD, texcoord.y-PosY)) < float2(0.0025,0.007)); + D = OneD-TwoD; + //E + float PosXE = -0.028+PosX, offsetE = 0.0005; + float OneE = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.009)); + float TwoE = all( abs(float2( texcoord.x -PosXE-offsetE, texcoord.y-PosY)) < float2(0.0025,0.007)); + float ThreeE = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.001)); + E = (OneE-TwoE)+ThreeE; + //P + float PosXP = -0.0215+PosX, PosYP = -0.0025+PosY, offsetP = 0.001, offsetP1 = 0.002; + float OneP = all( abs(float2( texcoord.x -PosXP, texcoord.y-PosYP)) < float2(0.0025,0.009*0.775)); + float TwoP = all( abs(float2( texcoord.x -PosXP-offsetP, texcoord.y-PosYP)) < float2(0.0025,0.007*0.680)); + float ThreeP = all( abs(float2( texcoord.x -PosXP+offsetP1, texcoord.y-PosY)) < float2(0.0005,0.009)); + P = (OneP-TwoP) + ThreeP; + //T + float PosXT = -0.014+PosX, PosYT = -0.008+PosY; + float OneT = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosYT)) < float2(0.003,0.001)); + float TwoT = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosY)) < float2(0.000625,0.009)); + T = OneT+TwoT; + //H + float PosXH = -0.0072+PosX; + float OneH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.001)); + float TwoH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.009)); + float ThreeH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.00325,0.009)); + H = (OneH-TwoH)+ThreeH; + //Three + float offsetFive = 0.001, PosX3 = -0.001+PosX; + float OneThree = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.009)); + float TwoThree = all( abs(float2( texcoord.x -PosX3 - offsetFive, texcoord.y-PosY)) < float2(0.003,0.007)); + float ThreeThree = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.001)); + Three = (OneThree-TwoThree)+ThreeThree; + //DD + float PosXDD = 0.006+PosX, offsetDD = 0.001; + float OneDD = all( abs(float2( texcoord.x -PosXDD, texcoord.y-PosY)) < float2(0.0025,0.009)); + float TwoDD = all( abs(float2( texcoord.x -PosXDD-offsetDD, texcoord.y-PosY)) < float2(0.0025,0.007)); + DD = OneDD-TwoDD; + //Dot + float PosXDot = 0.011+PosX, PosYDot = 0.008+PosY; + float OneDot = all( abs(float2( texcoord.x -PosXDot, texcoord.y-PosYDot)) < float2(0.00075,0.0015)); + Dot = OneDot; + //INFO + //I + float PosXI = 0.0155+PosX, PosYI = 0.004+PosY, PosYII = 0.008+PosY; + float OneI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosY)) < float2(0.003,0.001)); + float TwoI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYI)) < float2(0.000625,0.005)); + float ThreeI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYII)) < float2(0.003,0.001)); + I = OneI+TwoI+ThreeI; + //N + float PosXN = 0.0225+PosX, PosYN = 0.005+PosY,offsetN = -0.001; + float OneN = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN)) < float2(0.002,0.004)); + float TwoN = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN - offsetN)) < float2(0.003,0.005)); + N = OneN-TwoN; + //F + float PosXF = 0.029+PosX, PosYF = 0.004+PosY, offsetF = 0.0005, offsetF1 = 0.001; + float OneF = all( abs(float2( texcoord.x -PosXF-offsetF, texcoord.y-PosYF-offsetF1)) < float2(0.002,0.004)); + float TwoF = all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0025,0.005)); + float ThreeF = all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0015,0.00075)); + F = (OneF-TwoF)+ThreeF; + //O + float PosXO = 0.035+PosX, PosYO = 0.004+PosY; + float OneO = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.003,0.005)); + float TwoO = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.002,0.003)); + O = OneO-TwoO; + //Text Warnings: No Profile / Not Compatible + //PosY += 0.953; + PosX -= 0.483; + float PosXNN = -0.458+PosX, offsetNN = 0.0015; + float OneNN = all( abs(float2( texcoord.x -PosXNN, texcoord.y-PosY)) < float2(0.00325,0.009)); + float TwoNN = all( abs(float2( texcoord.x -PosXNN, texcoord.y-PosY-offsetNN)) < float2(0.002,0.008)); + NN = OneNN-TwoNN; + //PPP + float PosXPPP = -0.451+PosX, PosYPPP = -0.0025+PosY, offsetPPP = 0.001, offsetPPP1 = 0.002; + float OnePPP = all( abs(float2( texcoord.x -PosXPPP, texcoord.y-PosYPPP)) < float2(0.0025,0.009*0.775)); + float TwoPPP = all( abs(float2( texcoord.x -PosXPPP-offsetPPP, texcoord.y-PosYPPP)) < float2(0.0025,0.007*0.680)); + float ThreePPP = all( abs(float2( texcoord.x -PosXPPP+offsetPPP1, texcoord.y-PosY)) < float2(0.0005,0.009)); + PPP = (OnePPP-TwoPPP) + ThreePPP; + //C + float PosXC = -0.450+PosX, offsetC = 0.001; + float OneC = all( abs(float2( texcoord.x -PosXC, texcoord.y-PosY)) < float2(0.0035,0.009)); + float TwoC = all( abs(float2( texcoord.x -PosXC-offsetC, texcoord.y-PosY)) < float2(0.0025,0.007)); + C = OneC-TwoC; + if(NP) + No = (NN + PPP) * BT; //Blinking Text + if(NC) + Not = (NN + C) * BT; //Blinking Text + //Website + return D+E+P+T+H+Three+DD+Dot+I+N+F+O+No+Not ? (1-texcoord.y*50.0+48.85)*texcoord.y-0.500: Color; + } + else + return Color; +} +///////////////////////////////////////////////////////////ReShade.fxh///////////////////////////////////////////////////////////// + +// 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) +{ + 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 Monocular_Cues +{ + + pass Blur + { + VertexShader = PostProcessVS; + PixelShader = H_Blur_DC; + RenderTarget = texHB_DC; + } + pass BlurDC + { + VertexShader = PostProcessVS; + PixelShader = DepthCues; + RenderTarget = texDC; + } + pass UnsharpMask + { + VertexShader = PostProcessVS; + PixelShader = Out_DC; + } +} diff --git a/data_from_portwine/Reshade/Shaders/DisplayDepth.fx b/data_from_portwine/Reshade/Shaders/DisplayDepth.fx new file mode 100644 index 00000000..0e5ebad0 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/DisplayDepth.fx @@ -0,0 +1,258 @@ +/* + DisplayDepth by CeeJay.dk (with many updates and additions by the Reshade community) + + Visualizes the depth buffer. The distance of pixels determine their brightness. + Close objects are dark. Far away objects are bright. + Use this to configure the depth input preprocessor definitions (RESHADE_DEPTH_INPUT_*). +*/ + +#include "ReShade.fxh" + +uniform int iUIPresentType < + ui_type = "combo"; + ui_label = "Present type"; + ui_items = "Depth map\0" + "Normal map\0" + "Show both (Vertical 50/50)\0"; +> = 2; + +// -- Basic options -- +#if __RESHADE__ >= 40500 // If Reshade version is above or equal to 4.5 + #if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN + #define UPSIDE_DOWN_HELP_TEXT "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN is currently set to 1.\n"\ + "If the Depth map is shown upside down set it to 0." + #define iUIUpsideDown 1 + #else + #define UPSIDE_DOWN_HELP_TEXT "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN is currently set to 0.\n"\ + "If the Depth map is shown upside down set it to 1." + #define iUIUpsideDown 0 + #endif + + #if RESHADE_DEPTH_INPUT_IS_REVERSED + #define REVERSED_HELP_TEXT "RESHADE_DEPTH_INPUT_IS_REVERSED is currently set to 1.\n"\ + "If close objects in the Depth map are bright and far ones are dark set it to 0.\n"\ + "Also try this if you can see the normals, but the depth view is all black." + #define iUIReversed 1 + #else + #define REVERSED_HELP_TEXT "RESHADE_DEPTH_INPUT_IS_REVERSED is currently set to 0.\n"\ + "If close objects in the Depth map are bright and far ones are dark set it to 1.\n"\ + "Also try this if you can see the normals, but the depth view is all black." + #define iUIReversed 0 + #endif + + #if RESHADE_DEPTH_INPUT_IS_LOGARITHMIC + #define LOGARITHMIC_HELP_TEXT "RESHADE_DEPTH_INPUT_IS_LOGARITHMIC is currently set to 1.\n"\ + "If the Normal map has banding artifacts (extra stripes) set it to 0." + #define iUILogarithmic 1 + #else + #define LOGARITHMIC_HELP_TEXT "RESHADE_DEPTH_INPUT_IS_LOGARITHMIC is currently set to 0.\n"\ + "If the Normal map has banding artifacts (extra stripes) set it to 1." + #define iUILogarithmic 0 + #endif + + uniform int Depth_help < + ui_type = "radio"; ui_label = " "; + ui_text = + "\nThe right settings need to be set in the dialog that opens after clicking the \"Edit global preprocessor definitions\" button above.\n" + "\n" + UPSIDE_DOWN_HELP_TEXT "\n" + "\n" + REVERSED_HELP_TEXT "\n" + "\n" + LOGARITHMIC_HELP_TEXT; + >; +#else // "ui_text" was introduced in ReShade 4.5, so cannot show instructions in older versions + uniform bool bUIUseLivePreview < + ui_label = "Show live preview"; + ui_tooltip = "Enable this to show use the preview settings below rather than the saved preprocessor settings."; + > = true; + + uniform int iUIUpsideDown < + ui_type = "combo"; + ui_label = "Upside Down (Preview)"; + ui_items = "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN=0\0" + "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN=1\0"; + > = RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN; + + uniform int iUIReversed < + ui_type = "combo"; + ui_label = "Reversed (Preview)"; + ui_items = "RESHADE_DEPTH_INPUT_IS_REVERSED=0\0" + "RESHADE_DEPTH_INPUT_IS_REVERSED=1\0"; + > = RESHADE_DEPTH_INPUT_IS_REVERSED; + + uniform int iUILogarithmic < + ui_type = "combo"; + ui_label = "Logarithmic (Preview)"; + ui_items = "RESHADE_DEPTH_INPUT_IS_LOGARITHMIC=0\0" + "RESHADE_DEPTH_INPUT_IS_LOGARITHMIC=1\0"; + ui_tooltip = "Change this setting if the displayed surface normals have stripes in them."; + > = RESHADE_DEPTH_INPUT_IS_LOGARITHMIC; +#endif + +// -- Advanced options -- +#if __RESHADE__ >= 40500 +uniform int Advanced_help < + ui_category = "Advanced settings"; + ui_category_closed = true; + ui_type = "radio"; ui_label = " "; + ui_text = + "\nThe following settings also need to be set using \"Edit global preprocessor definitions\" above in order to take effect.\n" + "You can preview how they will affect the Depth map using the controls below.\n\n" + "It is rarely necessary to change these though, as their defaults fit almost all games."; + >; + + uniform bool bUIUseLivePreview < + ui_category = "Advanced settings"; + ui_label = "Show live preview"; + ui_tooltip = "Enable this to show use the preview settings below rather than the saved preprocessor settings."; + > = true; +#endif + +uniform float2 fUIScale < + ui_category = "Advanced settings"; + ui_type = "drag"; + ui_label = "Scale (Preview)"; + ui_tooltip = "Best use 'Present type'->'Depth map' and enable 'Offset' in the options below to set the scale.\n" + "Use these values for:\nRESHADE_DEPTH_INPUT_X_SCALE=\nRESHADE_DEPTH_INPUT_Y_SCALE=\n" + "\n" + "If you know the right resolution of the games depth buffer then this scale value is simply the ratio\n" + "between the correct resolution and the resolution Reshade thinks it is.\n" + "For example:\n" + "If it thinks the resolution is 1920 x 1080, but it's really 1280 x 720 then the right scale is (1.5 , 1.5)\n" + "because 1920 / 1280 is 1.5 and 1080 / 720 is also 1.5, so 1.5 is the right scale for both the x and the y"; + ui_min = 0.0; ui_max = 2.0; + ui_step = 0.001; +> = float2(RESHADE_DEPTH_INPUT_X_SCALE, RESHADE_DEPTH_INPUT_Y_SCALE); + +uniform int2 iUIOffset < + ui_category = "Advanced settings"; + ui_type = "drag"; + ui_label = "Offset (Preview)"; + ui_tooltip = "Best use 'Present type'->'Depth map' and enable 'Offset' in the options below to set the offset in pixels.\n" + "Use these values for:\nRESHADE_DEPTH_INPUT_X_PIXEL_OFFSET=\nRESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET="; + ui_step = 1; +> = int2(RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET, RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET); + +uniform bool bUIShowOffset < + ui_category = "Advanced settings"; + ui_label = "Blend Depth map into the image (to help with finding the right offset)"; +> = false; + +uniform float fUIFarPlane < + ui_category = "Advanced settings"; + ui_type = "drag"; + ui_label = "Far Plane (Preview)"; + ui_tooltip = "RESHADE_DEPTH_LINEARIZATION_FAR_PLANE=\n" + "Changing this value is not necessary in most cases."; + ui_min = 0.0; ui_max = 1000.0; + ui_step = 0.1; +> = RESHADE_DEPTH_LINEARIZATION_FAR_PLANE; + +uniform float fUIDepthMultiplier < + ui_category = "Advanced settings"; + ui_type = "drag"; + ui_label = "Multiplier (Preview)"; + ui_tooltip = "RESHADE_DEPTH_MULTIPLIER="; + ui_min = 0.0; ui_max = 1000.0; + ui_step = 0.001; +> = RESHADE_DEPTH_MULTIPLIER; + + +float GetLinearizedDepth(float2 texcoord) +{ + if (!bUIUseLivePreview) + { + return ReShade::GetLinearizedDepth(texcoord); + } + else + { + if (iUIUpsideDown) // RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN + texcoord.y = 1.0 - texcoord.y; + + texcoord.x /= fUIScale.x; // RESHADE_DEPTH_INPUT_X_SCALE + texcoord.y /= fUIScale.y; // RESHADE_DEPTH_INPUT_Y_SCALE + texcoord.x -= iUIOffset.x * BUFFER_RCP_WIDTH; // RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET + texcoord.y += iUIOffset.y * BUFFER_RCP_HEIGHT; // RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET + + float depth = tex2Dlod(ReShade::DepthBuffer, float4(texcoord, 0, 0)).x * fUIDepthMultiplier; + + const float C = 0.01; + if (iUILogarithmic) // RESHADE_DEPTH_INPUT_IS_LOGARITHMIC + depth = (exp(depth * log(C + 1.0)) - 1.0) / C; + + if (iUIReversed) // RESHADE_DEPTH_INPUT_IS_REVERSED + depth = 1.0 - depth; + + const float N = 1.0; + depth /= fUIFarPlane - depth * (fUIFarPlane - N); + + return depth; + } +} + +float3 GetScreenSpaceNormal(float2 texcoord) +{ + float3 offset = float3(BUFFER_PIXEL_SIZE, 0.0); + float2 posCenter = texcoord.xy; + float2 posNorth = posCenter - offset.zy; + float2 posEast = posCenter + offset.xz; + + float3 vertCenter = float3(posCenter - 0.5, 1) * GetLinearizedDepth(posCenter); + float3 vertNorth = float3(posNorth - 0.5, 1) * GetLinearizedDepth(posNorth); + float3 vertEast = float3(posEast - 0.5, 1) * GetLinearizedDepth(posEast); + + return normalize(cross(vertCenter - vertNorth, vertCenter - vertEast)) * 0.5 + 0.5; +} + +void PS_DisplayDepth(in float4 position : SV_Position, in float2 texcoord : TEXCOORD, out float3 color : SV_Target) +{ + float3 depth = GetLinearizedDepth(texcoord).xxx; + float3 normal = GetScreenSpaceNormal(texcoord); + + // Ordered dithering +#if 1 + const float dither_bit = 8.0; // Number of bits per channel. Should be 8 for most monitors. + // Calculate grid position + float grid_position = frac(dot(texcoord, (BUFFER_SCREEN_SIZE * float2(1.0 / 16.0, 10.0 / 36.0)) + 0.25)); + // Calculate how big the shift should be + float dither_shift = 0.25 * (1.0 / (pow(2, dither_bit) - 1.0)); + // Shift the individual colors differently, thus making it even harder to see the dithering pattern + float3 dither_shift_RGB = float3(dither_shift, -dither_shift, dither_shift); // Subpixel dithering + // Modify shift acording to grid position. + dither_shift_RGB = lerp(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position); + depth += dither_shift_RGB; +#endif + + color = depth; + if (iUIPresentType == 1) + color = normal; + if (iUIPresentType == 2) + color = lerp(normal, depth, step(BUFFER_WIDTH * 0.5, position.x)); + + if (bUIShowOffset) + { + float3 color_orig = tex2D(ReShade::BackBuffer, texcoord).rgb; + + // Blend depth and back buffer color with 'overlay' so the offset is more noticeable + color = lerp(2 * color * color_orig, 1.0 - 2.0 * (1.0 - color) * (1.0 - color_orig), max(color.r, max(color.g, color.b)) < 0.5 ? 0.0 : 1.0); + } +} + +technique DisplayDepth < + ui_tooltip = "This shader helps you set the right preprocessor settings for depth input.\n" + "To set the settings click on 'Edit global preprocessor definitions' and set them there - not in this shader.\n" + "The settings will then take effect for all shaders, including this one.\n" + "\n" + "By default calculated normals and depth are shown side by side.\n" + "Normals (on the left) should look smooth and the ground should be greenish when looking at the horizon.\n" + "Depth (on the right) should show close objects as dark and use gradually brighter shades the further away objects are.\n"; +> + +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_DisplayDepth; + } +} diff --git a/data_from_portwine/Reshade/Shaders/DrawText.fxh b/data_from_portwine/Reshade/Shaders/DrawText.fxh new file mode 100644 index 00000000..61974add --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/DrawText.fxh @@ -0,0 +1,228 @@ +#ifndef _DRAWTEXT_H_ +#define _DRAWTEXT_H_ + +#define _DRAWTEXT_GRID_X 14.0 +#define _DRAWTEXT_GRID_Y 7.0 + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// DrawText.fxh by kingreic1992 ( update: Sep.28.2019 ) // +// // +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// +// // +// Available functions: // +// DrawText_String( offset, text size, xy ratio, input coord, string array, array size, output) // +// float2 offset = top left corner of string, screen hight pixel unit. // +// float text size = text size, screen hight pixel unit. // +// float xy ratio = xy ratio of text. // +// float2 input coord = current texture coord. // +// int string array = string data in float2 array format, ex: "Demo Text" // +// int String0[9] = { __D, __e, __m, __o, __Space, __T, __e, __x, __t}; // +// int string size = size of the string array. // +// float output = output. // +// // +// DrawText_Digit( offset, text size, xy ratio, input coord, precision after dot, data, output) // +// float2 offset = same as DrawText_String. // +// float text size = same as DrawText_String. // +// float xy ratio = same as DrawText_String. // +// float2 input coord = same as DrawText_String. // +// int precision = digits after dot. // +// float data = input float. // +// float output = output. // +// // +// float2 DrawText_Shift(offset, shift, text size, xy ratio) // +// float2 offset = same as DrawText_String. // +// float2 shift = shift line(y) and column. // +// float text size = same as DrawText_String. // +// float xy ratio = same as DrawText_String. // +// // +/////////////////////////////////////////////////////////////////////////////////////////////////////// + + +//Sample Usage + +/* + +#include "DrawText.fxh" + +float4 main_fragment( float4 position : POSITION, + float2 txcoord : TEXCOORD) : COLOR { + float res = 0.0; + + int line0[9] = { __D, __e, __m, __o, __Space, __T, __e, __x, __t }; //Demo Text + int line1[15] = { __b, __y, __Space, __k, __i, __n, __g, __e, __r, __i, __c, __1, __9, __9, __2 }; //by kingeric1992 + int line2[6] = { __S, __i, __z, __e, __Colon, __Space }; // Size: %d. + + DrawText_String(float2(100.0 , 100.0), 32, 1, txcoord, line0, 9, res); + DrawText_String(float2(100.0 , 134.0), textSize, 1, txcoord, line1, 15, res); + DrawText_String(DrawText_Shift(float2(100.0 , 134.0), int2(0, 1), textSize, 1), 18, 1, txcoord, line2, 6, res); + DrawText_Digit(DrawText_Shift(DrawText_Shift(float2(100.0 , 134.0), int2(0, 1), textSize, 1), int2(8, 0), 18, 1), + 18, 1, txcoord, 0, textSize, res); + return res; +} +*/ + +//Text display +//Character indexing +#define __Space 0 // (space) +#define __Exclam 1 // ! +#define __Quote 2 // " +#define __Pound 3 // # +#define __Dollar 4 // $ +#define __Percent 5 // % +#define __And 6 // & +#define __sQuote 7 // ' +#define __rBrac_O 8 // ( +#define __rBrac_C 9 // ) +#define __Asterisk 10 // * +#define __Plus 11 // + +#define __Comma 12 // , +#define __Minus 13 // - + +#define __Dot 14 // . +#define __Slash 15 // / +#define __0 16 // 0 +#define __1 17 // 1 +#define __2 18 // 2 +#define __3 19 // 3 +#define __4 20 // 4 +#define __5 21 // 5 +#define __6 22 // 6 +#define __7 23 // 7 +#define __8 24 // 8 +#define __9 25 // 9 +#define __Colon 26 // : +#define __sColon 27 // ; + +#define __Less 28 // < +#define __Equals 29 // = +#define __Greater 30 // > +#define __Question 31 // ? +#define __at 32 // @ +#define __A 33 // A +#define __B 34 // B +#define __C 35 // C +#define __D 36 // D +#define __E 37 // E +#define __F 38 // F +#define __G 39 // G +#define __H 40 // H +#define __I 41 // I + +#define __J 42 // J +#define __K 43 // K +#define __L 44 // L +#define __M 45 // M +#define __N 46 // N +#define __O 47 // O +#define __P 48 // P +#define __Q 49 // Q +#define __R 50 // R +#define __S 51 // S +#define __T 52 // T +#define __U 53 // U +#define __V 54 // V +#define __W 55 // W + +#define __X 56 // X +#define __Y 57 // Y +#define __Z 58 // Z +#define __sBrac_O 59 // [ +#define __Backslash 60 // \.. +#define __sBrac_C 61 // ] +#define __Caret 62 // ^ +#define __Underscore 63 // _ +#define __Punc 64 // ` +#define __a 65 // a +#define __b 66 // b +#define __c 67 // c +#define __d 68 // d +#define __e 69 // e + +#define __f 70 // f +#define __g 71 // g +#define __h 72 // h +#define __i 73 // i +#define __j 74 // j +#define __k 75 // k +#define __l 76 // l +#define __m 77 // m +#define __n 78 // n +#define __o 79 // o +#define __p 80 // p +#define __q 81 // q +#define __r 82 // r +#define __s 83 // s + +#define __t 84 // t +#define __u 85 // u +#define __v 86 // v +#define __w 87 // w +#define __x 88 // x +#define __y 89 // y +#define __z 90 // z +#define __cBrac_O 91 // { +#define __vBar 92 // | +#define __cBrac_C 93 // } +#define __Tilde 94 // ~ +#define __tridot 95 // (...) +#define __empty0 96 // (null) +#define __empty1 97 // (null) +//Character indexing ends + +texture Texttex < source = "FontAtlas.png"; > { + Width = 512; + Height = 512; +}; + +sampler samplerText { + Texture = Texttex; +}; + +//accomodate for undef array size. +#define DrawText_String( pos, size, ratio, tex, array, arrSize, output ) \ + { float text = 0.0; \ + float2 uv = (tex * float2(BUFFER_WIDTH, BUFFER_HEIGHT) - pos) / size; \ + uv.y = saturate(uv.y); \ + uv.x *= ratio * 2.0; \ + float id = array[int(trunc(uv.x))]; \ + if(uv.x <= arrSize && uv.x >= 0.0) \ + text = tex2D(samplerText, (frac(uv) + float2( id % 14.0, trunc(id / 14.0))) \ + / float2( _DRAWTEXT_GRID_X, _DRAWTEXT_GRID_Y) ).x; \ + output += text; } + +float2 DrawText_Shift( float2 pos, int2 shift, float size, float ratio ) { + return pos + size * shift * float2(0.5, 1.0) / ratio; +} + +void DrawText_Digit( float2 pos, float size, float ratio, float2 tex, int digit, float data, inout float res) { + int digits[13] = { + __0, __1, __2, __3, __4, __5, __6, __7, __8, __9, __Minus, __Space, __Dot + }; + + float2 uv = (tex * float2(BUFFER_WIDTH, BUFFER_HEIGHT) - pos) / size; + uv.y = saturate(uv.y); + uv.x *= ratio * 2.0; + + float t = abs(data); + int radix = floor(t)? ceil(log2(t)/3.32192809):0; + + //early exit: + if(uv.x > digit+1 || -uv.x > radix+1) return; + + float index = t; + if(floor(uv.x) > 0) + for(int i = ceil(-uv.x); i<0; i++) index *= 10.; + else + for(int i = ceil(uv.x); i<0; i++) index /= 10.; + + index = (uv.x >= -radix-!radix)? index%10 : (10+step(0, data)); //adding sign + index = (uv.x > 0 && uv.x < 1)? 12:index; //adding dot + index = digits[(uint)index]; + + res += tex2D(samplerText, (frac(uv) + float2( index % 14.0, trunc(index / 14.0))) / + float2( _DRAWTEXT_GRID_X, _DRAWTEXT_GRID_Y)).x; +} + +#endif \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/FXAA.fx b/data_from_portwine/Reshade/Shaders/FXAA.fx new file mode 100644 index 00000000..3fefda1e --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/FXAA.fx @@ -0,0 +1,127 @@ +/** + * FXAA 3.11 + * + * for ReShade 3.0+ + */ + +#include "ReShadeUI.fxh" + +uniform float Subpix < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Amount of sub-pixel aliasing removal. Higher values makes the image softer/blurrier."; +> = 0.25; + +uniform float EdgeThreshold < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_label = "Edge Detection Threshold"; + ui_tooltip = "The minimum amount of local contrast required to apply algorithm."; +> = 0.125; +uniform float EdgeThresholdMin < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_label = "Darkness Threshold"; + ui_tooltip = "Pixels darker than this are not processed in order to increase performance."; +> = 0.0; + +//------------------------------ Non-GUI-settings ------------------------------------------------- + +#ifndef FXAA_QUALITY__PRESET + // Valid Quality Presets + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + #define FXAA_QUALITY__PRESET 15 +#endif + +#ifndef FXAA_GREEN_AS_LUMA + #define FXAA_GREEN_AS_LUMA 0 +#endif + +#ifndef FXAA_LINEAR_LIGHT + #define FXAA_LINEAR_LIGHT 0 +#endif + +//------------------------------------------------------------------------------------------------- + +#if (__RENDERER__ == 0xb000 || __RENDERER__ == 0xb100) + #define FXAA_GATHER4_ALPHA 1 + #define FxaaTexAlpha4(t, p) tex2Dgather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) tex2Dgatheroffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) tex2Dgather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) tex2Dgatheroffset(t, p, o, 1) +#endif + +#define FXAA_PC 1 +#define FXAA_HLSL_3 1 + +// Green as luma requires non-linear colorspace +#if FXAA_GREEN_AS_LUMA + #undef FXAA_LINEAR_LIGHT +#endif + +#include "FXAA.fxh" +#include "ReShade.fxh" + +// Samplers + +sampler FXAATexture +{ + Texture = ReShade::BackBufferTex; + MinFilter = Linear; MagFilter = Linear; + #if FXAA_LINEAR_LIGHT + SRGBTexture = true; + #endif +}; + +// Pixel shaders + +#if !FXAA_GREEN_AS_LUMA +float4 FXAALumaPass(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float4 color = tex2D(ReShade::BackBuffer, texcoord.xy); + color.a = sqrt(dot(color.rgb * color.rgb, float3(0.299, 0.587, 0.114))); + return color; +} +#endif + +float4 FXAAPixelShader(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + return FxaaPixelShader( + texcoord, // pos + 0, // fxaaConsolePosPos + FXAATexture, // tex + FXAATexture, // fxaaConsole360TexExpBiasNegOne + FXAATexture, // fxaaConsole360TexExpBiasNegTwo + BUFFER_PIXEL_SIZE, // fxaaQualityRcpFrame + 0, // fxaaConsoleRcpFrameOpt + 0, // fxaaConsoleRcpFrameOpt2 + 0, // fxaaConsole360RcpFrameOpt2 + Subpix, // fxaaQualitySubpix + EdgeThreshold, // fxaaQualityEdgeThreshold + EdgeThresholdMin, // fxaaQualityEdgeThresholdMin + 0, // fxaaConsoleEdgeSharpness + 0, // fxaaConsoleEdgeThreshold + 0, // fxaaConsoleEdgeThresholdMin + 0 // fxaaConsole360ConstDir + ); +} + +// Rendering passes + +technique FXAA +{ +#if !FXAA_GREEN_AS_LUMA + pass + { + VertexShader = PostProcessVS; + PixelShader = FXAALumaPass; + } +#endif + pass + { + VertexShader = PostProcessVS; + PixelShader = FXAAPixelShader; + #if FXAA_LINEAR_LIGHT + SRGBWriteEnable = true; + #endif + } +} diff --git a/data_from_portwine/Reshade/Shaders/FXAA.fxh b/data_from_portwine/Reshade/Shaders/FXAA.fxh new file mode 100644 index 00000000..92a37374 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/FXAA.fxh @@ -0,0 +1,2047 @@ +/*============================================================================ + + + NVIDIA FXAA 3.11 by TIMOTHY LOTTES + + +------------------------------------------------------------------------------ +COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. +------------------------------------------------------------------------------ +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR +LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, +OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE +THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +------------------------------------------------------------------------------ + INTEGRATION CHECKLIST +------------------------------------------------------------------------------ +(1.) +In the shader source, setup defines for the desired configuration. +When providing multiple shaders (for different presets), +simply setup the defines differently in multiple files. +Example, + + #define FXAA_PC 1 + #define FXAA_HLSL_5 1 + #define FXAA_QUALITY__PRESET 12 + +Or, + + #define FXAA_360 1 + +Or, + + #define FXAA_PS3 1 + +Etc. + +(2.) +Then include this file, + + #include "Fxaa3_11.h" + +(3.) +Then call the FXAA pixel shader from within your desired shader. +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. +As for FXAA 3.11 all inputs for all shaders are the same +to enable easy porting between platforms. + + return FxaaPixelShader(...); + +(4.) +Insure pass prior to FXAA outputs RGBL (see next section). +Or use, + + #define FXAA_GREEN_AS_LUMA 1 + +(5.) +Setup engine to provide the following constants +which are used in the FxaaPixelShader() inputs, + + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir + +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. + +(6.) +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + + // {xy} = center of pixel + FxaaFloat2 pos, + + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + +(7.) +Insure the texture sampler(s) used by FXAA are set to bilinear filtering. + + +------------------------------------------------------------------------------ + INTEGRATION - RGBL AND COLORSPACE +------------------------------------------------------------------------------ +FXAA3 requires RGBL as input unless the following is set, + + #define FXAA_GREEN_AS_LUMA 1 + +In which case the engine uses green in place of luma, +and requires RGB input is in a non-linear colorspace. + +RGB should be LDR (low dynamic range). +Specifically do FXAA after tonemapping. + +RGB data as returned by a texture fetch can be non-linear, +or linear when FXAA_GREEN_AS_LUMA is not set. +Note an "sRGB format" texture counts as linear, +because the result of a texture fetch is linear data. +Regular "RGBA8" textures in the sRGB colorspace are non-linear. + +If FXAA_GREEN_AS_LUMA is not set, +luma must be stored in the alpha channel prior to running FXAA. +This luma should be in a perceptual space (could be gamma 2.0). +Example pass before FXAA where output is gamma 2.0 encoded, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma + return color; + +Another example where output is linear encoded, +say for instance writing to an sRGB formated render target, +where the render target does the conversion back to sRGB after blending, + + color.rgb = ToneMap(color.rgb); // linear color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma + return color; + +Getting luma correct is required for the algorithm to work correctly. + + +------------------------------------------------------------------------------ + BEING LINEARLY CORRECT? +------------------------------------------------------------------------------ +Applying FXAA to a framebuffer with linear RGB color will look worse. +This is very counter intuitive, but happends to be true in this case. +The reason is because dithering artifacts will be more visiable +in a linear colorspace. + + +------------------------------------------------------------------------------ + COMPLEX INTEGRATION +------------------------------------------------------------------------------ +Q. What if the engine is blending into RGB before wanting to run FXAA? + +A. In the last opaque pass prior to FXAA, + have the pass write out luma into alpha. + Then blend into RGB only. + FXAA should be able to run ok + assuming the blending pass did not any add aliasing. + This should be the common case for particles and common blending passes. + +A. Or use FXAA_GREEN_AS_LUMA. + +============================================================================*/ + +/*============================================================================ + + INTEGRATION KNOBS + +============================================================================*/ +// +// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). +// FXAA_360_OPT is a prototype for the new optimized 360 version. +// +// 1 = Use API. +// 0 = Don't use API. +// +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PS3 + #define FXAA_PS3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360 + #define FXAA_360 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360_OPT + #define FXAA_360_OPT 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_PC + // + // FXAA Quality + // The high quality PC algorithm. + // + #define FXAA_PC 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE + // + // The console algorithm for PC is included + // for developers targeting really low spec machines. + // Likely better to just run FXAA_PC, and use a really low preset. + // + #define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 + #define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 + #define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 + #define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 + #define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 + #define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA + // + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT + // + // Controls algorithm's early exit path. + // On PS3 turning this ON adds 2 cycles to the shader. + // On 360 turning this OFF adds 10ths of a millisecond to the shader. + // Turning this off on console will result in a more blurry image. + // So this defaults to on. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD + // + // Only valid for PC OpenGL currently. + // Probably will not work when FXAA_GREEN_AS_LUMA = 1. + // + // 1 = Use discard on pixels which don't need AA. + // For APIs which enable concurrent TEX+ROP from same surface. + // 0 = Return unchanged color on pixels which don't need AA. + // + #define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET + // + // Used for GLSL 120 only. + // + // 1 = GL API supports fast pixel offsets + // 0 = do not use fast pixel offsets + // + #ifdef GL_EXT_gpu_shader4 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifndef FXAA_FAST_PIXEL_OFFSET + #define FXAA_FAST_PIXEL_OFFSET 0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA + // + // 1 = API supports gather4 on alpha channel. + // 0 = API does not support gather4 on alpha channel. + // + #if (FXAA_HLSL_5 == 1) + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifndef FXAA_GATHER4_ALPHA + #define FXAA_GATHER4_ALPHA 0 + #endif +#endif + +/*============================================================================ + FXAA CONSOLE PS3 - TUNING KNOBS +============================================================================*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS + // + // Consoles the sharpness of edges on PS3 only. + // Non-PS3 tuning is done with shader input. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 8.0 is sharper + // 4.0 is softer + // 2.0 is really soft (good for vector graphics inputs) + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD + // + // Only effects PS3. + // Non-PS3 tuning is done with shader input. + // + // The minimum amount of local contrast required to apply algorithm. + // The console setting has a different mapping than the quality setting. + // + // This only applies when FXAA_EARLY_EXIT is 1. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 0.25 and 0.125. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 0.125 leaves less aliasing, but is softer + // 0.25 leaves more aliasing, and is sharper + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 + #else + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 + #endif +#endif + +/*============================================================================ + FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET + // + // Choose the quality preset. + // This needs to be compiled into the shader as it effects code. + // Best option to include multiple presets is to + // in each shader define the preset, then include this file. + // + // OPTIONS + // ----------------------------------------------------------------------- + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + // + // NOTES + // ----------------------------------------------------------------------- + // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) + // 13 = about same speed as FXAA 3.9 and better than 12 + // 23 = closest to FXAA 3.9 visually and performance wise + // _ = the lowest digit is directly related to performance + // _ = the highest digit is directly related to style + // + #define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + + FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ + FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 3.0 + #define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 3.0 + #define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 4.0 + #define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 4.0 + #define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 4.0 + #define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ + FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 2.0 + #define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 3.0 + #define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) + #define FXAA_QUALITY__PS 9 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 4.0 + #define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) + #define FXAA_QUALITY__PS 10 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 4.0 + #define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) + #define FXAA_QUALITY__PS 11 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 4.0 + #define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ + FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.0 + #define FXAA_QUALITY__P2 1.0 + #define FXAA_QUALITY__P3 1.0 + #define FXAA_QUALITY__P4 1.0 + #define FXAA_QUALITY__P5 1.5 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + + API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +#else + #define FxaaBool bool + #define FxaaDiscard clip(-1) + #define FxaaFloat float + #define FxaaFloat2 float2 + #define FxaaFloat3 float3 + #define FxaaFloat4 float4 + #define FxaaHalf half + #define FxaaHalf2 half2 + #define FxaaHalf3 half3 + #define FxaaHalf4 half4 + #define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) + // Requires, + // #version 120 + // And at least, + // #extension GL_EXT_gpu_shader4 : enable + // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) + #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) + #if (FXAA_FAST_PIXEL_OFFSET == 1) + #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) + #else + #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) + #endif + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) + // Requires "#version 130" or better + #define FxaaTexTop(t, p) textureLod(t, p, 0.0) + #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) + #define FxaaInt2 float2 + #define FxaaTex sampler2D + #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) + #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_4 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) + #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p) + #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o) + #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) + #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) +#endif + + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + + FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 2nd sampler. + // This sampler needs to have an exponent bias of -1. + FxaaTex fxaaConsole360TexExpBiasNegOne, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 3nd sampler. + // This sampler needs to have an exponent bias of -2. + FxaaTex fxaaConsole360TexExpBiasNegTwo, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 fxaaQualityRcpFrame, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. + // This must be from a constant/uniform. + // {x___} = 8.0/screenWidthInPixels + // {_y__} = 8.0/screenHeightInPixels + // {__z_} = -4.0/screenWidthInPixels + // {___w} = -4.0/screenHeightInPixels + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + FxaaFloat fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + FxaaFloat fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaQualityEdgeThresholdMin, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This only applies when FXAA_EARLY_EXIT is 1. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin, + // + // Extra constants for 360 FXAA Console only. + // Use zeros or anything else for other platforms. + // These must be in physical constant registers and NOT immedates. + // Immedates will result in compiler un-optimizing. + // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; + #if (FXAA_GATHER4_ALPHA == 1) + #if (FXAA_DISCARD == 0) + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + #endif + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); + #else + FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); + #endif + #if (FXAA_DISCARD == 1) + #define lumaM luma4A.w + #endif + #define lumaE luma4A.z + #define lumaS luma4A.x + #define lumaSE luma4A.y + #define lumaNW luma4B.w + #define lumaN luma4B.z + #define lumaW luma4B.x + #else + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif +/*--------------------------------------------------------------------------*/ + #if (FXAA_GATHER4_ALPHA == 0) + FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #else + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0/range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if(pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if(!horzSpan) posB.x += lengthSign * 0.5; + if( horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0/4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + FxaaBool doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 3) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 4) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 5) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 6) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 7) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 8) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 9) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 10) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 11) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 12) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + #if (FXAA_DISCARD == 1) + return FxaaTexTop(tex, posM); + #else + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); + #endif +} +/*==========================================================================*/ +#endif + + + + +/*============================================================================ + + FXAA3 CONSOLE - PC VERSION + +------------------------------------------------------------------------------ +Instead of using this on PC, I'd suggest just using FXAA Quality with + #define FXAA_QUALITY__PRESET 10 +Or + #define FXAA_QUALITY__PRESET 20 +Either are higher qualilty and almost as fast as this on modern PC GPUs. +============================================================================*/ +#if (FXAA_PC_CONSOLE == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); + FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); + FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); + FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat lumaM = rgbyM.w; + #else + FxaaFloat lumaM = rgbyM.y; + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); + lumaNe += 1.0/384.0; + FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); + FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); + FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMinM = min(lumaMin, lumaM); + FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); + FxaaFloat lumaMaxM = max(lumaMax, lumaM); + FxaaFloat dirSwMinusNe = lumaSw - lumaNe; + FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; + FxaaFloat dirSeMinusNw = lumaSe - lumaNw; + if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir; + dir.x = dirSwMinusNe + dirSeMinusNw; + dir.y = dirSwMinusNe - dirSeMinusNw; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir1 = normalize(dir.xy); + FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); + FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; + FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); + FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; + FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); +/*--------------------------------------------------------------------------*/ + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); + #else + FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); + #endif + if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; + return rgbyB; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - 360 PIXEL SHADER + +------------------------------------------------------------------------------ +This optimized version thanks to suggestions from Andy Luedke. +Should be fully tex bound in all cases. +As of the FXAA 3.11 release, I have still not tested this code, +however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10. +And note this is replacing the old unoptimized version. +If it does not work, please let me know so I can fix it. +============================================================================*/ +#if (FXAA_360 == 1) +/*--------------------------------------------------------------------------*/ +[reduceTempRegUsage(4)] +float4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + float4 lumaNwNeSwSe; + #if (FXAA_GREEN_AS_LUMA == 0) + asm { + tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #else + asm { + tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #endif +/*--------------------------------------------------------------------------*/ + lumaNwNeSwSe.y += 1.0/384.0; + float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); + float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); +/*--------------------------------------------------------------------------*/ + float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + float lumaMinM = min(lumaMin, rgbyM.w); + float lumaMaxM = max(lumaMax, rgbyM.w); + #else + float lumaMinM = min(lumaMin, rgbyM.y); + float lumaMaxM = max(lumaMax, rgbyM.y); + #endif + if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM; +/*--------------------------------------------------------------------------*/ + float2 dir; + dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx); + dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy); + dir = normalize(dir); +/*--------------------------------------------------------------------------*/ + float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw; +/*--------------------------------------------------------------------------*/ + float4 dir2; + float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness; + dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5); + dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw; +/*--------------------------------------------------------------------------*/ + float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0)); + float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0)); + float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0)); + float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ + float4 rgbyA = rgbyN1 + rgbyP1; + float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5; +/*--------------------------------------------------------------------------*/ + float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB; + rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA; + return rgbyR; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) + +============================================================================== +The code below does not exactly match the assembly. +I have a feeling that 12 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h0.w(TRUE), v5.xwxx, #0 + 6: addh h0.z(TRUE), -h2, h0.w + 7: texpkb h1.w(TRUE), v5, #0 + 9: addh h0.x(TRUE), h0.z, -h1.w + 10: addh h3.w(TRUE), h0.z, h1 + 11: texpkb h2.w(TRUE), v5.zwzz, #0 + 13: addh h0.z(TRUE), h3.w, -h2.w + 14: addh h0.x(TRUE), h2.w, h0 + 15: nrmh h1.xz(TRUE), h0_n + 16: minh_m8 h0.x(TRUE), |h1|, |h1.z| + 17: maxh h4.w(TRUE), h0, h1 + 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n + 19: movr r1.zw(TRUE), v4.xxxy + 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww + 22: minh h5.w(TRUE), h0, h1 + 23: texpkb h0(TRUE), r2.xzxx, #0 + 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 + 27: maxh h4.x(TRUE), h2.z, h2.w + 28: texpkb h1(TRUE), r0.zwzz, #0 + 30: addh_d2 h1(TRUE), h0, h1 + 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 33: texpkb h0(TRUE), r0, #0 + 35: minh h4.z(TRUE), h2, h2.w + 36: fenct TRUE + 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 39: texpkb h2(TRUE), r1, #0 + 41: addh_d2 h0(TRUE), h0, h2 + 42: maxh h2.w(TRUE), h4, h4.x + 43: minh h2.x(TRUE), h5.w, h4.z + 44: addh_d2 h0(TRUE), h0, h1 + 45: slth h2.x(TRUE), h0.w, h2 + 46: sgth h2.w(TRUE), h0, h2 + 47: movh h0(TRUE), h0 + 48: addx.c0 rc(TRUE), h2, h2.w + 49: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; + | | | + 2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; + | | | + 3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; + | SCB1 | add | 10: ADDh h3.w, h0.---z, h1; + | | | + 4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h2.w---, h0; + | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; + | | | + 5 | SCT1 | mov | 15: NRMh h1.xz, h0; + | SRB | nrm | 15: NRMh h1.xz, h0; + | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; + | SCB1 | max | 17: MAXh h4.w, h0, h1; + | | | + 6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; + | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; + | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; + | SCB1 | min | 22: MINh h5.w, h0, h1; + | | | + 7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; + | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; + | | | + 8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | SCB0/1 | add | 30: ADDh/2 h1, h0, h1; + | | | + 9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; + | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; + | SCB1 | min | 35: MINh h4.z, h2, h2.--w-; + | | | + 10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; + | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; + | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; + | SCB0/1 | add | 41: ADDh/2 h0, h0, h2; + | | | + 11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; + | SCT1 | max | 42: MAXh h2.w, h4, h4.---x; + | SCB0/1 | add | 44: ADDh/2 h0, h0, h1; + | | | + 12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; + | SCT1 | set | 46: SGTh h2.w, h0, h2; + | SCB0/1 | mul | 47: MOVh h0, h0; + | | | + 13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; + | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 0% 0% 50% + 6: 100% 0% 75% + 7: 0% 100% 75% + 8: 0% 100% 100% + 9: 0% 100% 25% + 10: 0% 100% 100% + 11: 50% 0% 100% + 12: 50% 0% 100% + 13: 25% 0% 100% + +MEAN: 17% 61% 67% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 0% 100% + 2: 0% 0% 100% 0% 100% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 0% 0% 0% 100% 100% + 6: 100% 100% 0% 100% 100% + 7: 0% 0% 100% 100% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 0% 100% + 10: 0% 0% 100% 100% 100% + 11: 100% 100% 0% 100% 100% + 12: 100% 100% 0% 100% 100% + 13: 100% 0% 0% 100% 100% + +MEAN: 30% 23% 61% 76% 100% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 13 cycles, 3 r regs, 923,076,923 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O3 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 dir; + half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + lumaNe.w += half(1.0/512.0); + dir.x = -lumaNe.w; + dir.z = -lumaNe.w; + #else + lumaNe.y += half(1.0/512.0); + dir.x = -lumaNe.y; + dir.z = -lumaNe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSw.w; + dir.z += lumaSw.w; + #else + dir.x += lumaSw.y; + dir.z += lumaSw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x -= lumaNw.w; + dir.z += lumaNw.w; + #else + dir.x -= lumaNw.y; + dir.z += lumaNw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSe.w; + dir.z -= lumaSe.w; + #else + dir.x += lumaSe.y; + dir.z -= lumaSe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half4 dir1_pos; + dir1_pos.xy = normalize(dir.xyz).xz; + half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (7) + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (8) + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (9) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (11) + // compilier moves these scalar ops up to other cycles + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); + half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); + #else + half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y)); + half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y)); + #endif + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (12) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif +/*--------------------------------------------------------------------------*/ +// (13) + if(twoTapLt || twoTapGt) rgby2 = rgby1; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) + +============================================================================== +The code mostly matches the assembly. +I have a feeling that 14 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks). +Will look at fixing this for FXAA 3.12. +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h1.w(TRUE), v5.xwxx, #0 + 6: addh h0.x(TRUE), h1.w, -h2.y + 7: texpkb h2.w(TRUE), v5.zwzz, #0 + 9: minh h4.w(TRUE), h2.y, h2 + 10: maxh h5.x(TRUE), h2.y, h2.w + 11: texpkb h0.w(TRUE), v5, #0 + 13: addh h3.w(TRUE), -h0, h0.x + 14: addh h0.x(TRUE), h0.w, h0 + 15: addh h0.z(TRUE), -h2.w, h0.x + 16: addh h0.x(TRUE), h2.w, h3.w + 17: minh h5.y(TRUE), h0.w, h1.w + 18: nrmh h2.xz(TRUE), h0_n + 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| + 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w + 21: movr r1.zw(TRUE), v4.xxxy + 22: maxh h2.w(TRUE), h0, h1 + 23: fenct TRUE + 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 26: texpkb h0(TRUE), r0, #0 + 28: maxh h5.x(TRUE), h2.w, h5 + 29: minh h5.w(TRUE), h5.y, h4 + 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 32: texpkb h2(TRUE), r1, #0 + 34: addh_d2 h2(TRUE), h0, h2 + 35: texpkb h1(TRUE), v4, #0 + 37: maxh h5.y(TRUE), h5.x, h1.w + 38: minh h4.w(TRUE), h1, h5 + 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 41: texpkb h0(TRUE), r0, #0 + 43: addh_m8 h5.z(TRUE), h5.y, -h4.w + 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 46: texpkb h3(TRUE), r2, #0 + 48: addh_d2 h0(TRUE), h0, h3 + 49: addh_d2 h3(TRUE), h0, h2 + 50: movh h0(TRUE), h3 + 51: slth h3.x(TRUE), h3.w, h5.w + 52: sgth h3.w(TRUE), h3, h5.x + 53: addx.c0 rc(TRUE), h3.x, h3 + 54: slth.c0 rc(TRUE), h5.z, h5 + 55: movh h0(c0.NE.w), h2 + 56: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; + | | | + 2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; + | | | + 3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; + | SCB1 | min | 9: MINh h4.w, h2.---y, h2; + | | | + 4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h0.w---, h0; + | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; + | | | + 5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; + | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; + | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; + | | | + 6 | SCT1 | mov | 18: NRMh h2.xz, h0; + | SRB | nrm | 18: NRMh h2.xz, h0; + | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; + | | | + 7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; + | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; + | SCB1 | max | 22: MAXh h2.w, h0, h1; + | | | + 8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; + | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; + | SCB0 | max | 28: MAXh h5.x, h2.w---, h5; + | SCB1 | min | 29: MINh h5.w, h5.---y, h4; + | | | + 9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; + | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; + | SCB0/1 | add | 34: ADDh/2 h2, h0, h2; + | | | + 10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; + | SCB1 | min | 38: MINh h4.w, h1, h5; + | | | + 11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; + | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; + | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; + | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; + | | | + 12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; + | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; + | SCB0/1 | add | 48: ADDh/2 h0, h0, h3; + | | | + 13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; + | SCB0/1 | mul | 50: MOVh h0, h3; + | | | + 14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; + | SCT1 | set | 52: SGTh h3.w, h3, h5.---x; + | SCB0 | set | 54: SLThc0 rc, h5.z---, h5; + | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; + | | | + 15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; + | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 50% 0% 25% + 6: 0% 0% 25% + 7: 100% 0% 25% + 8: 0% 100% 50% + 9: 0% 100% 100% + 10: 0% 100% 50% + 11: 0% 100% 75% + 12: 0% 100% 100% + 13: 100% 0% 100% + 14: 50% 0% 50% + 15: 100% 0% 100% + +MEAN: 26% 60% 56% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 100% 0% + 2: 0% 0% 100% 100% 0% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 100% 100% 0% 100% 0% + 6: 0% 0% 0% 0% 100% + 7: 100% 100% 0% 0% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 100% 100% + 10: 0% 0% 100% 100% 100% + 11: 0% 0% 100% 100% 100% + 12: 0% 0% 100% 100% 100% + 13: 100% 100% 0% 100% 100% + 14: 100% 100% 0% 100% 100% + 15: 100% 100% 0% 100% 100% + +MEAN: 33% 33% 60% 86% 80% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 15 cycles, 3 r regs, 800,000,000 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O2 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaNe = rgbyNe.w + half(1.0/512.0); + #else + half lumaNe = rgbyNe.y + half(1.0/512.0); + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaSwNegNe = lumaSw.w - lumaNe; + #else + half lumaSwNegNe = lumaSw.y - lumaNe; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); + half lumaMinNwSw = min(lumaNw.w, lumaSw.w); + #else + half lumaMaxNwSw = max(lumaNw.y, lumaSw.y); + half lumaMinNwSw = min(lumaNw.y, lumaSw.y); + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half dirZ = lumaNw.w + lumaSwNegNe; + half dirX = -lumaNw.w + lumaSwNegNe; + #else + half dirZ = lumaNw.y + lumaSwNegNe; + half dirX = -lumaNw.y + lumaSwNegNe; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half3 dir; + dir.y = 0.0; + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x = lumaSe.w + dirX; + dir.z = -lumaSe.w + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.w); + #else + dir.x = lumaSe.y + dirX; + dir.z = -lumaSe.y + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir1_pos; + dir1_pos.xy = normalize(dir).xz; + half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (7) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNeSe = max(lumaNe, lumaSe.w); + #else + half lumaMaxNeSe = max(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (8) + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); + half lumaMin = min(lumaMinNwSw, lumaMinNeSe); +/*--------------------------------------------------------------------------*/ +// (9) + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxM = max(lumaMax, rgbyM.w); + half lumaMinM = min(lumaMin, rgbyM.w); + #else + half lumaMaxM = max(lumaMax, rgbyM.y); + half lumaMinM = min(lumaMin, rgbyM.y); + #endif +/*--------------------------------------------------------------------------*/ +// (11) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; +/*--------------------------------------------------------------------------*/ +// (12) + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (13) + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (14) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif + bool earlyExit = lumaRangeM < lumaMax; + bool twoTap = twoTapLt || twoTapGt; +/*--------------------------------------------------------------------------*/ +// (15) + if(twoTap) rgby2 = rgby1; + if(earlyExit) rgby2 = rgbyM; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif diff --git a/data_from_portwine/Reshade/Shaders/FakeHDR.fx b/data_from_portwine/Reshade/Shaders/FakeHDR.fx new file mode 100644 index 00000000..127e1b67 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/FakeHDR.fx @@ -0,0 +1,67 @@ +/** + * HDR + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + * + * Not actual HDR - It just tries to mimic an HDR look (relatively high performance cost) + */ + +#include "ReShadeUI.fxh" + +uniform float HDRPower < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 8.0; + ui_label = "Power"; +> = 1.30; +uniform float radius1 < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 8.0; + ui_label = "Radius 1"; +> = 0.793; +uniform float radius2 < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 8.0; + ui_label = "Radius 2"; + ui_tooltip = "Raising this seems to make the effect stronger and also brighter."; +> = 0.87; + +#include "ReShade.fxh" + +float3 HDRPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + + float3 bloom_sum1 = tex2D(ReShade::BackBuffer, texcoord + float2(1.5, -1.5) * radius1 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum1 += tex2D(ReShade::BackBuffer, texcoord + float2(-1.5, -1.5) * radius1 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum1 += tex2D(ReShade::BackBuffer, texcoord + float2( 1.5, 1.5) * radius1 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum1 += tex2D(ReShade::BackBuffer, texcoord + float2(-1.5, 1.5) * radius1 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum1 += tex2D(ReShade::BackBuffer, texcoord + float2( 0.0, -2.5) * radius1 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum1 += tex2D(ReShade::BackBuffer, texcoord + float2( 0.0, 2.5) * radius1 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum1 += tex2D(ReShade::BackBuffer, texcoord + float2(-2.5, 0.0) * radius1 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum1 += tex2D(ReShade::BackBuffer, texcoord + float2( 2.5, 0.0) * radius1 * BUFFER_PIXEL_SIZE).rgb; + + bloom_sum1 *= 0.005; + + float3 bloom_sum2 = tex2D(ReShade::BackBuffer, texcoord + float2(1.5, -1.5) * radius2 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum2 += tex2D(ReShade::BackBuffer, texcoord + float2(-1.5, -1.5) * radius2 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum2 += tex2D(ReShade::BackBuffer, texcoord + float2( 1.5, 1.5) * radius2 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum2 += tex2D(ReShade::BackBuffer, texcoord + float2(-1.5, 1.5) * radius2 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum2 += tex2D(ReShade::BackBuffer, texcoord + float2( 0.0, -2.5) * radius2 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum2 += tex2D(ReShade::BackBuffer, texcoord + float2( 0.0, 2.5) * radius2 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum2 += tex2D(ReShade::BackBuffer, texcoord + float2(-2.5, 0.0) * radius2 * BUFFER_PIXEL_SIZE).rgb; + bloom_sum2 += tex2D(ReShade::BackBuffer, texcoord + float2( 2.5, 0.0) * radius2 * BUFFER_PIXEL_SIZE).rgb; + + bloom_sum2 *= 0.010; + + float dist = radius2 - radius1; + float3 HDR = (color + (bloom_sum2 - bloom_sum1)) * dist; + float3 blend = HDR + color; + color = pow(abs(blend), abs(HDRPower)) + HDR; // pow - don't use fractions for HDRpower + + return saturate(color); +} + +technique HDR +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = HDRPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/FilmGrain.fx b/data_from_portwine/Reshade/Shaders/FilmGrain.fx new file mode 100644 index 00000000..c00d16e0 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/FilmGrain.fx @@ -0,0 +1,104 @@ +/** + * FilmGrain version 1.0 + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + * + * Computes a noise pattern and blends it with the image to create a film grain look. + */ + +#include "ReShadeUI.fxh" + +uniform float Intensity < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "How visible the grain is. Higher is more visible."; +> = 0.50; +uniform float Variance < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Controls the variance of the Gaussian noise. Lower values look smoother."; +> = 0.40; +uniform float Mean < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Affects the brightness of the noise."; +> = 0.5; + +uniform int SignalToNoiseRatio < __UNIFORM_SLIDER_INT1 + ui_min = 0; ui_max = 16; + ui_label = "Signal-to-Noise Ratio"; + ui_tooltip = "Higher Signal-to-Noise Ratio values give less grain to brighter pixels. 0 disables this feature."; +> = 6; + +uniform float Timer < source = "timer"; >; + +#include "ReShade.fxh" + +float3 FilmGrainPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + + //float inv_luma = dot(color, float3(-0.2126, -0.7152, -0.0722)) + 1.0; + float inv_luma = dot(color, float3(-1.0/3.0, -1.0/3.0, -1.0/3.0)) + 1.0; //Calculate the inverted luma so it can be used later to control the variance of the grain + + /*---------------------. + | :: Generate Grain :: | + '---------------------*/ + + const float PI = 3.1415927; + + //time counter using requested counter from ReShade + float t = Timer * 0.0022337; + + //PRNG 2D - create two uniform noise values and save one DP2ADD + float seed = dot(texcoord, float2(12.9898, 78.233));// + t; + float sine = sin(seed); + float cosine = cos(seed); + float uniform_noise1 = frac(sine * 43758.5453 + t); //I just salt with t because I can + float uniform_noise2 = frac(cosine * 53758.5453 - t); // and it doesn't cost any extra ASM + + //Get settings + float stn = SignalToNoiseRatio != 0 ? pow(abs(inv_luma), (float)SignalToNoiseRatio) : 1.0; // Signal to noise feature - Brighter pixels get less noise. + float variance = (Variance*Variance) * stn; + float mean = Mean; + + //Box-Muller transform + uniform_noise1 = (uniform_noise1 < 0.0001) ? 0.0001 : uniform_noise1; //fix log(0) + + float r = sqrt(-log(uniform_noise1)); + r = (uniform_noise1 < 0.0001) ? PI : r; //fix log(0) - PI happened to be the right answer for uniform_noise == ~ 0.0000517.. Close enough and we can reuse a constant. + float theta = (2.0 * PI) * uniform_noise2; + + float gauss_noise1 = variance * r * cos(theta) + mean; + //float gauss_noise2 = variance * r * sin(theta) + mean; //we can get two gaussians out of it :) + + //gauss_noise1 = (ddx(gauss_noise1) - ddy(gauss_noise1)) * 0.50 + gauss_noise2; + + + //Calculate how big the shift should be + //float grain = lerp(1.0 - Intensity, 1.0 + Intensity, gauss_noise1); + float grain = lerp(1.0 + Intensity, 1.0 - Intensity, gauss_noise1); + + //float grain2 = (2.0 * Intensity) * gauss_noise1 + (1.0 - Intensity); + + //Apply grain + color = color * grain; + + //color = (grain-1.0) *2.0 + 0.5; + + //color = lerp(color,colorInput.rgb,sqrt(luma)); + + /*-------------------------. + | :: Debugging features :: | + '-------------------------*/ + + //color.rgb = frac(gauss_noise1).xxx; //show the noise + //color.rgb = (gauss_noise1 > 0.999) ? float3(1.0,1.0,0.0) : 0.0 ; //does it reach 1.0? + + return color.rgb; +} + +technique FilmGrain +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = FilmGrainPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Flair.fx b/data_from_portwine/Reshade/Shaders/Flair.fx new file mode 100644 index 00000000..57492c53 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Flair.fx @@ -0,0 +1,789 @@ + ////---------// + ///**Flair**/// + //---------//// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//* Lens Flares are based on Blooming HDR Original Code +//* For Reshade 3.0+ +//* --------------------------------- +//* Flair +//* Let's add some ------ to your images. +//* Flares +//* Due Diligence +//* Eye Adaptation +//* https://knarkowicz.wordpress.com/2016/01/09/automatic-exposure/ Search Ref. Temporal Adaptation +//* If I miss any please tell me. +//* +//* LICENSE +//* ============ +//* Flare is licenses under: Attribution-NoDerivatives 4.0 International +//* +//* 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. +//* +//* NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. +//* +//* 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-nd/4.0/ +//* +//* Have fun, +//* Jose Negrete AKA BlueSkyDefender +//* +//* https://github.com/BlueSkyDefender/Depth3D +//* Special thanks to NVIDIA on compatibility with GeForce GPUs and feedback on shader development +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Shared Texture for Blooming HDR or any other shader that want's to use it. +texture TexFlareShared { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + +//You can also make a text file named "DisableFlare.txt" to dissable this shader output and +//only use the Share Texture above in your your shader. + +uniform int Flare_Type < + ui_type = "combo"; + ui_items = "Star Full\0Star Half\0Cross +\0Cross x\0Flare +Skew\0Flare -Skew\0Flare Horizontal\0Flare Vertical\0"; + ui_label = "Flare Type"; + ui_category = "Flare Type"; +> = 0; + +uniform bool Auto_Flare_Intensity < + ui_label = "Auto Flare Intensity"; + ui_tooltip = "This will enable the shader to adjust Flare Intensity automatically.\n" + "Auto Bloom Intensity will set Bloom Intensity below."; + ui_category = "Flare Adjustments"; +> = false; + +uniform float Flare_Clamp_A < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Flare Brightness Threshold"; + ui_tooltip = "Use this to set the color based brightness threshold for what is and what isn't allowed.\n" + "Number 1.0 is default."; + ui_category = "Flare Adjustments"; +> = 1.0; + +uniform float Flare_Clamp_B < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Flare Max Brightness Cutoff"; + ui_tooltip = "Use this to set the max cutoff point of the brightness things in the image.\n" + "Number 1.0 is default."; + ui_category = "Flare Adjustments"; +> = 1.0; + +uniform float Flare_Spread < + ui_type = "slider"; + ui_min = -1.0; ui_max = 1.0; ui_step = 0.01; + ui_label = "Flare Spread"; + ui_tooltip = "Use this to adjust Flare size & you can override this.\n" + "Number 0.5 is default."; + ui_category = "Flare Adjustments"; +> = 0.5; + +uniform float Flare_Power < + ui_type = "slider"; + ui_min = 0.0; ui_max = 12.5; ui_step = 0.125; + ui_label = "Flare Intensity"; + ui_tooltip = "Use this to set Flare Intensity for your content.\n" + "Number 1.0 is default."; + ui_category = "Flare Adjustments"; +> = 1.0; + +uniform float Flare_Saturation < + ui_type = "slider"; + ui_min = 0.0; ui_max = 10.0; ui_step = 0.1; + ui_label = "Flare Saturation"; + ui_tooltip = "Adjustment The amount to adjust the saturation of the flare color.\n" + "Number 1.0 is default."; + ui_category = "Flare Adjustments"; +> = 5.0; +//User_Flare_Color needs Flare_Color_Map to be set to -1 and the rest uncommented. +uniform int Flare_Color_Map < + ui_type = "slider"; + ui_min = -1; ui_max = 8; + ui_label = "Flare Color Map"; + ui_tooltip = "Use this to set MIP levels for the color map used to se Flare Color.\n" + "This samples color in the general area to achieve this effect.\n" + "Number 4 is default & Zero is Off."; + ui_category = "Flare Adjustments"; +> = 4; + +uniform float3 User_Flare_Color < + ui_type = "color"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Flare Color Adjust"; + ui_tooltip = "Use this to set your own color settings."; + ui_category = "Flare Adjustments"; +> = float3(1.0,1.0,1.0); + +uniform float Flare_Localization < + ui_type = "slider"; + ui_min = -1.0; ui_max = 1.0; ui_step = 0.1; + ui_label = "Flare Localization"; + ui_tooltip = "This localizes flare to a user selected area.\n" + "Number Zero is default."; + ui_category = "Flare Adjustments"; +> = 0.0; + +uniform int CA_Type < + ui_type = "combo"; + ui_items = "Off\0Type BD\0Type Box\0Type Hozi\0Type Verti\0"; + ui_label = "Flare CA Type"; + ui_category = "Flare Chromatic Aberration"; +> = 1; + +uniform float3 Flare_PBD < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Flare CA Adjust"; + ui_tooltip = "Use this to set chromatic aberration for your content."; + ui_category = "Flare Chromatic Aberration"; +> = float3(1.0,0.5,0.0); + +//Depth Map// +uniform int Depth_Map < + ui_type = "combo"; + ui_items = "Normal\0Reversed\0"; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "Linearization for the zBuffer also known as Depth Map.\n" + "DM0 is Z-Normal and DM1 is Z-Reversed.\n"; + ui_category = "Depth Map Masking"; +> = 0; + +uniform float Depth_Map_Adjust < + ui_type = "drag"; + ui_min = 0.25; ui_max = 250.0; ui_step = 0.25; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "This allows for you to adjust the DM precision.\n" + "Adjust this to keep it as low as possible.\n" + "Default is 1.5"; + ui_category = "Depth Map Masking"; +> = 1.5; + +uniform bool Depth_Map_Flip < + ui_label = "Depth Map Flip"; + ui_tooltip = "Flip the depth map if it is upside down."; + ui_category = "Depth Map Masking"; +> = false; + +uniform bool Mask_Sky < + ui_label = "Sky Mask"; + ui_tooltip = "Mask Sky using depth"; + ui_category = "Depth Map Masking"; +> = false; + +uniform bool Flair_Falloff < + ui_label = "Falloff"; + ui_tooltip = "A depth mask is use to add a fall off distance"; + ui_category = "Depth Map Masking"; +> = false; + +#if __RENDERER__ >= 0x20000 //Vulkan + #define Rend 1 +#else + #define Rend 0 +#endif +/////////////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +uniform float timer < source = "timer"; >; +//Total amount of frames since the game started. +uniform uint framecount < source = "framecount"; >; +uniform float frametime < source = "frametime";>; +//Made Up Values that look nice not correct. +static const float OffsetA[25] = { 0.0, 1.0, 3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0, 21.0, 23.0, 25.0, 27.0, 29.0, 31.0, 33.0, 35.0, 37.0, 39.0, 41.0, 43.0, 45.0, 47.0 }; +static const float OffsetB[25] = { 0.0, 2.0, 4.0, 6.0, 8.0,10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 22.0, 24.0, 26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 38.0, 40.0, 42.0, 44.0, 46.0, 48.0 }; +static const float OffsetC[25] = { 0.5, 1.5, 3.5, 5.5, 7.5, 9.5, 11.5, 13.5, 15.5, 17.5, 19.5, 21.5, 23.5, 25.5, 27.5, 29.5, 31.5, 33.5, 35.5, 37.5, 39.5, 41.5, 43.5, 45.5, 47.5 }; +static const float OffsetD[25] = { 0.5, 2.5, 4.5, 6.5, 8.5,10.5, 12.5, 14.5, 16.5, 18.5, 20.5, 22.5, 24.5, 26.5, 28.5, 30.5, 32.5, 34.5, 36.5, 38.5, 40.5, 42.5, 44.5, 46.5, 48.5 }; +static const float Weight[25] = { 0.10761,0.10306,0.09750, 0.09110,0.08409,0.07666,0.06903,0.06139,0.05394,0.04680,0.0401,0.0339,0.0284,0.0234,0.0191,0.0154,0.0122,0.0096,0.0074,0.0057,0.0043,0.0032,0.0024,0.0017,0.0012 }; +#define FS Flare_Spread < 0 ? Flare_Spread * 4.0 : Flare_Spread * 2.2 +#define Flare_Softness 0 //saturate(abs(Flare_Spread)) //Removed because of Opti +#define Alternate framecount % 2 == 0 +//Eye Adaptation Set from 0 to 1 +static const float Adapt_Seek = 0.5;//Use this to Adjust Eye Adaptation Speed +static const float Adapt_Adjust = 0.5;//Use this to Adjust Eye Seeking Radius for Average Brightness. + +float lum(float3 RGB){ return dot(RGB, float3(0.2126, 0.7152, 0.0722) );} +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +texture TexDepthBuffer : DEPTH; + +texture TexBackBuffer : COLOR; + +sampler DepthBufferF + { + Texture = TexDepthBuffer; + }; + +sampler BackBufferF + { + Texture = TexBackBuffer; + }; + +texture texFlare { Width = BUFFER_WIDTH * 0.25; Height = BUFFER_HEIGHT * 0.25; Format = RGBA16f; }; + +sampler SamplerGlammor + { + Texture = texFlare; + }; + +texture TexBC { Width = BUFFER_WIDTH * 0.5; Height = BUFFER_HEIGHT * 0.5; Format = RGBA8; }; + +sampler SamplerBC + { + Texture = TexBC; + }; + +texture TexMBB { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT ; Format = RGBA8; MipLevels = 8; }; + +sampler SamplerMBB + { + Texture = TexMBB; + MagFilter = POINT; + MinFilter = POINT; + MipFilter = POINT; + }; + +texture TexFlarePast { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; + +sampler SamplerPastFlare + { + Texture = TexFlarePast; + MagFilter = POINT; + MinFilter = POINT; + MipFilter = POINT; + }; + +void A0(float2 texcoord,float PosX,float PosY,inout float D, inout float E, inout float P, inout float T, inout float H, inout float III, inout float DD ) +{ + float PosXD = -0.035+PosX, offsetD = 0.001;D = all( abs(float2( texcoord.x -PosXD, texcoord.y-PosY)) < float2(0.0025,0.009));D -= all( abs(float2( texcoord.x -PosXD-offsetD, texcoord.y-PosY)) < float2(0.0025,0.007)); + float PosXE = -0.028+PosX, offsetE = 0.0005;E = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.009));E -= all( abs(float2( texcoord.x -PosXE-offsetE, texcoord.y-PosY)) < float2(0.0025,0.007));E += all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.001)); + float PosXP = -0.0215+PosX, PosYP = -0.0025+PosY, offsetP = 0.001, offsetP1 = 0.002;P = all( abs(float2( texcoord.x -PosXP, texcoord.y-PosYP)) < float2(0.0025,0.009*0.775));P -= all( abs(float2( texcoord.x -PosXP-offsetP, texcoord.y-PosYP)) < float2(0.0025,0.007*0.680));P += all( abs(float2( texcoord.x -PosXP+offsetP1, texcoord.y-PosY)) < float2(0.0005,0.009)); + float PosXT = -0.014+PosX, PosYT = -0.008+PosY;T = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosYT)) < float2(0.003,0.001));T += all( abs(float2( texcoord.x -PosXT, texcoord.y-PosY)) < float2(0.000625,0.009)); + float PosXH = -0.0072+PosX;H = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.001));H -= all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.009));H += all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.00325,0.009)); + float offsetFive = 0.001, PosX3 = -0.001+PosX;III = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.009));III -= all( abs(float2( texcoord.x -PosX3 - offsetFive, texcoord.y-PosY)) < float2(0.003,0.007));III += all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.001)); + float PosXDD = 0.006+PosX, offsetDD = 0.001;DD = all( abs(float2( texcoord.x -PosXDD, texcoord.y-PosY)) < float2(0.0025,0.009));DD -= all( abs(float2( texcoord.x -PosXDD-offsetDD, texcoord.y-PosY)) < float2(0.0025,0.007)); +} +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +texture texLumF {Width = 256; Height = 256; Format = R16F; 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 SamplerLumG + { + Texture = texLumF; + }; + +float LuminanceG(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float2 texXY = texcoord; + float2 midHV = (Adapt_Seek-1) * float2(BUFFER_WIDTH * 0.5,BUFFER_HEIGHT * 0.5) * pix; + texcoord = float2((texXY.x*Adapt_Seek)-midHV.x,(texXY.y*Adapt_Seek)-midHV.y); + return lum(tex2D(BackBufferF,texcoord).rgb); +} +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +texture texAvgLumF { Width = 256; Height = 256; Format = R16F; }; + +sampler SamplerAvgLumG + { + Texture = texAvgLumF; + }; + +texture TexAvgLumaLastF { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16F; }; + +sampler SamplerAvgLumaLastG + { + Texture = TexAvgLumaLastF; + }; + +float Average_LuminanceF(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float AA = (1-Adapt_Adjust) * 1000, L = tex2Dlod(SamplerLumG,float4(texcoord,0,11)).x, PL = tex2D(SamplerAvgLumaLastG, texcoord).x; + //Temporal Adaptation + return PL + (L - PL) * (1.0 - exp(-frametime/AA)); +} +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +float2 DepthMap(float2 texcoord : TEXCOORD0) +{ + if (Depth_Map_Flip) + texcoord.y = 1 - texcoord.y; + + float zBuffer = tex2Dlod(DepthBufferF, float4(texcoord,0,0)).x,Raw; //Depth Buffer + + //Conversions to linear space..... + //Near & Far Adjustment + float Far = 1.0, Near = 0.125/Depth_Map_Adjust,DA = Depth_Map_Adjust*2; //Division Depth Map Adjust - Near + + float2 Z = float2( zBuffer, 1-zBuffer ); + + if (Depth_Map == 0)//DM0. Normal + { + zBuffer = Far * Near / (Far + Z.x * (Near - Far)); + Raw = pow(abs(Z.x),DA); + } + else if (Depth_Map == 1)//DM1. Reverse + { + zBuffer = Far * Near / (Far + Z.y * (Near - Far)); + Raw = pow(abs(Z.y),DA); + } + + return saturate(float2(zBuffer,Raw)); +} + +float4 BB( float2 texcoord ) +{ + return tex2Dlod(BackBufferF, float4(texcoord,0,0)).rgba; +} + +void ColorBB(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 MBB : SV_Target) +{ + MBB = BB( texcoord ).rgb; +} + +float4 GBightColors( float2 texcoord ) +{ float DM = smoothstep(0,1,DepthMap(texcoord).x); + //Forced Depth Masking + if(DM == 1) + DM = 1; + else + DM = 0; + + if(!Mask_Sky) + DM = 0; + + float4 CM = lerp(tex2Dlod(SamplerMBB,float4(texcoord,0,clamp(Flare_Color_Map,0,8))).rgba,0,DM); + float4 BC = lerp(BB(texcoord),0,DM); + // Check whether fragment output is higher than threshold,if so output as brightness color. + float I_A = lum(BC.rgb), I_B = 1-I_A; + I_A *= I_B >= 1-Flare_Clamp_B;//Trim from Top + BC.a = I_A > lerp(0.9,0.999,Flare_Clamp_A);// ? 1 : 0; + BC.rgb *= BC.a ; + + if(Flare_Color_Map > 0) + BC.rgb = CM.rgb * BC.a; + else if(Flare_Color_Map == -1) + BC.rgb *= User_Flare_Color; + + if(Flair_Falloff) + BC.rgb = lerp(BC.rgb,0.0,DepthMap(texcoord).y); + + //Bloom Saturation + BC.rgb = lerp(lum(BC.rgb),BC.rgb,Flare_Saturation); + + float2 Stored_TC = texcoord, FL; + if (Flare_Localization != 0) + { + Stored_TC *= 1.0 - Stored_TC; + + float vignette = Stored_TC.x*Stored_TC.y*12.5; + + if (Flare_Localization < 0) + FL = float2(0,abs(Flare_Localization)); + else + FL = float2(abs(Flare_Localization),1); + + vignette = 1-smoothstep(FL.x,FL.y,vignette); + + if (Flare_Localization < 0) + vignette = 1-vignette; + + BC.rgb = lerp(BC.rgb,0.0,vignette); + } + return float4(saturate(BC.rgb),BC.a); +} + +void StoredBB(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 BC : SV_Target) +{ + BC = GBightColors( texcoord ).rgb; +} +#if !Rend +//Done this way to reduce TempRegisters for DX9 compatablity. +float3 Glammor(sampler2D Sample, float2 texcoord, float N, int Switch, float BBS) +{ + float3 GBloom = Switch ? tex2D(Sample,texcoord).rgb : GBightColors(texcoord).rgb; + GBloom *= Weight[0]; + [loop] + for(int i = 1; i < N; ++i) + { float4 offset = float4(OffsetA[i] * pix.xy,OffsetB[i] * pix.xy); + if (Alternate) + offset = float4(OffsetC[i] * pix.xy,OffsetD[i] * pix.xy); + //+ & X + if(Flare_Type == 4 || Flare_Type == 5 || Flare_Type == 6 || Flare_Type == 7) + { + float4 XXZZ = float4( offset.x,-offset.x, offset.z,-offset.z); + float4 YYWW = float4( offset.y,-offset.y, offset.w,-offset.w); + if(Flare_Type == 5 || Flare_Type == 7) + XXZZ = Switch ? 0 : float4(-offset.x, offset.x,-offset.z, offset.z); + if(Flare_Type == 6) + YYWW = Switch ? 0 : float4( offset.y,-offset.y, offset.w,-offset.w); + + GBloom += tex2Dlod(Sample, float4(texcoord + float2( XXZZ.x, YYWW.x) * BBS,0,0) ).rgb * Weight[i]; + GBloom += tex2Dlod(Sample, float4(texcoord + float2( XXZZ.y, YYWW.y) * BBS,0,0) ).rgb * Weight[i]; + + GBloom += tex2Dlod(Sample, float4(texcoord + float2( XXZZ.z, YYWW.z) * BBS,0,0) ).rgb * Weight[i]; + GBloom += tex2Dlod(Sample, float4(texcoord + float2( XXZZ.w, YYWW.w) * BBS,0,0) ).rgb * Weight[i]; + } + else + { + float4 YYXX = Switch ? 0 : float4( offset.y,-offset.y,-offset.x, offset.x); + + GBloom += tex2Dlod(Sample, float4(texcoord + float2( offset.x, YYXX.x) * BBS,0,0) ).rgb * Weight[i]; + GBloom += tex2Dlod(Sample, float4(texcoord + float2(-offset.x, YYXX.y) * BBS,0,0) ).rgb * Weight[i]; + GBloom += tex2Dlod(Sample, float4(texcoord + float2( YYXX.z, offset.y) * BBS,0,0) ).rgb * Weight[i]; + GBloom += tex2Dlod(Sample, float4(texcoord + float2( YYXX.w,-offset.y) * BBS,0,0) ).rgb * Weight[i]; + + float4 WWZZ = Switch ? 0 : float4( offset.w,-offset.w,-offset.z, offset.z); + + GBloom += tex2Dlod(Sample, float4(texcoord + float2( offset.z, WWZZ.x) * BBS,0,0) ).rgb * Weight[i]; + GBloom += tex2Dlod(Sample, float4(texcoord + float2(-offset.z, WWZZ.y) * BBS,0,0) ).rgb * Weight[i]; + GBloom += tex2Dlod(Sample, float4(texcoord + float2( WWZZ.z, offset.w) * BBS,0,0) ).rgb * Weight[i]; + GBloom += tex2Dlod(Sample, float4(texcoord + float2( WWZZ.w,-offset.w) * BBS,0,0) ).rgb * Weight[i]; + } + + } + GBloom *= 0.5; + + return GBloom; +} + +float3 GlammorA(float2 texcoord ) +{ + float N, BBS = FS; + if(Flare_Type == 0 || Flare_Type == 1 || Flare_Type == 2 || Flare_Type == 6 || Flare_Type == 7) + N = int(lerp(5,25,abs(Flare_Spread))); + else if(Flare_Type == 3 || Flare_Type == 4 || Flare_Type == 5 ) + N = 1; + + return Glammor(SamplerBC, texcoord, N, 1, BBS); +} + +float3 GlammorB(float2 texcoord ) +{ + float N, BBS = FS; + if(Flare_Type == 0 || Flare_Type == 1 || Flare_Type == 3 || Flare_Type == 4 || Flare_Type == 5 ) + N = int(lerp(5,25,abs(Flare_Spread))); + else if(Flare_Type == 2 || Flare_Type == 6 || Flare_Type == 7 ) + N = 1; + + if(Flare_Type == 1) + BBS *= 0.5; + + return Glammor(SamplerBC, texcoord, N, 0, BBS); +} +#else +float3 GlammorA(float2 texcoord ) +{ float3 GBloom = tex2D(SamplerBC,texcoord).rgb; + float N, BBS = FS; + GBloom *= Weight[0]; + if(Flare_Type == 0 || Flare_Type == 1 || Flare_Type == 2 || Flare_Type == 6 || Flare_Type == 7) + N = 25; + else if(Flare_Type == 3 || Flare_Type == 4 || Flare_Type == 5 ) + N = 1; + + [unroll] + for(int i = 1; i < N; ++i) + { float4 offset = float4(OffsetA[i] * pix.xy,OffsetB[i] * pix.xy); + if (Alternate) + offset = float4(OffsetC[i] * pix.xy,OffsetD[i] * pix.xy); + //+ + if(Flare_Type == 6) + { + GBloom += tex2D(SamplerBC, texcoord + float2( offset.x, 0) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x, 0) * BBS ).rgb * Weight[i]; + + GBloom += tex2D(SamplerBC, texcoord + float2( offset.z, 0) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z, 0) * BBS ).rgb * Weight[i]; + } + else if(Flare_Type == 7) + { + GBloom += tex2D(SamplerBC, texcoord + float2( 0, offset.y) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( 0,-offset.y) * BBS ).rgb * Weight[i]; + + GBloom += tex2D(SamplerBC, texcoord + float2( 0, offset.w) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( 0,-offset.w) * BBS ).rgb * Weight[i]; + } + else + { + GBloom += tex2D(SamplerBC, texcoord + float2( offset.x, 0) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x, 0) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( 0, offset.y) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( 0,-offset.y) * BBS ).rgb * Weight[i]; + + GBloom += tex2D(SamplerBC, texcoord + float2( offset.z, 0) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z, 0) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( 0, offset.w) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( 0,-offset.w) * BBS ).rgb * Weight[i]; + } + } + GBloom *= 0.5; + + return GBloom; +} + +float3 GlammorB(float2 texcoord ) +{ float3 GBloom = GBightColors(texcoord).rgb; + float N, BBS = FS; + GBloom *= Weight[0]; + if(Flare_Type == 0 || Flare_Type == 1 || Flare_Type == 3 || Flare_Type == 4 || Flare_Type == 5 ) + N = 25; + else if(Flare_Type == 2 || Flare_Type == 6 || Flare_Type == 7 ) + N = 1; + + if(Flare_Type == 1) + BBS *= 0.5; + + [unroll] + for(int i = 1; i < N; ++i) + { float4 offset = float4(OffsetA[i] * pix.xy,OffsetB[i] * pix.xy); + if (Alternate) + offset = float4(OffsetC[i] * pix.xy,OffsetD[i] * pix.xy); + //X + if(Flare_Type == 4) + { + GBloom += tex2D(SamplerBC, texcoord + float2( offset.x, offset.y) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x,-offset.y) * BBS ).rgb * Weight[i]; + + GBloom += tex2D(SamplerBC, texcoord + float2( offset.z, offset.w) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z,-offset.w) * BBS ).rgb * Weight[i]; + } + else if(Flare_Type == 5) + { + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x, offset.y) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( offset.x,-offset.y) * BBS ).rgb * Weight[i]; + + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z, offset.w) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( offset.z,-offset.w) * BBS ).rgb * Weight[i]; + } + else + { + GBloom += tex2D(SamplerBC, texcoord + float2( offset.x, offset.y) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x,-offset.y) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.x, offset.y) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( offset.x,-offset.y) * BBS ).rgb * Weight[i]; + + GBloom += tex2D(SamplerBC, texcoord + float2( offset.z, offset.w) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z,-offset.w) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2(-offset.z, offset.w) * BBS ).rgb * Weight[i]; + GBloom += tex2D(SamplerBC, texcoord + float2( offset.z,-offset.w) * BBS ).rgb * Weight[i]; + } + } + GBloom *= 0.5; + + return GBloom; +} +#endif + +// Spread the blur a bit more. +void Glammor(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 GBloom : SV_Target) +{ GBloom = 0; + float GI = Flare_Power, AL = smoothstep(0,1,1. - tex2D(SamplerAvgLumG,0.0).x); + if(Auto_Flare_Intensity) + GI *= AL; + GBloom = ( GlammorA(texcoord) + GlammorB(texcoord) ) * GI; +} + +float2 BD(float2 p, float k1) //Polynomial Lens +{ + if(!CA_Type == 1) + discard; + p *= 0.5 + 0.5;//Center + // Normalize the u,v coordinates in the range [-1;+1] + p = (2.0f * p - 1.0f) / 1.0f; + // Calculate l2 norm + float r2 = p.x*p.x + p.y*p.y; + float r4 = pow(r2,2); + // Forward transform + float x2 = p.x * (1.0 + k1 * r2); + float y2 = p.y * (1.0 + k1 * r2); + // De-normalize to the original range + p.x = (x2 + 1.0) * 1.0 / 2.0; + p.y = (y2 + 1.0) * 1.0 / 2.0; + +return p; +} + +float2 HVP(float2 texcoord, float k1) +{ + if(!CA_Type == 2) + discard; + float X = k1; + float Y = k1; + float midW = (X - 1)*(BUFFER_WIDTH*0.5)*pix.x; + float midH = (Y - 1)*(BUFFER_HEIGHT*0.5)*pix.y; + + return float2((texcoord.x*X)-midW,(texcoord.y*Y)-midH); +} + +float2 HP(float2 texcoord, float k1) +{ + if(!CA_Type == 3) + discard; + float X = k1; + float Y = 1; + float midW = (X - 1)*(BUFFER_WIDTH*0.5)*pix.x; + float midH = (Y - 1)*(BUFFER_HEIGHT*0.5)*pix.y; + + return float2((texcoord.x*X)-midW,(texcoord.y*Y)-midH); +} + +float2 VP(float2 texcoord, float k1) +{ + if(!CA_Type == 4) + discard; + float X = 1; + float Y = k1; + float midW = (X - 1)*(BUFFER_WIDTH*0.5)*pix.x; + float midH = (Y - 1)*(BUFFER_HEIGHT*0.5)*pix.y; + + return float2((texcoord.x*X)-midW,(texcoord.y*Y)-midH); +} + +float3 CAFlare(float2 texcoord) +{ + float2 uv_red, uv_green, uv_blue; + float DM, color_red, color_green, color_blue, K1_Red = Flare_PBD.x , K1_Green = Flare_PBD.y , K1_Blue = Flare_PBD.z ; + if(CA_Type == 1) + { + uv_red = BD(texcoord.xy,K1_Red * 0.03); + uv_green = BD(texcoord.xy,K1_Green * 0.03); + uv_blue = BD(texcoord.xy,K1_Blue * 0.03); + } + else if(CA_Type == 2) + { + uv_red = HVP(texcoord.xy,1-K1_Red * 0.025); + uv_green = HVP(texcoord.xy,1-K1_Green * 0.025); + uv_blue = HVP(texcoord.xy,1-K1_Blue * 0.025); + } + else if(CA_Type == 3) + { + uv_red = HP(texcoord.xy,1-K1_Red * 0.025); + uv_green = HP(texcoord.xy,1-K1_Green * 0.025); + uv_blue = HP(texcoord.xy,1-K1_Blue * 0.025); + } + else if(CA_Type == 4) + { + uv_red = VP(texcoord.xy,1-K1_Red * 0.025); + uv_green = VP(texcoord.xy,1-K1_Green * 0.025); + uv_blue = VP(texcoord.xy,1-K1_Blue * 0.025); + } + + if(CA_Type > 0) + { + color_red = tex2Dlod(SamplerGlammor,float4(uv_red,0,Flare_Softness)).r; + color_green = tex2Dlod(SamplerGlammor,float4(uv_green,0,Flare_Softness)).g; + color_blue = tex2Dlod(SamplerGlammor,float4(uv_blue,0,Flare_Softness)).b; + } + else + { + color_red = tex2Dlod(SamplerGlammor,float4(texcoord,0,Flare_Softness)).r; + color_green = tex2Dlod(SamplerGlammor,float4(texcoord,0,Flare_Softness)).g; + color_blue = tex2Dlod(SamplerGlammor,float4(texcoord,0,Flare_Softness)).b; + } + + return float3(color_red,color_green,color_blue); +} + +void PS_StoreAvgLumaF(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float Stored : SV_Target0, out float3 Shared : SV_Target1) +{ + Stored = tex2D(SamplerAvgLumG,texcoord).x; + Shared = (CAFlare(texcoord) + tex2D(SamplerPastFlare,texcoord).rgb) ; +} + +float3 ShaderGlammor(float2 texcoord) +{ float DM; + float3 Color = BB(texcoord).rgb, FBloom = (CAFlare(texcoord) + tex2D(SamplerPastFlare,texcoord).rgb) ; + //Gamma Correction + Color = pow(abs(Color),2.2); + + //Bloom + Color = Color + FBloom; + + Color = pow(abs(Color),rcp(2.2)); + + return Color; +} + +void Past_Flare(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 Stored : SV_Target) +{ + Stored = CAFlare(texcoord); +} + +void A1(float2 texcoord,float PosX,float PosY,inout float I, inout float N, inout float F, inout float O) +{ + float PosXI = 0.0155+PosX, PosYI = 0.004+PosY, PosYII = 0.008+PosY;I = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosY)) < float2(0.003,0.001));I += all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYI)) < float2(0.000625,0.005));I += all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYII)) < float2(0.003,0.001)); + float PosXN = 0.0225+PosX, PosYN = 0.005+PosY,offsetN = -0.001;N = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN)) < float2(0.002,0.004));N -= all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN - offsetN)) < float2(0.003,0.005)); + float PosXF = 0.029+PosX, PosYF = 0.004+PosY, offsetF = 0.0005, offsetF1 = 0.001;F = all( abs(float2( texcoord.x -PosXF-offsetF, texcoord.y-PosYF-offsetF1)) < float2(0.002,0.004));F -= all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0025,0.005));F += all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0015,0.00075)); + float PosXO = 0.035+PosX, PosYO = 0.004+PosY;O = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.003,0.005));O -= all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.002,0.003)); +} + +////////////////////////////////////////////////////////Watermark///////////////////////////////////////////////////////////////////////// +float4 OutF(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float3 Color = ShaderGlammor(texcoord).rgb; + float PosX = 0.9525f*BUFFER_WIDTH*pix.x,PosY = 0.975f*BUFFER_HEIGHT*pix.y,A,B,C,D,E,F,G,H,I,J,K,L,PosXDot = 0.011+PosX, PosYDot = 0.008+PosY;L = all( abs(float2( texcoord.x -PosXDot, texcoord.y-PosYDot)) < float2(0.00075,0.0015));A0(texcoord,PosX,PosY,A,B,C,D,E,F,G );A1(texcoord,PosX,PosY,H,I,J,K); + return timer <= 12500 ? A+B+C+D+E+F+G+H+I+J+K+L ? 0.02 : float4(Color,1.) : float4(Color,1.); +} +///////////////////////////////////////////////////////////////////ReShade.fxh////////////////////////////////////////////////////////////////////// +void PostProcessVS(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD) +{// Vertex shader generating a triangle covering the entire screen + 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); +}//Using this to make it portable +//*Rendering passes*// +technique Flair +{ + pass ColorMap + { + VertexShader = PostProcessVS; + PixelShader = ColorBB; + RenderTarget = TexMBB; + } + pass Past + { + VertexShader = PostProcessVS; + PixelShader = Past_Flare; + RenderTarget = TexFlarePast; + } + pass BrigthColors + { + VertexShader = PostProcessVS; + PixelShader = StoredBB; + RenderTarget = TexBC; + } + pass Star + { + VertexShader = PostProcessVS; + PixelShader = Glammor; + RenderTarget = texFlare; + } + pass Lum + { + VertexShader = PostProcessVS; + PixelShader = LuminanceG; + RenderTarget = texLumF; + } + pass Avg_Lum + { + VertexShader = PostProcessVS; + PixelShader = Average_LuminanceF; + RenderTarget = texAvgLumF; + } + pass StoreAvgLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_StoreAvgLumaF; + RenderTarget0 = TexAvgLumaLastF; + RenderTarget1 = TexFlareShared; + } + #if !exists "DisableFlare.txt" + pass FlareOut + { + VertexShader = PostProcessVS; + PixelShader = OutF; + } + #endif +} diff --git a/data_from_portwine/Reshade/Shaders/GloomAO.fx b/data_from_portwine/Reshade/Shaders/GloomAO.fx new file mode 100644 index 00000000..000455fa --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/GloomAO.fx @@ -0,0 +1,1477 @@ +////-----------// +///**GloomAO**/// +//-----------//// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// *// +//For Reshade 4.0+ SSDO Ver 0.2.7 +//----------------------------- +// Screen Space Directional Occlusion +// +// Due Diligence +// +// Normal from Depth PureDepthAO +// http://theorangeduck.com/page/pure-depth-ssao +// - Daniel Holden +// http://theorangeduck.com/page/about +// +// Approximating Dynamic Global Illumination in Image Space +// https://people.mpi-inf.mpg.de/~ritschel/Papers/SSDO.pdf +// - Tobias Ritschel | Thorsten Grosch | Hans-Peter Seidel +// MPI Informatik - The Max Planck Institute for Informatics +// +// SSGI - OpenGL demonstration project - SSAO vs SSDO +// https://github.com/jdupuy/ssgi/blob/master/src/shaders/ssgi.glsl +// - Jonathan Dupuy AKA jdupuy +// http://onrendering.com +// +// SSDO - ReShade Shader +// https://github.com/pascalmatthaeus/ppfx/blob/master/Shaders/PPFX_SSDO.fx +// - Pascal Matthäus AKA Euda +// https://github.com/pascalmatthaeus +// +// Poisson Sampling Generator +// https://github.com/bartwronski/PoissonSamplingGenerator +// - Bart Wronski AKA bartwronski +// http://bartwronski.com/ +// +// Interleaved Gradient Noise +// http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare +// - Jorge Jimenez +// https://www.iryoku.com/aboutme +// +// Wagner Based Poisson Noise +// https://github.com/spite/Wagner/blob/master/fragment-shaders/poisson-disc-blur-fs.glsl +// - Jaume Sanchez AKA spite +// http://www.clicktorelease.com +// +// Adapted Median +// https://github.com/brimson/reshaders/blob/12619ecb296e058a4b20ec443d54611d87dd7e9c/shaders/cMotionBlur.fx +// - Paul Dang AKA Brimson +// https://github.com/brimson +// +// Temporal AA "Epic Games" implementation + Some Magic +// - yvtjp +// https://www.shadertoy.com/view/4tcXD2 +// https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf +// https://yvt.jp/ +// +// If I missed any please tell me. +// +// Special Thank ???? +// +// LICENSE +// ============ +// Overwatch & Code out side the work of people mention above is licenses under: Attribution-NoDerivatives 4.0 International +// +// 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. +// +// NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. +// +// 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-nd/4.0 +// +// Have fun, +// Written by Jose Negrete AKA BlueSkyDefender , October 2021 +// https://github.com/BlueSkyDefender/Depth3D +// +// Notes to the other developers: https://github.com/BlueSkyDefender/AstrayFX +// +// GloomAO Update Notes are at the bottom +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if exists "Overwatch.fxh" //Overwatch Interceptor// + #include "Overwatch.fxh" + #define OS 0 +#else// DA_Y = [Depth Adjust] DA_Z = [Offset] DA_W = [Depth Linearization] DB_X = [Depth Flip] + static const float DA_Y = 7.5, DA_Z = 0.0, DA_W = 0.0, DB_X = 0; + // DC_X = [Barrel Distortion K1] DC_Y = [Barrel Distortion K2] DC_Z = [Barrel Distortion K3] DC_W = [Barrel Distortion Zoom] + static const float DC_X = 0, DC_Y = 0, DC_Z = 0, DC_W = 0; + // DD_X = [Horizontal Size] DD_Y = [Vertical Size] DD_Z = [Horizontal Position] DD_W = [Vertical Position] + static const float DD_X = 1, DD_Y = 1, DD_Z = 0.0, DD_W = 0.0; + //Triggers + static const int RE = 0, NC = 0, RH = 0, NP = 0, ID = 0, SP = 0, DC = 0, HM = 0, DF = 0, NF = 0, DS = 0, LBC = 0, LBM = 0, DA = 0, NW = 0, PE = 0, FV = 0, ED = 0; + //Overwatch.fxh State + #define OS 1 +#endif + +//Depth Buffer Adjustments +#define DB_Size_Position 0 //[Off | On] This is used to reposition and adjust the size of the depth buffer. +#define BD_Correction 0 //[Off | On] Barrel Distortion Correction for non conforming BackBuffer. + +//Other Settings +#define Text_Info_Key 93 //Menu Key Text Information Key Default 93 is the Menu Key. You can use this site https://keycode.info to pick your own. +#define Disable_Debug_Info 0 //[Off | On] Use this to disable help information that gives you hints for fixing many games with Overwatch.fxh. +#define Minimize_Web_Info 0 //[Off | On] Use this to minimize the website logo on startup. +#define Force_Texture_Details 0//[Off | On] This is used to add Texture Detail AO into SSDO output. WIP +#define SSDO_Buffer_Size 2 // [1-2] You can use this to set the resolution of the main SSDO Buffer. + +//Help / Guide Information stub uniform a idea from LucasM +uniform int GloomAO < + ui_text = "GloomAO is an Screen Space Directional Occlusion algorithm based on generalize SSAO. SSDO was created by the people at MPI Informatik.\n" + "The researches Tobias Ritschel, Thorsten Grosch, and Hans-Peter Seidel. Where instrumental in making this happen, so Thank you.\n" + "SSDO physically plausible occlusion allows better simulated depth cues based on gradient and contrast information.\n" + "This AO shader is free and shouldn't sit behind a paywall. If you paid for this shader ask for a refund right away.\n" + "As for my self I do want to provide the community with free shaders and any donations will help keep that motivation alive.\n" + "For more information and help please feel free to visit http://www.Depth3D.info or https://blueskydefender.github.io/AstrayFX\n " + "Help with this shader fuctions specifically visit the WIki @ https://github.com/BlueSkyDefender/AstrayFX/wiki/RadiantGI\n" + "Please enjoy this shader and Thank You for using GloomAO."; + ui_category = "GloomAO"; + ui_category_closed = true; + ui_label = " "; + ui_type = "radio"; +>; +//uniform float3 TEST < ui_type = "slider"; ui_min = 0; ui_max = 1; > = 1.0; +uniform int SSDO_MipSampling < + ui_type = "combo"; + ui_items = "Full Resolution\0Half Resolution\0Quarter Resolution\0Full Resolution Adptive\0Half Resolution Adaptive\0Quarter Resolution Adaptive\0"; + ui_label = "Sampling Quality"; + ui_tooltip = "Use this to improve performance by sampling Mipmaps.\n" + "Artifacts are more prominent at lower quality settings."; + ui_category = "SSDO"; +> = 4; + +uniform int SSDO_Levels < + ui_type = "slider"; + ui_min = 0; ui_max = 64; + ui_label = "Samples"; + ui_tooltip = "The Samples slider is used to increase or decrease samples amount as a side effect this reduces noise at the cost of performance."; + ui_category = "SSDO"; +> = 32; + +uniform float SSDO_SampleRadius < + ui_type = "slider"; + ui_min = 1.0; ui_max = 5000.0;// ui_step = 0.1; + ui_label = "Sampling Radius"; + ui_tooltip = "This lets you extend the Sample Radius or Sample Range of the SSDO Algo.\n" + "Setting this too high will decrease performance.";//High values reduce cache coherence, This will lead to cache misses and decrease performance. + ui_category = "SSDO"; +> = 2500.0; +#if Force_Texture_Details +uniform float SSDO_2DTexture_Detail < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Texture Details"; + ui_tooltip = "Lets you add Texture Details to SSDO so you can have Obscurance on 2D information.\n" + "Defaults is [0.0] Off"; + ui_category = "SSDO"; +> = 0.0; +#else +static const int SSDO_2DTexture_Detail = 0; +#endif +uniform float2 NCD < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Near Details"; + ui_tooltip = "Lets you adjust detail of objects near the cam and or like weapon hand AO.\n" + "The 2nd Option is for Weapon Hands in game that fall out of range.\n" + "Defaults are [Near Details X 0.125] [Weapon Hand Y 0.0]"; + ui_category = "SSDO"; +> = float2(0.125,0.0); + +uniform float SSDO_Trimming < + ui_type = "slider"; + ui_min = 0; ui_max = 0.5; + ui_label = "Depth Trimming"; + ui_tooltip = "Use this to limit the local falloff of the ao in the image also known as Depth Range Check."; + ui_category = "SSDO"; +> = 0.1; + +uniform float SSDO_Fade < + ui_type = "slider"; + ui_min = -1.0; ui_max = 1.0; + ui_label = "Depth Fade-Out"; + ui_tooltip = "SSDO Application Power that is based on Depth scaling for controlled fade In-N-Out.\n" //That's What A Hamburger's All About + "Can be set from -1 to 1 and is Set to Zero for No Culling.\n" + "Default is 0.5."; + ui_category = "SSDO"; +> = 1.0; +/* +uniform int BM < + ui_type = "combo"; + ui_label = "Blend Mode"; + ui_tooltip = "Use this to change the look of GI when applied to the final image."; + ui_items = "Mix\0Overlay\0Softlight\0Add\0"; + ui_category = "Image"; + > = 0; +*/ +static const int Blend_Mode = 3; //Phased out Since I wanted this shader to be more simple. + +uniform int SSDO_X2 < //Thank you Nathaniel for the name + ui_type = "combo"; + ui_items = "Square Off\0Square Input\0Square Luma Positive\0Square Luma Negitive\0"; + ui_label = "Square Input"; + ui_tooltip = "This option squares the input of BackBuffer for SSDO.\n" + "You can also favor Illuminated areas or Darker areas.\n" + "This is basically effects the GI Color and AO, Default is Off."; + ui_category = "Image";// Starting to define my look. +> = 0; + +uniform float SSDO_Power< + ui_type = "slider"; + ui_min = 0.0; ui_max = 5.0; + ui_label = "Total Power"; + ui_tooltip = "This option controls the over all intensity of the effect."; + ui_category = "Image"; +> = 1.5; + +uniform float SSDO_ColorPower< + ui_type = "slider"; + ui_min = 0.0; ui_max = 5.0; + ui_label = "Color Power"; + ui_tooltip = "This option controls the GI Color intensity."; + ui_category = "Image"; +> = 1.5; + +uniform float SSDO_Saturation < + ui_type = "slider"; + ui_min = 0.0; ui_max = 5.0; + ui_label = "Saturation"; + ui_tooltip = "Applys color saturation to the indriect bounce of light."; + ui_category = "Image"; +> = 1.0; + +uniform float SSDO_Intensity_Masking < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Intensity Mask"; + ui_tooltip = "Mask out intense light sources from receiving AO."; + ui_category = "Image"; +> = 0.0; + +uniform int Depth_Map < + ui_type = "combo"; + ui_items = "DM0 Normal\0DM1 Reversed\0"; + ui_label = "Depth Map Selection"; + ui_tooltip = "Linearization for the zBuffer also known as Depth Map.\n" + "DM0 is Z-Normal and DM1 is Z-Reversed.\n"; + ui_category = "Depth Map"; +> = DA_W; + +uniform float Depth_Map_Adjust < + ui_type = "drag"; + ui_min = 1.0; ui_max = 500.0; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "This allows for you to adjust the DM precision.\n" + "Adjust this to keep it as low as possible.\n" + "Default is 7.5"; + ui_category = "Depth Map"; +> = DA_Y; + +uniform float Offset < + ui_type = "drag"; + ui_min = -1.0; ui_max = 1.0; + ui_label = "Depth Map Offset"; + ui_tooltip = "Depth Map Offset is for non conforming ZBuffer.\n" + "It is rare that you would need to use this option.\n" + "Use this to make adjustments to DM 0 or DM 1.\n" + "Default and starts at Zero and it is Off."; + ui_category = "Depth Map"; +> = DA_Z; + +uniform float SSDO_Max_Depth < + ui_type = "slider"; + ui_min = 0.5; ui_max = 1.0; + ui_label = "Max Depth"; + ui_tooltip = "SSDO Max Depth is used to limit the max range SSDO should pull information from the Depth Buffer.\n" //That's What A Hamburger's All About + "Think about it like a Wall where all information stops, keep in mind this is not like Depth Fade.\n" + "Default is 0.999."; + ui_category = "Depth Map"; +> = 0.999; + +uniform bool Depth_Map_Flip < + ui_label = "Depth Map Flip"; + ui_tooltip = "Flip the depth map if it is upside down."; + ui_category = "Depth Map"; +> = DB_X; + +uniform int Debug < + ui_type = "combo"; + ui_items = "GloomAO\0Debug\0Depth & Normals\0"; + ui_label = "Debug View"; + ui_tooltip = "View Debug Buffers."; + ui_category = "Extra Options"; +> = 0; + +uniform int SamplesXY < + ui_type = "slider"; + ui_min = 1; ui_max = 6; + ui_label = "Denoise Power";//Ya CeeJay.dk you got your way.. + ui_tooltip = "This raises or lowers Samples used for the Final DeNoisers which in turn affects Performance.\n" + "This also has the side effect of smoothing out the image so you get that Normal Like Smoothing.\n" + "Default is 3 and you can override this a bit."; + ui_category = "Extra Options"; +> = 3; + +uniform float Persistence < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "TAA Power"; + ui_tooltip = "Increase persistence of the frames this is really the Temporal Part.\n" + "Default is 0.125 and a value of 1.0 is off."; + ui_category = "Extra Options"; +> = 0.125; + +uniform bool Dither_SSDO < + ui_label = "Dither SSDO"; + ui_tooltip = "Add Noise to AO so that it can limit banding in some game."; + ui_category = "Extra Options"; +> = true; + +#if DB_Size_Position || SP == 2 +uniform float2 Horizontal_and_Vertical < + ui_type = "drag"; + ui_min = 0.0; ui_max = 2; + ui_label = "Horizontal & Vertical Size"; + ui_tooltip = "Adjust Horizontal and Vertical Resize. Default is 1.0."; + ui_category = "Depth Corrections"; +> = float2(DD_X,DD_Y); +uniform float2 Image_Position_Adjust< + ui_type = "drag"; + ui_min = -1.0; ui_max = 1.0; + ui_label = "Horizontal & Vertical Position"; + ui_tooltip = "Adjust the Image Position if it's off by a bit. Default is Zero."; + ui_category = "Depth Corrections"; +> = float2(DD_Z,DD_W); +#else +static const float2 Horizontal_and_Vertical = float2(DD_X,DD_Y); +static const float2 Image_Position_Adjust = float2(DD_Z,DD_W); +#endif +#if BD_Correction +uniform int BD_Options < + ui_type = "combo"; + ui_items = "On\0Off\0"; + ui_label = "Distortion Options"; + ui_tooltip = "Use this to Turn BD Off or On.\n" + "Default is ON."; + ui_category = "Depth Corrections"; +> = 0; + +uniform float3 Colors_K1_K2_K3 < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = -2.0; ui_max = 2.0; + ui_tooltip = "Adjust the Distortion K1, K2, & K3.\n" + "Default is 0.0"; + ui_label = "BD K1 K2 K3"; + ui_category = "Depth Corrections"; +> = float3(DC_X,DC_Y,DC_Z); + +uniform float Zoom < + ui_type = "drag"; + ui_min = -0.5; ui_max = 0.5; + ui_label = "BD Zoom"; + ui_category = "Depth Corrections"; +> = DC_W; +#else + #if DC + uniform bool BD_Options < + ui_label = "Toggle Barrel Distortion"; + ui_tooltip = "Use this if you modded the game to remove Barrel Distortion."; + ui_category = "Depth Corrections"; + > = !true; + #else + static const int BD_Options = 1; + #endif +static const float3 Colors_K1_K2_K3 = float3(DC_X,DC_Y,DC_Z); +static const float Zoom = DC_W; +#endif +#if BD_Correction || DB_Size_Position + uniform bool Depth_Guide < + ui_label = "Alinement Guide"; + ui_tooltip = "Use this for a guide for alinement."; + ui_category = "Depth Corrections"; + > = !true; +#else + static const int Depth_Guide = 0; +#endif +//Use for real HDR. //Do not Use. +#define HDR_Toggle 0 //For HDR //Do not Use. +uniform bool Text_Info < source = "key"; keycode = Text_Info_Key; toggle = true; mode = "toggle";>; +uniform int framecount < source = "framecount"; >; // Total amount of frames since the game started. +#define Alternate framecount % 2.0 == 0 // Alternate per frame + +texture DepthBufferTex : DEPTH; + +sampler ZBufferSSDO + { + Texture = DepthBufferTex; + }; + +texture BackBufferTex : COLOR; + +sampler BackBufferSSDO + { + Texture = BackBufferTex; + }; + +texture2D accuTexSSDO { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT ; Format = RGBA8; MipLevels = 4; }; +sampler2D SSDOaccuFrames { Texture = accuTexSSDO; }; + +texture texNormalsSSDO { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RG16f; MipLevels = 4; }; + +sampler SamplerNormalsSSDO +{ + Texture = texNormalsSSDO; +}; + +texture texColorsSSDO { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 8; }; + +sampler SamplerColorsSSDO +{ + Texture = texColorsSSDO; +}; + +texture texDepthSSDO { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT; Format = R32f; MipLevels = 4; }; + +sampler SamplerDepthSSDO +{ + Texture = texDepthSSDO; +}; + +texture texSSDO { Width = BUFFER_WIDTH / SSDO_Buffer_Size; Height = BUFFER_HEIGHT / SSDO_Buffer_Size; Format = RGBA8; MipLevels = 2; }; + +sampler SamplerSSDO +{ + Texture = texSSDO; +}; + +texture texCEAGD_H_SSDO { Width = BUFFER_WIDTH / 2; Height = BUFFER_HEIGHT / 2; Format = RGBA8; }; + +sampler SamplerSSDOH +{ + Texture = texCEAGD_H_SSDO; +}; + +texture texCEAGD_V_SSDO { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT; Format = RGBA8; }; + +sampler SamplerSSDOV +{ + Texture = texCEAGD_V_SSDO; +}; +//Pre Defined value for PI +#define PI 3.14159265358979323846264 +#define pix float2(BUFFER_RCP_WIDTH,BUFFER_RCP_HEIGHT) +uniform float clock < source = "timer"; >; // A timer that starts when the Game starts. + +static const float2 XYoffset[8] = { float2( 0,+pix.y ), float2( 0,-pix.y), float2(+pix.x, 0), float2(-pix.x, 0), float2(-pix.x,-pix.y), float2(+pix.x,-pix.y), float2(-pix.x,+pix.y), float2(+pix.x,+pix.y) }; + +float Scale_SSDO_Fade() +{ + return lerp(0,2,saturate(abs(SSDO_Fade)) ); +} + +float Offset_Switch() +{ + return Offset >= -0.0015 && Offset <= 0.0015 ? 0 : Offset; +} + +static const float2 POISSON_SAMPLES[64] = +{ +float2( 0.5273496125406625f, 0.32843211798055333f ), +float2( -0.9204308268276714f, -0.07983643921713124f ), +float2( 0.6643335271236648f, -0.6896971714892444f ), +float2( -0.4485055311020943f, -0.8026704829903724f ), +float2( -0.5089046351832555f, 0.6458887612871638f ), +float2( 0.08897250178211012f, -0.2806489141686402f ), +float2( -0.29838092677534184f, 0.10278438048827801f ), +float2( -0.862115316272164f, -0.48356308603032117f ), +float2( 0.5999430799342932f, -0.14561568677130635f ), +float2( 0.08785280092966417f, -0.9462682543249354f ), +float2( 0.07087614249781364f, 0.8602082808602768f ), +float2( -0.8534726000488865f, 0.29681151269733946f ), +float2( 0.9539380967370391f, 0.030097899562570734f ), +float2( 0.10087936756781524f, 0.34573585367530424f ), +float2( -0.20159182487876662f, -0.4490941013720869f ), +float2( 0.6782242471078768f, 0.6658563096694241f ), +float2( -0.10394741987685427f, -0.7221204563776964f ), +float2( 0.319809955759203f, -0.6790019202399492f ), +float2( 0.3839401781148807f, -0.3690247708221736f ), +float2( -0.22207725541276904f, 0.849453247755017f ), +float2( -0.47529541958366694f, 0.37684164173216f ), +float2( -0.5367298351175375f, -0.19642553224785247f ), +float2( -0.13522275308104328f, 0.560514350786896f ), +float2( 0.3870397244317962f, -0.14841260985099053f ), +float2( 0.37049654041868246f, 0.5154922403112734f ), +float2( 0.6672724378901226f, -0.5213728466474493f ), +float2( 0.7826123622504166f, 0.4639934736267554f ), +float2( -0.015411930763345674f, 0.014250559941404296f ), +float2( -0.4760921395716165f, 0.022730166563585057f ), +float2( -0.6084367587131735f, -0.5187337391472053f ), +float2( 0.2795395707170242f, 0.16224024832087033f ), +float2( 0.3736006279406249f, 0.9117234096211635f ), +float2( -0.6919417915679925f, -0.07760236473727093f ), +float2( 0.0744476719248192f, 0.20311070507786347f ), +float2( -0.2222943155587649f, -0.9478651097451272f ), +float2( -0.10033941671817023f, 0.3960078920620986f ), +float2( 0.4568029060767225f, -0.8791627760764141f ), +float2( -0.8785382515186919f, 0.10180549622612695f ), +float2( 0.8537682559640656f, -0.38658822274799526f ), +float2( 0.0609609200214567f, -0.5420008791782059f ), +float2( -0.23669353949304686f, -0.26999886626839875f ), +float2( -0.7151483708986462f, 0.4483280195001876f ), +float2( -0.47610621490338256f, -0.4030389610541533f ), +float2( -0.6126689926468303f, -0.7490506324903827f ), +float2( -0.255018095671136f, -0.1266388390537941f ), +float2( 0.12077897961942986f, -0.7580461130803654f ), +float2( 0.25776824865464415f, -0.273887482324501f ), +float2( 0.36800354072014885f, 0.03615086613505087f ), +float2( 0.09086994649736232f, 0.5592777484289124f ), +float2( 0.3475335327722212f, 0.7240680900695486f ), +float2( -0.3390135610972872f, 0.43925808523465654f ), +float2( 0.20295677355509983f, 0.9663359071038066f ), +float2( -0.4532808819917399f, 0.8089615780465481f ), +float2( -0.09813012107560773f, -0.1766103593720822f ), +float2( 0.9222515851215884f, 0.283088863183107f ), +float2( -0.7572137302598909f, 0.5924401327732448f ), +float2( 0.27251111237710013f, 0.390873918753542f ), +float2( -0.7292711663101386f, -0.3397294444419196f ), +float2( -0.118184652957795f, 0.16462830825770766f ), +float2( -0.41261675793648533f, -0.6389515272662722f ), +float2( 0.7148481592421466f, 0.19825111300217793f ), +float2( 0.13181440606510209f, -0.13462617904858257f ), +float2( 0.6564465799531382f, -0.3053207424251268f ), +float2( -0.6667623629118123f, 0.1886689773307198f ), +}; + +// YUV-RGB conversion routine from Hyper3D +float3 encodePalYuv(float3 rgb) +{ + float3 RGB2Y = float3( 0.299, 0.587, 0.114); + float3 RGB2Cb = float3(-0.169,-0.331, 0.500); + float3 RGB2Cr = float3( 0.500,-0.419,-0.081); + + return float3(dot(rgb, RGB2Y), dot(rgb, RGB2Cb), dot(rgb, RGB2Cr)); +} + +float3 decodePalYuv(float3 ycc) +{ + float3 YCbCr2R = float3( 1.000, 0.000, 1.400); + float3 YCbCr2G = float3( 1.000,-0.343,-0.711); + float3 YCbCr2B = float3( 1.000, 1.765, 0.000); + + return float3(dot(ycc, YCbCr2R), dot(ycc, YCbCr2G), dot(ycc, YCbCr2B)); +} + +float3 HUEToRGB( in float H ) +{ + return saturate( float3( abs( H * 6.0f - 3.0f ) - 1.0f, + 2.0f - abs( H * 6.0f - 2.0f ), + 2.0f - abs( H * 6.0f - 4.0f ))); +} + +float3 RGBToHCV( in float3 RGB ) +{ + // Based on work by Sam Hocevar and Emil Persson + float4 P = ( RGB.g < RGB.b ) ? float4( RGB.bg, -1.0f, 2.0f/3.0f ) : float4( RGB.gb, 0.0f, -1.0f/3.0f ); + float4 Q1 = ( RGB.r < P.x ) ? float4( P.xyw, RGB.r ) : float4( RGB.r, P.yzx ); + float C = Q1.x - min( Q1.w, Q1.y ); + float H = abs(( Q1.w - Q1.y ) / ( 6.0f * C + 0.000001f ) + Q1.z ); + return float3( H, C, Q1.x ); +} + +float3 RGBToHSL( in float3 RGB ) +{ + RGB.xyz = max( RGB.xyz, 0.000001f ); + float3 HCV = RGBToHCV(RGB); + float L = HCV.z - HCV.y * 0.5f; + float S = HCV.y / ( 1.0f - abs( L * 2.0f - 1.0f ) + 0.000001f); + return float3( HCV.x, S, L ); +} + +float3 HSLToRGB( in float3 HSL ) +{ + float3 RGB = HUEToRGB(HSL.x); + float C = (1.0f - abs(2.0f * HSL.z - 1.0f)) * HSL.y; + return ( RGB - 0.5f ) * C + HSL.z; +} + +float3 Saturator(float3 C) +{ + C.rgb = RGBToHSL(C.rgb); + C.y *= SSDO_Saturation; + return HSLToRGB(C.rgb); +} + +float max3(float x, float y, float z) +{ + return max(x, max(y, z)); +} + +float3 inv_Tonemapper(float4 color) +{ //Timothy Lottes fast_reversible + return color.rgb * rcp((1.0 + max(color.w,0.001)) - max3(color.r, color.g, color.b)); +} + +float Luma(float3 C) +{ + float3 Luma; + + if (HDR_Toggle == 0) + { + Luma = float3(0.2126, 0.7152, 0.0722); // (HD video) https://en.wikipedia.org/wiki/Luma_(video) + } + else + { + Luma = float3(0.2627, 0.6780, 0.0593); // (HDR video) https://en.wikipedia.org/wiki/Rec._2100 + } + + return dot(C,Luma); +} + +float fmod(float a, float b) +{ + float c = frac(abs(a / b)) * abs(b); + return a < 0 ? -c : c; +} + +float MCNoise(float2 TC,float FC ,float seed) +{ //This is the noise I used for rendering + float motion = FC, a = 12.9898, b = 78.233, c = 43758.5453, dt = dot(TC.xy + 0.5, float2(a,b)), sn = fmod(dt,PI + seed) * motion; + return frac( sin( sn ) * c ); +} int T_01() { return 12500; } + +#define Scale SSDO_Buffer_Size +float Interleaved_Gradient_Noise(float2 TC) +{ //Magic Numbers + float3 MNums = float3(0.06711056, 0.00583715, 52.9829189); + return frac( MNums.z * frac(dot(TC,MNums.xy)) ); +} + +#if BD_Correction || DC +float2 D(float2 p, float k1, float k2, float k3) //Lens + Radial lens undistort filtering Left & Right +{ // Normalize the u,v coordinates in the range [-1;+1] + p = (2. * p - 1.); + // Calculate Zoom + p *= 1 + Zoom; + // Calculate l2 norm + float r2 = p.x*p.x + p.y*p.y; + float r4 = r2 * r2; + float r6 = r4 * r2; + // Forward transform + float x2 = p.x * (1. + k1 * r2 + k2 * r4 + k3 * r6); + float y2 = p.y * (1. + k1 * r2 + k2 * r4 + k3 * r6); + // De-normalize to the original range + p.x = (x2 + 1.) * 1. * 0.5; + p.y = (y2 + 1.) * 1. * 0.5; + +return p; +} +#endif + +float Depth_Info(float2 texcoord) +{ + #if BD_Correction || DC + if(BD_Options == 0) + { + float3 K123 = Colors_K1_K2_K3 * 0.1; + texcoord = D(texcoord.xy,K123.x,K123.y,K123.z); + } + #endif + #if DB_Size_Position || SP || LBC || LB_Correction + texcoord.xy += float2(-Image_Position_Adjust.x,Image_Position_Adjust.y)*0.5; + #if LBC || LB_Correction + float2 H_V = Horizontal_and_Vertical * float2(1,LBDetection() ? 1.315 : 1 ); + #else + float2 H_V = Horizontal_and_Vertical; + #endif + float2 midHV = (H_V-1) * float2(BUFFER_WIDTH * 0.5,BUFFER_HEIGHT * 0.5) * pix; + texcoord = float2((texcoord.x*H_V.x)-midHV.x,(texcoord.y*H_V.y)-midHV.y); + #endif + + if (Depth_Map_Flip) + texcoord.y = 1 - texcoord.y; + + //Conversions to linear space..... + float zBuffer = tex2Dlod(ZBufferSSDO, float4(texcoord,0,0)).x, zBufferWH = zBuffer, Far = 1.0, Near = 0.125/(0.00000001+Depth_Map_Adjust), NearWH = 0.125/(Depth_Map ? NCD.y : 10*NCD.y), OtherSettings = Depth_Map ? NCD.y : 100 * NCD.y ; //Near & Far Adjustment + //Man Why can't depth buffers Just Be Normal + float2 C = float2( Far / Near, 1.0 - Far / Near ), Z = Offset_Switch() < 0 ? min( 1.0, zBuffer * ( 1.0 + abs(Offset_Switch()) ) ) : float2( zBuffer, 1.0 - zBuffer ), Offsets = float2(1 + OtherSettings,1 - OtherSettings), zB = float2( zBufferWH, 1-zBufferWH ); + + if(Offset_Switch() > 0 || Offset_Switch() < 0) + Z = Offset_Switch() < 0 ? float2( Z.x, 1.0 - Z.y ) : min( 1.0, float2( Z.x * (1.0 + Offset_Switch()) , Z.y / (1.0 - Offset_Switch()) ) ); + + if (NCD.y > 0) + zB = min( 1, float2( zB.x * Offsets.x , zB.y / Offsets.y )); + + if (Depth_Map == 0) + { //DM0 Normal + zBuffer = rcp(Z.x * C.y + C.x); + zBufferWH = Far * NearWH / (Far + zB.x * (NearWH - Far)); + } + else if (Depth_Map == 1) + { //DM1 Reverse + zBuffer = rcp(Z.y * C.y + C.x); + zBufferWH = Far * NearWH / (Far + zB.y * (NearWH - Far)); + } + + return saturate( lerp(NCD.y > 0 ? zBufferWH : zBuffer,zBuffer,0.925) ); +} int T_02() { return 25000; } +#if Force_Texture_Details +void SSDOColors(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, + out float4 Colors : SV_Target0) +{ float Intensity = 1-dot(0.333,tex2Dlod(BackBufferSSDO,float4(texcoords,0,0)).xyz) > lerp(0.0,0.5,SSDO_Intensity_Masking); + Colors = float4(tex2D(BackBufferSSDO,texcoords).rgb, Intensity); +} +#endif +float2 PackNormals(float3 n) +{ + float f = rsqrt(8*n.z+8); + return n.xy * f + 0.5; +} + +float SUMTexture_lookup(float2 TC, float dx, float dy) +{ float Depth = 1-Depth_Info( TC ); + Depth = (Depth - 0)/ (lerp(1,10,saturate(1-SSDO_2DTexture_Detail)) - 0); + float2 uv = (TC.xy + float2(dx , dy ) * pix); + float3 c = tex2Dlod( SamplerColorsSSDO, float4(uv.xy,0, 0) ).rgb * 0.5; + //c = smoothstep(0,1,normalize(c)); + // return as luma + return (0.2126*c.r + 0.7152*c.g + 0.0722*c.b) * Depth * 0.00666f; +} + +float3 TextureNormals(float2 UV, float Depth) +{ + if(saturate(SSDO_2DTexture_Detail) > 0) + { + // simple sobel edge detection + float dx = 0.0; + dx += -1.0 * SUMTexture_lookup(UV, -1.5, -1.5); + dx += -2.0 * SUMTexture_lookup(UV, -1.5, 0.0); + dx += -1.0 * SUMTexture_lookup(UV, -1.5, 1.5); + dx += 1.0 * SUMTexture_lookup(UV, 1.5, -1.5); + dx += 2.0 * SUMTexture_lookup(UV, 1.5, 0.0); + dx += 1.0 * SUMTexture_lookup(UV, 1.5, 1.5); + + float dy = 0.0; + dy += -1.0 * SUMTexture_lookup(UV, -1.5, -1.5); + dy += -2.0 * SUMTexture_lookup(UV, 0.0, -1.5); + dy += -1.0 * SUMTexture_lookup(UV, 1.5, -1.5); + dy += 1.0 * SUMTexture_lookup(UV, -1.5, 1.5); + dy += 2.0 * SUMTexture_lookup(UV, 0.0, 1.5); + dy += 1.0 * SUMTexture_lookup(UV, 1.5, 1.5); + + float edge = sqrt(dx*dx + dy*dy); + edge *= edge; + + float angle = atan2(dx,dy); + + float X = edge * sin(angle); X = -X; + float Y = edge * sin(angle + 7.5 * PI / 3.);// Adjust me to rotate Normals + float Z = edge * (X - Y); + + return min(1,lerp(float3(X,Y,Z) * Depth, 0, float3(X,Y,Z) == 0.5)); + } + else + return 0; + +} + +//PureDepthAO +#if Force_Texture_Details +void NormalsDepth(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, + out float2 Normals : SV_Target0, + out float Depth : SV_Target1) +{ +#else +void NormalsColorsDepth(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, + out float2 Normals : SV_Target0, + out float4 Colors : SV_Target1, + out float Depth : SV_Target2) +{ +#endif + // WTF right well I got tired of working on this so I just half assed it. + float2 off1 = float2( pix.x, 0); // right + float2 off4 = float2( 0,-pix.y); // up + //A 2x2 Taps is done here. You can also do 4x4 tap + float2 uv0 = texcoords; // center + float2 uv1 = texcoords + off1; // right + float2 uv2 = texcoords + float2(-pix.x, 0); // left + float2 uv3 = texcoords + float2( 0, pix.y); // down + float2 uv4 = texcoords + off4; // up + + float depth = Depth_Info( uv0 ); + float depthR = Depth_Info( uv1 ); + float depthL = Depth_Info( uv2 ); + float depthD = Depth_Info( uv3 ); + float depthU = Depth_Info( uv4 ); + + //Had to add depth to offsets 1 and 2 and needed to flip offset 1..... + float3 P1 = float3( off1 * depth, depth - depthR); + float3 P2 = float3( off4 * depth, depth - depthD); + + float3 normal = cross(P2, P1); + + float3 P0; + + int best_Z_horizontal = abs(depthR - depth) < abs(depthL - depth) ? 1 : 2; + int best_Z_vertical = abs(depthD - depth) < abs(depthU - depth) ? 3 : 4; + + if (best_Z_horizontal == 1 && best_Z_vertical == 4) + { //triangle 0 = P0: center, P1: right, P2: up + P1 = float3(uv1 - 0.5, 1) * depthR; + P2 = float3(uv4 - 0.5, 1) * depthU; + } + if (best_Z_horizontal == 1 && best_Z_vertical == 3) + { //triangle 1 = P0: center, P1: down, P2: right + P1 = float3(uv3 - 0.5, 1) * depthD; + P2 = float3(uv1 - 0.5, 1) * depthR; + } + if (best_Z_horizontal == 2 && best_Z_vertical == 4) + { //triangle 2 = P0: center, P1: up, P2: left + P1 = float3(uv4 - 0.5, 1) * depthU; + P2 = float3(uv2 - 0.5, 1) * depthL; + } + if (best_Z_horizontal == 2 && best_Z_vertical == 3) + { //triangle 3 = P0: center, P1: left, P2: down + P1 = float3(uv2 - 0.5, 1) * depthL; + P2 = float3(uv3 - 0.5, 1) * depthD; + } + + P0 = float3(uv0 - 0.5, 1) * depth; + + float3 Enormal = cross(P2 - P0, P1 - P0); + Enormal.x = -Enormal.x; + + Enormal = lerp( normal + TextureNormals(texcoords, depth), Enormal, distance( normalize(normal), normalize(Enormal) ) >= 0.7f ); + + Normals = PackNormals(normalize(Enormal)); + #if !Force_Texture_Details + float Intensity = 1-dot(0.333,tex2Dlod(BackBufferSSDO,float4(texcoords,0,0)).xyz) > lerp(0.0,0.5,SSDO_Intensity_Masking); + Colors = float4(tex2D(BackBufferSSDO,texcoords).rgb, Intensity); + #endif + Depth = depth; +} + +float3 UnpackNormals(float2 enc) +{ + float2 fenc = enc*4-2; + float f = dot(fenc,fenc), g = sqrt(1-f/4); + float3 n; + n.xy = fenc*g; + n.z = 1-f/2; + return n; +} + +float4 NDSampler(float2 TC, float Mip) +{ + float3 Norm = UnpackNormals(tex2Dlod(SamplerNormalsSSDO,float4(TC,0,Mip)).xy); + float Depth = tex2Dlod(SamplerDepthSSDO,float4(TC,0,Mip)).x; + + return float4(Norm,Depth); +} + +float2 Rotate2D( float2 r, float l ) +{ float2 Directions; + sincos(l,Directions[0],Directions[1]);//same as float2(cos(l),sin(l)) + return float2( dot( r, float2(Directions[1], -Directions[0]) ), dot( r, Directions.xy ) ); +} + +float3 GetPosition(float2 texcoords,float2 raycoords,float Depth, float FDepth) +{ + // Compute Correct Pos + return float3(float2(raycoords.x-texcoords.x,texcoords.y-raycoords.y) * Depth, Depth - FDepth); +} int nonplus() { return T_01() == 0 || T_02() == 0 ? 1 : 0;} + +float4 SSDO(float4 vpos : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + int SSDO_Samples = clamp(SSDO_Levels,1,64); + float SSDO_SRM = SSDO_SampleRadius, SSDO_AngleThreshold = 1.0, + SSDO_Contribution_Range = SSDO_SRM*pix.x*max(SSDO_Trimming,0.001);//simple scale for aka "Zthiccness." + const float ATTF = 1e-5; // attenuation factor + float random = MCNoise( texcoords , 1, 1 ) * 2 - 1, IGN = Interleaved_Gradient_Noise(floor( texcoords.xy / pix / Scale)); + float4 SSDO, Normals_Depth = NDSampler(texcoords, 0); + float D0 = smoothstep(-NCD.x,1.0,Normals_Depth.w),D_Fade = SSDO_Fade < 0 ? lerp(1-Scale_SSDO_Fade() * 2,0, 1-Normals_Depth.w ) : smoothstep(0,2,Normals_Depth.w / Scale_SSDO_Fade()); + int Mip_Switch = SSDO_MipSampling == 4 || SSDO_MipSampling == 5 ? 1 : 0; + [loop] + for (int i = 1.0; i <= SSDO_Samples; i++) + { //Ref said to use continue.... But, better perf with discard. + if(texcoords.x >= 1 || texcoords.y >= 1) + discard; + + if(Normals_Depth.w > SSDO_Max_Depth) + continue; + //Dumb Magic combo Noise.... Ended up liking this for some damn reason. ////normalize(frac(float2(IGN*BUFFER_WIDTH,IGN*BUFFER_HEIGHT)*i)*2.0-1.0) + float2 RayDir = (pix * (SSDO_SRM/SSDO_Samples)) * IGN * Rotate2D( POISSON_SAMPLES[i], IGN ) / D0; // tossed out reflect(coord,random) Because Sampled Mips didn't work with the code above.... May need Yakube to fix this. + RayDir *= sign(dot(normalize(float3(RayDir.x,-RayDir.y,1.0)),Normals_Depth.xyz)); // flip directions + + float2 RayCoords = texcoords + RayDir.xy; + int Adaptive_Mipping = SSDO_MipSampling <= 2 ? SSDO_MipSampling : lerp(SSDO_MipSampling == 5 ? 3 : 2, Mip_Switch ? 1 : 0, Normals_Depth.w); + float4 vsFetch = NDSampler(RayCoords,Adaptive_Mipping) ; + + float3 LocalGI = tex2Dlod(SamplerColorsSSDO,float4(RayCoords,0,3)).xyz ; + LocalGI *= SSDO_ColorPower; + + // Compute the bounce geometric shape towards the direction of the blocker. Aka Position + float3 Pos = GetPosition( texcoords, RayCoords, Normals_Depth.w - ATTF, vsFetch.w + ATTF); + float3 normalizedPos = normalize(Pos); + + float AO = smoothstep(0,SSDO_AngleThreshold,dot(normalizedPos,Normals_Depth.xyz)); + //float AO = max(0.0,dot(normalizedPos,Normals_Depth.xyz)); + AO *= sign( length(Normals_Depth.xyz-vsFetch.xyz) ); + // Listed as attenuation...... + float SSDO_RangeCheck = max(0.0,SSDO_Contribution_Range-length(Pos))/SSDO_Contribution_Range; + SSDO += lerp(saturate(1-LocalGI) * AO * SSDO_RangeCheck * SSDO_RangeCheck,0,D_Fade); + } + + SSDO /= SSDO_Samples; + return float4(saturate(1.0-SSDO.rgb),1); +} + +float NormalMask(float2 texcoords,float Mip) +{ + float Mask = distance(NDSampler( texcoords, 0),NDSampler( texcoords, Mip)); + return Mask > 0.005; +} + +float3 SSDO_MipBLur(sampler Tex, float2 texcoords,float Mip) +{ + return tex2Dlod(Tex, float4(texcoords, 0, Mip)).rgb; +} + +static const float EvenSteven[21] = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 , 22, 24, 26, 28, 30, 32, 34, 36, 38, 40}; // It's not odd... + +float gaussian(float x, float sigma) +{ + return (rsqrt( PI * pow(sigma,2))) * exp(-(pow(x,2) / (2.0 * pow(sigma,2)))); +} float Helper() { float Temp_Location = T_01() == 12500 ? 0 : 1 ; return Temp_Location;} +//Custom Edge Avoiding Gaussian Denoiser +float4 Denoise(sampler Tex, float2 texcoords, int SXY, int Dir , float R ) +{ + float4 StoredNormals_Depth = NDSampler( texcoords, 0);//Fix 2nd option by using the 2D texture Mask form the Normals from 2D. + float4 center = tex2Dlod(Tex, float4(texcoords ,0, 0)), color = 0.0;//Like why do SmoothNormals when 2nd Level Denoiser is like Got you B#*@!........ + float total = 0.0, NormalBlurFactor = Debug == 1 ? 0.125f : 0.5f, DepthBlurFactor = 0.0125f, DM = smoothstep(0,1,StoredNormals_Depth.w) > 0.999; + + if(SXY > 0) // Who would win Raw Boi or Gaussian Boi + { [fastopt] + for (int i = -SXY * 0.5; i <= SXY * 0.5; ++i) + { + float2 D = Dir ? float2( i, 0) : float2( 0, i), TC = texcoords + D * R * pix; + + float4 ModifiedNormals_Depth = NDSampler( TC, Debug == 1 ? 1.0f : 0.0f);//Use lower mip level here on finnished product. + float ModN = length(StoredNormals_Depth.xyz - ModifiedNormals_Depth.xyz), ModD = saturate( StoredNormals_Depth.w - ModifiedNormals_Depth.w); + + float D_Dist2 = max(ModD, 0.0), d_w = min(exp(-(D_Dist2)/DepthBlurFactor), 1.0)-0.0000000001f;//Magic number..... + float N_Dist2 = max(ModN, 0.0), n_w = min(exp(-(N_Dist2)/NormalBlurFactor), 1.0); + + //if(ModN < 0.25 && ModD < 0.01) + float Weight = gaussian(i, sqrt(SXY));//Looks better + Weight *= d_w; + Weight *= n_w; + color += tex2Dlod(Tex, float4(TC ,0, 0.5)) * Weight; + total += Weight; + + } + } + return SamplesXY > 0 ? lerp(color / total,center,DM) : center; +} + +float4 CEAGD_H_SSDO(float4 vpos : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + return pow(abs(Denoise(SamplerSSDO,texcoords, EvenSteven[clamp(SamplesXY,0,20)], 0, 2.5 )),SSDO_Power); +} + +float4 CEAGD_V_SSDO(float4 vpos : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + return Denoise(SamplerSSDOH, texcoords, EvenSteven[clamp(SamplesXY,0,20)], 1, 2.5 ); +} + +float4 TAA_SSDO(float2 texcoords,float Mip) +{ + return tex2Dlod(SamplerSSDOV, float4(texcoords, 0, Mip)).rgba; +} + +float4 TAA_SSDO(float4 vpos : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + float Per = 1-Persistence; + float4 PastColor = tex2Dlod(SSDOaccuFrames,float4(texcoords,0,0) );//Past Back Buffer + PastColor = (1-Per) * TAA_SSDO(texcoords, 0) + Per * PastColor; + + float3 antialiased = PastColor.xyz; + float mixRate = min(PastColor.w, 0.5), MB = 0.0;//WIP + + float3 BB = TAA_SSDO(texcoords, 0).rgb; + + antialiased = lerp(antialiased * antialiased, BB * BB, mixRate); + antialiased = sqrt(antialiased); + + float3 minColor = encodePalYuv( TAA_SSDO(texcoords, 0).rgb ) - MB; + float3 maxColor = encodePalYuv( TAA_SSDO(texcoords, 0).rgb ) + MB; + for(int i = 1; i < 8; ++i) + { //DX9 work around. + minColor = min(minColor,encodePalYuv( TAA_SSDO( texcoords + XYoffset[i], 0).rgb )) - MB; + maxColor = max(maxColor,encodePalYuv( TAA_SSDO( texcoords + XYoffset[i], 0).rgb )) + MB; + } + antialiased = encodePalYuv(antialiased); + + float3 preclamping = antialiased; + antialiased = clamp(antialiased, minColor, maxColor); + + mixRate = rcp(1.0 / mixRate + 1.0); + + float3 diff = antialiased - preclamping; + + diff.x = dot(diff,diff); + + float clampAmount = diff.x; + + mixRate += clampAmount ; + mixRate = clamp(mixRate, 0.05, 0.5); + + antialiased = decodePalYuv(antialiased); + + return float4(antialiased,mixRate); +} + +void AccumulatedFramesSSDO(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, out float4 acc : SV_Target0) +{ + acc = tex2D(BackBufferSSDO,texcoords).rgba; +} float Text_Info_Plus() { return nonplus() ? Alternate : Text_Info; } + +//Color Mixing +float3 overlay(float3 c, float3 b) { return c<0.5f ? 2.0f*c*b:(1.0f-2.0f*(1.0f-c)*(1.0f-b));} +float3 softlight(float3 c, float3 b) { return b<0.5f ? (2.0f*c*b+c*c*(1.0f-2.0f*b)):(sqrt(c)*(2.0f*b-1.0f)+2.0f*c*(1.0f-b));} +float3 mult(float3 c, float3 b) { return c * b;} + +float3 Composite(float3 Color, float3 Cloud) +{ + float3 Output, FiftyGray = Cloud - 0.5; + + if(Blend_Mode == 0) + Output = lerp((overlay( Color, FiftyGray) + softlight( Color, FiftyGray)) * 0.5 , mult( Color, Cloud ), 0.5); + else if(Blend_Mode == 1) + Output = overlay( Color, FiftyGray); + else if(Blend_Mode == 2) + Output = softlight( Color, FiftyGray); + else + Output = mult( Color , Cloud ); + + return Output; +} + +float4 SSDOMixing(float2 texcoords ) +{ + float Depth = NDSampler( texcoords,0).w, Guide = Depth_Guide ? ( Depth + + NDSampler(texcoords + float2( pix.x * 2, 0), 1).w + + NDSampler(texcoords + float2(-pix.x * 2, 0), 2).w + + NDSampler(texcoords + float2( 0 , pix.y * 2), 3).w + + NDSampler(texcoords + float2( 0 ,-pix.y * 2), 4).w ) * 0.2f : 0.00000001f; + //Mip Denoiser + float3 ssdo = SSDO_MipBLur( SSDOaccuFrames, texcoords,0.0);//lerp(SSDO_MipBLur( SSDOaccuFrames, texcoords,2),SSDO_MipBLur( SSDOaccuFrames, texcoords,0),NormalMask(texcoords,1)); + float Intencity_Mask = tex2Dlod(SamplerColorsSSDO,float4(texcoords,0,2.5)).w; + float ILuma = Luma(tex2Dlod(SamplerColorsSSDO,float4(texcoords,0,4.5)).xyz) * 2.0; + + if(smoothstep(0,1,Depth) > SSDO_Max_Depth) + ssdo = 1; + float3 Noise = float3(MCNoise( texcoords , 1, 1 ), MCNoise( texcoords , 1, 2 ), MCNoise( texcoords , 1, 3 )); + float3 SS = smoothstep( 0.0, 0.1, Saturator(ssdo).rgb ); + SS *= 0.0225; + + if(SSDO_X2 == 1) + ssdo *= ssdo; + if(SSDO_X2 == 2) + ssdo *= lerp(1,ssdo,ILuma); + if(SSDO_X2 == 3) + ssdo *= lerp(1,ssdo,1-ILuma); + + if(Dither_SSDO) + ssdo = saturate(Saturator(ssdo)+ Noise * SS); + else + ssdo = saturate(Saturator(ssdo)); + + float3 Layer = lerp(Composite(tex2D(SamplerColorsSSDO,texcoords).xyz,ssdo),tex2D(SamplerColorsSSDO,texcoords).xyz,1-Intencity_Mask) ; + + if (Debug == 1) + return float4(lerp(ssdo, tex2D(SamplerColorsSSDO,texcoords).xyz,1-Intencity_Mask) ,1.0) ; + else if (Debug == 2) + return float4(texcoords.x + texcoords.y < 1 ? NDSampler( texcoords, 0).w : NDSampler( texcoords, 0).xyz * 0.5 + 0.5,1.0); + else + return float4(Depth_Guide ? Layer.rgb * float3((Depth/Guide> 0.998),1,(Depth/Guide > 0.998)) : Layer.rgb,1.0); +} +////////////////////////////////////////////////////////////////Overwatch//////////////////////////////////////////////////////////////////////////// +float Text_Switch() { return RH || NC || NP || NF || PE || DS || OS || DA || NW || FV ? 0 : 1; } +static const float CH_A = float(0x69f99), CH_B = float(0x79797), CH_C = float(0xe111e), + CH_D = float(0x79997), CH_E = float(0xf171f), CH_F = float(0xf1711), + CH_G = float(0xe1d96), CH_H = float(0x99f99), CH_I = float(0xf444f), + CH_J = float(0x88996), CH_K = float(0x95159), CH_L = float(0x1111f), + CH_M = float(0x9fd99), CH_N = float(0x9bd99), CH_O = float(0x69996), + CH_P = float(0x79971), CH_Q = float(0x69b5a), CH_R = float(0x79759), + CH_S = float(0xe1687), CH_T = float(0xf4444), CH_U = float(0x99996), + CH_V = float(0x999a4), CH_W = float(0x999f9), CH_X = float(0x99699), + CH_Y = float(0x99e8e), CH_Z = float(0xf843f), CH_0 = float(0x6bd96), + CH_1 = float(0x46444), CH_2 = float(0x6942f), CH_3 = float(0x69496), + CH_4 = float(0x99f88), CH_5 = float(0xf1687), CH_6 = float(0x61796), + CH_7 = float(0xf8421), CH_8 = float(0x69696), CH_9 = float(0x69e84), + CH_APST = float(0x66400), CH_PI = float(0x0faa9), CH_UNDS = float(0x0000f), + CH_HYPH = float(0x00600), CH_TILD = float(0x0a500), CH_PLUS = float(0x02720), + CH_EQUL = float(0x0f0f0), CH_SLSH = float(0x08421), CH_EXCL = float(0x33303), + CH_QUES = float(0x69404), CH_COMM = float(0x00032), CH_FSTP = float(0x00002), + CH_QUOT = float(0x55000), CH_BLNK = float(0x00000), CH_COLN = float(0x00202), + CH_LPAR = float(0x42224), CH_RPAR = float(0x24442); +#define MAP_SIZE float2(4,5) +//returns the status of a bit in a bitmap. This is done value-wise, so the exact representation of the float doesn't really matter. +float getBit( float map, float index ) +{ // Ooh -index takes out that divide :) + return fmod( floor( map * exp2(-index) ), 2.0 ); +} float DT_Information(){ float DT_Text = Text_Switch() ? T_02() : T_01(); return clock <= DT_Text; } + +float drawChar( float Char, float2 pos, float2 size, float2 TC ) +{ // Subtract our position from the current TC so that we can know if we're inside the bounding box or not. + TC -= pos; + // Divide the screen space by the size, so our bounding box is 1x1. + TC /= size; + // Create a place to store the result & Branchless bounding box check. + float res = step(0.0,min( TC.x, TC.y)) - step(1.0,max( TC.x, TC.y)); + // Go ahead and multiply the TC by the bitmap size so we can work in bitmap space coordinates. + TC *= MAP_SIZE; + // Get the appropriate bit and return it. + res*=getBit( Char, 4.0 * floor( TC.y) + floor( TC.x) ); + return saturate( res); +} + +float4 Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float2 TC = float2(texcoord.x,1-texcoord.y); + float Gradient = (1-texcoord.y*50.0+48.85)*texcoord.y-0.500, BT = smoothstep(0,1,sin(clock*(3.75/1000))), Size = 1.1, Depth3D, Read_Help, Supported, SetFoV, FoV, Post, Effect, NoPro, NotCom, Mod, Needs, Net, Over, Set, AA, Emu, Not, No, Help, Fix, Need, State, SetAA, SetWP, Work; + float4 Color = SSDOMixing(texcoord); + + [branch] if(DT_Information() || Text_Info_Plus()) + { // Set a general character size... + float2 charSize = float2(.00875, .0125) * Size; + // Starting position. + float2 charPos = float2( 0.009, 0.9725); + //Needs Copy Depth and/or Depth Selection + Needs += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_Y, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_N, charPos, charSize, TC); + //Network Play May Need Modded DLL + charPos = float2( 0.009, 0.955); + Work += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_W, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_K, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_Y, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_Y, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_L, charPos, charSize, TC); + //Disable CA/MB/Dof/Grain + charPos = float2( 0.009, 0.9375); + Effect += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_B, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_B, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_G, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_N, charPos, charSize, TC); + //Disable TAA/MSAA/AA + charPos = float2( 0.009, 0.920); + SetAA += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_B, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); + //Set FoV + charPos = float2( 0.009, 0.9025); + SetFoV += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_V, charPos, charSize, TC); + //Read Help + charPos = float2( 0.894, 0.9725); + Read_Help += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_P, charPos, charSize, TC); + //New Start + charPos = float2( 0.009, 0.018); + // No Profile + NoPro += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_E, charPos, charSize, TC); charPos.x = 0.009; + //Not Compatible + NotCom += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_B, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_E, charPos, charSize, TC); charPos.x = 0.009; + //Needs Fix/Mod + Mod += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_X, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_D, charPos, charSize, TC); charPos.x = 0.009; + //Overwatch.fxh Missing + State += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_V, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_W, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_FSTP, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_X, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_G, charPos, charSize, TC); + //New Size + float D3D_Size_A = 1.375,D3D_Size_B = 0.75; + float2 charSize_A = float2(.00875, .0125) * D3D_Size_A, charSize_B = float2(.00875, .0125) * D3D_Size_B; + //New Start Pos + charPos = float2( 0.862, 0.018); + //Depth3D.Info Logo/Website + Depth3D += drawChar( CH_D, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_E, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_P, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_T, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_H, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_3, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_D, charPos, charSize_A, TC); charPos.x += 0.008 * D3D_Size_A; + Depth3D += drawChar( CH_FSTP, charPos, charSize_A, TC); charPos.x += 0.01 * D3D_Size_A; + charPos = float2( 0.963, 0.018); + Depth3D += drawChar( CH_I, charPos, charSize_B, TC); charPos.x += .01 * D3D_Size_B; + Depth3D += drawChar( CH_N, charPos, charSize_B, TC); charPos.x += .01 * D3D_Size_B; + Depth3D += drawChar( CH_F, charPos, charSize_B, TC); charPos.x += .01 * D3D_Size_B; + Depth3D += drawChar( CH_O, charPos, charSize_B, TC); + //Text Information + if(DS) + Need = Needs; + if(RH) + Help = Read_Help; + if(NW) + Net = Work; + if(PE) + Post = Effect; + if(DA) + AA = SetAA; + if(FV) + FoV = SetFoV; + //Blinking Text Warnings + if(NP) + No = NoPro * BT; + if(NC) + Not = NotCom * BT; + if(NF) + Fix = Mod * BT; + if(OS) + Over = State * BT; + //Website + return Depth3D+(Disable_Debug_Info ? 0 : Help+Post+No+Not+Net+Fix+Need+Over+AA+Set+FoV+Emu) ? Minimize_Web_Info ? lerp(Gradient + Depth3D,Color,saturate(Depth3D*0.98)) : Gradient : Color; + } + else + return Helper() ? 0 : Color; +} + +//////////////////////////////////////////////////////////Reshade.fxh///////////////////////////////////////////////////////////// +// 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) +{ + 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); +} + +technique SSDO_Plus +< ui_label = "GloomAO"; + ui_tooltip = "GloomAO: Screen Space Directional Occlusion"; > +{ + #if Force_Texture_Details + pass SSDO_Colors + { + VertexShader = PostProcessVS; + PixelShader = SSDOColors; + RenderTarget = texColorsSSDO; + } + pass SSDO_Normals_Depth + { + VertexShader = PostProcessVS; + PixelShader = NormalsDepth; + RenderTarget0 = texNormalsSSDO; + RenderTarget1 = texDepthSSDO; + } + #else + pass SSDO_Normals_Depth_Colors + { + VertexShader = PostProcessVS; + PixelShader = NormalsColorsDepth; + RenderTarget0 = texNormalsSSDO; + RenderTarget1 = texColorsSSDO; + RenderTarget2 = texDepthSSDO; + } + #endif + pass SSDO + { + VertexShader = PostProcessVS; + PixelShader = SSDO; + RenderTarget = texSSDO; + } + pass SSDO_EADFDDS + { + VertexShader = PostProcessVS; + PixelShader = CEAGD_H_SSDO; + RenderTarget = texCEAGD_H_SSDO; + } + pass SSDO_EADFDUS + { + VertexShader = PostProcessVS; + PixelShader = CEAGD_V_SSDO; + RenderTarget = texCEAGD_V_SSDO; + } + pass TAA_SSDO + { + VertexShader = PostProcessVS; + PixelShader = TAA_SSDO; + } + pass AccumilateFrames + { + VertexShader = PostProcessVS; + PixelShader = AccumulatedFramesSSDO; + RenderTarget0 = accuTexSSDO; + } + pass SSDO_Out + { + VertexShader = PostProcessVS; + PixelShader = Out; + //SRGBWriteEnable = true; + } + + +} diff --git a/data_from_portwine/Reshade/Shaders/LUT.fx b/data_from_portwine/Reshade/Shaders/LUT.fx new file mode 100644 index 00000000..f93cf753 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/LUT.fx @@ -0,0 +1,80 @@ +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// ReShade effect file +// visit facebook.com/MartyMcModding for news/updates +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Marty's LUT shader 1.0 for ReShade 3.0 +// Copyright © 2008-2016 Marty McFly +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#ifndef fLUT_TextureName + #define fLUT_TextureName "lut.png" +#endif +#ifndef fLUT_TileSizeXY + #define fLUT_TileSizeXY 32 +#endif +#ifndef fLUT_TileAmount + #define fLUT_TileAmount 32 +#endif + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#include "ReShadeUI.fxh" + +uniform float fLUT_AmountChroma < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.00; ui_max = 1.00; + ui_label = "LUT chroma amount"; + ui_tooltip = "Intensity of color/chroma change of the LUT."; +> = 1.00; + +uniform float fLUT_AmountLuma < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.00; ui_max = 1.00; + ui_label = "LUT luma amount"; + ui_tooltip = "Intensity of luma change of the LUT."; +> = 1.00; + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +#include "ReShade.fxh" +texture texLUT < source = fLUT_TextureName; > { Width = fLUT_TileSizeXY*fLUT_TileAmount; Height = fLUT_TileSizeXY; Format = RGBA8; }; +sampler SamplerLUT { Texture = texLUT; }; + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void PS_LUT_Apply(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0) +{ + float4 color = tex2D(ReShade::BackBuffer, texcoord.xy); + float2 texelsize = 1.0 / fLUT_TileSizeXY; + texelsize.x /= fLUT_TileAmount; + + float3 lutcoord = float3((color.xy*fLUT_TileSizeXY-color.xy+0.5)*texelsize.xy,color.z*fLUT_TileSizeXY-color.z); + float lerpfact = frac(lutcoord.z); + lutcoord.x += (lutcoord.z-lerpfact)*texelsize.y; + + float3 lutcolor = lerp(tex2D(SamplerLUT, lutcoord.xy).xyz, tex2D(SamplerLUT, float2(lutcoord.x+texelsize.y,lutcoord.y)).xyz,lerpfact); + + color.xyz = lerp(normalize(color.xyz), normalize(lutcolor.xyz), fLUT_AmountChroma) * + lerp(length(color.xyz), length(lutcolor.xyz), fLUT_AmountLuma); + + res.xyz = color.xyz; + res.w = 1.0; +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +technique LUT +{ + pass LUT_Apply + { + VertexShader = PostProcessVS; + PixelShader = PS_LUT_Apply; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Layer.fx b/data_from_portwine/Reshade/Shaders/Layer.fx new file mode 100644 index 00000000..55b68683 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Layer.fx @@ -0,0 +1,98 @@ +/*------------------. +| :: Description :: | +'-------------------/ + + Layer (version 0.2) + + Author: CeeJay.dk + License: MIT + + About: + Blends an image with the game. + The idea is to give users with graphics skills the ability to create effects using a layer just like in an image editor. + Maybe they could use this to create custom CRT effects, custom vignettes, logos, custom hud elements, toggable help screens and crafting tables or something I haven't thought of. + + Ideas for future improvement: + * More blend modes + * Tiling control + * A default Layer texture with something useful in it + + History: + (*) Feature (+) Improvement (x) Bugfix (-) Information (!) Compatibility + + Version 0.2 by seri14 & Marot Satil + * Added the ability to scale and move the layer around on XY axis +*/ + +#include "ReShade.fxh" + +#ifndef LAYER_SOURCE +#define LAYER_SOURCE "Layer.png" +#endif +#ifndef LAYER_SIZE_X +#define LAYER_SIZE_X 1280 +#endif +#ifndef LAYER_SIZE_Y +#define LAYER_SIZE_Y 720 +#endif + +#if LAYER_SINGLECHANNEL + #define TEXFORMAT R8 +#else + #define TEXFORMAT RGBA8 +#endif + +#include "ReShadeUI.fxh" + +uniform float2 Layer_Pos < __UNIFORM_DRAG_FLOAT2 + ui_label = "Layer Position"; + ui_min = 0.0; ui_max = 1.0; + ui_step = (1.0 / 200.0); +> = float2(0.5, 0.5); + +uniform float Layer_Scale < __UNIFORM_DRAG_FLOAT1 + ui_label = "Layer Scale"; + ui_min = (1.0 / 100.0); ui_max = 4.0; + ui_step = (1.0 / 250.0); +> = 1.0; + +uniform float Layer_Blend < __UNIFORM_COLOR_FLOAT1 + ui_label = "Layer Blend"; + ui_tooltip = "How much to blend layer with the original image."; + ui_min = 0.0; ui_max = 1.0; + ui_step = (1.0 / 255.0); // for slider and drag +> = 1.0; + +texture Layer_Tex < + source = LAYER_SOURCE; +> { + Format = TEXFORMAT; + Width = LAYER_SIZE_X; + Height = LAYER_SIZE_Y; +}; + +sampler Layer_Sampler +{ + Texture = Layer_Tex; + AddressU = BORDER; + AddressV = BORDER; +}; + +void PS_Layer(float4 pos : SV_Position, float2 texCoord : TEXCOORD, out float4 passColor : SV_Target) +{ + const float4 backColor = tex2D(ReShade::BackBuffer, texCoord); + const float2 pixelSize = 1.0 / (float2(LAYER_SIZE_X, LAYER_SIZE_Y) * Layer_Scale / BUFFER_SCREEN_SIZE); + const float4 layer = tex2D(Layer_Sampler, texCoord * pixelSize + Layer_Pos * (1.0 - pixelSize)); + + passColor = lerp(backColor, layer, layer.a * Layer_Blend); + passColor.a = backColor.a; +} + +technique Layer +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_Layer; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Levels.fx b/data_from_portwine/Reshade/Shaders/Levels.fx new file mode 100644 index 00000000..20378d2c --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Levels.fx @@ -0,0 +1,85 @@ +/** + * Levels version 1.2 + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + * + * Allows you to set a new black and a white level. + * This increases contrast, but clips any colors outside the new range to either black or white + * and so some details in the shadows or highlights can be lost. + * + * The shader is very useful for expanding the 16-235 TV range to 0-255 PC range. + * You might need it if you're playing a game meant to display on a TV with an emulator that does not do this. + * But it's also a quick and easy way to uniformly increase the contrast of an image. + * + * -- Version 1.0 -- + * First release + * -- Version 1.1 -- + * Optimized to only use 1 instruction (down from 2 - a 100% performance increase :) ) + * -- Version 1.2 -- + * Added the ability to highlight clipping regions of the image with #define HighlightClipping 1 + */ + +#include "ReShadeUI.fxh" + +uniform int BlackPoint < __UNIFORM_SLIDER_INT1 + ui_min = 0; ui_max = 255; + ui_label = "Black Point"; + ui_tooltip = "The black point is the new black - literally. Everything darker than this will become completely black."; +> = 16; + +uniform int WhitePoint < __UNIFORM_SLIDER_INT1 + ui_min = 0; ui_max = 255; + ui_label = "White Point"; + ui_tooltip = "The new white point. Everything brighter than this becomes completely white"; +> = 235; + +uniform bool HighlightClipping < + ui_label = "Highlight clipping pixels"; + ui_tooltip = "Colors between the two points will stretched, which increases contrast, but details above and below the points are lost (this is called clipping).\n" + "This setting marks the pixels that clip.\n" + "Red: Some detail is lost in the highlights\n" + "Yellow: All detail is lost in the highlights\n" + "Blue: Some detail is lost in the shadows\n" + "Cyan: All detail is lost in the shadows."; +> = false; + +#include "ReShade.fxh" + +float3 LevelsPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float black_point_float = BlackPoint / 255.0; + float white_point_float = WhitePoint == BlackPoint ? (255.0 / 0.00025) : (255.0 / (WhitePoint - BlackPoint)); // Avoid division by zero if the white and black point are the same + + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + color = color * white_point_float - (black_point_float * white_point_float); + + if (HighlightClipping) + { + float3 clipped_colors; + + clipped_colors = any(color > saturate(color)) // any colors whiter than white? + ? float3(1.0, 0.0, 0.0) + : color; + clipped_colors = all(color > saturate(color)) // all colors whiter than white? + ? float3(1.0, 1.0, 0.0) + : clipped_colors; + clipped_colors = any(color < saturate(color)) // any colors blacker than black? + ? float3(0.0, 0.0, 1.0) + : clipped_colors; + clipped_colors = all(color < saturate(color)) // all colors blacker than black? + ? float3(0.0, 1.0, 1.0) + : clipped_colors; + + color = clipped_colors; + } + + return color; +} + +technique Levels +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = LevelsPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/LiftGammaGain.fx b/data_from_portwine/Reshade/Shaders/LiftGammaGain.fx new file mode 100644 index 00000000..56d5cc90 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/LiftGammaGain.fx @@ -0,0 +1,52 @@ +/** + * Lift Gamma Gain version 1.1 + * by 3an and CeeJay.dk + */ + +#include "ReShadeUI.fxh" + +uniform float3 RGB_Lift < __UNIFORM_SLIDER_FLOAT3 + ui_min = 0.0; ui_max = 2.0; + ui_label = "RGB Lift"; + ui_tooltip = "Adjust shadows for red, green and blue."; +> = float3(1.0, 1.0, 1.0); +uniform float3 RGB_Gamma < __UNIFORM_SLIDER_FLOAT3 + ui_min = 0.0; ui_max = 2.0; + ui_label = "RGB Gamma"; + ui_tooltip = "Adjust midtones for red, green and blue."; +> = float3(1.0, 1.0, 1.0); +uniform float3 RGB_Gain < __UNIFORM_SLIDER_FLOAT3 + ui_min = 0.0; ui_max = 2.0; + ui_label = "RGB Gain"; + ui_tooltip = "Adjust highlights for red, green and blue."; +> = float3(1.0, 1.0, 1.0); + + +#include "ReShade.fxh" + +float3 LiftGammaGainPass(float4 position : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + + // -- Lift -- + color = color * (1.5 - 0.5 * RGB_Lift) + 0.5 * RGB_Lift - 0.5; + color = saturate(color); // Is not strictly necessary, but does not cost performance + + // -- Gain -- + color *= RGB_Gain; + + // -- Gamma -- + color = pow(abs(color), 1.0 / RGB_Gamma); + + return saturate(color); +} + + +technique LiftGammaGain +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = LiftGammaGainPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/LumaSharpen.fx b/data_from_portwine/Reshade/Shaders/LumaSharpen.fx new file mode 100644 index 00000000..10831c8b --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/LumaSharpen.fx @@ -0,0 +1,200 @@ +/** + LumaSharpen version 1.5.0 + by Christian Cann Schuldt Jensen ~ CeeJay.dk + + It blurs the original pixel with the surrounding pixels and then subtracts this blur to sharpen the image. + It does this in luma to avoid color artifacts and allows limiting the maximum sharpning to avoid or lessen halo artifacts. + This is similar to using Unsharp Mask in Photoshop. + + Version 1.5.1 + - UI improvements for Reshade 3.x + */ + +#include "ReShadeUI.fxh" + +uniform float sharp_strength < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.1; ui_max = 3.0; + ui_label = "Shapening strength"; + ui_tooltip = "Strength of the sharpening"; + +> = 0.65; +uniform float sharp_clamp < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; ui_step = 0.005; + ui_label = "Sharpening limit"; + ui_tooltip = "Limits maximum amount of sharpening a pixel receives\nThis helps avoid \"haloing\" artifacts which would otherwise occur when you raised the strength too much."; +> = 0.035; +uniform int pattern < + ui_type = "combo"; + ui_items = "Fast" "\0" + "Normal" "\0" + "Wider" "\0" + "Pyramid shaped" "\0"; + ui_label = "Sample pattern"; + ui_tooltip = "Choose a sample pattern.\n" + "Fast is faster but slightly lower quality.\n" + "Normal is normal.\n" + "Wider is less sensitive to noise but also to fine details.\n" + "Pyramid has a slightly more aggresive look."; +> = 1; +uniform float offset_bias < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 6.0; + ui_label = "Offset bias"; + ui_tooltip = "Offset bias adjusts the radius of the sampling pattern. I designed the pattern for an offset bias of 1.0, but feel free to experiment."; +> = 1.0; +uniform bool show_sharpen < + ui_label = "Show sharpening pattern"; + ui_tooltip = "Visualize the strength of the sharpen\nThis is useful for seeing what areas the sharpning affects the most"; +> = false; + +#include "ReShade.fxh" + + /*-----------------------------------------------------------. + / Developer settings / + '-----------------------------------------------------------*/ +#define CoefLuma float3(0.2126, 0.7152, 0.0722) // BT.709 & sRBG luma coefficient (Monitors and HD Television) +//#define CoefLuma float3(0.299, 0.587, 0.114) // BT.601 luma coefficient (SD Television) +//#define CoefLuma float3(1.0/3.0, 1.0/3.0, 1.0/3.0) // Equal weight coefficient + + /*-----------------------------------------------------------. + / Main code / + '-----------------------------------------------------------*/ + +float3 LumaSharpenPass(float4 position : SV_Position, float2 tex : TEXCOORD) : SV_Target +{ + // -- Get the original pixel -- + float3 ori = tex2D(ReShade::BackBuffer, tex).rgb; // ori = original pixel + + // -- Combining the strength and luma multipliers -- + float3 sharp_strength_luma = (CoefLuma * sharp_strength); //I'll be combining even more multipliers with it later on + + /*-----------------------------------------------------------. + / Sampling patterns / + '-----------------------------------------------------------*/ + float3 blur_ori; + + // [ NW, , NE ] Each texture lookup (except ori) + // [ ,ori, ] samples 4 pixels + // [ SW, , SE ] + + // -- Pattern 1 -- A (fast) 7 tap gaussian using only 2+1 texture fetches. + if (pattern == 0) + { + // -- Gaussian filter -- + // [ 1/9, 2/9, ] [ 1 , 2 , ] + // [ 2/9, 8/9, 2/9] = [ 2 , 8 , 2 ] + // [ , 2/9, 1/9] [ , 2 , 1 ] + + blur_ori = tex2D(ReShade::BackBuffer, tex + (BUFFER_PIXEL_SIZE / 3.0) * offset_bias).rgb; // North West + blur_ori += tex2D(ReShade::BackBuffer, tex + (-BUFFER_PIXEL_SIZE / 3.0) * offset_bias).rgb; // South East + + //blur_ori += tex2D(ReShade::BackBuffer, tex + (BUFFER_PIXEL_SIZE / 3.0) * offset_bias); // North East + //blur_ori += tex2D(ReShade::BackBuffer, tex + (-BUFFER_PIXEL_SIZE / 3.0) * offset_bias); // South West + + blur_ori /= 2; //Divide by the number of texture fetches + + sharp_strength_luma *= 1.5; // Adjust strength to aproximate the strength of pattern 2 + } + + // -- Pattern 2 -- A 9 tap gaussian using 4+1 texture fetches. + if (pattern == 1) + { + // -- Gaussian filter -- + // [ .25, .50, .25] [ 1 , 2 , 1 ] + // [ .50, 1, .50] = [ 2 , 4 , 2 ] + // [ .25, .50, .25] [ 1 , 2 , 1 ] + + blur_ori = tex2D(ReShade::BackBuffer, tex + float2(BUFFER_PIXEL_SIZE.x, -BUFFER_PIXEL_SIZE.y) * 0.5 * offset_bias).rgb; // South East + blur_ori += tex2D(ReShade::BackBuffer, tex - BUFFER_PIXEL_SIZE * 0.5 * offset_bias).rgb; // South West + blur_ori += tex2D(ReShade::BackBuffer, tex + BUFFER_PIXEL_SIZE * 0.5 * offset_bias).rgb; // North East + blur_ori += tex2D(ReShade::BackBuffer, tex - float2(BUFFER_PIXEL_SIZE.x, -BUFFER_PIXEL_SIZE.y) * 0.5 * offset_bias).rgb; // North West + + blur_ori *= 0.25; // ( /= 4) Divide by the number of texture fetches + } + + // -- Pattern 3 -- An experimental 17 tap gaussian using 4+1 texture fetches. + if (pattern == 2) + { + // -- Gaussian filter -- + // [ , 4 , 6 , , ] + // [ ,16 ,24 ,16 , 4 ] + // [ 6 ,24 , ,24 , 6 ] + // [ 4 ,16 ,24 ,16 , ] + // [ , , 6 , 4 , ] + + blur_ori = tex2D(ReShade::BackBuffer, tex + BUFFER_PIXEL_SIZE * float2(0.4, -1.2) * offset_bias).rgb; // South South East + blur_ori += tex2D(ReShade::BackBuffer, tex - BUFFER_PIXEL_SIZE * float2(1.2, 0.4) * offset_bias).rgb; // West South West + blur_ori += tex2D(ReShade::BackBuffer, tex + BUFFER_PIXEL_SIZE * float2(1.2, 0.4) * offset_bias).rgb; // East North East + blur_ori += tex2D(ReShade::BackBuffer, tex - BUFFER_PIXEL_SIZE * float2(0.4, -1.2) * offset_bias).rgb; // North North West + + blur_ori *= 0.25; // ( /= 4) Divide by the number of texture fetches + + sharp_strength_luma *= 0.51; + } + + // -- Pattern 4 -- A 9 tap high pass (pyramid filter) using 4+1 texture fetches. + if (pattern == 3) + { + // -- Gaussian filter -- + // [ .50, .50, .50] [ 1 , 1 , 1 ] + // [ .50, , .50] = [ 1 , , 1 ] + // [ .50, .50, .50] [ 1 , 1 , 1 ] + + blur_ori = tex2D(ReShade::BackBuffer, tex + float2(0.5 * BUFFER_PIXEL_SIZE.x, -BUFFER_PIXEL_SIZE.y * offset_bias)).rgb; // South South East + blur_ori += tex2D(ReShade::BackBuffer, tex + float2(offset_bias * -BUFFER_PIXEL_SIZE.x, 0.5 * -BUFFER_PIXEL_SIZE.y)).rgb; // West South West + blur_ori += tex2D(ReShade::BackBuffer, tex + float2(offset_bias * BUFFER_PIXEL_SIZE.x, 0.5 * BUFFER_PIXEL_SIZE.y)).rgb; // East North East + blur_ori += tex2D(ReShade::BackBuffer, tex + float2(0.5 * -BUFFER_PIXEL_SIZE.x, BUFFER_PIXEL_SIZE.y * offset_bias)).rgb; // North North West + + //blur_ori += (2 * ori); // Probably not needed. Only serves to lessen the effect. + + blur_ori /= 4.0; //Divide by the number of texture fetches + + sharp_strength_luma *= 0.666; // Adjust strength to aproximate the strength of pattern 2 + } + + /*-----------------------------------------------------------. + / Sharpen / + '-----------------------------------------------------------*/ + + // -- Calculate the sharpening -- + float3 sharp = ori - blur_ori; //Subtracting the blurred image from the original image + +#if 0 //older 1.4 code (included here because the new code while faster can be difficult to understand) + // -- Adjust strength of the sharpening -- + float sharp_luma = dot(sharp, sharp_strength_luma); //Calculate the luma and adjust the strength + + // -- Clamping the maximum amount of sharpening to prevent halo artifacts -- + sharp_luma = clamp(sharp_luma, -sharp_clamp, sharp_clamp); //TODO Try a curve function instead of a clamp + +#else //new code + // -- Adjust strength of the sharpening and clamp it-- + float4 sharp_strength_luma_clamp = float4(sharp_strength_luma * (0.5 / sharp_clamp),0.5); //Roll part of the clamp into the dot + + //sharp_luma = saturate((0.5 / sharp_clamp) * sharp_luma + 0.5); //scale up and clamp + float sharp_luma = saturate(dot(float4(sharp,1.0), sharp_strength_luma_clamp)); //Calculate the luma, adjust the strength, scale up and clamp + sharp_luma = (sharp_clamp * 2.0) * sharp_luma - sharp_clamp; //scale down +#endif + + // -- Combining the values to get the final sharpened pixel -- + float3 outputcolor = ori + sharp_luma; // Add the sharpening to the the original. + + /*-----------------------------------------------------------. + / Returning the output / + '-----------------------------------------------------------*/ + + if (show_sharpen) + { + //outputcolor = abs(sharp * 4.0); + outputcolor = saturate(0.5 + (sharp_luma * 4.0)).rrr; + } + + return saturate(outputcolor); +} + +technique LumaSharpen +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = LumaSharpenPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Macros.fxh b/data_from_portwine/Reshade/Shaders/Macros.fxh new file mode 100644 index 00000000..b4da885f --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Macros.fxh @@ -0,0 +1,625 @@ +//////////////////////////////////////////////////////////// +// BASIC MACROS FOR RESHADE 4 // +// AUTHOR: TREYM // +//////////////////////////////////////////////////////////// +// Modified by dddfault // +// // +// Changelogs : // +// Added Sampler texture boundary resolver option // +// Added float2 parameters option // +//////////////////////////////////////////////////////////// +// Macros Guide: // +//////////////////////////////////////////////////////////// + +/* //////////////////////////////////////////////////// * + * //////////////////////////////////////////////////// * + + Usage of these macros is very simple once you understand + the syntax and variable names. Let's start with a Simple + integer slider. To begin, type: + + UI_INT + + Next we need to add _S to indicate that this is a + "slider" widget. Follow the syntax below: + + UI_INT_S(INT_NAME, "Label", "Tooltip", 0, 100, 50) + + Using just a single line of code, we have created a UI + tweakable integer named INT_NAME with a minimum value of + 0, a maximum value of 100, and a default value of 50. + + Next, let's create that same widget, but within a UI + category. This time, we'll type: + + CAT_INT_S(INT_NAME, "Category", "Label", "Tooltip", 0, 100, 50) + + As you can see, the syntax follows the same pattern but + with a new input for "Category" + + Below you will find a useful list of examples to get you + started. I hope you find these useful and they help your + workflow. Happy coding! + + - TreyM + + * //////////////////////////////////////////////////// * + * //////////////////////////////////////////////////// * + + Widget Types + Input = _I + Slider = _S + Drag = _D + + * //////////////////////////////////////////////////// * + + BOOLEAN Macro + UI_BOOL(BOOL_NAME, "Label", "Tooltip", true) + + BOOLEAN Categorized Macro + CAT_BOOL(BOOL_NAME, "Category", "Label", "Tooltip", true) + + * //////////////////////////////////////////////////// * + + INTEGER Combo Widget + UI_COMBO(INT_NAME, "Label", "Tooltip", 0, 2, 0, "Item 1\0Item 2\0Item 3\0") + + INTEGER Drag Widget + UI_INT_D(INT_NAME, "Label", "Tooltip", 0, 100, 50) + + INTEGER Input Widget + UI_INT_I(INT_NAME, "Label", "Tooltip", 0, 100, 50) + + INTEGER Radio Widget + UI_RADIO(INT_NAME, "Label", "Tooltip", 0, 2, 0, " Item 1 \0 Item 2 \0 Item 3\0") + + INTEGER Slider Widget + UI_INT_S(INT_NAME, "Label", "Tooltip", 0, 100, 50) + + INTEGER Categorized Combo Widget + CAT_COMBO(INT_NAME, "Category", "Label", "Tooltip", 0, 2, 0, " Item 1 \0 Item 2 \0 Item 3\0") + + INTEGER Categorized Drag Widget + CAT_INT_D(INT_NAME, "Category", "Label", "Tooltip", 0, 100, 50) + + INTEGER Categorized Input Widget + CAT_INT_I(INT_NAME, "Category", "Label", "Tooltip", 0, 100, 50) + + INTEGER Categorized Radio Widget + CAT_RADIO(INT_NAME, "Category", "Label", "Tooltip", 0, 2, 0, " Item 1 \0 Item 2 \0 Item 3\0") + + INTEGER Categorized Slider Widget + CAT_INT_S(INT_NAME, "Category", "Label", "Tooltip", 0, 100, 50) + + * //////////////////////////////////////////////////// * + + FLOAT Drag Widget + UI_FLOAT_D(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5) + + FLOAT Input Widget + UI_FLOAT_I(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5) + + FLOAT Slider Widget + UI_FLOAT_S(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5) + + FLOAT Categorized Drag Widget + CAT_FLOAT_D(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5) + + FLOAT Categorized Input Widget + CAT_FLOAT_I(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5) + + FLOAT Categorized Slider Widget + CAT_FLOAT_S(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5) + + FLOAT macro with full control (value after "Tooltip" is ui_step) + UI_FLOAT_FULL(FLOAT_NAME, "ui_type", "Label", "Tooltip", 0.1, 0.0, 1.0, 0.5) + + FLOAT Categorized macro with full control (value after "Tooltip" is ui_step) + CAT_FLOAT_FULL(FLOAT_NAME, "ui_type", "Category", "Label", "Tooltip", 0.1, 0.0, 1.0, 0.5) + + * //////////////////////////////////////////////////// * + + FLOAT2 Drag Widget + UI_FLOAT2_D(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) + + FLOAT2 Input Widget + UI_FLOAT2_I(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) + + FLOAT2 Slider Widget + UI_FLOAT2_S(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) + + FLOAT2 Categorized Drag Widget + CAT_FLOAT2_D(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) + + FLOAT2 Categorized Input Widget + CAT_FLOAT2_I(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) + + FLOAT2 Categorized Slider Widget + CAT_FLOAT2_S(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) + + FLOAT2 macro with full control (value after "Tooltip" is ui_step) + UI_FLOAT2_FULL(FLOAT_NAME, "ui_type", "Label", "Tooltip", 0.1, 0.0, 1.0, 0.5, 0.5) + + FLOAT2 Categorized macro with full control (value after "Tooltip" is ui_step) + CAT_FLOAT2_FULL(FLOAT_NAME, "ui_type", "Category", "Label", "Tooltip", 0.1, 0.0, 1.0, 0.5, 0.5) + + * //////////////////////////////////////////////////// * + + FLOAT3 Drag Widget + UI_FLOAT3_D(FLOAT_NAME, "Label", "Tooltip", 0.5, 0.5, 0.5) + + FLOAT3 Input Widget + UI_FLOAT3_I(FLOAT_NAME, "Label", "Tooltip", 0.5, 0.5, 0.5) + + FLOAT3 Slider Widget + UI_FLOAT3_S(FLOAT_NAME, "Label", "Tooltip", 0.5, 0.5, 0.5) + + FLOAT3 Categorized Drag Widget + CAT_FLOAT3_D(FLOAT_NAME, "Category", "Label", "Tooltip", 0.5, 0.5, 0.5) + + FLOAT3 Categorized Input Widget + CAT_FLOAT3_I(FLOAT_NAME, "Category", "Label", "Tooltip", 0.5, 0.5, 0.5) + + FLOAT3 Categorized Slider Widget + CAT_FLOAT3_S(FLOAT_NAME, "Category", "Label", "Tooltip", 0.5, 0.5, 0.5) + + * //////////////////////////////////////////////////// * + + FLOAT3 Color Widget + UI_COLOR(FLOAT_NAME, "Label", "Tooltip", 0.5, 0.5, 0.5) + + FLOAT3 Categorized Color Widget + CAT_COLOR(FLOAT_NAME, "Category", "Label", "Tooltip", 0.5, 0.5, 0.5) + + * //////////////////////////////////////////////////// * + + SAMPLER Macro + SAMPLER(SamplerName, TextureName) + + SAMPLER Macro with texture boundary resolver option + SAMPLER_UV(SamplerName, TextureName, ResolverType) + + TEXTURE Macro + TEXTURE(TextureName, "TexturePath") + + TEXTURE Full Macro + TEXTURE_FULL(TextureName, "TexturePath", Width, Height, Format) + + * //////////////////////////////////////////////////// * + + TECHNIQUE Macro + TECHNIQUE(TechniqueName, PassMacro) + + PASS Macro + PASS(PassID, VertexShader, PixelShader) + + PASS Macro with RenderTarget + PASS_RT(PassID, VertexShader, PixelShader, RenderTarget) + + //////////////////////////////////////////////////// + * //////////////////////////////////////////////////// */ + +// INTEGER MACROS //////////////////////////////// + #define UI_COMBO(var, label, tooltip, minval, maxval, defval, items) \ + uniform int var \ + < \ + ui_type = "combo"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_items = items; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_COMBO(var, category, label, tooltip, minval, maxval, defval, items) \ + uniform int var \ + < \ + ui_type = "combo"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_items = items; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define UI_INT_I(var, label, tooltip, minval, maxval, defval) \ + uniform int var \ + < \ + ui_type = "input"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_INT_I(var, category, label, tooltip, minval, maxval, defval) \ + uniform int var \ + < \ + ui_type = "input"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define UI_INT_S(var, label, tooltip, minval, maxval, defval) \ + uniform int var \ + < \ + ui_type = "slider"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_INT_S(var, category, label, tooltip, minval, maxval, defval) \ + uniform int var \ + < \ + ui_type = "slider"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define UI_INT_D(var, label, tooltip, minval, maxval, defval) \ + uniform int var \ + < \ + ui_type = "drag"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_INT_D(var, category, label, tooltip, minval, maxval, defval) \ + uniform int var \ + < \ + ui_type = "drag"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define UI_RADIO(var, label, tooltip, minval, maxval, defval, items) \ + uniform int var \ + < \ + ui_type = "radio"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_items = items; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_RADIO(var, category, label, tooltip, minval, maxval, defval, items) \ + uniform int var \ + < \ + ui_type = "radio"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_items = items; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + +// BOOL MACROS /////////////////////////////////// + #define UI_BOOL(var, label, tooltip, def) \ + uniform bool var \ + < \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = def; + + #define CAT_BOOL(var, category, label, tooltip, def) \ + uniform bool var \ + < \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = def; + +// FLOAT MACROS ////////////////////////////////// + #define UI_FLOAT_D(var, label, tooltip, minval, maxval, defval) \ + uniform float var \ + < \ + ui_type = "drag"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_FLOAT_D(var, category, label, tooltip, minval, maxval, defval) \ + uniform float var \ + < \ + ui_type = "drag"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define UI_FLOAT_FULL(var, uitype, label, tooltip, uistep, minval, maxval, defval) \ + uniform float var \ + < \ + ui_type = uitype; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_step = uistep; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_FLOAT_FULL(var, uitype, category, label, tooltip, uistep, minval, maxval, defval) \ + uniform float var \ + < \ + ui_type = uitype; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_step = uistep; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define UI_FLOAT_I(var, label, tooltip, minval, maxval, defval) \ + uniform float var \ + < \ + ui_type = "input"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_FLOAT_I(var, category, label, tooltip, minval, maxval, defval) \ + uniform float var \ + < \ + ui_type = "input"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define UI_FLOAT_S(var, label, tooltip, minval, maxval, defval) \ + uniform float var \ + < \ + ui_type = "slider"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define CAT_FLOAT_S(var, category, label, tooltip, minval, maxval, defval) \ + uniform float var \ + < \ + ui_type = "slider"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = defval; + + #define UI_FLOAT2_D(var, label, tooltip, minval, maxval, defval1, defval2) \ + uniform float2 var \ + < \ + ui_type = "drag"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = float2(defval1, defval2); + + #define CAT_FLOAT2_D(var, category, label, tooltip, minval, maxval, defval1, defval2) \ + uniform float2 var \ + < \ + ui_type = "drag"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = float2(defval1, defval2); + + #define UI_FLOAT2_FULL(var, uitype, label, tooltip, uistep, minval, maxval, defval1, defval2) \ + uniform float2 var \ + < \ + ui_type = uitype; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_step = uistep; \ + ui_min = minval; \ + ui_max = maxval; \ + > = float2(defval1, defval2); + + #define CAT_FLOAT2_FULL(var, uitype, category, label, tooltip, uistep, minval, defval1, defval2) \ + uniform float2 var \ + < \ + ui_type = uitype; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_step = uistep; \ + ui_min = minval; \ + ui_max = maxval; \ + > = float2(defval1, defval2); + + #define UI_FLOAT2_I(var, label, tooltip, minval, maxval, defval1, defval2) \ + uniform float2 var \ + < \ + ui_type = "input"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = float2(defval1, defval2); + + #define CAT_FLOAT2_I(var, category, label, tooltip, minval, maxval, defval1, defval2) \ + uniform float2 var \ + < \ + ui_type = "input"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = float2(defval1, defval2); + + #define UI_FLOAT2_S(var, label, tooltip, minval, maxval, defval1, defval2) \ + uniform float2 var \ + < \ + ui_type = "slider"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = float2(defval1, defval2); + + #define CAT_FLOAT2_S(var, category, label, tooltip, minval, maxval, defval1, defval2) \ + uniform float2 var \ + < \ + ui_type = "slider"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + ui_min = minval; \ + ui_max = maxval; \ + > = float2(defval1, defval2); + + #define UI_FLOAT3_D(var, label, tooltip, defval1, defval2, defval3) \ + uniform float3 var \ + < \ + ui_type = "drag"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = float3(defval1, defval2, defval3); + + #define CAT_FLOAT3_D(var, category, label, tooltip, defval1, defval2, defval3) \ + uniform float3 var \ + < \ + ui_type = "drag"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = float3(defval1, defval2, defval3); + + #define UI_FLOAT3_I(var, label, tooltip, defval1, defval2, defval3) \ + uniform float3 var \ + < \ + ui_type = "input"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = float3(defval1, defval2, defval3); + + #define CAT_FLOAT3_I(var, category, label, tooltip, defval1, defval2, defval3) \ + uniform float3 var \ + < \ + ui_type = "input"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = float3(defval1, defval2, defval3); + + #define UI_FLOAT3_S(var, label, tooltip, defval1, defval2, defval3) \ + uniform float3 var \ + < \ + ui_type = "slider"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = float3(defval1, defval2, defval3); + + #define CAT_FLOAT3_S(var, category, label, tooltip, defval1, defval2, defval3) \ + uniform float3 var \ + < \ + ui_type = "slider"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = float3(defval1, defval2, defval3); + + +// COLOR WIDGET MACROS /////////////////////////// + #define UI_COLOR(var, label, tooltip, defval1, defval2, defval3) \ + uniform float3 var \ + < \ + ui_type = "color"; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = float3(defval1, defval2, defval3); + + #define CAT_COLOR(var, category, label, tooltip, defval1, defval2, defval3) \ + uniform float3 var \ + < \ + ui_type = "color"; \ + ui_category = category; \ + ui_label = label; \ + ui_tooltip = tooltip; \ + > = float3(defval1, defval2, defval3); + + +// SAMPLER MACRO ///////////////////////////////// + #define SAMPLER(sname, tname) \ + sampler sname \ + { \ + Texture = tname; \ + }; + + #define SAMPLER_UV(sname, tname, addUVW) \ + sampler sname \ + { \ + Texture = tname; \ + AddressU = addUVW; \ + AddressV = addUVW; \ + AddressW = addUVW; \ + }; + + +// TEXTURE MACROs //////////////////////////////// + #define TEXTURE(tname, src) \ + texture tname \ + { \ + Width = BUFFER_WIDTH; \ + Height = BUFFER_HEIGHT; \ + Format = RGBA8; \ + }; + + #define TEXTURE_FULL(tname, src, width, height, fomat) \ + texture tname \ + { \ + Width = width; \ + Height = height; \ + Format = fomat; \ + }; + + +// TECHNIQUE MACROS ////////////////////////////// + #define TECHNIQUE(tname, pass) \ + technique tname \ + { \ + pass \ + } + + #define PASS(ID, vs, ps) pass \ + { \ + VertexShader = vs; \ + PixelShader = ps; \ + } + + #define PASS_RT(ID, vs, ps, rt) pass \ + { \ + VertexShader = vs; \ + PixelShader = ps; \ + RenderTarget = rt; \ + } diff --git a/data_from_portwine/Reshade/Shaders/Monochrome.fx b/data_from_portwine/Reshade/Shaders/Monochrome.fx new file mode 100644 index 00000000..3b4ede49 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Monochrome.fx @@ -0,0 +1,131 @@ +/*------------------. +| :: Description :: | +'-------------------/ + + Monochrome (version 1.1) + + Author: CeeJay.dk + License: MIT + + About: + Removes color making everything monochrome. + + Ideas for future improvement: + * Tinting + * Select a hue to keep its color, thus making it stand out against a monochrome background + * Try Lab colorspace + * Apply color gradient + * Add an option to normalize the coefficients + * Publish best-selling book titled "256 shades of grey" + + History: + (*) Feature (+) Improvement (x) Bugfix (-) Information (!) Compatibility + + Version 1.0 + * Converts image to monochrome + * Allows users to add saturation back in. + + Version 1.1 + * Added many presets based on B/W camera films + + Improved settings UI + ! Made settings backwards compatible with SweetFX + +*/ + + +/*---------------. +| :: Includes :: | +'---------------*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +uniform int Monochrome_preset < + ui_type = "combo"; + ui_label = "Preset"; + ui_tooltip = "Choose a preset"; + //ui_category = ""; + ui_items = "Custom\0" + "Monitor or modern TV\0" + "Equal weight\0" + "Agfa 200X\0" + "Agfapan 25\0" + "Agfapan 100\0" + "Agfapan 400\0" + "Ilford Delta 100\0" + "Ilford Delta 400\0" + "Ilford Delta 400 Pro & 3200\0" + "Ilford FP4\0" + "Ilford HP5\0" + "Ilford Pan F\0" + "Ilford SFX\0" + "Ilford XP2 Super\0" + "Kodak Tmax 100\0" + "Kodak Tmax 400\0" + "Kodak Tri-X\0"; +> = 0; + +uniform float3 Monochrome_conversion_values < __UNIFORM_COLOR_FLOAT3 + ui_label = "Custom Conversion values"; +> = float3(0.21, 0.72, 0.07); + +/* +uniform bool Normalize < + ui_label = "Normalize"; + ui_tooltip = "Normalize the coefficients?"; +> = false; +*/ + +uniform float Monochrome_color_saturation < __UNIFORM_SLIDER_FLOAT1 + ui_label = "Saturation"; + ui_min = 0.0; ui_max = 1.0; +> = 0.0; + +float3 MonochromePass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + + float3 Coefficients = float3(0.21, 0.72, 0.07); + + float3 Coefficients_array[18] = + { + Monochrome_conversion_values, //Custom + float3(0.21, 0.72, 0.07), //sRGB monitor + float3(0.3333333, 0.3333334, 0.3333333), //Equal weight + float3(0.18, 0.41, 0.41), //Agfa 200X + float3(0.25, 0.39, 0.36), //Agfapan 25 + float3(0.21, 0.40, 0.39), //Agfapan 100 + float3(0.20, 0.41, 0.39), //Agfapan 400 + float3(0.21, 0.42, 0.37), //Ilford Delta 100 + float3(0.22, 0.42, 0.36), //Ilford Delta 400 + float3(0.31, 0.36, 0.33), //Ilford Delta 400 Pro & 3200 + float3(0.28, 0.41, 0.31), //Ilford FP4 + float3(0.23, 0.37, 0.40), //Ilford HP5 + float3(0.33, 0.36, 0.31), //Ilford Pan F + float3(0.36, 0.31, 0.33), //Ilford SFX + float3(0.21, 0.42, 0.37), //Ilford XP2 Super + float3(0.24, 0.37, 0.39), //Kodak Tmax 100 + float3(0.27, 0.36, 0.37), //Kodak Tmax 400 + float3(0.25, 0.35, 0.40) //Kodak Tri-X + }; + + Coefficients = Coefficients_array[Monochrome_preset]; + + // Calculate monochrome + float3 grey = dot(Coefficients, color); + + // Adjust the remaining saturation + color = lerp(grey, color, Monochrome_color_saturation); + + // Return the result + return saturate(color); +} + +technique Monochrome +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = MonochromePass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/NFAA.fx b/data_from_portwine/Reshade/Shaders/NFAA.fx new file mode 100644 index 00000000..5edac6ad --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/NFAA.fx @@ -0,0 +1,357 @@ + ////-------------// + ///**NFAA Fast**/// + //-------------//// + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //* Normal Filter Anti Aliasing. + //* For ReShade 3.0+ & Freestyle + //* --------------------------------- + //* NFAA + //* Due Diligence + //* Based on port by b34r + //* https://www.gamedev.net/forums/topic/580517-nfaa---a-post-process-anti-aliasing-filter-results-implementation-details/?page=2 + //* Later rewritten by Eric B. AKA Kourinn + //* https://github.com/BlueSkyDefender/AstrayFX/pull/17 + //* If I missed any please tell me. + //* + //* LICENSE + //* ============ + //* Normal Filter Anti Aliasing is licenses under: Attribution-NoDerivatives 4.0 International + //* + //* 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. + //* + //* NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + //* + //* 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-nd/4.0/ + //* + //* Have fun, + //* Jose Negrete AKA BlueSkyDefender + //* + //* https://github.com/BlueSkyDefender/Depth3D + //* + //* Have fun, + //* Jose Negrete AKA BlueSkyDefender + //* + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define BUFFER_PIXEL_SIZE float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +#define BUFFER_ASPECT_RATIO (BUFFER_WIDTH * BUFFER_RCP_HEIGHT) + +uniform int EdgeDetectionType < + ui_type = "combo"; + ui_items = "Luminance edge detection\0Perceived Luminance edge detection\0Color edge detection\0Perceived Color edge detection\0"; + ui_label = "Edge Detection Type"; +> = 3; + +uniform float EdgeDetectionThreshold < + ui_type = "drag"; + ui_label = "Edge Detection Threshold"; + ui_tooltip = "The difference in Luminence/Color that would be perceived as an edge.\n" + "Try lowering this slightly if the Edge Mask misses some edges.\n" + "Default is 0.063"; + ui_min = 0.050; ui_max = 0.200; ui_step = 0.001; +> = 0.100; + +uniform float EdgeSearchRadius < + ui_type = "drag"; + ui_label = "Edge Search Radius"; + ui_tooltip = "The radius to search for edges.\n" + "Try raising this if using in-game upscaling.\n" + "Default is 1.000"; + ui_min = 0.000; ui_max = 4.000; ui_step = 0.001; +> = 1.000; + +uniform float UnblurFilterStrength < + ui_type = "drag"; + ui_label = "Unblur Filter Strength"; + ui_tooltip = "Adjusts the Edge Mask and Corner Mask contrast for filtering unwanted edge blur.\n" + "Try raising this if text or icons become blurry.\n" + "Try lowering this if edges are still too aliased.\n" + "Default is 1.000"; + ui_min = 0.000; ui_max = 2.000; ui_step = 0.001; +> = 1.000; + +uniform float BlurStrength < + ui_type = "drag"; + ui_label = "Blur Strength"; + ui_tooltip = "Adjusts the Normal Map weights for stronger edge blur.\n" + "Try raising this if edges are still too aliased.\n" + "Try lowering this if text or icons become blurry.\n" + "Default is 1.000"; + ui_min = 0.000; ui_max = 2.000; ui_step = 0.001; +> = 1.000; + +uniform float2 BlurSize < + ui_type = "drag"; + ui_label = "Blur Size"; + ui_tooltip = "Adjusts the Normal Map depth for larger/longer edge blur.\n" + "Inputs are blur size parallel and perpendicular to the edge respectively.\n" + "Try raising this if edges are still too aliased.\n" + "Try lowering this if text or icons become blurry.\n" + "Defaults are 2.000 and 1.000"; + ui_min = 0.000; ui_max = 4.000; ui_step = 0.001; +> = float2(2.000, 1.000); + +uniform int DebugOutput < + ui_type = "combo"; + ui_label = "Debug Output"; + ui_items = "None\0Edge Mask View\0Corner Mask View\0Normal Map View\0Pre-Blur Mask View\0Post-Blur Mask View\0"; + ui_tooltip = "Edge Mask View shows the Edge Detection and Unblur Filter Strength.\n" + "Corner Mask View shows the Corner Detection and Unblur Filter Strength.\n" + "Normal Map View shows the Normal Map depth, used for Blur Size and Blur Direction.\n" + "Pre-Blur Mask View shows just the edges that will be blurred.\n" + "Post-Blur Mask View shows just the edges have been blurred."; + ui_spacing = 2; +> = 0; + +////////////////////////////////////////////////////////////Variables//////////////////////////////////////////////////////////////////// + +// sRGB Luminance +static const float3 LinearizeVector[4] = { float3(0.2126, 0.7152, 0.0722), float3(0.299, 0.587, 0.114), float3(0.3333333, 0.3333333, 0.3333333), float3(0.299, 0.587, 0.114) }; + +static const float Cos45 = 0.70710678118654752440084436210485; + +static const float MaxSlope = 1024.0; + +texture BackBufferTex : COLOR; + +sampler BackBuffer { Texture = BackBufferTex; }; + +////////////////////////////////////////////////////////////Functions//////////////////////////////////////////////////////////////////// + +float LinearDifference(float3 A, float3 B) +{ + float lumDiff = dot(A, LinearizeVector[EdgeDetectionType]) - dot(B, LinearizeVector[EdgeDetectionType]); + if (EdgeDetectionType < 2) + return lumDiff; + + float3 C = abs(A - B); + return max(max(C.r, C.g), C.b) * (lumDiff < 0.0 ? -1.0 : 1.0); // sign intrinsic can return 0, which we don't want. Plus this is faster. +} + +float2 Rotate45(float2 p) { + return float2(mad(p.x, Cos45, -p.y * Cos45), mad(p.x, Cos45, p.y * Cos45)); + // return float2(p.x * Cos45 - p.y * Cos45, p.x * Cos45 + p.y * Cos45); +} + +////////////////////////////////////////////////////////////NFAA//////////////////////////////////////////////////////////////////// + +float4 NFAA(float2 texcoord, float4 offsets[4]) +{ + float4 color = tex2Dlod(BackBuffer, float4(texcoord, 0.0, 0.0)); + + // Find Edges + // +---+---+---+---+---+ + // | | | | | | + // +---+---+---+---+---+ + // | | e | f | g | | + // +---+--(a)-(b)--+---+ + // | | h | P | i | | + // +---+--(c)-(d)--+---+ + // | | j | k | l | | + // +---+---+---+---+---+ + // | | | | | | + // +---+---+---+---+---+ + // Much better at horizontal/vertical lines, slightly better diagonals, always compares 6 pixels, not 2. + float3 a = tex2Dlod(BackBuffer, offsets[0]).rgb; + float3 b = tex2Dlod(BackBuffer, offsets[1]).rgb; + float3 c = tex2Dlod(BackBuffer, offsets[2]).rgb; + float3 d = tex2Dlod(BackBuffer, offsets[3]).rgb; + + // Original edge detection from b34r & BlueSkyDefender + // +---+---+---+---+---+ + // | | | | | | + // +---+---+---+---+---+ + // | | | t | | | + // +---+---+---+---+---+ + // | | l | C | r | | + // +---+---+---+---+---+ + // | | | b | | | + // +---+---+---+---+---+ + // | | | | | | + // +---+---+---+---+---+ + // float angle = 0.0; + // float3 t = tex2Dlod(BackBuffer, float4(mad(float2(0.0, -EdgeSearchRadius), BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)).rgb; + // float3 b = tex2Dlod(BackBuffer, float4(mad(float2(-0.0, EdgeSearchRadius), BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)).rgb; + // float3 r = tex2Dlod(BackBuffer, float4(mad(float2(EdgeSearchRadius, 0.0), BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)).rgb; + // float3 l = tex2Dlod(BackBuffer, float4(mad(float2(-EdgeSearchRadius, 0.0), BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)).rgb; + // float2 n = float2(LinearDifference(t, b), LinearDifference(r, l)); + + // i.e. top vs bottom = a + b - (c + d) = (e + 2*f + g) / 4 - (j + 2*k + l) / 4 + float2 normal = float2(LinearDifference(b + d, a + c), LinearDifference(c + d, a + b)); // right - left, bottom - top + float edge = length(normal); + + float edgeMask = 1.0; + float cornerMask = 1.0; + if (edge > EdgeDetectionThreshold) + { + // Lets make that edgeMask for a sharper image. + float edgeConfidence = log2(edge / EdgeDetectionThreshold); + edgeMask = saturate(mad(edgeConfidence, UnblurFilterStrength - 2.0, 1.0)); + // edgeMask = saturate((1.0 - (UnblurFilterStrength - 2.0) * edgeConfidence); + + // Then subtract corners from edge mask to avoid bluring text and detailed icons + float4 corners = float4(LinearDifference(a + b + c, 3.0 * d), LinearDifference(a + b + d, 3.0 * c), LinearDifference(a + c + d, 3.0 * b), LinearDifference(c + d + b, 3.0 * a)); + float corner = dot(abs(corners), 0.25); + cornerMask = saturate(edgeMask + corner); + + // calculate x/y coordinates along the edge at specified distances and offsets + // +---+---+---+---+---+ +---+---+---+---+---+ + // | | | | | | | | | | | | + // +---+---+---+---+---+ +---+---+---+---+---+ + // | | | | | | | | | (e) | | + // +---+(g)a---b(e)+---+ +---+---a---b(f)+---+ + // | |-O | P | O | | | | | P | | | + // +---+(h)c---d(f)+---+ +---+(g)c---d---+---+ + // | | | | | | | | (h) | | | + // +---+---+---+---+---+ +---+---+---+---+---+ + // | | | | | | | | | | | | + // +---+---+---+---+---+ +---+---+---+---+---+ + + // slope m = normal.r / normal.g + // distance d + // y = mx + // d^2 = y^2 + x^2 = (mx)^2+x^2 + // d^2 = x^2(1 + m^2) + // x^2 = d^2/(1 + m^2) + + // Follow the edge for 1/2 of BlurSize.x + float4 offset; + float m = normal.g != 0 ? normal.r / normal.g : MaxSlope; + float d = 0.5 * BlurSize.x; + offset.x = sqrt(d *d / (1.0 + m * m)); + offset.y = m * offset.x; + // Then move perpendicular to the edge for 1/2 of BlurSize.y + m = normal.r != 0 ? -normal.g / normal.r : MaxSlope; + d = 0.5 * BlurSize.y; + offset.z = sqrt(d * d / (1.0 + m * m)); + offset.w = m * offset.z; + + float3 e = tex2Dlod(BackBuffer, float4(mad(offset.xy + offset.zw, BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)).rgb; + float3 f = tex2Dlod(BackBuffer, float4(mad(offset.xy - offset.zw, BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)).rgb; + float3 g = tex2Dlod(BackBuffer, float4(mad(-offset.xy - offset.zw, BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)).rgb; + float3 h = tex2Dlod(BackBuffer, float4(mad(-offset.xy + offset.zw, BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)).rgb; + + // It's possible to reduce taps by re-using edge detection taps a, b, c, d, + // but it's not worth it. Nearby pixels should already be cached, and it would need more math. + + // apply blur + if (DebugOutput != 4) + color.rgb = lerp(color.rgb, (e + f + g + h) * 0.25, BlurStrength * 0.5 * (1.0 - cornerMask)); + + // Pre/Post Blur Mask + if (DebugOutput > 3) + color.a = cornerMask; + + // original blur from b34r & BlueSkyDefender + // may need some work to be functional again, due to some variable name refactoring after I reversed how/why it worked + // +---+---+---+---+---+ + // | | | | | | + // +---+---+---+---+---+ + // |\\\| | x | x | | + // +---+---+---+---+---+ + // | |\\\|\\\| x | | + // +---+---+---+---+---+ + // | | | x |\\\|\\\| + // +---+---+---+---+---+ + // | | | | | | + // +---+---+---+---+---+ + // y = -0.5x; n.x = 1; n.y = 0.5; nl = 1.18; dn.x = 0.85; dn.y = 0.42; + // t0/1 = 0.425, 0.21; d ~= 0.5 + // t2/3 = 0.765, -0.38; d ~= 0.85 + // float2 dn = n / nl * BlurSize; + // float4 t0 = tex2Dlod(BackBuffer, float4(mad(-dn * 0.5, BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)); + // float4 t1 = tex2Dlod(BackBuffer, float4(mad(dn * 0.5, BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)); + // float4 t2 = tex2Dlod(BackBuffer, float4(mad(float2(dn.x, -dn.y) * 0.9, BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)); + // float4 t3 = tex2Dlod(BackBuffer, float4(mad(float2(-dn.x, dn.y) * 0.9, BUFFER_PIXEL_SIZE, texcoord), 0.0, 0.0)); + // color = lerp(mad(color, 0.23, 0.175 * (t2 + t3) + 0.21 * (t0 + t1)), color, edgeMask); + } + else { + color.a = 0.0; + } + + if(DebugOutput == 1) // Edge Mask + { + color.rgb = edgeMask; + } + if(DebugOutput == 2) // Corner Mask + { + color.rgb = cornerMask; + } + else if (DebugOutput == 3) // Normal Map + { + // Normal map, right = red, green = top, configured using white box with black background + float3 normalMap; + normalMap.b = 1.0; + normalMap.rg = mad(float2(-normal.r, normal.g) * BlurSize.x * BlurStrength, 0.25, 0.5); + normalMap.rg = lerp(float2(0.5, 0.5), saturate(normalMap.rg), (1.0 - edgeMask) * BlurSize.y); + color.rgb = normalMap; + } + else if (DebugOutput > 3) { // Pre/Post Blur Mask + uint row = floor(texcoord.y / 0.1); + uint col = floor(texcoord.x * BUFFER_ASPECT_RATIO / 0.1); + + float3 lightGray = 0.5; + float3 darkGray = 0.1667; + + lightGray = lerp(lightGray, color.rgb, color.a); + darkGray = lerp(darkGray, color.rgb, color.a); + + // Create checkerboad background to depict transparency + if (row % 2 == 0) { + if (col % 2 == 0) { + color.rgb = lightGray; + } + else { + color.rgb = darkGray; + } + } + else { + if (col % 2 == 0) { + color.rgb = darkGray; + } + else { + color.rgb = lightGray; + } + } + + } + + color.a = 1.0; + return color; +} + +void NFAA_VS(in uint id : SV_VertexID, out float4 position : SV_POSITION, out float2 texcoord : TEXCOORD, out float4 offsets[4] : TEXCOORD1 ) +{ + 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); + + float2 offset = Cos45 * EdgeSearchRadius * BUFFER_PIXEL_SIZE; + offsets[0] = float4(mad(float2(-1.0, -1.0), offset, texcoord), 0.0, 0.0); + offsets[1] = float4(mad(float2(1.0, -1.0), offset, texcoord), 0.0, 0.0); + offsets[2] = float4(mad(float2(-1.0, 1.0), offset, texcoord), 0.0, 0.0); + offsets[3] = float4(mad(float2(1.0, 1.0), offset, texcoord), 0.0, 0.0); +} + +float4 NFAA_PS(in float4 position : SV_Position, in float2 texcoord : TEXCOORD, in float4 offsets[4] : TEXCOORD1) : SV_Target +{ + return NFAA(texcoord, offsets); +} + +technique NFAA +{ + pass NFAA_Fast + { + VertexShader = NFAA_VS; + PixelShader = NFAA_PS; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Nostalgia.fx b/data_from_portwine/Reshade/Shaders/Nostalgia.fx new file mode 100644 index 00000000..75181b10 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Nostalgia.fx @@ -0,0 +1,602 @@ +/*------------------. +| :: Description :: | +'-------------------/ + + Nostalgia (version 1.3) + + Author: CeeJay.dk + License: MIT + + About: + In this effect I try to recreate the looks of systems from a bygone era. + I've started with reducing the color to that of systems with 16 color palette. + + Ideas for future improvement: + * Try HSL / HCY / Lab or other colorspaces. I'm not sure RGB is the best choice for color matching. + * Pixelation + * Scanlines + * CRT patterns + * Curvature + * More Dithering (both good and the bad dithering used back then) + * Levels (might be needed because older system were often displayed on televisions and older monitors - not modern monitors) + + History: + (*) Feature (+) Improvement (x) Bugfix (-) Information (!) Compatibility + + Version 1.0 by CeeJay.dk + * Color reduction to C64 palette + + Version 1.1 by CeeJay.dk + * Added ability to set a custom palette + * Added EGA palette + + Improved settings UI + - Commented much of the code + + Version 1.2 by microdee + + Added more color palettes from wikipedia + + Palettes can have different color counts + + Version 1.3 by CeeJay.dk + * Added Aek16 palette + + Made Nostalgia do color matching in linear space which improves color matching + * Added checker board dithering + * Added scanlines +*/ + + +/*---------------. +| :: Includes :: | +'---------------*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +/*--------------. +| :: Defines :: | +'--------------*/ + +#ifndef Nostalgia_linear + #define Nostalgia_linear 1 +#endif + +/*------------------. +| :: UI Settings :: | +'------------------*/ + +uniform int Nostalgia_scanlines +< + ui_type = "combo"; + ui_label = "Scanlines"; + ui_items = + "None\0" + "Type 1\0" + "Type 2\0"; + //ui_category = ""; +> = 1; + +uniform int Nostalgia_color_reduction +< + ui_type = "combo"; + ui_label = "Color reduction type"; + //ui_tooltip = "Choose a color reduction type"; + //ui_category = ""; + ui_items = + "None\0" + "Palette\0" + //"Quantize\0" + ; +> = 1; + +uniform bool Nostalgia_dither +< + ui_label = "Dither"; +> = 0; + +uniform int Nostalgia_palette < + ui_type = "combo"; + ui_label = "Palette"; + ui_tooltip = "Choose a palette"; + //ui_category = ""; + ui_items = + "Custom\0" + "C64 palette\0" + "EGA palette\0" + "IBMPC palette\0" + "ZXSpectrum palette\0" + "AppleII palette\0" + "NTSC palette\0" + "Commodore VIC-20\0" + "MSX Systems\0" + "Thomson MO5\0" + "Amstrad CPC\0" + "Atari ST\0" + "Mattel Aquarius\0" + "Gameboy\0" + "Aek16 palette"; +> = 0; + +uniform float3 Nostalgia_color_0 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 0"; + ui_category = "Custom palette"; +> = float3( 0. , 0. , 0. ); //Black; + +uniform float3 Nostalgia_color_1 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 1"; + ui_category = "Custom palette"; > += float3(255. , 255. , 255. ) / 255.; //White + +uniform float3 Nostalgia_color_2 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 2"; + ui_category = "Custom palette"; +> = float3(136. , 0. , 0. ) / 255.; //Red; + +uniform float3 Nostalgia_color_3 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 3"; + ui_category = "Custom palette"; +> = float3(170. , 255. , 238. ) / 255.; //Cyan + +uniform float3 Nostalgia_color_4 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 4"; + ui_category = "Custom palette"; +> = float3(204. , 68. , 204. ) / 255.; //Violet + +uniform float3 Nostalgia_color_5 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 5"; + ui_category = "Custom palette"; +> = float3( 0. , 204. , 85. ) / 255.; //Green + +uniform float3 Nostalgia_color_6 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 6"; + ui_category = "Custom palette"; +> = float3( 0. , 0. , 170. ) / 255.; //Blue + +uniform float3 Nostalgia_color_7 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 7"; + ui_category = "Custom palette"; +> = float3(238. , 238. , 119. ) / 255.; //Yellow 1 + +uniform float3 Nostalgia_color_8 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 8"; + ui_category = "Custom palette"; +> = float3(221. , 136. , 85. ) / 255.; //Orange + +uniform float3 Nostalgia_color_9 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 9"; + ui_category = "Custom palette"; +> = float3(102. , 68. , 0. ) / 255.; //Brown + +uniform float3 Nostalgia_color_10 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 10"; + ui_category = "Custom palette"; +> = float3(255. , 119. , 119. ) / 255.; //Yellow 2 + +uniform float3 Nostalgia_color_11 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 11"; + ui_category = "Custom palette"; +> = float3( 51. , 51. , 51. ) / 255.; //Grey 1 + +uniform float3 Nostalgia_color_12 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 12"; + ui_category = "Custom palette"; +> = float3(119. , 119. , 119. ) / 255.; //Grey 2 + +uniform float3 Nostalgia_color_13 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 13"; + ui_category = "Custom palette"; +> = float3(170. , 255. , 102. ) / 255.; //Lightgreen + +uniform float3 Nostalgia_color_14 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 14"; + ui_category = "Custom palette"; +> = float3( 0. , 136. , 255. ) / 255.; //Lightblue + +uniform float3 Nostalgia_color_15 < __UNIFORM_COLOR_FLOAT3 + ui_label = "Color 15"; + ui_category = "Custom palette"; +> = float3(187. , 187. , 187. ) / 255.; //Grey 3 + +/* +uniform bool Nostalgia_linear //Can't currently make a UI setting for this since I need the preprocessor for that and it does not accept uniforms from the UI +< + ui_label = "Linear"; + //ui_category = "Color options"; +> = 0; +*/ + +/*--------------. +| :: Sampler :: | +'--------------*/ + +sampler Linear +{ + Texture = ReShade::BackBufferTex; + SRGBTexture = true; +}; + + +/*-------------. +| :: Effect :: | +'-------------*/ + +float3 PS_Nostalgia(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float3 color; + int colorCount = 16; + + #if Nostalgia_linear == 1 + color = tex2D(Linear, texcoord.xy).rgb; + #else + color = tex2D(ReShade::BackBuffer, texcoord.xy).rgb; + #endif + + + if (Nostalgia_color_reduction) + { + float3 palette[16] = //Custom palette + { + Nostalgia_color_0, + Nostalgia_color_1, + Nostalgia_color_2, + Nostalgia_color_3, + Nostalgia_color_4, + Nostalgia_color_5, + Nostalgia_color_6, + Nostalgia_color_7, + Nostalgia_color_8, + Nostalgia_color_9, + Nostalgia_color_10, + Nostalgia_color_11, + Nostalgia_color_12, + Nostalgia_color_13, + Nostalgia_color_14, + Nostalgia_color_15 + }; + + if (Nostalgia_palette == 1) //C64 palette from http://www.c64-wiki.com/index.php/Color + { + palette[0] = float3( 0. , 0. , 0. ) / 255.; //Black + palette[1] = float3(255. , 255. , 255. ) / 255.; //White + palette[2] = float3(136. , 0. , 0. ) / 255.; //Red + palette[3] = float3(170. , 255. , 238. ) / 255.; //Cyan + palette[4] = float3(204. , 68. , 204. ) / 255.; //Violet + palette[5] = float3( 0. , 204. , 85. ) / 255.; //Green + palette[6] = float3( 0. , 0. , 170. ) / 255.; //Blue + palette[7] = float3(238. , 238. , 119. ) / 255.; //Yellow 1 + palette[8] = float3(221. , 136. , 85. ) / 255.; //Orange + palette[9] = float3(102. , 68. , 0. ) / 255.; //Brown + palette[10] = float3(255. , 119. , 119. ) / 255.; //Yellow 2 + palette[11] = float3( 51. , 51. , 51. ) / 255.; //Grey 1 + palette[12] = float3(119. , 119. , 119. ) / 255.; //Grey 2 + palette[13] = float3(170. , 255. , 102. ) / 255.; //Lightgreen + palette[14] = float3( 0. , 136. , 255. ) / 255.; //Lightblue + palette[15] = float3(187. , 187. , 187. ) / 255.; //Grey 3 + } + + if (Nostalgia_palette == 2) //EGA palette + { + palette[0] = float3(0.0, 0.0, 0.0 ); //Black + palette[1] = float3(0.0, 0.0, 0.666667); //Blue + palette[2] = float3(0.0, 0.666667, 0.0 ); //Green + palette[3] = float3(0.0, 0.666667, 0.666667); //Cyan + palette[4] = float3(0.666667, 0.0, 0.0 ); //Red + palette[5] = float3(0.666667, 0.0, 0.666667); //Magenta + palette[6] = float3(0.666667, 0.333333, 0.0 ); //Brown + palette[7] = float3(0.666667, 0.666667, 0.666667); //Light gray + palette[8] = float3(0.333333, 0.333333, 0.333333); //Dark gray + palette[9] = float3(0.333333, 0.333333, 1.0 ); //Bright blue + palette[10] = float3(0.333333, 1.0, 0.333333); //Bright green + palette[11] = float3(0.333333, 1.0, 1.0 ); //Bright cyan + palette[12] = float3(1.0, 0.333333, 0.333333); //Bright red + palette[13] = float3(1.0, 0.333333, 1.0 ); //Bright magenta + palette[14] = float3(1.0, 1.0, 0.333333); //Bright yellow + palette[15] = float3(1.0, 1.0, 1.0 ); //White + } + + if (Nostalgia_palette == 3) //IBMPC palette + { + palette[0] = float3(0,0,0); + palette[1] = float3(0,0,0.8); + palette[2] = float3(0,0.6,0); + palette[3] = float3(0,0.6,0.8); + palette[4] = float3(0.8,0,0); + palette[5] = float3(0.8,0,0.8); + palette[6] = float3(0.8,0.6,0); + palette[7] = float3(0.8,0.8,0.8); + palette[8] = float3(0.4,0.4,0.4); + palette[9] = float3(0.4,0.4,1); + palette[10] = float3(0.4,1,0.4); + palette[11] = float3(0.4,1,1); + palette[12] = float3(0.99,0.4,0.4); + palette[13] = float3(1,0.4,1); + palette[14] = float3(1,1,0.4); + palette[15] = float3(1,1,1); + } + + if (Nostalgia_palette == 4) //ZX Spectrum palette + { + palette[0] = float3(0,0,0); + palette[1] = float3(0,0,0.811764705882353); + palette[2] = float3(0,0.811764705882353,0); + palette[3] = float3(0,0.811764705882353,0.811764705882353); + palette[4] = float3(0.811764705882353,0,0); + palette[5] = float3(0.811764705882353,0,0.752941176470588); + palette[6] = float3(0.811764705882353,0.811764705882353,0); + palette[7] = float3(0.811764705882353,0.811764705882353,0.811764705882353); + palette[8] = float3(0,0,0); + palette[9] = float3(0,0,1); + palette[10] = float3(0,1,0); + palette[11] = float3(0,1,1); + palette[12] = float3(1,0,0); + palette[13] = float3(1,0,1); + palette[14] = float3(1,1,0); + palette[15] = float3(1,1,1); + } + + if (Nostalgia_palette == 5) //AppleII palette + { + palette[0] = float3(0,0,0); + palette[1] = float3(0.890196078431373,0.117647058823529,0.376470588235294); + palette[2] = float3(0.376470588235294,0.305882352941176,0.741176470588235); + palette[3] = float3(1,0.266666666666667,0.992156862745098); + palette[4] = float3(0,0.63921568627451,0.376470588235294); + palette[5] = float3(0.611764705882353,0.611764705882353,0.611764705882353); + palette[6] = float3(0.0784313725490196,0.811764705882353,0.992156862745098); + palette[7] = float3(0.815686274509804,0.764705882352941,1); + palette[8] = float3(0.376470588235294,0.447058823529412,0.0117647058823529); + palette[9] = float3(1,0.415686274509804,0.235294117647059); + palette[10] = float3(0.611764705882353,0.611764705882353,0.611764705882353); + palette[11] = float3(1,0.627450980392157,0.815686274509804); + palette[12] = float3(0.0784313725490196,0.96078431372549,0.235294117647059); + palette[13] = float3(0.815686274509804,0.866666666666667,0.552941176470588); + palette[14] = float3(0.447058823529412,1,0.815686274509804); + palette[15] = float3(1,1,1); + } + + if (Nostalgia_palette == 6) //NTSC palette + { + palette[0] = float3(0.831372549019608,0.831372549019608,0.831372549019608); + palette[1] = float3(0.866666666666667,0.776470588235294,0.474509803921569); + palette[2] = float3(0.0392156862745098,0.96078431372549,0.776470588235294); + palette[3] = float3(0.0470588235294118,0.917647058823529,0.380392156862745); + palette[4] = float3(1,0.156862745098039,0.709803921568627); + palette[5] = float3(1,0.109803921568627,0.298039215686275); + palette[6] = float3(0.149019607843137,0.254901960784314,0.607843137254902); + palette[7] = float3(0,0.87843137254902,0.905882352941176); + palette[8] = float3(1,1,1); + palette[9] = float3(1,0.317647058823529,1); + palette[10] = float3(0.16078431372549,0.16078431372549,0.16078431372549); + palette[11] = float3(0.16078431372549,0.16078431372549,0.16078431372549); + palette[12] = float3(0.16078431372549,0.16078431372549,0.16078431372549); + palette[13] = float3(0.831372549019608,0.831372549019608,0.831372549019608); + palette[14] = float3(0.866666666666667,0.776470588235294,0.474509803921569); + palette[15] = float3(0.0392156862745098,0.96078431372549,0.776470588235294); + } + + if (Nostalgia_palette == 7) // Commodore VIC-20 + { + palette[0] = float3(0,0,0); + palette[1] = float3(1,1,1); + palette[2] = float3(0.470588235294118,0.16078431372549,0.133333333333333); + palette[3] = float3(0.529411764705882,0.83921568627451,0.866666666666667); + palette[4] = float3(0.666666666666667,0.372549019607843,0.713725490196078); + palette[5] = float3(0.101960784313725,0.509803921568627,0.149019607843137); + palette[6] = float3(0.250980392156863,0.192156862745098,0.552941176470588); + palette[7] = float3(0.749019607843137,0.807843137254902,0.447058823529412); + palette[8] = float3(0.666666666666667,0.454901960784314,0.286274509803922); + palette[9] = float3(0.917647058823529,0.705882352941177,0.537254901960784); + palette[10] = float3(0.72156862745098,0.411764705882353,0.384313725490196); + palette[11] = float3(0.780392156862745,1,1); + palette[12] = float3(0.917647058823529,0.623529411764706,0.964705882352941); + palette[13] = float3(0.580392156862745,0.87843137254902,0.537254901960784); + palette[14] = float3(0.501960784313725,0.443137254901961,0.8); + palette[15] = float3(1,1,0.698039215686274); + } + + if (Nostalgia_palette == 8) // MSX Systems + { + palette[0] = float3(0,0,0); + palette[1] = float3(1,1,1); + palette[2] = float3(0.243137254901961,0.72156862745098,0.286274509803922); + palette[3] = float3(0.454901960784314,0.815686274509804,0.490196078431373); + palette[4] = float3(0.349019607843137,0.333333333333333,0.87843137254902); + palette[5] = float3(0.501960784313725,0.462745098039216,0.945098039215686); + palette[6] = float3(0.725490196078431,0.368627450980392,0.317647058823529); + palette[7] = float3(0.396078431372549,0.858823529411765,0.937254901960784); + palette[8] = float3(0.858823529411765,0.396078431372549,0.349019607843137); + palette[9] = float3(1,0.537254901960784,0.490196078431373); + palette[10] = float3(0.8,0.764705882352941,0.368627450980392); + palette[11] = float3(0.870588235294118,0.815686274509804,0.529411764705882); + palette[12] = float3(0.227450980392157,0.635294117647059,0.254901960784314); + palette[13] = float3(0.717647058823529,0.4,0.709803921568627); + palette[14] = float3(0.8,0.8,0.8); + palette[15] = float3(1,1,0.698039215686274); + } + + if (Nostalgia_palette == 9) // Thomson MO5 + { + palette[0] = float3(0,0,0); + palette[1] = float3(1,1,1); + palette[2] = float3(1,0,0); + palette[3] = float3(0,1,0); + palette[4] = float3(1,1,0); + palette[5] = float3(0,0,1); + palette[6] = float3(1,0,1); + palette[7] = float3(0,1,1); + palette[8] = float3(0,0,0); + palette[9] = float3(0.733333333333333,0.733333333333333,0.733333333333333); + palette[10] = float3(0.866666666666667,0.466666666666667,0.466666666666667); + palette[11] = float3(0.466666666666667,0.866666666666667,0.466666666666667); + palette[12] = float3(0.866666666666667,0.866666666666667,0.466666666666667); + palette[13] = float3(0.466666666666667,0.466666666666667,0.866666666666667); + palette[14] = float3(0.866666666666667,0.466666666666667,0.933333333333333); + palette[15] = float3(0.733333333333333,1,1); + } + + if (Nostalgia_palette == 10) // Amstrad CPC + { + palette[0] = float3(0,0,0); + palette[1] = float3(1,1,1); + palette[2] = float3(0,0,0.498039215686275); + palette[3] = float3(0.498039215686275,0,0); + palette[4] = float3(0.498039215686275,0,0.498039215686275); + palette[5] = float3(0,0.498039215686275,0); + palette[6] = float3(1,0,0); + palette[7] = float3(0,0.498039215686275,0.498039215686275); + palette[8] = float3(0.498039215686275,0.498039215686275,0); + palette[9] = float3(0.498039215686275,0.498039215686275,0.498039215686275); + palette[10] = float3(0.498039215686275,0.498039215686275,1); + palette[11] = float3(1,0.498039215686275,0); + palette[12] = float3(1,0.498039215686275,0.498039215686275); + palette[13] = float3(0.498039215686275,1,0.498039215686275); + palette[14] = float3(0.498039215686275,1,1); + palette[15] = float3(1,1,0.498039215686275); + } + + if (Nostalgia_palette == 11) // Atari ST + { + palette[0] = float3(0,0,0); + palette[1] = float3(1,0.886274509803922,0.882352941176471); + palette[2] = float3(0.376470588235294,0.0392156862745098,0.0117647058823529); + palette[3] = float3(0.811764705882353,0.133333333333333,0.0549019607843137); + palette[4] = float3(0.16078431372549,0.345098039215686,0.0352941176470588); + palette[5] = float3(0.937254901960784,0.16078431372549,0.0705882352941176); + palette[6] = float3(0.356862745098039,0.349019607843137,0.0431372549019608); + palette[7] = float3(0.352941176470588,0.352941176470588,0.352941176470588); + palette[8] = float3(0.803921568627451,0.372549019607843,0.207843137254902); + palette[9] = float3(0.494117647058824,0.509803921568627,0.756862745098039); + palette[10] = float3(0.305882352941176,0.623529411764706,0.0980392156862745); + palette[11] = float3(0.792156862745098,0.509803921568627,0.364705882352941); + palette[12] = float3(1,0.392156862745098,0.215686274509804); + palette[13] = float3(1,0.525490196078431,0.368627450980392); + palette[14] = float3(0.631372549019608,0.63921568627451,0.76078431372549); + palette[15] = float3(1,0.768627450980392,0.517647058823529); + } + + if (Nostalgia_palette == 12) // Mattel Aquarius + { + palette[0] = float3(0,0,0); + palette[1] = float3(1,1,1); + palette[2] = float3(0.494117647058824,0.0980392156862745,0.164705882352941); + palette[3] = float3(0.764705882352941,0,0.105882352941176); + palette[4] = float3(0.725490196078431,0.694117647058824,0.337254901960784); + palette[5] = float3(0.784313725490196,0.725490196078431,0.0274509803921569); + palette[6] = float3(0.231372549019608,0.592156862745098,0.180392156862745); + palette[7] = float3(0.0274509803921569,0.749019607843137,0); + palette[8] = float3(0.250980392156863,0.650980392156863,0.584313725490196); + palette[9] = float3(0,0.776470588235294,0.643137254901961); + palette[10] = float3(0.749019607843137,0.749019607843137,0.749019607843137); + palette[11] = float3(0.513725490196078,0.152941176470588,0.564705882352941); + palette[12] = float3(0.717647058823529,0,0.819607843137255); + palette[13] = float3(0.0196078431372549,0.0509803921568627,0.407843137254902); + colorCount = 14; + } + + if (Nostalgia_palette == 13) // Gameboy + { + palette[0] = float3(0.0588235294117647,0.219607843137255,0.0588235294117647); + palette[1] = float3(0.607843137254902,0.737254901960784,0.0588235294117647); + palette[2] = float3(0.188235294117647,0.384313725490196,0.188235294117647); + palette[3] = float3(0.545098039215686,0.674509803921569,0.0588235294117647); + colorCount = 4; + } + + + if (Nostalgia_palette == 14) //aek16 ( http://eastfarthing.com/blog/2016-05-06-palette/ ) + { + palette[0] = float3(0.247059, 0.196078, 0.682353); // + palette[1] = float3(0.890196, 0.054902, 0.760784); // + palette[2] = float3(0.729412, 0.666667, 1.000000); // + palette[3] = float3(1., 1.000000, 1. ); //White + palette[4] = float3(1.000000, 0.580392, 0.615686); // + palette[5] = float3(0.909804, 0.007843, 0.000000); // + palette[6] = float3(0.478431, 0.141176, 0.239216); // + palette[7] = float3(0., 0. , 0. ); //Black + palette[8] = float3(0.098039, 0.337255, 0.282353); // + palette[9] = float3(0.415686, 0.537255, 0.152941); // + palette[10] = float3(0.086275, 0.929412, 0.458824); // + palette[11] = float3(0.196078, 0.756863, 0.764706); // + palette[12] = float3(0.019608, 0.498039, 0.756863); // + palette[13] = float3(0.431373, 0.305882, 0.137255); // + palette[14] = float3(0.937255, 0.890196, 0.019608); // + palette[15] = float3(0.788235, 0.560784, 0.298039); // + } + + // :: Dither :: // + + if (Nostalgia_dither == 1) //aek16 ( http://eastfarthing.com/blog/2016-05-06-palette/ ) + { + + //Calculate grid position + float grid_position = frac(dot(texcoord, BUFFER_SCREEN_SIZE * 0.5) + 0.25); //returns 0.25 and 0.75 + + //Calculate how big the shift should be + float dither_shift = (0.25) * (1.0 / (pow(2,2.0) - 1.0)); // 0.25 seems good both when using math and when eyeballing it. So does 0.75 btw. + + //Shift the individual colors differently, thus making it even harder to see the dithering pattern + float3 dither_shift_RGB = float3(dither_shift, dither_shift, dither_shift); //dithering + + //modify shift acording to grid position. + dither_shift_RGB = lerp(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position); //shift acording to grid position. + + //shift the color by dither_shift + //color.rgb += lerp(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position); //shift acording to grid position. + color.rgb += dither_shift_RGB; + } + + // :: Color matching :: // + + float3 diff = color - palette[0]; //find the difference in color compared to color 0 + + float dist = dot(diff,diff); //squared distance of difference - we don't need to calculate the square root of this + + float closest_dist = dist; //this has to be the closest distance so far as it's the first we have checked + float3 closest_color = palette[0]; //and closest color so far is this one + + for (int i = 1 ; i < colorCount ; i++) //for colors 1 to colorCount + { + diff = color - palette[i]; //find the difference in color + + dist = dot(diff,diff); //squared distance of difference - we don't need to calculate the square root of this + + if (dist < closest_dist) //is the distance closer than the previously closest distance? + { + closest_dist = dist; //closest distance is now this distance + closest_color = palette[i]; //closest color is now this color + } + } + + color = closest_color; //return the pixel + } + + if (Nostalgia_scanlines == 1) + { + color *= frac(texcoord.y * (BUFFER_HEIGHT * 0.5)) + 0.5; //Scanlines + } + if (Nostalgia_scanlines == 2) + { + float grey = dot(color,float(1.0/3.0)); + color = (frac(texcoord.y * (BUFFER_HEIGHT * 0.5)) < 0.25) ? color : color * ((-grey*grey+grey+grey) * 0.5 + 0.5); + } + + return color; //return the pixel +} + + +/*----------------. +| :: Technique :: | +'----------------*/ + +technique Nostalgia +{ + pass NostalgiaPass + { + VertexShader = PostProcessVS; + PixelShader = PS_Nostalgia; + + #if Nostalgia_linear == 1 + SRGBWriteEnable = true; + #endif + + ClearRenderTargets = false; + } +} diff --git a/data_from_portwine/Reshade/Shaders/OneShot/Limbo_Mod.fx b/data_from_portwine/Reshade/Shaders/OneShot/Limbo_Mod.fx new file mode 100644 index 00000000..4f1073ed --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/OneShot/Limbo_Mod.fx @@ -0,0 +1,211 @@ + ////-------------// + ///**Limbo Mod**/// + //-------------//// + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //* Super Simple Limbo Like Shader implementation: + //* For ReShade 3.0+ + //* --------------------------------- + //* Limbo Mod + //* Due Diligence + //* https://reshade.me + //* https://github.com/crosire/reshade-shaders/blob/a9ab2880eebf5b1b29cad0a16a5f0910fad52492/Shaders/DisplayDepth.fx + //* + //* + //* LICENSE + //* ============ + //* Limbo Mod is licenses under: Attribution 2.0 Generic (CC BY 2.0)l + //* + //* You are free to: + //* Share - copy and redistribute the material in any medium or format. + //* Adapt - remix, transform, and build upon the material 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. + //* + //* 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/2.0/ + //* + //* Have fun, + //* Jose Negrete AKA BlueSkyDefender + //* + //* https://github.com/BlueSkyDefender/Depth3D + //* April 1 2021 + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "ReShade.fxh" + +uniform float G_Radius< + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "Subtle Blur Radius"; + ui_tooltip = "Increase persistence of the frames this is really the Temporal Part.\n" + "Default is 0.625. But, a value around 0.625 is recommended."; + ui_category = "Limbo Lighting"; +> = 0.5; + +uniform float Target_Lighting < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "Target Lighting"; + ui_tooltip = "Use this to target the brighter areas of the game.\n" + "Default is 0.5. But, any value around 0 - 2 can be used."; + ui_category = "Limbo Lighting"; +> = 0.5; + +uniform float2 Depth_Map_Adjust < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Depth Near and Far"; + ui_tooltip = "Adjust the depth map precision near and far."; + ui_category = "Depth Buffer"; +> = float2(0.075,0.750); + +uniform float Dither_Bit < + ui_type = "drag"; + ui_min = 1; ui_max = 15; + ui_label = "Dither Bit"; + ui_tooltip = "Dither is an intentionally applied form of noise used to randomize quantization error, preventing banding in images."; + ui_category = "Depth Buffer"; +> = 8; + + +/////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) + +texture DepthBufferTex : DEPTH; + +sampler DepthBuffer + { + Texture = DepthBufferTex; + }; + +texture BackBufferTex : COLOR; + +sampler BackBuffer + { + Texture = BackBufferTex; + }; + +texture Mips_Buffer_A { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;MipLevels = 4;}; + +sampler MipMaps_A + { + Texture = Mips_Buffer_A; + }; + +texture Mips_Buffer_B { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;MipLevels = 4;}; + +sampler MipMaps_B + { + Texture = Mips_Buffer_B; + }; +uniform float frametime < source = "frametime"; >; +float DepthM(float2 texcoord) +{ + float zBuffer = ReShade::GetLinearizedDepth(texcoord).x; + +zBuffer = (zBuffer - Depth_Map_Adjust.x)/(Depth_Map_Adjust.y - Depth_Map_Adjust.x); + // Dither for DepthBuffer adapted from gedosato ramdom dither https://github.com/PeterTh/gedosato/blob/master/pack/assets/dx9/deband.fx + // I noticed in some games the depth buffer started to have banding so this is used to remove that. + + float DB = Dither_Bit; + float noise = frac(sin(dot(texcoord * frametime, float2(12.9898, 78.233))) * 43758.5453); + float dither_shift = (1.0 / (pow(2,DB) - 1.0)); + float dither_shift_half = (dither_shift * 0.5); + dither_shift = dither_shift * noise - dither_shift_half; + + zBuffer += -dither_shift; + zBuffer += dither_shift; + zBuffer += -dither_shift; + + // Dither End + + return zBuffer; +} + +float4 BB_M(float2 TC) +{ + return tex2D(BackBuffer, TC ); +} + + +float4 DirectLighting(float2 texcoords ) +{ + float4 BC = BB_M(texcoords); + + float GS = dot(BC.rgb,0.333), Boost = 1; + + BC.rgb /= GS; + BC.rgb *= saturate(GS - lerp(0.0,0.5,saturate(Target_Lighting))); + Boost = lerp(1,2.5,saturate(Target_Lighting)); + + return float4(BC.rgb * Boost,BC.a); +} + +float4 GussBlur(sampler image, float2 TC, int dir, float Mips) +{ + //direction + float W0 = G_Radius > 0 ? 0.1964825501511404 : 1, W1 = 0.2969069646728344, W2 = 0.09447039785044732, W3 = 0.010381362401148057; + float2 off0 = pix * lerp(0,5,G_Radius); + float2 off1 = dir ? float2( 0, 1.411764705882353) * off0 : float2(1.411764705882353, 0) * off0; + float2 off2 = dir ? float2( 0, 3.294117647058823) * off0 : float2(3.294117647058823, 0) * off0; + float2 off3 = dir ? float2( 0, 5.176470588235294) * off0 : float2(5.176470588235294, 0) * off0; + float4 color = tex2Dlod(image, float4(TC,0,Mips)) * W0; + if(G_Radius > 0) + { + color += tex2Dlod(image, float4(TC + off1,0,Mips) ) * W1; + color += tex2Dlod(image, float4(TC - off1,0,Mips) ) * W1; + color += tex2Dlod(image, float4(TC + off2,0,Mips) ) * W2; + color += tex2Dlod(image, float4(TC - off2,0,Mips) ) * W2; + color += tex2Dlod(image, float4(TC + off2,0,Mips) ) * W3; + color += tex2Dlod(image, float4(TC - off2,0,Mips) ) * W3; + } + + return color; +} + +void Buffers_Mip_A(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 MipMapper_A : SV_Target0) +{ + + MipMapper_A = DirectLighting( texcoord ); +} + +void Buffers_Mip_B(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 MipMapper_B : SV_Target0) +{ + + MipMapper_B = GussBlur(MipMaps_A, texcoord, 0, lerp(0,4,G_Radius)); +} + + +float4 Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float4 BWorColor = dot(GussBlur(MipMaps_B, texcoord, 1, lerp(0,4,G_Radius)),0.333); + return DepthM(texcoord) + (dot(tex2Dlod(MipMaps_A,float4(texcoord,0,0)),0.333) * BWorColor ); +} + +technique Limbo_Mod + { + pass Mips_A + { + VertexShader = PostProcessVS; + PixelShader = Buffers_Mip_A; + RenderTarget0 = Mips_Buffer_A; + } + pass Mips_B + { + VertexShader = PostProcessVS; + PixelShader = Buffers_Mip_B; + RenderTarget0 = Mips_Buffer_B; + } + pass Out + { + VertexShader = PostProcessVS; + PixelShader = Out; + } + } diff --git a/data_from_portwine/Reshade/Shaders/OneShot/SnowScape.fx b/data_from_portwine/Reshade/Shaders/OneShot/SnowScape.fx new file mode 100644 index 00000000..2e7ff51c --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/OneShot/SnowScape.fx @@ -0,0 +1,473 @@ + ////--------------// + ///**Snow Scape**/// + //--------------//// + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //* Super Simple Snow Shader "Snow Scape" implementation: + //* For ReShade 3.0+ + //* --------------------------------- + //* Snow Scape + //* Due Diligence + //* Based on POM + //* http://graphics.cs.brown.edu/games/SteepParallax/index.html + //* Other Needed Links for the code here. + //* http://www.shadertoy.com/view/XtKyzD + //* https://reshade.me + //* https://github.com/crosire/reshade-shaders/blob/a9ab2880eebf5b1b29cad0a16a5f0910fad52492/Shaders/DisplayDepth.fx + //* I am not sure I got it all. + //* + //* LICENSE + //* ============ + //* Snow Scape is licenses under: Attribution 2.0 Generic (CC BY 2.0)l + //* + //* You are free to: + //* Share - copy and redistribute the material in any medium or format. + //* Adapt - remix, transform, and build upon the material 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. + //* + //* 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/2.0/ + //* + //* Have fun, + //* Jose Negrete AKA BlueSkyDefender + //* + //* https://github.com/BlueSkyDefender/Depth3D + //* + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "ReShade.fxh" + +#define MaxDepth_Cutoff 0.999 //[0.1 - 1.0] +#define SN_offset float2(2,2) // Smooth Normals Set the first value from 1-6 + +uniform float BG < + ui_type = "slider"; + ui_min = 0.5; ui_max = 1.0; + ui_label = "Best Guess Sensitivity"; + ui_tooltip = "Increases the sensitiviy of the Algo used for gussing where the user is looking at.\n" + "Default is 0.9625. But, any value around 0.5 - 1.0 can be used. Decreasing this makes it stronger."; + ui_category = "Snow"; +> = 0.9625; + +uniform float SSC < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "Snow Scape Adjust"; + ui_tooltip = "Increase persistence of the frames this is really the Temporal Part.\n" + "Default is 0.625. But, a value around 0.625 is recommended."; + ui_category = "Snow"; +> = 0.625; + +uniform float HMP < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "Height Map Scaling"; + ui_tooltip = "Increases the Detail that it takes from the color information from the world.\n" + "Default is 0.5. But, any value around 0 - 2 can be used."; + ui_category = "Snow"; +> = 0.5; + +uniform float Elevation < + ui_type = "slider"; + ui_min = 0; ui_max = 50; + ui_label = "Elevation"; + ui_tooltip = "Increase Parallax Occlusion Mapping Elevation.\n" + "Default is 10. But, a value around 1-25 is recommended."; + ui_category = "Snow"; +> = 10; + +uniform bool I_Ice < + ui_label = "Invert Snow"; + ui_tooltip = "Use this so you can invert the Height Map."; + ui_category = "Snow"; +> = !true; + +uniform float Depth_Map_Adjust < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "Adjust the depth map and sharpness distance."; + ui_category = "Depth Buffer"; +> = 1.0; + +/////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// +texture DepthBufferTex : DEPTH; + +sampler DepthBuffer + { + Texture = DepthBufferTex; + }; + +texture BackBufferTex : COLOR; + +sampler BackBuffer + { + Texture = BackBufferTex; + }; + +texture SnowMask_A { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 11;}; + +sampler CSnowMask + { + Texture = SnowMask_A; + }; + +texture Normals_A { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16; MipLevels = 11;}; + +sampler N_Sampler_A + { + Texture = Normals_A; + }; + +texture Normals_B { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16; MipLevels = 11;}; + +sampler N_Sampler_B + { + Texture = Normals_B; + }; + +texture BB_Depth_A { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;MipLevels = 11;}; + +sampler CDBuffer + { + Texture = BB_Depth_A; + }; + +texture Bump_C { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;MipLevels = 11;}; + +sampler BumpMap + { + Texture = Bump_C; + }; + + +//Total amount of frames since the game started. +uniform uint framecount < source = "framecount"; >; +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +#define PI 3.14159265358979323846264 // PI + +float fmod(float a, float b) +{ + float c = frac(abs(a / b)) * abs(b); + return a < 0 ? -c : c; +} + +float2 DepthM(float2 texcoord) +{ + float zBuffer = ReShade::GetLinearizedDepth(texcoord).x; //Depth Buffer + zBuffer = smoothstep(0,Depth_Map_Adjust,zBuffer); + return float2(zBuffer,(1-zBuffer - 0.5)/(1.0 - 0.5) ); +} + +float4 BB_H(float2 TC) +{ + return tex2D(BackBuffer, TC ); +} + +float3 DepthNormals(float2 texcoord) +{ + float3 offset = float3(pix.xy, 0.0); + float2 posCenter = texcoord.xy; + float2 posNorth = posCenter - offset.zy; + float2 posEast = posCenter + offset.xz; + + float3 vertCenter = float3(posCenter - 0.5, 1) * DepthM(posCenter).x; + float3 vertNorth = float3(posNorth - 0.5, 1) * DepthM(posNorth).x; + float3 vertEast = float3(posEast - 0.5, 1) * DepthM(posEast).x; + + return normalize(cross(vertCenter - vertNorth, vertCenter - vertEast)) ; +} + +void MCNoise(inout float Noise,float2 TC, float FC,float seed) +{ //This is the noise I used for rendering + float motion = FC, a = 12.9898, b = 78.233, c = 43758.5453, dt= dot( TC.xy * 2.0 , float2(a,b)), sn= fmod(dt,PI); + Noise = frac(frac(tan(distance(sn*(seed+dt), float2(a,b) )) * c) + 0.61803398875f * motion); +} + +float LumaMask(sampler Texture,float2 texcoord) +{ +float2 samples[12] = { + float2(-0.326212,-0.405805), + float2(-0.840144,-0.073580), + float2(-0.695914, 0.457137), + float2(-0.203345, 0.620716), + float2( 0.962340,-0.194983), + float2( 0.473434,-0.480026), + float2( 0.519456, 0.767022), + float2( 0.185461,-0.893124), + float2( 0.507431, 0.064425), + float2( 0.896420, 0.412458), + float2(-0.321940,-0.932615), + float2(-0.791559,-0.597705) + }; + int MipM = 5; + float4 sum = tex2Dlod(Texture,float4(texcoord,0,MipM)); + for (int i = 0; i < 12; i++) + { + float Spread = 0.0275; + sum += tex2Dlod(Texture,float4(texcoord + Spread * samples[i],0,MipM)); + } + + sum /= 13; + return dot(sum,0.333); + +} +float4 Mask(float2 texcoord) +{ +//Code for Guessing where the user was looking at was removed in favor of martys improved world normals. +//Nope added Guessing back Marty Improved World Normals not ready yet. But, I hope for the future. +// I am silly I forgot what I did befor..... so I had to rewrite this from memory welp....Forgot a lot lol Fuck...... +//Not the same code in the video. since I forgot what I did and my cloud stroage seems to forget what I did if I rename the file. +//New thing was made........ Happy guessing. +float3 Normals = tex2Dlod(N_Sampler_B,float4(texcoord,0,0)).xyz; +//Changed my mind since my memory sucks New system Guessing where the user is looking at with 8 Detectors kind of like SuperDepth3D. +float2 Location[8] = { + float2(0.25,0.5 ),//Left of Center + float2(0.5 ,0.25),//Above Center + float2(0.5 ,0.5 ),//Center + float2(0.5 ,0.75),//Below Center + float2(0.75,0.5 ),//Right of Center + float2(0.25,0.75),//Down Left + float2(0.75,0.75),//Down Right + float2(0.5 ,0.125)//Way Above Center + }; + + float Best_Guess = 0.5,Center,Above,Below,Left,Right,DL,DR,WAC,WTF; + + if(DepthM(Location[2]).x > BG)//Center + Center = 1; + if(DepthM(Location[1]).x > BG)//Above + Above = 1; + if(DepthM(Location[3]).x > BG)//Below + Below = 1; + if(DepthM(Location[0]).x > BG)//Left + Left = 1; + if(DepthM(Location[4]).x > BG)//Right + Right = 1; + if(DepthM(Location[5]).x > BG)//Down Left + DL = 1; + if(DepthM(Location[6]).x > BG)//Down Right + DR = 1; + if(DepthM(Location[7]).x > BG)//Down Right + WAC = 1; + +//Now we guess Where/What the fuck the User is looking at. +if(!Center && !Above && !Below && !Left && !Right && !DL && !DR && WAC) + Best_Guess = 0.250; +if(!Center && Above && !Below && !Left && !Right && !DL && !DR && WAC) + Best_Guess = 0.125; +if( Center && Above && !Below && !Left && !Right && !DL && !DR && WAC) + Best_Guess = 0.0; +if( !Center && !Above && !Below && !Left && !Right && !DL && !DR && !WAC) + Best_Guess = 1.0; +if( Center && Above && Below && Left && Right && !DL && DR && WAC) + Best_Guess = 0.0625; +if( Center && Above && Below && Left && Right && DL && !DR && WAC) + Best_Guess = 0.0625; + + //to be used later to guess if the user if close to a wall...... But, got lazy. + //if( !Center && !Above && !Below && !Left && !Right && !DL && !DR && !WAC) + //WTF = 1; + // float DD = saturate(tex2Dlod(N_Sampler_B,float4(texcoord,0,10)).w),DS = smoothstep(0,0.1,DD),Depth = smoothstep(0,1,DepthM(0.5).x); + + float Top = dot(float3(0,1,0), Normals), Wall = step(Best_Guess,dot(float3(0,0,1), Normals));; + float Snow = smoothstep(1-SSC,1,WTF ? Top : Top-Wall); + + float Noise; + MCNoise( Noise, texcoord, 1 , 1 ); + //Hold over for wave noise + float2 Di[4] = {float2(pix.x,0),float2(-pix.x,0),float2(0,pix.y),float2(0,-pix.y)}; + float3 SN = 1-BB_H(texcoord).rgb; + [fastopt] + for (int i = 0; i < 4; i ++) + { + SN += (1-BB_H(texcoord + Di[i] * Noise * (0.1*100)).rgb); + } + + float HeightMap = Top * dot(saturate(SN/5) , HMP); + + HeightMap = I_Ice ? 1-HeightMap : HeightMap; + + return float4(Snow, lerp(0,HeightMap,Snow) ,Snow,1); +} + +float Bump(float2 TC) +{ + float2 t, l, r, d, MA = 5; + float2 UV = TC.xy, SW = pix * MA; + float3 NormalsFromHeightMap, NHM_A, NHM_B; + + float Noise; + MCNoise( Noise, TC, 1 , 1 ); + + t.x = Mask( float2( UV.x , UV.y - SW.y ) ).y; + d.x = Mask( float2( UV.x , UV.y + SW.y ) ).y; + l.x = Mask( float2( UV.x - SW.x , UV.y ) ).y; + r.x = Mask( float2( UV.x + SW.x , UV.y ) ).y; + SW *= 0.5; + t.y = Mask( float2( UV.x , UV.y - SW.y ) ).y; + d.y = Mask( float2( UV.x , UV.y + SW.y ) ).y; + l.y = Mask( float2( UV.x - SW.x , UV.y ) ).y; + r.y = Mask( float2( UV.x + SW.x , UV.y ) ).y; + + NHM_A = float3(-float2(-(r.x - l.x),-(t.x - d.x)) * 0.5 + 0.4,1); + NHM_B = float3(-float2(-(r.y - l.y),-(t.y - d.y)) * 0.5 + 0.4,1); + + NormalsFromHeightMap = lerp(NHM_A , NHM_B, 0.5); + +return saturate(dot(0.5,NormalsFromHeightMap)); +} + +float HeightMap(float2 TC) +{ + float HM1 = tex2Dlod(CSnowMask,float4(TC,0,1)).y; + float HM2 = tex2Dlod(CSnowMask,float4(TC,0,3)).y; + float HM = (HM1 + HM2)/2; + return HM * DepthM(TC).y; +} + +float2 Parallax( float2 Diverge, float2 Coordinates) +{ float2 TC = Coordinates; + float D = abs(length(Diverge)); + float Cal_Steps = D + (D * 0.05); + + //ParallaxSteps + float Steps = clamp(Cal_Steps * 2,1,255); + + // Offset per step progress & Limit + float LayerDepth = rcp(Steps); + + //Offsets listed here Max Seperation is 3% - 8% of screen space with Depth Offsets & Netto layer offset change based on MS. + float2 MS = Diverge * pix; + float2 deltaCoordinates = MS * LayerDepth, ParallaxCoord = Coordinates; + float CurrentDepthMapValue = Mask(ParallaxCoord).x, CurrentLayerDepth = 0; + + [loop] //Steep parallax mapping + for ( int i = 0; i < Steps; i++ ) + { // Doing it this way should stop crashes in older version of reshade, I hope. + if (CurrentDepthMapValue <= CurrentLayerDepth) + break; // Once we hit the limit Stop Exit Loop. + // Shift coordinates horizontally in linear fasion + ParallaxCoord -= deltaCoordinates; + // Get depth value at current coordinates + CurrentDepthMapValue = HeightMap( ParallaxCoord ); + // Get depth of next layer + CurrentLayerDepth += LayerDepth; + } + + // Parallax Occlusion Mapping + float2 PrevParallaxCoord = ParallaxCoord + deltaCoordinates, DepthDifference; + float afterDepthValue = CurrentDepthMapValue - CurrentLayerDepth; + float beforeDepthValue = HeightMap( ParallaxCoord ) - CurrentLayerDepth + LayerDepth; + // Interpolate coordinates + float weight = afterDepthValue / (afterDepthValue - beforeDepthValue); + ParallaxCoord = PrevParallaxCoord * max(0,weight) + ParallaxCoord * min(1,1.0f - weight); + + return ParallaxCoord; +} + +//Super Simple Sparkly Shader https://www.shadertoy.com/view/XtKyzD +float SSSS(float2 TC) +{ + float2 Noise; + Noise.x = tex2D(BumpMap,TC).y; + Noise.y = tex2D(BumpMap,TC).z; + float result = Noise.x; + result *= Noise.y; + result = pow(abs(result), 12.0); + return 5.0*result; +} + +void Out(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float3 color : SV_Target) +{ + float2 TC = Parallax(float2(0,-Elevation * DepthM(texcoord).y) , texcoord ).xy; + float Snow = Mask(TC.xy).x, SS = tex2Dlod(BumpMap,float4(TC,0,2)).w; + float3 Snow_Color = float3(0.75,0.8,0.85), Snow_Scape = (Mask(TC.xy).x - 0.01) * Snow_Color + SSSS(TC.xy * 0.75); + + float3 T_A_A = lerp(Snow_Scape + LumaMask(CDBuffer,TC)*0.2, BB_H( TC.xy ).rgb,1-Snow); +// if(TC.y > 1) +// color = Snow_Color; +// else + color = T_A_A * lerp(SS,1,1-Snow); +} + +float3 SmoothNormals(float2 TC, int NS,int Dir, float SNOffset) +{ //Smooth Normals done in two passes now Faster. But, still slow. + float4 StoredNormals_Depth = float4(Dir ? DepthNormals(TC) : tex2Dlod(N_Sampler_A,float4(TC,0,0)).xyz,DepthM(TC).x), SmoothedNormals = float4(StoredNormals_Depth.xyz,1); + + [loop] // -1 0 +1 on x and y + for(float xy = -NS; xy <= NS; xy++) + { + if(smoothstep(0,1,StoredNormals_Depth.w) > MaxDepth_Cutoff) + break; + float2 XY = Dir ? float2(xy,0) : float2(0,xy); + float2 offsetcoords = TC + XY * pix * SNOffset; + float4 Normals_Depth = float4(Dir ? DepthNormals(offsetcoords) : tex2Dlod(N_Sampler_A,float4(offsetcoords,0,0)).xyz,DepthM(offsetcoords).x); + if (abs(StoredNormals_Depth.w - Normals_Depth.w) < 0.001 && dot(Normals_Depth.xyz, StoredNormals_Depth.xyz) > 0.5f) + { + SmoothedNormals.xyz += Normals_Depth.xyz; + ++SmoothedNormals.w; + } + } + + return SmoothedNormals.xyz / SmoothedNormals.w; +} + +void Buffers_A(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 Normals : SV_Target0, out float4 BackBuffer_Depth : SV_Target1, out float4 Snow_Info : SV_Target2) +{ + //AO was removed seems going over board for this simple effect. + Normals = SmoothNormals(texcoord, SN_offset.x, 1, SN_offset.y); + BackBuffer_Depth = float4(tex2D(BackBuffer,texcoord).rgb,DepthM(texcoord).x); + Snow_Info = float4(Mask(texcoord).xyz,0); +} + +void Buffers_B(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 Normals_LM : SV_Target0) +{ //AO was removed seems going over board for this simple effect. + Normals_LM = float4(SmoothNormals(texcoord, SN_offset.x, 0, SN_offset.y).xyz,DepthM(texcoord).x); +} + +void Buffers_C(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 BumpMap_Else : SV_Target0) +{ + float2 Noise; + //should add fake glitter movement comp..... here + MCNoise( Noise.x, texcoord , framecount * -0.005, 1 ); + MCNoise( Noise.y, texcoord , framecount * +0.005, 2 ); + + BumpMap_Else = float4(0,Noise.x,Noise.y,Bump(texcoord)); +} + +technique OS_SnowScape + { + pass Alpha + { + VertexShader = PostProcessVS; + PixelShader = Buffers_A; + RenderTarget0 = Normals_A; + RenderTarget1 = BB_Depth_A; + RenderTarget2 = SnowMask_A; + } + pass Beta + { + VertexShader = PostProcessVS; + PixelShader = Buffers_B; + RenderTarget0 = Normals_B; + } + pass Gamma + { + VertexShader = PostProcessVS; + PixelShader = Buffers_C; + RenderTarget0 = Bump_C; + } + pass Out + { + VertexShader = PostProcessVS; + PixelShader = Out; + } + } diff --git a/data_from_portwine/Reshade/Shaders/Overwatch.fxh b/data_from_portwine/Reshade/Shaders/Overwatch.fxh new file mode 100644 index 00000000..5e163beb --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Overwatch.fxh @@ -0,0 +1,3208 @@ +////----------------------------------------// +///SuperDepth3D Overwatch Automation Shader/// +//----------------------------------------//// +// Version 2.1.7 +//---------------------------------------OVERWATCH---------------------------------------// +// If you are reading this stop. Go away and never look back. From this point on if you // +// still think it's is worth looking at this..... Then no one can save you or your soul. // +// You will be cursed with never enjoying any memes to their fullest potential.......... // +// Ya that's it. JK // +// The name comes from this. // +// https://en.wikipedia.org/wiki/Overwatch_(military_tactic) // +// Since this File looks ahead and sends information the Main shader to prepare it self. // +//---------------------------------------------------------------------------------------// +// Special Thanks to CeeJay.dk for code simplification and guidance. // +// You can contact him here https://github.com/CeeJayDK // +//----------------------------------------LICENSE----------------------------------------// +// ===================================================================================== // +// Overwatch is licenses under: Copyright (C) Depth3D - All Rights Reserved // +// // +// Unauthorized copying of this file, via any medium is strictly prohibited // +// Proprietary and confidential. // +// // +// You are allowed to obviously download this and use this for your personal use. // +// Just don't redistribute this file unless I authorize it. // +// // +// Written by Jose Negrete , December 2019 // +// ===================================================================================== // +//--------------------------------------Code Start---------------------------------------// + +//Weapon Setting are at the bottom of this file. + +//SuperDepth3D Defaults +static const float ZPD_D = 0.025; //ZPD +static const float Depth_Adjust_D = 7.5; //Depth Adjust +static const float Offset_D = 0.0; //Offset +static const int Depth_Linearization_D = 0; //Linearization +static const int Depth_Flip_D = 0; //Depth Flip +static const int Auto_Balance_D = 0; //Auto Balance +static const float Auto_Depth_D = 0.1; //Auto Depth Range +static const int Weapon_Hand_D = 0; //Weapon Profile +static const float BD_K1_D = 0.0; //Barrel Distortion K1 +static const float BD_K2_D = 0.0; //Barrel Distortion K2 +static const float BD_K3_D = 0.0; //Barrel Distortion K3 +static const float BD_Zoom_D = 0.0; //Barrel Distortion Zoom +static const float HVS_X_D = 1.0; //Horizontal Size +static const float HVS_Y_D = 1.0; //Vertical Size +static const float HVP_X_D = 0; //Horizontal Position +static const float HVP_Y_D = 0; //Vertical Position +static const int ZPD_Boundary_Type_D = 0; //ZPD Boundary Type +static const float ZPD_Boundary_Scaling_D = 0.5; //ZPD Boundary Scaling +static const float ZPD_Boundary_Fade_Time_D = 0.25; //ZPD Boundary Fade Time +static const float Weapon_Near_Depth_Max_D = 0.0; //Weapon Near Depth Max +static const float ZPD_Weapon_Boundary_Adjust = 0.0; //ZPD Weapon Boundary Adjust +static const float Separation = 0.0; //ZPD Separation +static const float Null_Z = 0.0; // +static const float HUDX_D = 0.0; //Heads Up Display Cut Off Point +static const float Manual_ZPD_Balance = 0.5; //Manual Balance Mode Adjustment +static const float Null_Y = 0.0; // +static const float Weapon_Near_Depth_Min_D = 0.0; //Weapon Near Depth Min +static const float Check_Depth_Limit = 0.0; //Check Depth Limit + +//Special Toggles Defaults +static const int REF = 0; //Resident Evil Fix +static const int HMT = 0; //HUD Mode Trigger +static const int IDF = 0; //Inverted Depth Fix +static const int SPF = 0; //Size & Position Fix +static const int BDF = 0; //Barrel Distortion Fix +static const int DFW = 0; //Delay Frame Workaround +static const int ALB = 0; //Auto Letter Box +static const int LBD = 0; //Letter Box Depth +static const int STD = 0; //Specialized Depth Trigger +static const int BMT = 0; //Balance Mode Toggle +//Special Toggles Generic +static const int RHW = 0; //Read Help Warning +static const int EDW = 0; //Emulator Detected Warning + +//Special Toggles Warnings +static const int NCW = 0; //Not Compatible Warning +static const int NPW = 0; //No Profile Warning +static const int NFM = 0; //Needs Fix/Mod +static const int DSW = 0; //Depth Selection Warning +static const int DAA = 0; //Disable Anti-Aliasing +static const int NWW = 0; //Network Warning +static const int PEW = 0; //Disable Post Effect Warning +static const int WPW = 0; //Weapon Profile Warning +static const int FOV = 0; //Set Game FoV + +//Special Handling +#if exists "LEGOBatman.exe" //Lego Batman + #define sApp 0xA100000 +#elif exists "LEGOBatman2.exe" //LEGO Batman 2 + #define sApp 0xA100000 +#elif exists "GameComponentsOzzy_Win32Steam_Release.dll"//Batman BlackGate + #define sApp 0xA200000 +#else + #define sApp __APPLICATION__ +#endif + +//Check for ReShade Version for 64bit game Bug. +#if !defined(__RESHADE__) || __RESHADE__ < 43000 + #if exists "ACU.exe" //Assassin's Creed Unity + #define App 0xA0762A98 + #elif exists "BatmanAK.exe" //Batman Arkham Knight + #define App 0x4A2297E4 + #elif exists "DOOMx64.exe" //DOOM 2016 + #define App 0x142EDFD6 + #elif exists "RED-Win64-Shipping.exe" //DragonBall Fighters Z + #define App 0x31BF8AF6 + #elif exists "HellbladeGame-Win64-Shipping.exe" //Hellblade Senua's Sacrifice + #define App 0xAAA18268 + #elif exists "TheForest.exe" //The Forest + #define App 0xABAA2255 + #elif exists "MonsterHunterWorld.exe" //Monster Hunter World + #define App 0xDB3A28BD + #elif exists "FarCry5.exe" //Farcry 5 + #define App 0xC150B805 + #else + #define App sApp + #endif +#else + #define App sApp +#endif + +//Game Hashes// +#if (App == 0xC19572DDF || App == 0xFBEE8027 ) //PCSX2 | CEMU + #define RH 1 + #define SP 2 + #define HM 1 + #define DS 1 + #define ED 1 +#elif (App == 0xC753DADB ) //ES: Oblivion + #define DB_W 2 + #define DB_Y 3 +#elif (App == 0x7B81CCAB || App == 0xFB9A99AB ) //BorderLands 2 & Pre-Sequel + #define DA_Y 25.0 + #define DA_Z 0.00025 + #define DA_X 0.03750 + #define DB_Y 2 + #define DB_W 4 + #define DE_X 4 + #define DE_Y 0.625 + #define DE_Z 0.300 + #define DF_X 0.300 + #define NW 1 +#elif (App == 0x2D950D30 ) //Fallout 4 + #define DA_X 0.05 + //#define DA_Y 7.8 + #define DB_Y 3 + #define DB_W 6 + #define DF_Y 0.012 + #define DE_X 3 + #define DE_Y 0.750 + #define DE_Z 0.375 + #define FV 1 + #define RH 1 + #define DS 1 +#elif (App == 0x3950D04E ) //Skyrim: SE + #define DA_Y 6.25 + #define DB_Y 2 + #define DB_W 7 +#elif (App == 0x142EDFD6 || App == 0x2A0ECCC9 || App == 0x8B0C2031 ) //DOOM 2016 + #define DA_Y 23.125 + #define DA_Z -0.00010 + #define DA_X 0.071 + #define DB_Z 0.1125 + #define DF_Y 0.01875 + #define DB_Y 1 //Auto Mode Works But this game is better locked. + #define DE_X 3 + #define DE_Y 0.500 + #define DE_Z 0.4375 + #define DB_W 8 + #define DG_Z 0.001 + #define BM 1 + #define DG_X 0.145 + #define PE 1 +#elif (App == 0x17232880 || App == 0x9D77A7C4 || App == 0x22EF526F ) //CoD:Black Ops | CoD:MW2 |CoD:MW3 + #define DA_Y 12.5 + #define DB_Y 3 + #define DB_W 9 +#elif (App == 0xD691718C ) //CoD:Black Ops II + #define DA_Y 13.75 + #define DA_W 1 + #define DB_W 10 +#elif (App == 0x7448721B ) //CoD:Ghost + #define DA_Y 13.75 + #define DB_Y 2 + #define DA_W 1 + #define DB_W 11 +#elif (App == 0x23AB8876 || App == 0xBF4D4A41 ) //CoD:AW | CoD:MW Re + #define DA_Y 13.75 + #define DB_Y 2 + #define DA_W 1 + #define DB_W 12 +#elif (App == 0x1544075 ) //CoD:IW + #define DA_Y 13.75 + #define DB_Y 2 + #define DA_W 1 + #define DB_W 13 +#elif (App == 0x697CDA52 ) //CoD:WaW + #define DA_Y 12.5 + #define DB_Y 3 + #define DB_W 14 +#elif (App == 0x4383C12A || App == 0x239E5522 || App == 0x3591DE9C ) //CoD | CoD:UO | CoD:2 + #define DB_W 15 + #define RH 1 +#elif (App == 0x73FA91DC ) //CoD: Black Ops IIII + #define DA_Y 22.5 + #define DA_W 1 + #define DB_W 16 +#elif (App == 0x37BD797D ) //Quake DarkPlaces + #define DA_Y 15.0 + #define DB_Y 2 + #define DB_W 17 +#elif (App == 0x34F4B6C ) //Quake 2 XP + #define DB_Y 2 + #define DB_W 18 +#elif (App == 0xED7B83DE ) //Quake 4 #ED7B83DE + #define DA_Y 15.0 + #define DB_W 19 +#elif (App == 0x886386A ) //Metro Redux Games + #define DA_Y 12.5 + #define DB_Y 2 + #define DB_W 21 +#elif (App == 0xF5C7AA92 || App == 0x493B5C71 ) //S.T.A.L.K.E.R: Games + #define DA_Y 10.0 + #define DB_Y 4 + #define DB_W 26 +#elif (App == 0xDE2F0F4D ) //Prey 2006 + #define DB_W 28 + #define DB_Y 3 +#elif (App == 0x36976F6D ) //Prey 2017 + #define DA_W 1 + #define DA_X 0.04625 + #define DA_Y 21.25 + #define DB_Y 2 + #define DE_X 3 + #define DE_Y 0.5 + #define DE_Z 0.300 + #define DF_Y 0.05 + #define WSM 4 + #define OW_WP "Read Help & Change Me\0Custom WP\0Prey High Settings and <\0Prey 2017 Very High\0" + #define RH 1 + #define PE 1 + #define WW 1 +#elif (App == 0xBF757E3A ) //Return to Castle Wolfenstein + #define DA_Y 8.75 + #define DB_Y 2 + #define DB_W 31 +#elif (App == 0xC770832 || App == 0x3E42619F ) //Wolfenstein: The New Order | The Old Blood + #define DA_Y 25.0 + #define DB_Y 5 + #define DA_Z 0.00125 + #define DB_W 33 +#elif (App == 0x6FC1FF71 ) //Black Mesa + #define DA_Y 8.75 + #define DA_Z 0.000125 + #define DA_X 0.0325 + #define DB_Y 2 + #define DB_W 35 + #define DB_Z 0.08625 +#elif (App == 0x6D3CD99E ) //Blood 2 + #define DA_X 0.105 + #define DB_Y 2 + #define DE_X 3 + //#define DE_Y 0.50 + #define DE_Z 0.475 + #define WSM 5 + #define DB_W 2 + #define OW_WP "Read Help & Change Me\0Custom WP\0Blood 2 All Weapons\0Blood 2 Bonus Weapons\0Blood 2 Former\0" + #define WW 1 + #define NF 1 + #define RH 1 +#elif (App == 0xF22A9C7D || App == 0x5416A79D ) //SOMA + #define DA_Y 23.125 //21.25 //25.0 + #define DA_X 0.1025 //0.110 //0.095 + #define DB_Y 5 + #define BM 1 + #define DG_X 0.15625 + #define DA_Z -0.00025 + #define DG_W 0.1 + #define DB_W 38 + #define DG_Z 0.341 + #define DE_X 3 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DF_X 0.25 + #define FV 1 + #define RH 1 +#elif (App == 0x6FB6410B ) //Cryostasis + #define DA_Y 13.75 + #define DB_Y 3 + #define DB_W 39 +#elif (App == 0x16B8D61A) //Unreal Gold with v227 + #define DA_Y 17.5 + #define DB_Y 1 + #define DB_W 40 + #define DF_W 0.534 + #define HM 1 +#elif (App == 0xEB9EEB74 || App == 0x8238E9CA ) //Serious Sam Revolution | Serious Sam 2 + #define DA_X 0.075 + #define DA_Y 10.0 + #define DB_Y 1 + #define DE_X 4 + #define DE_Y 0.85 + #define DE_Z 0.375 + #define DB_Z 0.150 + #define DA_Z 0.1111 + #define DF_X 0.1125 + #define DB_W 41 + #define DF_W 0.5 + #define HM 1 +#elif (App == 0x308AEBEA ) //TitanFall 2 + #define DB_Y 4 + #define DB_W 44 +#elif (App == 0x5FCFB1E5 ) //Project Warlock + #define DA_Y 17.5 + #define DB_Y 2 + #define DA_W 1 + #define DB_W 45 +#elif (App == 0x7DCCBBBD ) //Kingpin Life of Crime + #define DA_Y 10.0 + #define DB_Y 4 + #define DB_W 46 + #define RH 1 +#elif (App == 0x9C5C946E ) //EuroTruckSim2 + #define DB_W 47 +#elif (App == 0xB302EC7 || App == 0x91D9EBAF ) //F.E.A.R | F.E.A.R 2: Project Origin + #define DA_X 0.110 + #define DA_Y 12.0 + #define DA_Z 0.00025 + #define DB_Y 5 + #define DE_X 3 + //#define DE_Y 0.625 + #define DE_Z 0.375 + //#define DG_W 0.25 + #define DB_W 48 + //#define DF_X 0.225 + #define DS 1 //? + #define FV 1 + #define RH 1 +#elif (App == 0x2C742D7C ) //Immortal Redneck CP alt 1.9375 + #define DA_Y 20.0 + #define DB_Y 5 + #define DB_W 50 +#elif (App == 0x663E66FE ) //NecroVisioN & NecroVisioN: Lost Company + #define DA_Y 10.0 + #define DB_Y 2 + #define DB_W 52 +#elif (App == 0xAA6B948E ) //Rage64 + #define DA_Y 20.0 + #define DB_Y 2 + #define DB_W 53 +#elif (App == 0x44BD41E1 ) //Bioshock Remaster + #define DA_Z 0.001 + #define DB_Y 3 + #define DB_W 55 +#elif (App == 0x7CF5A01 ) //Bioshock 2 Remaster + #define DA_Z 0.001 + #define DB_W 56 + #define DB_Y 3 + #define DF_W 0.5034 + #define HM 1 +#elif (App == 0x22BA110F ) //Turok: DH 2017 + #define DA_X 0.002 + #define DA_Y 250.0 +#elif (App == 0x5F1DBD3B ) //Turok2: SoE 2017 + #define DA_X 0.002 + #define DA_Y 250.0 +#elif (App == 0x3FDD232A ) //FEZ + #define DA_X 0.2125 + #define DB_Y 4 + #define DA_Z -0.901 +#elif (App == 0x619964A3 ) //What Remains of Edith Finch + #define DA_Y 50.0 + #define DA_Z 0.000025 + #define DA_W 1 + #define DB_Y 2 +#elif (App == 0x941D8A46 ) //Tomb Raider Anniversary :) + #define DA_Y 75.0 + #define DA_Z 0.0206 + #define DB_Y 2 +#elif (App == 0xF0100C34 ) //Two Worlds Epic Edition + #define DA_Y 43.75 + #define DA_Z 0.07575 +#elif (App == 0xA4C82737 ) //Silent Hill: Homecoming + #define DA_Y 25.0 + #define DA_X 0.0375 + #define DA_Z 0.11625 + #define DB_Y 4 + #define DF_W 0.5 + #define HM 1 +#elif (App == 0x61243AED ) //Shadow Warrior Classic source port + #define DA_Y 10.0 + #define DA_X 0.05 + #define DA_Z 1.0 + #define DB_Y 5 +#elif (App == 0x5AE8FA62 ) //Shadow Warrior Classic Redux + #define DA_Y 10.0 + #define DA_X 0.05 + #define DA_Z 1.0 + #define DB_Y 5 +#elif (App == 0xFE54BF56 ) //No One Lives Forever and 2 + #define DA_X 0.0375 + #define RH 1 +#elif (App == 0x9E7AA0C4 ) //Shadow Tactics: Blades of the Shogun + #define DA_Y 7.0 + #define DA_Z 0.001 + #define DA_X 0.150 + #define DB_Y 5 + #define DB_Z 0.305 + #define DB_X 1 + #define RH 1 +#elif (App == 0xE63BF4A4 ) //World of Warcraft DX12 + #define DA_Y 7.5 + #define DA_W 1 + #define DB_Y 3 + #define DB_Z 0.1375 + #define NW 1 + #define RH 1 +#elif (App == 0x5961D1CC ) //Requiem: Avenging Angel + #define DA_Y 37.5 + #define DA_X 0.0375 + #define DA_Z 0.8 + #define DF_W 0.501 + #define HM 1 +#elif (App == 0x86D33094 || App == 0x19019D10 ) //Rise of the TombRaider | TombRaider 2013 + #define DA_X 0.0725 + #define DB_Y 3 + #define DA_Y 25.0 + #define DA_Z 0.0200375 + #define DE_X 2 + #define DE_Y 0.375 + #define DE_Z 0.375 +#elif (App == 0x60F436C6 ) //RESIDENT EVIL 2 BIOHAZARD RE2 + #define DA_X 0.1375 + #define DB_Y 3 + #define DB_Z 0.015 + #define DA_Y 51.25 + #define DA_W 1 + #define DA_Z 0.00015 + #define RE 1 +#elif (App == 0xF0D4DB3D ) //Never Alone + #define DA_X 0.1375 + #define DB_Y 2 + #define DA_Y 31.25 + #define DA_Z 0.004 +#elif (App == 0x3EB1D73A ) //Magica 2 + #define DA_X 0.2 + #define DB_Y 5 + #define DA_Y 27.5 + #define DA_Z 0.007 +#elif (App == 0x6D35D4BE ) //Lara Croft and the Temple of Osiris + #define DA_X 0.15 + #define DB_Y 4 + #define DB_Z 0.4 + #define DA_Y 75.0 + #define DA_Z 0.021 + #define RE 1 +#elif (App == 0xAAA18268 ) //Hellblade + #define DB_Y 1 + #define DA_Y 25.0 + #define DA_W 1 + #define DA_Z 0.0005 + #define DB_Z 0.25 //Under Review +#elif (App == 0x287BBA4C || App == 0x59BFE7AC ) //Grim Dawn 64bit/32bit + #define DB_Y 2 + #define DA_Y 125.0 + #define DA_Z 0.003 +#elif (App == 0x8EAF7114 ) //Firewatch + #define DB_Y 3 + #define DA_Y 5.0 + #define DA_X 0.0375 + #define DB_X 1 + #define DA_W 1 +#elif (App == 0x6BDF0098 ) //Dungeons 2 + #define DA_X 0.100 + #define DB_Y 3 + #define DA_Z 0.005 + #define DB_X 1 +#elif (App == 0x56E482C9 ) //DreamFall Chapters + #define DA_Y 10.0 + #define DA_X 0.0375 + #define DB_Y 2 + #define DA_Z 0.001 + #define DB_X 1 +#elif (App == 0x31BF8AF6 ) //DragonBall Fighters Z + #define DA_Y 10.0 + #define DA_W 1 + #define DA_X 0.130 + #define DB_Y 3 + #define DB_Z 0.625 //I know, I know........ +#elif (App == 0x3F017CF ) //Call of Cthulhu + #define DA_W 1 + #define DA_X 0.0375 + #define DB_Y 3 +#elif (App == 0x874318FE || App == 0x7CBA2E8C || App == 0x69277DAF ) //Batman Arkham Asylum / City / Origins + #define DA_Y 18.75 + #define DA_X 0.0375 + #define DA_Z 0.00025 + #define DB_Y 4 + #define DB_Z 0.15 + #define RH 1 +#elif (App == 0xA100000 ) //Lego Batman 1 & 2 + #define DA_Y 27.5 + #define DA_X 0.125 + #define DA_Z 0.001 + #define DB_Y 2 + #define DB_Z 0.025 + #define RE 1 +#elif (App == 0x5F2CA572 ) //Lego Batman 3 + #define DA_X 0.03 + #define DA_Z 0.001 + #define DB_Y 4 + #define RH 1 +#elif (App == 0xA200000 ) //Batman BlackGate + #define DA_Y 12.5 + #define DA_X 0.0375 + #define DA_Z 0.00025 + #define DB_Y 3 +#elif (App == 0xCB1CCDC ) //BATMAN TTS + #define NC 1 //Not Compatible +#elif (App == 0x4A2297E4 ) //Batman Arkham Knight + #define DA_Y 22.500 + #define DA_X 0.04375 + #define DB_Y 4 +#elif (App == 0xE9A02687 ) //BattleTech + #define DA_W 1 + #define DB_X 1 + #define DA_Y 75.0 + #define DA_X 0.250 + #define DB_Y 1 + #define RE 1 + #define RH 1 +#elif (App == 0x1335BAB8 ) //BattleField 1 + #define DA_W 1 + #define DA_Y 8.125 + #define DA_X 0.04 + #define DB_Y 5 + #define RE 2 +#elif (App == 0xA0762A98 ) //Assassin's Creed Unity + #define DA_W 1 + #define DA_Y 25.0 + #define DA_Z 0.00025 + #define DA_X 0.04375 + #define DB_Z 0.2 +#elif (App == 0xC990B77C ) //Assassin's Origins + #define DA_W 1 + #define DA_Y 50.0 + #define DA_X 0.0475 + #define DB_Y 1 + #define DE_X 2 + #define DE_Y 0.4 + #define DE_Z 0.375 + #define DB_Z 0.1 +#elif (App == 0xBF222C03 ) //Among The Sleep + #define DA_X 0.05 + #define DA_Y 15.0 + #define DA_Z 0.0005 + #define DB_Y 4 + #define DB_X 1 + #define ID 1 +#elif (App == 0xB75F3C89 ) //Amnesia: The Dark Descent + #define DA_X 0.05 + #define DA_Y 45.0 + #define DA_Z 0.0005 + #define DB_Y 3 +#elif (App == 0x91FF5778 ) //Amnesia: Machine for Pigs + #define DA_X 0.05 + #define DA_Y 45.0 + #define DA_Z 0.0005 + #define DB_Y 3 +#elif (App == 0x8B0F15E7 ) //Alan Wake + #define DA_X 0.03 + #define DA_Y 32.5 + #define DB_Y 1 + #define RH 1 +#elif (App == 0xCFE885A2 ) //Alan Wake's American Nightmare + #define DA_X 0.03 + #define DA_Y 32.5 + #define DB_Y 1 + #define RH 1 +#elif (App == 0x56D8243B ) //Agony Unrated + #define DA_W 1 + #define DA_X 0.04375 + #define DA_Y 43.75 + #define DB_Y 5 + #define RH 1 +#elif (App == 0x23D5135F ) //Alien Isolation + #define DA_X 0.07 + #define DF_Y 0.0125 + #define DA_Y 22.5 // or 23.0 + #define DA_Z 0.0005 + #define DB_Y 2 + #define DE_X 2 + #define DE_Y 0.7 + #define DE_Z 0.375 + #define DG_Z 0.0325 + #define DE_W 0.1 + #define DC 1 + #define DC_X 0.22 + #define DC_Y -0.1 + #define DC_W -0.022 + #define RH 1 + #define PE 1 +#elif (App == 0x5839915F ) //35MM + #define DA_Y 35.00 + #define DB_X 1 + #define DB_Y 2 + #define RH 1 +#elif (App == 0x578862 ) //Condemned Criminal Origins + #define DA_Y 162.5 + #define DA_Z 0.00025 + #define DA_X 0.040 + #define DB_Y 4 + #define DB_W 49 + #define RH 1 +#elif (App == 0xA67FA4BC ) //Outlast + #define DA_Y 30.0 + #define DA_Z 0.0004 + #define DA_X 0.043750 + #define DB_Y 5 + #define RH 1 +#elif (App == 0xDCC7F877 ) //Outlast II + #define DA_W 1 + #define DA_Y 50.0 + #define DA_Z 0.0004 + #define DA_X 0.056250 + #define DB_Y 4 + #define RH 1 +#elif (App == 0x60F43F45 ) //Resident Evil 7 + #define DA_W 1 + #define DA_Y 30.0 + #define DA_Z 0.0002 + #define DA_X 0.0625 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DC 1 + #define DC_X 0.24 + #define DC_Y 0.1 + #define DC_Z -0.024 + #define DC_W -0.05 + #define RH 1 +#elif (App == 0x1B8B9F54 ) //TheEvilWithin + #define DA_Y 40.0 + #define DA_Z 0.0001 + #define DA_X 0.1 + #define DB_Y 4 +#elif (App == 0x7D9B7A37 ) //TheEvilWithin II + #define DA_Y 30.0 + #define DA_Z 0.0001 + #define DA_X 0.04 + #define DB_Y 5 +#elif (App == 0xBF49B12E ) //Vampyr + #define DA_W 1 + #define DA_Y 23.0 + #define DA_X 0.05 + #define DB_Y 5 +#elif (App == 0x85F0A0FF ) //LUST for Darkness + #define DA_W 1 + #define DB_X 1 + #define DA_Y 13.75 + #define DA_Z 0.001 + #define DA_X 0.04 + #define DB_Y 4 + #define DB_Z 0.125 + #define RH 1 +#elif (App == 0x706C8618 ) //Layer of Fear + #define DB_X 1 + #define DA_Y 17.50 + #define DA_X 0.035 + #define DB_Y 5 + #define RH 1 +#elif (App == 0x2F0BD376 ) //Minecraft / BuildGDX + #define DA_Y 22.5 + #define DA_X 0.0625 + #define DB_W 25 + #define DB_Y 3 + #define DE_X 4 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DF_Y 0.005 + #define RH 1 +#elif (App == 0x84D341E3 || App == 0x15A08799) //Little Nightmares & Little Nightmares II + #define DA_W 1 + #define DA_Y 33.75 + #define DA_X 0.25 + #define DF_Y 0.125 + #define DA_Z 0.0015 + #define DB_Y 5 //ZPD Boundary Scaling + #define DB_Z 0.325 //Auto Depth Adjust + #define PE 1 +#elif (App == 0xC0AC5174 ) //Observer + #define DA_W 1 + #define DA_Y 20.0 + #define DA_X 0.05 + #define DF_Y 0.01 + #define DA_Z 0.0005 + #define DB_Y 5 //Fall Back + #define DE_X 2 + #define DE_Y 0.275 + #define DE_Z 0.400 + #define DG_W 0.1875 // Slight adjustment to the ZPD Boundary + #define BM 1 // Had to use this mode since Auto Mode was not cutting it. + #define DG_X 0.1 + #define RH 1 + #define PE 1 +#elif (App == 0xABAA2255 ) //The Forest + #define DA_W 1 + #define DB_X 1 + #define DA_Y 7.5 + #define DA_X 0.04375 + #define DB_Y 3 + #define RH 1 +#elif (App == 0x67A4A23A ) //Crash Bandicoot N.Saine Trilogy + #define DA_Y 7.5 + #define DF_Y 0.0625 + #define DA_Z -0.250 + #define DA_X 0.1 + #define DB_Y 4 + #define DF_W 0.580 + #define HM 1 +#elif (App == 0xE160AE14 ) //Spyro Reignited Trilogy + #define DA_W 1 + #define DA_Y 12.5 + #define DA_Z 0.0001 + #define DA_X 0.05625 + #define DB_Y 3 +#elif (App == 0x5833F81C ) //Dying Light + #define DA_W 1 + #define DF_Y 0.045 + #define DA_X 0.05 + #define DA_Y 17.5 + #define DA_Z -0.5 + #define DB_Y 4 + #define NW 1 + #define PE 1 + #define FV 1 + #define DG_Z 0.070 //Min + #define DE_W 0.100 //Max + //#define DB_W 62 +#elif (App == 0x42C1A2B ) //CoD: WWII + #define DA_X 0.04 + #define DA_W 1 + #define DB_Y 4 + #define DB_W 12 +#elif (App == 0x86562CC2 ) //STARWARS Jedi Fallen Order + #define DA_X 0.140 + #define DA_W 1 + #define DA_Y 13.75 + #define DA_Z 0.00025 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.1875 + #define DE_Z 0.475 + #define DB_Z 0.375 + #define RH 1 + #define NF 1 +#elif (App == 0x88004DC9 || App == 0x1DDA9341) //Strange Brigade DX12 & Vulkan + #define DA_X 0.0625 + #define DF_Y 0.02 + #define DA_Y 20.0 + #define DA_Z 0.0001 + #define DB_Y 5 + #define DE_X 2 + #define DE_Y 0.3 + #define DE_Z 0.475 + #define RH 1 +#elif (App == 0xC0052CC4) //Halo The Master Chief Collection + #define DA_X 0.037 + #define DA_W 1 + #define DA_Y 75.0 + #define DB_Y 5 + #define DE_X 3 + #define DE_Y 0.375 + #define DE_Z 0.375 + #define WSM 3 + #define OW_WP "Read Help & Change Me\0Custom WP\0Halo: Reach\0Halo: CE Anniversary\0Halo 2: Anniversary\0Halo 3\0Halo 3: ODST\0Halo 4\0" + #define RH 1 +#elif (App == 0x2AB9ECF9) //System ReShock + #define DA_X 0.05 + #define DA_W 1 + #define DA_Y 11.25 + #define DA_Z 0.00125 + #define DB_Y 4 + #define DE_X 4 + #define DE_Y 0.4375 + #define DE_Z 0.375 + #define DE_W 0.055 +#elif (App == 0xC50993EC) //COD: Modern Warfare 2019 + #define DA_X 0.0375 + #define DA_W 1 + #define DA_Y 37.5 + #define DA_Z 0.000125 + #define DB_Y 5 + #define DB_W 12 + #define RH 1 +#elif (App == 0xA640659C) //MegaMan 2.5D in 3D + #define DA_X 0.150 + #define DA_Y 8.75 + #define DA_Z -1005.0 + #define DE_X 1 + #define DE_Y 0.275 + #define DE_Z 0.375 + #define RH 1 +#elif (App == 0x49654776) //Paratopic + #define DA_X 0.05 + #define DA_W 1 + #define DA_Y 8.75 + #define DA_Z 0.000250 + #define DB_Y 3 + #define DB_X 1 + #define RH 1 +#elif (App == 0xF7590C95) //Yume Nikki -Dream Diary- + #define DA_X 0.0625 + #define DA_W 1 + #define DA_Y 20.0 + #define DA_Z 0.002 + #define DB_X 1 + #define DB_Y 1 + #define DE_X 1 + #define DE_Y 0.35 + #define DE_Z 0.25 + #define NC 1 + #define RH 1 +#elif (App == 0x65F37CDF) //American Truck Simulator + #define DA_X 0.05375 + #define DA_Y 15.0 + #define DA_Z 0.005 + #define DB_X 1 + #define DB_Y 2 + #define DB_W 47 +#elif (App == 0xB5789234) //The Park + #define DA_X 0.05625 + #define DA_W 1 + #define DA_Y 12.5 + #define DB_Y 1 + #define RH 1 +#elif (App == 0xB7C22840) //Strife + #define DA_X 0.1 + #define DA_Y 250.0 + #define DB_W 59 + #define RH 1 +#elif (App == 0x21DC397E || App == 0x653AF1E1) //Gold Source + #define DA_X 0.045 + #define DA_Y 21.25 + #define DA_Z 0.0003 + #define DB_Y 3 + #define DB_W 60 +#elif (App == 0xC2E621A5) //No Man Sky + #define DA_X 0.04375 + #define DA_W 1 + #define DA_Y 72.5 + #define DB_Y 5 + #define DB_Z 0.0 + #define DE_X 1 + #define DE_Y 0.375 + #define DE_Z 0.4 + #define RH 1 +#elif (App == 0x1E9DCD00) //Witch it + #define DA_X 0.0475 + #define DA_W 1 + #define DA_Y 47.5 + #define DB_Y 5 + #define DE_W 0.325 +#elif (App == 0x6B58D180) //Outlaws + #define DA_X 0.14375 + #define DA_Y 30 + #define DB_Y 5 + #define DB_Z 0.225 +#elif (App == 0x5AC0F7E3) //SoF + #define DA_X 0.04375 + #define DA_Y 17.5 + #define DB_Y 5 + #define DB_W 22 + #define DF_X 0.5 +#elif (App == 0xEA8E05B6) //Only If + #define DA_X 0.100 + #define DB_Y 1 + #define DE_X 1 +#elif (App == 0xFDE0387 ) //Stranger Odd Worlds + #define DA_X 0.100 + #define DA_Y 7.5 + #define DB_X 1 + #define DB_Y 1 + #define DE_X 2 + #define DF_W 0.5 + #define HM 1 +#elif (App == 0x242D82C4 ) //Okami HD + #define DA_X 0.200 + #define DA_W 1 + #define DA_Z 0.001 + #define DB_Y 1 + #define DE_X 2 + #define DE_Y 0.125 + #define DE_Z 0.375 + #define DF_W 0.5 + #define HM 1 +#elif (App == 0x75B36B20 ) //Eldritch + #define DA_Y 125.0 + #define DA_X 0.05 + #define DB_Y 4 + #define DE_X 1 + #define DB_Z 0.05 +#elif (App == 0x97CBF34C ) //Dementium 2 + #define DA_Y 18.75 + #define DA_X 0.04125 + #define DB_Y 5 + #define DB_W 51 + #define DB_X 1 + #define RH 1 +#elif (App == 0x5925FCC8 ) //Dusk + #define DA_Y 25.0 + #define DA_X 0.05 + #define DB_Y 5 + #define DA_W 1 + #define DB_X 1 + #define DE_X 3 + #define DE_Z 0.375 +#elif (App == 0xDDA80A38 ) //Deus Ex Rev DX9 + #define DA_X 0.04375 + #define DA_Y 20 + #define DB_Y 3 + #define DB_W 23 + #define DF_W 0.534 + #define HM 1 + #define DF_X 0.025 +#elif (App == 0x1714C977) //Deus Ex DX9 + #define DA_X 0.05 + #define DA_Y 125.0 + #define DB_Y 3 + #define DB_W 24 + #define DF_W 1.0 + #define HM 1 + #define DF_X 0.05 +#elif (App == 0x92583CDD ) //Legend of Dungeon + #define DA_Y 12.5 + #define DA_Z 0.185 + #define DA_X 0.075 + #define DB_Y 4 + #define DB_X 1 +#elif (App == 0xDB3A28BD ) //Monster Hunter World + #define DA_Y 17.5 + #define DA_X 0.075 + #define DA_W 1 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.300 + #define DE_Z 0.4375 + #define NW 1 +#elif (App == 0xC073C2BB ) //StreetFighter V + #define DA_Y 14.0 + #define DA_X 0.250 + #define DA_W 1 + #define DB_Y 4 + #define DB_Z 0.550 + #define DE_X 1 + #define DE_Y 0.375 + #define DE_Z 0.375 +#elif (App == 0xCFB8DD02 ) //DIRT RALLY 2.0 + #define DA_Y 11.25 + #define DA_X 0.040 + #define DE_W 0.350 +#elif (App == 0x2F55D5A3 || App == 0x4A5220AF ) //ShadowWarrior 2013 DX11 & DX9 + #define DA_X 0.035 + #define DB_Y 4 + #define DE_X 4 + #define DE_Z 0.375 +#elif (App == 0x56301DED ) //ShadowWarrior 2 + #define DA_X 0.035 + #define DA_W 1 + #define DB_Y 4 + #define DE_X 4 + #define DE_Z 0.375 + #define NW 1 +#elif (App == 0x892CA092 ) //Farcry + #define DA_Y 7.0 + #define DA_Z 0.000375 + #define DB_Z 0.105 + #define DA_X 0.055 + #define DB_Y 4 + #define DB_W 63 + #define DF_X 0.13875 +#elif (App == 0x9140DBE0 ) //Farcry 2 + #define DA_X 0.05 + #define DB_Y 4 + #define DB_W 64 + #define DE_X 4 + #define DE_Z 0.375 + #define RH 1 +#elif (App == 0xA4B66433 ) //Farcry 3 + #define DA_X 0.05 + #define DB_Y 4 + #define DE_X 4 + #define DE_Z 0.375 + #define DE_W 0.350 + #define RH 1 +#elif (App == 0xC150B652 ) //Farcry 4 + #define DA_Y 8.75 + #define DA_W 1 + #define DA_X 0.0375 + #define DB_Y 4 + #define DE_X 4 + #define DE_Z 0.375 + #define DE_W 0.360 +#elif (App == 0x2EB82B07 ) //Farcry Primal + #define DA_Y 8.75 + #define DA_W 1 + #define DA_X 0.0375 + #define DB_Y 4 + #define DE_X 4 + #define DE_Z 0.375 + #define DE_W 0.360 +#elif (App == 0xC150B805 ) //Farcry 5 + #define DA_Y 8.75 + #define DA_W 1 + #define DA_X 0.0375 + #define DB_Y 4 + #define DE_X 4 + #define DE_Z 0.375 + #define DE_W 0.360 + #define RH 1 +#elif (App == 0xE3AD2F05 ) //Sauerbraten + #define DA_Y 25.0 + #define DA_X 0.05 + #define DB_Y 5 + #define DB_W 73 + #define DF_X 0.150 +#elif (App == 0xF0F2CF6A ) //Dragon Ball Z: Kakarot + #define DA_W 1 + #define DA_Y 24.0 + #define DA_X 0.250 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.375 + #define DE_Z 0.400 + #define DB_Z 0.500 //Yay I know +#elif (App == 0xFA2C0106 ) //Hat in Time + #define DA_X 0.125 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.162 + #define DE_Z 0.4375 + #define RH 1 +#elif (App == 0xCD0E316F ) //Sonic Adventure DX Modded with BetterSADX + #define DA_Y 8.75 + #define DA_X 0.1125 + #define DB_Y 3 + #define DE_X 2 + #define DE_Y 0.375 + #define DE_Z 0.4375 + #define DB_Z 0.250 + #define RH 1 +#elif (App == 0xF9B1845A ) //Rime + #define DA_W 1 + #define DA_Y 15.0 + #define DA_X 0.145 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.299 + #define DE_Z 0.400 +#elif (App == 0x71170B42 ) //Blood: Fresh Suppy + #define DA_Y 212.5 + #define DA_X 0.175 + #define BM 1 + #define DG_X 0.275 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.375 + #define DE_Z 0.375 + #define DG_W 0.25 + #define DS 1 +#elif (App == 0x8F615A99 ) //Frostpunk + #define DA_Y 9.375 + #define DA_X 0.250 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.400 +#elif (App == 0x29B47A0A ) //KingMaker + #define DB_X 1 + #define DA_W 1 + #define DA_Y 18.75 + #define DA_Z 0.0075 + #define DA_X 0.150 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.300 +#elif (App == 0xBF70711C ) //Singularity + #define DA_Y 15.0 + #define DA_X 0.0375 + #define DB_W 66 + #define DE_X 1 + #define DE_Z 0.375 + #define DF_X 0.175 + #define RH 1 +#elif (App == 0x905631F2 ) //Crysis DX10 64bit + #define DA_X 0.0375 + #define DB_Y 5 + #define DB_W 44 + #define DE_X 3 + #define DE_Z 0.375 + #define DF_X -0.175 +#elif (App == 0x6061750E ) //Mirror's Edge + #define DA_Y 12.25 + #define DF_Y 0.020 + #define DA_X 0.040 + #define DB_Y 5 + #define DB_Z 0.01 + #define DE_X 1 + #define DE_Y 0.50 + #define DE_Z 0.375 + #define DB_W 70 + #define DS 1 +#elif (App == 0xC3AF1228 || App == 0x95A994C8 ) //Spellforce + #define DA_Y 145.0 + #define DA_Z 0.001 + #define DB_Z 0.05 + #define DA_X 0.05 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.235 + #define DE_Z 0.375 + #define HM 1 + #define DF_W 0.5 +#elif (App == 0xD372612E ) //Raft + #define DA_W 1 + #define DB_X 1 + #define DA_X 0.04375 + #define DB_Y 4 + #define NW 1 +#elif (App == 0xC06FE818 ) //BorderLands 3 + #define DA_Y 18.0 + #define DA_Z 0.0001375 + #define DA_X 0.04 + #define DB_Z 0.05 + #define DA_W 1 + #define DB_Y 4 + #define DB_W 5 + #define DE_X 4 + #define DE_Y 0.425 + #define DE_Z 0.300 + #define DF_X 0.085 + #define NW 1 + #define DA 1 + #elif (App == 0x3C8DE8E8 ) //Metro Exodus + #define DA_Y 12.5 // What A mess + //#define DA_X 0.05 + #define DA_Z 0.000375 + #define DA_W 1 + #define DB_Y 4 + //#define DE_W 0.08 + #define DE_W 0.0275 +#elif (App == 0x7FC671B6 ) //Doom Eternal + #define DA_Y 50.0 + #define DA_Z 0.00009375 + #define DA_W 1 + #define DB_Y 3 + #define DE_X 4 + #define DE_Y 0.550 + #define DE_Z 0.333 + #define DB_W 68 + //#define DG_Z 0.080 //Min + #define DE_W 0.125 //Max + //#define DE_W 0.09375 + #define DA_X 0.03125 + #define DF_Y 0.03125 + //#define DA_X 0.0375 //Alternet settings Not used. + #define PE 1 +#elif (App == 0x47F294E9 ) //Octopath Traveler + #define DA_Y 250.0 + #define DA_Z 0.000375 + #define DA_X 0.1175 + #define DA_W 1 + #define DB_Y 2 + #define DE_X 1 + #define DE_Y 0.5625 + #define DE_Z 0.375 + #define DG_W 0.2125 + #define RH 1 +#elif (App == 0x21CB998 ) //.Hack//G.U. + #define DA_Y 22.5 + #define DA_X 0.125 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.3 + #define RH 1 + #define NF 1 +#elif (App == 0x9CC5C8E0 ) //GTA V + #define DA_Y 18.75 + #define DA_W 1 + #define DA_X 0.0475 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.325 + #define DE_Z 0.375 + #define DB_Z 0.05 + #define RH 1 + #define PE 1 + #define NF 1 +#elif (App == 0x8CD23575 ) //Dark Souls: Remastered + #define DA_Y 75.0 + //#define DA_Z 0.001 + #define DA_X 0.05625 + #define DF_Y 0.05 + #define DB_Y 2 + #define DE_X 2 + #define DE_Y 0.250 + #define DE_Z 0.375 + //#define DE_W 0.0625 + #define PE 1 + #define FV 1 +#elif (App == 0x9E071BC0 ) //Dark Souls III + #define DA_Y 25.0 + #define DA_Z 0.000125 + #define DA_X 0.1 + #define DF_Y 0.05625 + #define DB_Y 3 + #define DE_X 2 + #define DE_Y 0.5000 + #define DE_Z 0.4375 + #define DG_Z 0.1125 //Min + //#define DE_W 0.225 + #define PE 1 + #define FV 1 +#elif (App == 0x5D4939C9 ) //Dark Souls II + #define DA_Y 22.5 + #define DA_Z 0.00025 + #define DA_X 0.110 + #define DB_Y 3 + #define DE_X 2 + #define DE_Y 0.50 + #define DE_Z 0.40 + #define DE_W 0.1 +#elif (App == 0xFB111509 ) //Dark Souls II Scholar of the First Sin + #define DA_Y 68.75 + #define DA_X 0.05 + #define DF_Y 0.05 + #define DB_Y 2 + #define DE_X 2 + #define DE_Y 0.250 + #define DE_Z 0.375 + #define DG_Z 0.025 //Min + //#define DE_W 0.125 //Max + #define PE 1 + #define FV 1 +#elif (App == 0xCE5313C2 ) //BorderLands Enhanced + #define DA_Y 18.75 + #define DA_Z 0.0005 + #define DA_X 0.055 + #define DF_Y 0.02 + #define DB_Z 0.075 + #define DB_Y 1 + #define DB_W 3 + #define DE_X 3 + #define DE_Y 0.425 + #define DE_Z 0.375 + #define DG_Z 0.3975 + #define DF_X 0.225 + #define NW 1 +#elif (App == 0x2ECAAF29 || App == 0xE19E4830 || App == 0xE19E4830 ) //Half-Life 2 | Left 4 Dead 2 + #define DA_Y 8.75 + #define DA_X 0.04 + #define DB_Z 0.115 + #define DB_Y 3 + #define DB_W 20 + #define DE_X 4 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DF_X 0.105 + #define RH 1 +#elif (App == 0x68EF1B4E || App == 0xC103D998 ) //Serious Sam Fusion | Serious Sam 4: Planet Badass + #define DA_W 1 + #define DA_X 0.075 + #define DA_Y 10.0 + #define DA_Z 0.1 + #define DB_Y 1 + #define DB_W 42 + #define DE_X 4 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DB_Z 0.150 + #define NW 1 + #define RH 1 + #define PE 1 +#elif (App == 0xEACB4D0D ) //Final Fantasy XV Windows Edition + #define DA_X 0.0375 + #define DA_Y 30.0 + #define DB_Y 3 + #define DE_X 2 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define RH 1 +#elif (App == 0xAC4DF2C4 ) //Mafia II Definitive Edition + #define DA_X 0.05 + #define DA_Y 37.5 + #define DA_Z 0.0007 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DF 1 + #define RH 1 +#elif (App == 0xEA75DEDE ) //Lost Planet Colonies + #define DA_X 0.05 + #define DA_Y 37.5 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define RH 1 +#elif (App == 0xEFC486AF ) //Lost Planet 2 DX11 + #define DA_X 0.04375 + #define DA_Y 37.5 + #define DA_Z 0.001 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.5 + #define DE_Z 0.375 +#elif (App == 0x97937D77 ) //Lost Planet 3 Dx9 + #define DA_X 0.05 + #define DA_Y 20.0 + #define DA_Z 0.001 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.5 + #define DE_Z 0.375 + //#define DE_W 0.3875 + #define RH 1 +#elif (App == 0x9896B9F5 ) //Old City: Leviathan + #define DA_X 0.030 + #define DA_Y 82.5 + #define DA_Z 0.0015 + #define DB_Y 4 + #define DE_X 1 + //#define DE_Y 0.250 + #define DE_Z 0.375 + #define DB_Z 0.075 + //#define DG_Z 0.5 + #define DS 1 +#elif (App == 0xE4F6014F ) //Shovel Knight + #define DB_X 1 + #define DA_X 0.035 + #define DA_Y 22.5 + #define DA_Z 0.483 + #define RH 1 +#elif (App == 0x94EFD213 ) //Chex Quest HD + #define DA_W 1 + #define DA_X 0.1 + #define DA_Y 112.5 + #define DA_Z 0.0000125 + #define DB_Y 4 + #define DE_X 3 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DB_Z 0.125 + #define DB_W 74 +#elif (App == 0xF6F3C763 ) //WRATH + #define DA_X 0.065 + #define DA_Y 75.0 + #define DA_Z 0.00005 + #define DB_Y 2 + #define DE_X 3 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DB_Z 0.090 + #define DB_W 29 + #define DF_X 0.1 +#elif (App == 0xB05C57BC ) //HellBound + #define DA_W 1 + #define DA_X 0.0325 + #define DA_Y 25.0 + #define DB_Y 5 + #define DE_W 0.025 +#elif (App == 0x9FC060AE ) //STRIFE: Gold Edition + #define DA_X 0.0375 + #define DA_Y 23.75 + #define DA_Z 0.00025 + #define DB_X 1 + #define DB_Y 4 + #define NC 1 +#elif (App == 0x6DDCD106 ) //The Town of Light + #define DA_X 0.100 + #define DA_Y 10.0 + #define DB_X 1 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 +#elif (App == 0x6367B705 ) //Transference + #define DA_W 1 + #define DA_X 0.09375 + #define DA_Y 111.0 + #define DA_Z 0.00025 + #define DB_X 1 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DB_Z 0.05 + #define DE_W 0.05625 +#elif (App == 0x38ED56AE ) //Heavy Rain + #define DA_X 0.0325 + #define DA_Y 50.0 + //#define DA_Z 0.001 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DB_Z 0.0675 + #define NC 1 +#elif (App == 0x2F1ABF4A ) //Detroit Become Human + #define DA_W 1 + #define DB_X 1 + #define DA_X 0.0375 + #define DA_Y 50.0 + //#define DA_Z 0.001 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 +#elif (App == 0x9DA6C947 ) //Beyond Two Souls + #define DA_X 0.0625 + #define DF_Y 0.0275 + #define DA_Y 20.00 + #define DB_Y 3 + #define DE_X 1 + //#define DE_Y 0.5 + #define DE_Z 0.375 + #define DG_W 0.175 + //#define BM 1 + //#define DG_X 0.1375 + #define DS 1 + #define LBC 1 +#elif (App == 0x89351FC4 ) //3DSen Games + #define DA_W 1 + #define DB_X 1 + #define DA_X 0.1 + #define DA_Y 375.0 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.250 + #define DF 1 +#elif (App == 0xF55F26A1 ) //Tekken 7 + #define DA_W 1 + #define DF_Y 0.025 + #define DA_Y 100.0 + #define DA_Z 0.0001 + #define DB_Y 1 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DE_W 0.440 + #define DA 1 +#elif (App == 0x9BD7A4FD ) //Starwars Battle Front II + #define DA_W 1 + #define DA_X 0.05 + #define DA_Y 10.0 + #define DB_Y 3 + #define DE_X 2 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DE_W 0.075 +#elif (App == 0x14E41902 ) //jsHexen II + #define RH 1 + #define NF 1 + #define DA_X 0.06 + #define DA_Y 17.5 + #define DA_Z 0.0003 + #define DB_Y 4 + #define DB_W 22 +#elif (App == 0x12C96DB0 ) //Hexen 2 Hammer of Thyrion + #define RH 1 + #define NF 1 + #define DA_X 0.06 + #define DA_Y 17.5 + #define DA_Z 0.0003 + #define DB_Y 4 + #define DB_W 22 +#elif (App == 0x54A39BDC ) //Hexen 2 FTEQW 64 + #define DA_X 0.06 + #define DA_Y 30.0 + #define DA_Z 0.0003 + #define DB_Y 4 + #define DB_W 75 +#elif (App == 0x6281C1AC ) //DarkSiders Warmastered Edition + #define DA_X 0.05 + #define DA_Y 30.0 + #define DB_Y 3 + #define DE_X 2 + #define DE_Y 0.5 + #define DE_Z 0.375 +#elif (App == 0x763E5FA5 ) //DarkSiders 2 Depthinitve Edition + #define DA_X 0.05 + #define DA_Y 15.0 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.65 + #define DE_Z 0.375 + #define DB_Z 0.025 +#elif (App == 0x7F1A5568 ) //DarkSiders III + #define DA_W 1 + #define DA_X 0.0625 + #define DA_Y 50.0 + #define DA_Z 0.0001 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.250 + #define DE_Z 0.4 + #define DG_Z 0.450 + #define DG_W 0.125 +#elif (App == 0xB4C116F7 ) //Nioh + #define DA_W 1 + #define DA_X 0.1 + #define DA_Y 162.5 + #define DA_Z 0.000125 + #define DB_Z 0.200 + #define DB_Y 1 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.4 + #define DE_W 0.05 +#elif (App == 0xD30783B6 ) //X-Com + #define DA_X 0.03 + #define DA_Y 200.0 + #define DA_Z 0.000125 + #define DB_Z 0.050 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DE_W 0.025 + #define DS 1 +#elif (App == 0xBF53A67A ) //The Bureau: XCOM Declassified + #define DA_X 0.04375 + #define DA_Y 29.0 + #define DA_Z 0.0003 + #define DB_Y 2 + #define DE_X 2 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DS 1 +#elif (App == 0x1764D88A ) //X-Com 2 + #define DA_X 0.24 + #define DA_Y 29.0 + #define DA_Z 0.0001 + #define DB_Z 0.130 + #define DB_Y 3 + #define DE_X 2 + #define DE_Y 0.25 + #define DE_Z 0.375 + #define DE_W 0.075 +#elif (App == 0xC60A845F ) //My Friend Pedro + #define DB_X 1 + #define DA_W 1 + #define DA_X 0.075 + #define DA_Y 50.0 + #define DA_Z 0.000375 + #define DB_Y 4 + #define DB_Z 0.13 +#elif (App == 0xD45ACB4B ) //Murdered Soul Suspect + #define DA_X 0.05 + #define DA_Y 37.5 + #define DA_Z 0.001 + #define DB_Y 1 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DS 1 +#elif (App == 0x4FF5CF63 ) //Lords of the Fallen + #define DA_X 0.049 + #define DA_Y 70.0 + #define DA_Z 0.001 + #define DB_Y 2 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DE_W 0.415 + #define PE 1 +#elif (App == 0xD0AA19 ) //The Bards Tale 4 + #define DA_W 1 + #define DA_X 0.0375 + #define DA_Y 20.0 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DA 1 + #define PE 1 + #define RH 1 +#elif (App == 0x54D4EAFA) //Sekiro Shadows Die Twice + #define DA_W 1 + #define DF_Y 0.025 + #define DA_X 0.10 + #define DA_Y 31.25 + #define DA_Z -0.0525 + #define DG_W 0.25 //Pop out + //#define DB_Z 0.125 + #define DB_Y 1 + #define DE_X 2 + #define DE_Y 0.275 + #define DE_Z 0.375 + // #define DF_Z -0.125 + #define DA 1 + #define PE 1 +#elif (App == 0x36ECE27F ) //Supraland + #define DA_W 1 + #define DA_Y 22.5 + #define DB_Y 2 + #define DE_X 2 + #define DE_Y 0.8 + #define DE_Z 0.375 + #define PE 1 + #define DA 1 +#elif (App == 0x3604DCE6 ) //Remnant: From the Ashes + #define DA_W 1 + #define DA_X 0.07 + //#define DF_Y 0.038 + #define DA_Y 16.25 + #define DB_Y 2 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DA_Z -0.050 + //#define DF_Z -0.125 + //#define BM 1 + //#define DG_X 0.1 + #define NW 1 + #define PE 1 +#elif (App == 0x621202BC ) //Vanquish DGVoodoo2 + #define DA_X 0.05 + #define DA_Y 15.0 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define RH 1 + #define NF 1 + #define PE 1 +#elif (App == 0xA1214CD1 ) //Life is Strange + #define DA_X 0.125 + #define DA_Y 8.0 + #define DA_Z 0.0005 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define PE 1 + #define DS 1 + #define DA 1 +#elif (App == 0x913AD2D ) //SpaceHulk DeathWing Enhanced Edition + #define DA_W 1 + #define DA_X 0.05 + #define DA_Y 7.5 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DE_W 0.065 + #define PE 1 + #define NW 1 +#elif (App == 0xEB5CDE17 ) //Man Of Medan + #define DA_W 1 + #define DA_X 0.04375 + #define DA_Y 20.0 + #define DB_Z 0.3 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.300 + #define DE_Z 0.300 + #define LBM 1 + #define RH 1 + #define NW 1 + #define SP 1 + #define DD_W -0.240 +#elif (App == 0x62454263 ) //Red Dead Redemption 2 + #define DA_W 1 + #define DA_X 0.05 + #define DF_Y 0.11875 + #define DA_Y 35.5 + #define DB_Y 2 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define PE 1 + #define DA 1 + #define LBM 2 +#elif (App == 0xB5AE6CBA ) //Rage 2 + #define DA_W 1 + #define DA_X 0.04 + #define DA_Y 125.0 + #define DB_Y 2 + #define DE_W 0.06 + #define PE 1 + #define DA 1 +#elif (App == 0x8CEACA5C ) //Dead Island + #define DA_X 0.0475 + #define DA_Y 8.75 + #define DB_Y 2 + #define DF_Y 0.0875 +#elif (App == 0xBE9001DC ) //Dead Island DE + #define DA_W 1 + #define DA_X 0.0475 + #define DA_Y 8.75 + #define DB_Y 2 + #define DF_Y 0.0875 +#elif (App == 0xCDD5E6CF ) //Legend of Grimrock + #define DA_X 0.120 + #define DF_Y 0.135 + #define DA_Y 12.5 + #define DB_Y 3 +#elif (App == 0x7C0F0E77 ) //Soulcaliber VI + #define DA_W 1 + #define DA_X 0.070 + #define DA_Y 70.0 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.300 + #define DE_Z 0.375 + #define PE 1 + #define NW 1 +#elif (App == 0x424052D0 ) //Talos Principle + #define DA_W 1 + #define DA_X 0.10 + #define DF_Y 0.05 + #define DA_Y 20.5 + #define DA_Z 0.100 + #define DB_Z 0.200 + #define DB_Y 1 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DB_W 65 + #define DA 1 +#elif (App == 0x6EC76A83 ) //Watch Dogs 2 + #define DA_W 1 + #define DA_X 0.070 + #define DA_Y 12.0 + #define DB_Y 1 + #define DE_X 2 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define PE 1 + #define DA 1 +#elif (App == 0xD9691F81 ) //Destroy All Humans! + #define DA_W 1 + #define DA_X 0.050 + #define DA_Y 66.0 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DF_Y 0.025 + #define NF 1 + #define PE 1 + #define RH 1 +#elif (App == 0x9C5C8E4D ) //INSIDE + #define DA_X 0.050 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DC 1 + #define DC_X 0.6 + #define DC_Y -0.4 + #define DC_Z 0.087 + #define DC_W -0.03 + #define DB_X 1 +#elif (App == 0xABADF9C2 ) //Sonic Robo Blast 2 + #define DA_X 0.1 + #define DA_Y 27.5 + #define DB_Z 0.155 + #define DB_Y 2 + #define DF_Y 0.1 +#elif (App == 0x3867F04A ) //Castle of Illusion + #define DA_X 0.1 + #define DA_Y 40.0 + #define DA_Z 0.0005 + #define DB_Y 1 + #define DF_Y 0.01 + #define DA 1 +#elif (App == 0x76CD4369 ) //Resident Evil + #define DA_X 0.06875 + #define DA_Y 24.0 + #define DA_Z 0.00025 + #define DB_Y 2 + #define DE_X 2 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DF_Y 0.024 + #define DA 1 + #define SP 1 + #define DD_X 1.333 + #define DD_Y 0.933 + #define LBM 4 + #define DS 1 + #define RH 1 +#elif (App == 0x1AB66F8F ) //Dawn Of War III + #define DA_X 0.125 + #define DA_Y 25.0 + #define DB_Z 0.125 + #define DA_Z 0.002 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.200 + #define DE_Z 0.375 + #define DF_Y 0.250 + #define DA 1 +#elif (App == 0xD86799B9 ) //Devil May Cry 5 + #define DA_W 1 + #define DA_X 0.0375 + #define DA_Y 40.0 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.300 + #define DE_Z 0.350 + #define DG_W 0.277 //0.5625 //I Think Erroring on the safe side is needed here. + #define DC 1 + #define DC_X 0.025 + #define DC_Y 0.025 + #define DC_W -0.012 + #define DF_Y 0.02375 + #define PE 1 + #define RH 1 +#elif (App == 0x5BC45541 ) //Contrast + #define DA_X 0.075 + #define DA_Y 20.0 + #define DB_Y 1 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DF_Y 0.051 +#elif (App == 0xEA61D579 || App == 0xCFCF902B ) //The Citadel + #define DA_W 1 + #define DA_X 0.035 + #define DA_Y 18.6 + #define DB_Y 4 + #define DF_Y 0.05625 + #define SP 1 + //#define DD_Y 0.675 + //#define DD_W -0.4815 + #define DD_Y 0.9 + #define DD_W -0.111 + #define DB_W 72 + #define DS 1 +#elif (App == 0x5C0EBBE9 ) //A Plague Tale Innocence + #define DA_W 1 + #define DA_X 0.050 + #define DF_Y 0.025 + #define DA_Y 33.00 + #define DB_Y 3 + #define DE_X 2 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define PE 1 + #define RH 1 + #define NF 1 + #define DS 1 +#elif (App == 0xB2B11A3C ) //Catherine with a K + #define DA_X 0.05 + #define DF_Y 0.0125 + #define DA_Y 50.0 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DG_W 0.4375 + #define PE 1 + #define DA 1 +#elif (App == 0x7ABE98F0 ) //Samurai Jack + #define DA_W 1 + #define DA_X 0.1375 + #define DF_Y 0.0125 + #define DA_Y 20.0 + #define DB_Y 5 + #define DE_X 2 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DA 1 +#elif (App == 0xC4B4435F ) //Night Cry + #define DA_X 0.06 //ZPD + #define DF_Y 0.025 //Separation + #define DA_Y 50.0 //Depth + #define DB_X 1 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 +#elif (App == 0x49F7B9C0 || App == 0x837F12C9 ) //Control DX12 | QuantumBreak DX11 + #define DA_X 0.05625 + #define DF_Y 0.0625 + #define DA_Y 18.75 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define PE 1 + #define DA 1 +#elif (App == 0x5A7B540A ) //We Where Here Too + #define DA_W 1 + #define DB_X 1 + #define DA_X 0.05625 + #define DA_Y 42.5 + #define DB_Y 1 + #define NW 1 +#elif (App == 0x6AB553A ) //We Where here Together + #define DA_W 1 + #define DB_X 1 + #define DF_Y 0.05625 + #define DA_X 0.05625 + #define DA_Y 56.25 + #define DB_Y 3 + #define DE_X 3 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DB_W 30 + #define FV 1 + #define DA 1 + #define NW 1 +#elif (App == 0x75930301 ) //Void Bastards + #define DA_W 1 + #define DB_X 1 + #define DF_Y 0.02625 + #define DA_X 0.0875 + #define DA_Y 56.25 + #define DB_Y 2 + #define DE_X 1 + #define DE_Y 0.625 + #define DE_Z 0.375 + #define DS 1 + #define RH 1 +#elif (App == 0xDF3F2AB6 ) //Cloud Punk + #define DA_W 1 + #define DB_X 1 + #define DF_Y 0.1 + #define DA_X 0.0325 + #define DA_Y 72.5 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DS 1 + #define RH 1 + #define NF 1 +#elif (App == 0x4551A746 ) //The Swapper + //#define DB_X 1 + #define DF_Y 0.0125 + #define DA_X 0.05 + #define DA_Y 99.0 + #define DA_Z -0.010 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + //#define DF_Z 1.0 + //#define DD_X 0.800 + //#define DD_Y 0.705 + //#define DD_Z 0.250 + //#define DD_W 0.4125 + //#define SP 1 + #define DS 1 + #define RH 1 +#elif ( App == 0xE0B7AF16 || App == 0xB84E12B6 ) //Horizon Chase Turbo + #define DA_W 1 + #define DA_Y 12.5 + #define DA_X 0.175 + #define DF_Y 0.0625 + #define DB_Y 1 + #define DA_Z -0.125 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DS 1 +#elif (App == 0xCF0046B7 ) //SpecOps The Line + #define DA_Y 15.0 + #define DA_X 0.05 + #define DF_Y 0.01 + #define DB_Y 4 + #define DA_Z -0.00125 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DS 1 + #define PE 1 + #define FV 1 +#elif (App == 0x6C433D70 ) //Q.U.B.E 2 + #define DA_W 1 + #define DA_Y 75.0 + #define DA_X 0.05625 + #define DF_Y 0.01 + #define DB_Y 2 + #define DB_Z 0.05625 + #define DA_Z 0.00025 + #define DE_X 3 + #define DE_Y 0.450 + #define DE_Z 0.375 + #define PE 1 + #define FV 1 + #define DB_W 69 +#elif (App == 0xD87951C4 ) //Horizon Zero Dawn + //#define DA_W 1 + #define DA_Y 12.5 + #define DA_X 0.05 + //#define DF_Y 0.01 + #define DB_Y 2 + #define DB_Z 0.05 + #define DA_Z 0.0005 + #define DE_X 2 + #define DE_Y 0.3 + #define DE_Z 0.375 + #define PE 1 + #define FV 1 +#elif (App == 0xF1BFCA91 ) //ELEX + //#define DA_W 1 + //#define DA_Y 12.5 + #define DA_X 0.1 + //#define DF_Y 0.1 + #define DB_Y 2 + //#define DB_Z 0.1 + //#define DA_Z 0.0005 + #define DE_X 2 + #define DE_Y 0.500 + #define DE_Z 0.300 + #define PE 1 + #define DS 1 +#elif (App == 0x2E63D83A ) //Kingdom Come Diliverance + #define DA_W 1 + #define DA_Y 25.0 + #define DA_X 0.060 + //#define DF_Y 0.1 + #define DB_Y 1 + //#define DB_Z 0.1 + //#define DA_Z 0.0005 + #define DE_X 1 + #define DE_Y 0.500 + #define DE_Z 0.300 + #define PE 1 + #define FV 1 +#elif (App == 0xF9341C1 ) //Valheim + #define DA_W 1 + #define DB_X 1 + #define DA_Y 10.0 + #define DA_X 0.05125 + #define DF_Y 0.005 + #define DB_Y 2 + //#define DB_Z 0.125 + #define DA_Z 0.001 + #define DE_X 2 + #define DE_Y 0.500 + #define DE_Z 0.375 + #define DG_W 0.15 + #define PE 1 + #define DA 1 +#elif (App == 0x8C8F544C ) //Witcher 3 + #define DA_W 1 + //#define DB_X 1 + #define DA_Y 12.5 + #define DA_X 0.075 + #define DF_Y 0.0125 + //#define DF_Y 0.1 + #define DB_Y 4 + //#define DB_Z 0.125 + //#define DA_Z 0.0005 + #define DE_X 2 + #define DE_Y 0.500 + #define DE_Z 0.300 + #define PE 1 + #define DA 1 +#elif (App == 0xA05A15C4 ) //Spooky's House of Jump Scares + //#define DA_W 1 + //#define DB_X 1 + //#define DA_Y 12.5 + #define DA_X 0.150 + //#define DF_Y 0.1 + #define DB_Y 1 + //#define DB_Z 0.125 + //#define DA_Z 0.0005 + #define DE_X 1 + //#define DE_Y 0.500 + //#define DE_Z 0.300 + #define DS 1 + #define RH 1 + #define NF 1 + #define SP 1 + #define DD_X 0.625 + #define DD_Y 0.700 + #define DD_Z 0.600 + #define DD_W -0.425 +#elif (App == 0x483A8BD9 ) //Song of Horror + #define DA_W 1 + //#define DB_X 1 + #define DA_Y 112.5 + #define DA_X 0.1125 + #define DF_Y 0.1 + #define DB_Y 4 + //#define DB_Z 0.125 + //#define DA_Z 0.0005 + #define DE_X 2 + //#define DE_Y 0.500 + //#define DE_Z 0.300 + #define PE 1 + #define FV 1 + #define DA 1 + //#define DS 1 + //#define RH 1 + //#define NF 1 + //#define SP 1 + //#define DD_X 0.625 + //#define DD_Y 0.700 + //#define DD_Z 0.600 + //#define DD_W -0.425 +#elif (App == 0xB43B3B36 ) //Bendy and the Ink Machine + #define DA_W 1 + #define DB_X 1 + #define DA_Y 12.5 + #define DA_X 0.120 + #define DF_Y 0.025 + #define DB_Y 1 + //#define DB_Z 0.125 + //#define DA_Z 0.0005 + #define DE_X 1 + //#define DE_Y 0.500 + #define DE_Z 0.300 + #define PE 1 + #define FV 1 + //#define DA 1 + #define DS 1 + //#define RH 1 + //#define NF 1 + //#define SP 1 + //#define DD_X 0.625 + //#define DD_Y 0.700 + //#define DD_Z 0.600 + //#define DD_W -0.425 +#elif (App == 0xEFB2EF28 ) //Remothered: Tormented Fathers + #define DA_W 1 + //#define DB_X 1 + #define DA_Y 50.0 + #define DA_X 0.125 + #define DF_Y 0.050 + #define DB_Y 3 + //#define DB_Z 0.125 + #define DA_Z -1.250 + #define DE_X 2 + #define DE_Y 0.250 + #define DE_Z 0.375 + #define PE 1 + #define FV 1 + //#define DA 1 + //#define DS 1 + //#define RH 1 + //#define NF 1 + //#define SP 1 + //#define DD_X 0.625 + //#define DD_Y 0.700 + //#define DD_Z 0.600 + //#define DD_W -0.425 +#elif (App == 0x2EFA1BAF ) //Betrayer + //#define DA_W 1 + #define DA_Y 15.0 + #define DA_X 0.05 + //#define DF_Y 0.01 + #define DB_Y 4 + //#define DB_Z 0.05625 + //#define DA_Z 0.00025 + #define DE_X 3 + //#define DE_Y 0.450 + #define DE_Z 0.375 + #define PE 1 + #define FV 1 + #define DB_W 67 +#elif (App == 0x75CE6926 ) //Chronicle of Riddick Assault on Dark Athena + //#define DA_W 1 + //#define DA_Y 15.0 + //#define DA_X 0.1325 + #define DA_X 0.0666 + //#define DF_Y 0.01 + #define DB_Y 1 + //#define DB_Z 0.05625 + //#define DA_Z 0.00025 + #define DE_X 2 + //#define DE_Y 0.450 + //#define DE_Z 0.375 + #define PE 1 + #define DS 1 + #define RH 1 +#elif (App == 0xAA5644F9 || App == 0x1981FECC ) //Need For Speed: Heat | Payback + #define DA_W 1 + #define DA_Y 12.5 + #define DA_X 0.1 + #define DF_Y 0.1 + #define DB_Y 4 + //#define DB_Z 0.1 + //#define DA_Z 0.00025 + //#define DE_X 2 + //#define DE_Y 0.450 + //#define DE_Z 0.375 + #define PE 1 + #define DA 1 +#elif (App == 0xBD8B2F39 ) //Assassin's Creed Odyssey + #define DA_W 1 + #define DA_Y 30.0 + #define DA_X 0.05 + #define DF_Y 0.025 + #define DB_Y 4 + //#define DB_Z 0.125 + #define DA_Z -0.3 + #define DE_X 2 + #define DE_Y 0.250 + #define DE_Z 0.375 + #define DG_W 0.4 //Pop out allowed + #define PE 1 + #define FV 1 +#elif (App == 0x3D00A2BC ) //SM64 us f3dx2e + #define DA_Y 12.5 + #define DA_X 0.050 + #define DB_Y 4 + #define DE_X 2 +#elif (App == 0x892FCE80 ) //Star Trek EliteForce II + #define DA_Y 30.0 + #define DA_X 0.100 + #define DB_Z 0.250 + #define DB_Y 1 + #define DE_X 3 + #define DE_Z 0.375 + #define DB_W 76 +#elif (App == 0xC54A173B ) //Dead or Alive 6 + #define DA_W 1 + #define DA_Y 60.0 + #define DA_X 0.06 + #define DB_Y 5 + #define RH 1 + #define NW 1 + #define NF 1 +#elif (App == 0x934DC835 || App == 0xD063D305 || App == 0xE29F2D4 ) //Dead Rising | Dead Rising 2 | Dead Rising 2 Off The Record + #define DA_Y 25.0 + #define DA_X 0.125 + #define DB_Y 5 + #define DE_X 1 + #define DE_Z 0.375 + #define NW 1 +#elif (App == 0xF28EC9C2 || App == 0xF28EC143 ) //Dead Rising 3 | Dead Rising 4 + #define DA_Y 20.0 + #define DA_X 0.1 + #define DB_Y 5 + #define DE_X 2 + #define DE_Z 0.375 + #define RH 1 + #define NW 1 + #define NF 1 +#elif (App == 0xC402F6B8 ) //Iron Harvest + #define DA_W 1 + #define DA_Y 125.0 + #define DA_Z 0.0015 + #define DA_X 0.250 + #define DB_Y 3 + #define DE_X 1 + #define DE_Y 0.1 + #define DE_Z 0.4 + #define PE 1 + #define NW 1 + #define DA 1 +#elif (App == 0xA867FE21 ) //Senran Kagura Peach Ball + #define DA_Y 72.5 + #define DA_Z -0.0011 + #define DA_X 0.200 + #define DF_Y 0.200 + #define DB_Y 2 + #define DE_X 2 + #define DE_Y 0.075 + #define DE_Z 0.375 + #define SDT 1 + #define HM 1 + #define DF_W 0.5 +#elif (App == 0x1BDC0C4C ) //Quake Enhanced Edition + #define DA_X 0.07 + #define DA_Y 13.0 + #define DB_Y 1 + #define DE_X 3 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define NW 1 + #define PE 1 + #define DB_W 71 + #define DF_X 0.250 +#elif (App == 0xB3729F40 ) //Rocket League Steam + #define DA_Y 50.0 + #define DA_X 0.100 + #define DB_Y 5 + #define DS 1 + #define NW 1 + #define PE 1 +#elif (App == 0x1BB6E62A ) //AMIN EVIL RTX + #define DA_W 1 + #define DA_X 0.07 + #define DA_Y 12.5 + #define DA_Z 0.000125 + #define DB_Y 5 + #define DE_X 3 + #define DE_Y 0.5 + #define DE_Z 0.45 + #define PE 1 + #define DA 1 + #define DB_W 27 +#elif (App == 0xFBC55DDE ) //Tormented Shouls Demo - Add to real game if Application ID is given. + #define DA_W 1 + #define DA_Y 15.0 + #define DA_Z 0.00125 + #define DA_X 0.06125 + #define DB_X 1 + #define DB_Y 2 + #define DE_X 2 + //#define DG_Z 0.288 // This works. But, may be a bit overboard. Use this if users complain about edge pop out issues. I don't think it's needed. + #define PE 1 +#elif (App == 0x920D5D88 ) //Graven + #define DA_W 1 + #define DA_X 0.1 + #define DA_Y 50.0 + #define DA_Z 0.00005 + #define DB_Y 5 + #define DE_X 3 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define PE 1 + #define DA 1 + //#define DB_W 54 //Graven WP Not used Due to Clipping on world. Even if it looks good. Maybe Give people the option??? + #define DG_Z 0.125 +#elif (App == 0x6B2D15D6 ) //Rec Room Non VR + #define DA_W 1 + #define DA_Y 11.25 + //#define DA_Z 0.00125 + #define DA_X 0.100 + #define DF_Y 0.108 + #define DB_X 1 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.6 + #define DE_Z 0.375 + #define DG_Z 0.075 + #define NW 1 + #define DS 1 +#elif (App == 0xD0F69E54 ) //Yooka-Laylee + #define DA_Y 12.75 + #define DA_Z 0.001 + #define DA_X 0.09125 + #define DF_Y 0.00625 + #define DB_X 1 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.325 + #define DG_W 0.25 //allowed popout + //#define DE_Z 0.375 +#elif (App == 0x755C7E43 ) //Yooka-Laylee and the Impossible Lair + #define DA_W 1 + #define DA_Y 80.0 + #define DA_Z 0.00025 + #define DA_X 0.0725 + #define DF_Y 0.010 + #define DB_X 1 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.225 + #define DG_Z 0.41125 +#elif (App == 0x9FAEA815 ) //Amnesia Rebirth + #define DA_Y 15.0 + #define DA_Z 0.0002 + #define DA_X 0.100 + //#define DF_Y 0.005 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.525 + #define DE_Z 0.400 +#elif (App == 0x491EA19E ) //Cyberpunk 2077 + #define DA_W 1 + #define DA_Y 72.5 + #define DA_Z -0.00010 + #define DA_X 0.05125 + #define DB_Z 0.150 + #define DF_Y 0.05 + #define DB_Y 2 //?? Auto Mode didn't work well in this game. + #define DE_X 3 + #define DE_Y 0.500 + #define DE_Z 0.4375 + #define DB_W 34 + #define DF_X 0.20 + #define DG_W 0.08 + #define BM 1 + #define DG_X 0.130 + #define PE 1 +#elif (App == 0xB53B8500 ) //DEATH STRANDING + #define DA_W 1 + #define DA_Y 20.0 + #define DA_Z 0.000375 + #define DA_X 0.05 + //#define DB_Z 0.125 + #define DF_Y 0.01 + #define DB_Y 4 + #define DE_X 2 + #define DE_Y 0.375 + //#define DE_Z 0.375 + #define DG_Z 0.425 + #define DG_W 0.3 //Allow some popout + #define PE 1 + #define DA 1 +#elif (App == 0x87AC1510 ) //Ghostrunner + #define DA_W 1 + #define DA_Y 245.0 + #define DA_Z 0.0000025 // Magic + #define DA_X 0.050 + #define DF_Y 0.047 + #define DB_Z 0.0625 + #define DB_Y 1 + #define BM 1 + #define DG_X 0.180 + #define DE_X 3 + #define DE_Y 0.650 + #define DE_Z 0.400 + #define DB_W 43 + #define DF_X 0.1 + #define PE 1 + #define DA 1 +#elif (App == 0x11E6C55E ) //The Suicide of Rachel Foster + #define DA_W 1 + #define DA_Y 35.0 + #define DA_X 0.030 + #define DF_Y 0.020 + #define DB_Z 0.050 + #define DB_Y 5 + #define DE_X 3 + #define DE_Y 0.250 + #define DE_Z 0.425 + #define DG_Z 0.449 + #define DG_W 0.37 //Allow much popout "Please don't abuse this." + #define PE 1 + #define DA 1 + #define RH 1 + #define WSM 2 + #define DB_W 2 +#elif (App == 0xFC960068 ) //Devolverland Expo + #define DA_W 1 + #define DA_Y 30.0 + #define DA_X 0.050 + #define DB_Z 0.050 + #define DB_Y 5 + #define DE_X 3 + #define DE_Y 0.50 + #define DE_Z 0.375 + #define WSM 2 + #define DB_W 3 + #define PE 1 + #define DA 1 +#elif (App == 0x59DA13F1 ) //Conarium + #define DA_W 1 + #define DA_Y 18.75 + #define DA_X 0.0875 + #define DF_Y 0.0328125 + #define DB_Z 0.075 + #define DB_Y 3 + #define DE_X 3 + #define DE_Y 0.525 + #define DE_Z 0.400 + #define DG_Z 0.305 + #define DG_W 0.0875 //Allow much popout "Please don't abuse this." + #define PE 1 + #define DA 1 + #define RH 1 + #define WSM 2 + #define DB_W 4 + #define DF_X 0.150 +#elif (App == 0xCE21A723 ) //Bully Scholarship Edition + #define DA_Y 13.0 + #define DA_X 0.070 + #define DE_X 1 + #define DE_Y 0.5 + #define DE_Z 0.375 + #define DG_Z 0.360 + #define BM 1 + #define DG_X 0.1375 + #define DS 1 + #define FV 1 +#elif (App == 0x289ABD5C ) //World Rally Championship 10 + #define DA_W 1 + #define DA_Y 20.5 + //#define DA_Z 0.000075 + #define DA_X 0.1375 + #define DF_Y 0.03 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.055 + #define DE_Z 0.4875 + #define WSM 2 + #define DB_W 5 + #define DF_X 0.125 + #define PE 1 + #define DA 1 +#elif (App == 0xBCCAD1AE || App == 0x3D2B24D7 ) //Project Cars | Project Cars 2 + #define DA_Y 7.0 + //#define DA_Z 0.000075 + #define DA_X 0.16875 + //#define DF_Y 0.01 + //#define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.375 + #define DE_Z 0.400 + #define DG_Z 0.125 //0.125//0.3125 + #define DE_W 0.275//0.275//0.35625 + #define DG_W 0.20 // Needed for old car. + #define BM 1 + #define DG_X 0.165 + #define PE 1 + #define DA 1 + #define DS 1 + #define NW 1 +#elif (App == 0x98C69E31 || App == 0xA8778B7D ) // F1 2019 | F1 2020 DX12 + #define DA_W 1 + #define DG_W 0.25 + #define DA_Y 14.5 + #define DA_X 0.07 + #define DB_Y 5 + #define DE_X 2 + #define DE_Z 0.400 + #define DG_Z 0.400 + #define PE 1 + #define NW 1 +#elif (App == 0x164EF6B5 ) //Grid 2019 + #define DA_W 1 + #define DA_Y 11.5 + #define DA_X 0.15875 + #define DE_X 1 + //#define DE_Y 0.50 + #define DE_Z 0.400 + //#define DG_Z 0.125 + //#define DE_W 0.275 + #define DG_W 0.25 + #define BM 1 + #define DG_X 0.1625 + #define PE 1 + #define DA 1 + //#define DS 1 + #define NW 1 +#elif (App == 0x54568EA ) //Assetto Corsa + #define DA_X 0.05 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.750 + #define DE_Z 0.375 + #define DG_W 0.2 + #define PE 1 + #define DA 1 + #define NW 1 + #define FV 1 +#elif (App == 0x7658447E ) //Dagon* + #define DA_W 1 + #define DB_X 1 + #define DA_X 0.0625 + #define DA_Y 11.5 + #define DA_Z 0.00025 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.625 + #define DE_Z 0.375 + #define DB_Z 0 + #define DG_W 0.25 + #define DS 1 + #define PE 1 +#elif (App == 0xC57720A6 ) //Crysis 2 DX11 1.9 + #define DA_X 0.07 + //#define DA_Y 11.5 + #define DA_Z 0.00025 + #define DB_Y 2 + #define DE_X 3 + //#define DE_Y 0.625 + //#define DE_Z 0.375 + //#define DG_W 0.25 + #define WSM 2 + #define DB_W 7 + #define DF_X 0.225 + #define DS 1 //? + #define PE 1 + #define RH 1 +#elif (App == 0xDB778A3B ) //Portal 2 + #define DA_X 0.05 + #define DA_Y 20.5 + #define DA_Z 0.001 + #define DB_Z 0.105 + #define DB_Y 3 + #define DE_X 3 + #define DE_Y 0.7 + #define DE_Z 0.375 + #define DG_W 0.125 + #define DB_W 36 + #define DG_Z 0.430 + #define DS 1 + #define PE 1 +#elif (App == 0x194A6354 ) //The Medium + #define DA_W 1 + #define DA_X 0.125 + #define DF_Y 0.0225 + #define DA_Y 55.0 + #define DA_Z -0.025 // This can be still adjusted. + #define DB_Z 0.145 + #define DB_Y 2 + #define DE_X 1 + #define DE_Y 0.375 + #define DE_Z 0.375 + #define DG_W 0.6125 + #define PE 1 +#elif (App == 0xD829EFC1 ) //Ride 4 + #define DA_W 1 + #define DA_Y 16.25 + #define DA_X 0.13 + #define DE_X 2 + #define DE_Y 0.16875 + #define DE_Z 0.4875 + //#define DG_Z 0.125 //Near + //#define DE_W 0.275 //Max + #define DG_W 0.7 + #define BM 1 + #define DG_X 0.165 + #define PE 1 + #define NW 1 +#elif (App == 0x19D0F410 ) //Zombie Army Trilogy + #define DA_Y 12.5 + #define DA_X 0.155 + #define DA_Z -0.00025 + #define DB_Y 5 + #define DE_X 1 + #define DE_Y 0.375 + #define DE_Z 0.375 + #define DG_W 0.7 + //#define BM 1 + //#define DG_X 0.165 + #define PE 1 + #define NW 1 +#elif (App == 0x8842D13 ) //Genshin Impact + #define DA_W 1 + #define DB_X 1 + #define DA_Y 9.375 + #define DA_X 0.1 + #define DA_Z -0.01 + #define DB_Y 5 + #define DE_X 1 + //#define DE_Y 0.4375 + #define DE_Z 0.375 + #define DF_Y 0.01 + #define DG_W 0.1 + #define NW 1 +#elif (App == 0xEEAF4DE ) //Guardians of the galaxy + #define DA_W 1 + #define DA_Y 54.0 + #define DA_X 0.05 + #define DB_Y 1 + #define DB_Z 0.12 + #define DE_X 1 + #define DE_Y 0.375 + #define DE_Z 0.400 + #define DF_Y 0.0375 + #define DG_W 0.2 + #define DA 1 + #define PE 1 +#elif (App == 0x967BB1CC ) //HROT + #define DA_X 0.055 + #define DF_Y 0.025 + #define DA_Y 150.0 + #define DB_Z 0.0875 + #define DB_Y 2 + #define DE_X 3 + #define DE_Y 0.550 + #define DE_Z 0.375 + #define WSM 2 //Weapon Settings Mode + #define DB_W 11 + #define DS 1 + #define PE 1 +#elif (App == 0x11763BB7 ) //FATAL Frame Maiden of the Black Water.... Too Damn spooky.... + #define DA_X 0.0825 + #define DF_Y 0.04125 + #define DA_Y 16.25 + #define DB_Z 0.275 + #define DB_Y 4 + #define DE_X 1 + #define DE_Y 0.250 + #define DE_Z 0.375 + #define PE 1 + #define DA 1 +#else + #define NP 1 //No Profile +#endif +//Change Output +//#ifndef checks whether the given token has been #defined earlier in the file or in an included file +// X = [ZPD] Y = [Depth Adjust] Z = [Offset] W = [Depth Linearization] +#ifndef DA_X + #define DA_X ZPD_D +#endif +#ifndef DA_Y + #define DA_Y Depth_Adjust_D +#endif +#ifndef DA_Z + #define DA_Z Offset_D +#endif +#ifndef DA_W + #define DA_W Depth_Linearization_D +#endif +// X = [Depth Flip] Y = [Auto Balance] Z = [Auto Depth] W = [Weapon Hand] +#ifndef DB_X + #define DB_X Depth_Flip_D +#endif +#ifndef DB_Y + #define DB_Y Auto_Balance_D +#endif +#ifndef DB_Z + #define DB_Z Auto_Depth_D +#endif +#ifndef DB_W + #define DB_W Weapon_Hand_D +#endif +// X = [HUD] Y = [Barrel Distortion K1] Z = [Barrel Distortion K2] W = [Barrel Distortion Zoom] +#ifndef DC_X + #define DC_X BD_K1_D +#endif +#ifndef DC_Y + #define DC_Y BD_K2_D +#endif +#ifndef DC_Z + #define DC_Z BD_K3_D +#endif +#ifndef DC_W + #define DC_W BD_Zoom_D +#endif +// X = [Horizontal Size] Y = [Vertical Size] Z = [Horizontal Position] W = [Vertical Position] +#ifndef DD_X + #define DD_X HVS_X_D +#endif +#ifndef DD_Y + #define DD_Y HVS_Y_D +#endif +#ifndef DD_Z + #define DD_Z HVP_X_D +#endif +#ifndef DD_W + #define DD_W HVP_Y_D +#endif +// X = [ZPD Boundary Type] Y = [ZPD Boundary Scaling] Z = [ZPD Boundary Fade Time] W = [Weapon NearDepth Max] +#ifndef DE_X + #define DE_X ZPD_Boundary_Type_D +#endif +#ifndef DE_Y + #define DE_Y ZPD_Boundary_Scaling_D +#endif +#ifndef DE_Z + #define DE_Z ZPD_Boundary_Fade_Time_D +#endif +#ifndef DE_W + #define DE_W Weapon_Near_Depth_Max_D +#endif +// X = [ZPD Weapon Boundary] Y = [Separation] Z = [Null] W = [HUD] +#ifndef DF_X + #define DF_X ZPD_Weapon_Boundary_Adjust +#endif +#ifndef DF_Y + #define DF_Y Separation +#endif +#ifndef DF_Z + #define DF_Z Null_Z +#endif +#ifndef DF_W + #define DF_W HUDX_D +#endif +// X = [ZPD Balance] Y = [Null] Z = [Weapon NearDepth Min] W = [Check Depth Limit] +#ifndef DG_X + #define DG_X Manual_ZPD_Balance +#endif +#ifndef DG_Y + #define DG_Y Null_Y +#endif +#ifndef DG_Z + #define DG_Z Weapon_Near_Depth_Min_D +#endif +#ifndef DG_W + #define DG_W Check_Depth_Limit +#endif + +//Special Toggles +#ifndef RE + #define RE REF //Resident Evil Fix +#endif +#ifndef NC + #define NC NCW //Not Compatible Warning +#endif +#ifndef RH + #define RH RHW //Read Help Warning +#endif +#ifndef ED + #define ED EDW //Emulator Detected Warning +#endif +#ifndef NP + #define NP NPW //No Profile Warning +#endif +#ifndef ID + #define NI IDF //Inverted Depth Fix +#endif +#ifndef SP + #define SP SPF //Size & Position Fix +#endif +#ifndef DC + #define DC BDF //Barrel Distortion Fix +#endif +#ifndef HM + #define HM HMT //HUD Mode Trigger +#endif +#ifndef DF + #define DF DFW //Delay Frame Workaround +#endif +#ifndef NF + #define NF NFM //Needs Fix and/or Modding +#endif +#ifndef DS + #define DS DSW //Depth Selection Warning +#endif +#ifndef LBC + #define LBC ALB //Auto Letter Box +#endif +#ifndef LBM + #define LBM LBD //Letter Box Depth +#endif +#ifndef SDT + #define SDT STD //Specialized Depth Trigger +#endif +#ifndef DA + #define DA DAA //Disable Anti-Aliasing +#endif +#ifndef NW + #define NW NWW //Network Warning +#endif +#ifndef PE + #define PE PEW //Disable Post Effect Warning +#endif +#ifndef WW + #define WW WPW //Weapon Profile Warning +#endif +#ifndef FV + #define FV FOV //Set Game FoV +#endif +#ifndef BM + #define BM BMT //Balance Mode Toggle +#endif +//Weapon Settings "Use #define WSM 1 or 2" +#ifndef OW_WP //This is used if OW_WP is not called in the Above Profile + #define OW_WP "WP Off\0Custom WP\0WP 0\0WP 1\0WP 2\0WP 3\0WP 4\0WP 5\0WP 6\0WP 7\0WP 8\0WP 9\0WP 10\0WP 11\0WP 12\0WP 13\0WP 14\0WP 15\0WP 16\0WP 17\0WP 18\0WP 19\0WP 20\0WP 21\0WP 22\0WP 23\0WP 24\0WP 25\0WP 26\0WP 27\0WP 28\0WP 29\0WP 30\0WP 31\0WP 32\0WP 33\0WP 34\0WP 35\0WP 36\0WP 37\0WP 38\0WP 39\0WP 40\0WP 41\0WP 42\0WP 43\0WP 44\0WP 45\0WP 46\0WP 47\0WP 48\0WP 49\0WP 50\0WP 51\0WP 52\0WP 53\0WP 54\0WP 55\0WP 56\0WP 57\0WP 58\0WP 59\0WP 60\0WP 61\0WP 62\0WP 63\0WP 64\0WP 65\0WP 66\0WP 67\0WP 68\0WP 69\0WP 70\0WP 71\0WP 72\0WP 73\0WP 74\0" +#endif +#ifndef WSM //One is Profiles List A | Two is Profiles List B | Three is MCC | Four is Prey | Five is Blood 2 + #define WSM 1 //Weapon Setting Mode +#endif + +#if WSM == 1 +float3 Weapon_Profiles(float WP ,float3 Weapon_Adjust) //Tried Switch But, can't compile in some older versions of ReShade. +{ if (WP == 2) + Weapon_Adjust = float3(0.425,5.0,1.125); //WP 0 | ES: Oblivion + if (WP == 3) + Weapon_Adjust = float3(0.276,16.25,9.15); //WP 1 | BorderLands + if (WP == 4) + Weapon_Adjust = float3(0.5,32.5,7.15); //WP 2 | BorderLands 2 + if (WP == 5) + Weapon_Adjust = float3(0.284,10.5,0.8725); //WP 3 | BorderLands 3 + if (WP == 6) + Weapon_Adjust = float3(0.253,39.0,97.5); //WP 4 | Fallout 4 + if (WP == 7) + Weapon_Adjust = float3(0.276,20.0,9.5625); //WP 5 | Skyrim: SE + if (WP == 8) + Weapon_Adjust = float3(0.338,21.0,9.1375); //WP 6 | DOOM 2016 + if (WP == 9) + Weapon_Adjust = float3(0.255,177.5,63.025); //WP 7 | CoD:Black Ops | CoD:MW2 | CoD:MW3 + if (WP == 10) + Weapon_Adjust = float3(0.254,100.0,0.9843); //WP 8 | CoD:Black Ops II + if (WP == 11) + Weapon_Adjust = float3(0.254,203.125,0.98435);//WP 9 | CoD:Ghost + if (WP == 12) + Weapon_Adjust = float3(0.254,203.125,0.98433);//WP 10 | CoD:AW | CoD:MW Re + if (WP == 13) + Weapon_Adjust = float3(0.254,125.0,0.9843); //WP 11 | CoD:IW + if (WP == 14) + Weapon_Adjust = float3(0.255,200.0,63.0); //WP 12 | CoD:WaW + if (WP == 15) + Weapon_Adjust = float3(0.510,162.5,3.975); //WP 13 | CoD | CoD:UO | CoD:2 + if (WP == 16) + Weapon_Adjust = float3(0.254,23.75,0.98425); //WP 14 | CoD: Black Ops IIII + if (WP == 17) + Weapon_Adjust = float3(0.375,60.0,15.15625); //WP 15 | Quake DarkPlaces + if (WP == 18) + Weapon_Adjust = float3(0.7,14.375,2.5); //WP 16 | Quake 2 XP + if (WP == 19) + Weapon_Adjust = float3(0.750,30.0,1.050); //WP 17 | Quake 4 + if (WP == 20) + Weapon_Adjust = float3(0.278,62.5,9.1); //WP 18 | Half-Life 2 + if (WP == 21) + Weapon_Adjust = float3(0.450,12.0,23.75); //WP 19 | Metro Redux Games + if (WP == 22) + Weapon_Adjust = float3(0.350,12.5,2.0); //WP 20 | Soldier of Fortune + if (WP == 23) + Weapon_Adjust = float3(0.286,1500.0,7.0); //WP 21 | Deus Ex rev + if (WP == 24) + Weapon_Adjust = float3(35.0,250.0,0); //WP 21 | Deus Ex + if (WP == 25) + Weapon_Adjust = float3(0.625,350.0,0.785); //WP 23 | Minecraft + if (WP == 26) + Weapon_Adjust = float3(0.255,6.375,53.75); //WP 24 | S.T.A.L.K.E.R: Games + if (WP == 27) + Weapon_Adjust = float3(0.450,5.5625,0.0); //WP 25 | AMID EVIL RTX + if (WP == 28) + Weapon_Adjust = float3(0.750,30.0,1.025); //WP 26 | Prey 2006 + if (WP == 29) + Weapon_Adjust = float3(0.266,30.0,14.0); //WP 27 | Wrath + if (WP == 30) + Weapon_Adjust = float3(3.625,20.0,0); //WP 28 | We Where Here Together + if (WP == 31) + Weapon_Adjust = float3(0.7,9.0,2.3625); //WP 29 | Return to Castle Wolfenstine + if (WP == 32) + Weapon_Adjust = float3(0.4894,62.50,0.98875); //WP 30 | Wolfenstein + if (WP == 33) + Weapon_Adjust = float3(1.0,93.75,0.81875); //WP 31 | Wolfenstein: The New Order #C770832 / The Old Blood #3E42619F + if (WP == 34) + Weapon_Adjust = float3(1.150,55.0,0.9); //WP 32 | Cyberpunk 2077 + if (WP == 35) + Weapon_Adjust = float3(0.278,37.50,9.1); //WP 33 | Black Mesa + if (WP == 36) + Weapon_Adjust = float3(0.277,105.0,8.8625); //WP 34 | Portal 2 + if (WP == 37) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 35 | Game + if (WP == 38) + Weapon_Adjust = float3(0.78,21.25,0.1875); //WP 36 | SOMA + if (WP == 39) + Weapon_Adjust = float3(0.444,20.0,1.1875); //WP 37 | Cryostasis + if (WP == 40) + Weapon_Adjust = float3(0.286,80.0,7.0); //WP 38 | Unreal Gold with v227 + if (WP == 41) + Weapon_Adjust = float3(0.280,18.75,9.03); //WP 39 | Serious Sam Revolution #EB9EEB74/Serious Sam HD: The First Encounter /The Second Encounter /Serious Sam 2 #8238E9CA/ Serious Sam 3: BFE* + if (WP == 42) + Weapon_Adjust = float3(0.3,17.5,0.9015); //WP 40 | Serious Sam Fusion + if (WP == 43) + Weapon_Adjust = float3(1.2,12.5,0.3); //WP 41 | GhostRunner DX12 + if (WP == 44) + Weapon_Adjust = float3(0.277,20.0,8.8); //WP 42 | TitanFall 2 + if (WP == 45) + Weapon_Adjust = float3(0.7,16.250,0.300); //WP 43 | Project Warlock + if (WP == 46) + Weapon_Adjust = float3(0.625,9.0,2.375); //WP 44 | Kingpin Life of Crime + if (WP == 47) + Weapon_Adjust = float3(0.28,20.0,9.0); //WP 45 | EuroTruckSim2 + if (WP == 48) + Weapon_Adjust = float3(0.460,12.5,1.0); //WP 46 | F.E.A.R #B302EC7 & F.E.A.R 2: Project Origin #91D9EBAF + if (WP == 49) + Weapon_Adjust = float3(1.5,37.5,0.99875); //WP 47 | Condemned Criminal Origins + if (WP == 50) + Weapon_Adjust = float3(2.0,16.25,0.09); //WP 48 | Immortal Redneck CP alt 1.9375 + if (WP == 51) + Weapon_Adjust = float3(0.485,62.5,0.9625); //WP 49 | Dementium 2 + if (WP == 52) + Weapon_Adjust = float3(0.489,68.75,1.02); //WP 50 | NecroVisioN & NecroVisioN: Lost Company #663E66FE + if (WP == 53) + Weapon_Adjust = float3(1.0,237.5,0.83625); //WP 51 | Rage64 + if (WP == 54) + Weapon_Adjust = float3(13.870,50.0,0.0); //WP 52 | Graven + if (WP == 55) + Weapon_Adjust = float3(0.425,15.0,99.0); //WP 53 | Bioshock Remastred + if (WP == 56) + Weapon_Adjust = float3(0.425,21.25,99.5); //WP 54 | Bioshock 2 Remastred + if (WP == 57) + Weapon_Adjust = float3(0.425,5.25,1.0); //WP 55 | No One Lives Forever + if (WP == 58) + Weapon_Adjust = float3(0.519,31.25,8.875); //WP 56 | No One Lives Forever 2 + if (WP == 59) + Weapon_Adjust = float3(0.5,8.0,0); //WP 57 | Strife + if (WP == 60) + Weapon_Adjust = float3(0.350,9.0,1.8); //WP 58 | Gold Source + if (WP == 61) //Unity Limit if using else if + Weapon_Adjust = float3(1.825,13.75,0); //WP 59 | No Man Sky FPS Mode + if (WP == 62) + Weapon_Adjust = float3(1.953,5.25,0); //WP 60 | Dying Light + if (WP == 63) + Weapon_Adjust = float3(0.287,180.0,9.0); //WP 61 | Farcry + if (WP == 64) + Weapon_Adjust = float3(0.2503,55.0,1000.0); //WP 62 | Farcry 2 + if (WP == 65) + Weapon_Adjust = float3(0.279,100.0,0.905); //WP 63 | Talos Principle + if (WP == 66) + Weapon_Adjust = float3(0.2503,52.5,987.5); //WP 64 | Singularity + if (WP == 67) + Weapon_Adjust = float3(0.251,12.5,925.0); //WP 65 | Betrayer + if (WP == 68) + Weapon_Adjust = float3(1.035,16.0,0.185); //WP 66 | Doom Eternal + if (WP == 69) + Weapon_Adjust = float3(1.553,16.875,0.0); //WP 67 | Q.U.B.E 2 + if (WP == 70) + Weapon_Adjust = float3(0.251,5.6875,950.0); //WP 68 | Mirror Edge + if (WP == 71) + Weapon_Adjust = float3(0.345,10.125,1.825); //WP 69 | Quake Enhanced Edition + if (WP == 72) + Weapon_Adjust = float3(0.430,6.250,0.100); //WP 70 | The Citadel 186 + if (WP == 73) + Weapon_Adjust = float3(0.800,15.0,0.3); //WP 71 | Sauerbraten 2 + if (WP == 74) + Weapon_Adjust = float3(13.3,62.5,0.0); //WP 72 | Chex Quest HD + if (WP == 75) + Weapon_Adjust = float3(0.75,112.5,0.5); //WP 73 | Hexen 2 + if (WP == 76) //DX 9 Temp Registers Limit + Weapon_Adjust = float3(0.350,17.5,2.050); //WP 74 | Star Trek EliteForce II + + return Weapon_Adjust; +} +#elif WSM == 2 +float3 Weapon_Profiles(float WP ,float3 Weapon_Adjust) //Could reduce from 76 to 57 to save on compiling time. +{ if (WP == 2) + Weapon_Adjust = float3(0.6,6.5,0.0); //WP 0 | The Suicide of Rachel Foster + if (WP == 3) + Weapon_Adjust = float3(1.653,17.5,0.0); //WP 1 | Devolverland Expo + if (WP == 4) + Weapon_Adjust = float3(1.489,16.875,0.0); //WP 2 | Conarium + if (WP == 5) + Weapon_Adjust = float3(0.270,25.0,0.951); //WP 3 | WRC 10 + if (WP == 6) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 4 | Game + if (WP == 7) + Weapon_Adjust = float3(0.275,11.0,10.0); //WP 5 | Crysis 2 DX11 1.9 + if (WP == 8) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 6 | Game + if (WP == 9) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 7 | Game + if (WP == 10) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 8 | Game + if (WP == 11) + Weapon_Adjust = float3(4.100,25.0,0.0); //WP 9 | HROT + if (WP == 12) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 10 | Game + if (WP == 13) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 11 | Game + if (WP == 14) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 12 | Game + if (WP == 15) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 13 | Game + if (WP == 16) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 14 | Game + if (WP == 17) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 15 | Game + if (WP == 18) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 16 | Game + if (WP == 19) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 17 | Game + if (WP == 20) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 18 | Game + if (WP == 21) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 19 | Game + if (WP == 22) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 20 | Game + if (WP == 23) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 21 | Game + if (WP == 24) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 21 | Game + if (WP == 25) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 23 | Game + if (WP == 26) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 24 | Game + if (WP == 27) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 25 | Game + if (WP == 28) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 26 | Game + if (WP == 29) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 27 | Game + if (WP == 30) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 28 | Game + if (WP == 31) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 29 | Game + if (WP == 32) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 30 | Game + if (WP == 33) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 31 | Game + if (WP == 34) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 32 | Game + if (WP == 35) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 33 | Game + if (WP == 36) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 34 | Game + if (WP == 37) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 35 | Game + if (WP == 38) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 36 | Game + if (WP == 39) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 37 | Game + if (WP == 40) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 38 | Game + if (WP == 41) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 39 | Game + if (WP == 42) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 40 | Game + if (WP == 43) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 41 | Game + if (WP == 44) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 42 | Game + if (WP == 45) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 43 | Game + if (WP == 46) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 44 | Game + if (WP == 47) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 45 | Game + if (WP == 48) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 46 | Game + if (WP == 49) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 47 | Game + if (WP == 50) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 48 | Game + if (WP == 51) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 49 | Game + if (WP == 52) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 50 | Game + if (WP == 53) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 51 | Game + if (WP == 54) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 52 | Game + if (WP == 55) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 53 | Game + if (WP == 56) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 54 | Game + if (WP == 57) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 55 | Game + if (WP == 58) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 56 | Game + if (WP == 59) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 57 | Game + if (WP == 60) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 58 | Game + if (WP == 61) //Unity Limit if using else if + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 59 | Game + if (WP == 62) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 60 | Game + if (WP == 63) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 61 | Game + if (WP == 64) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 62 | Game + if (WP == 65) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 63 | Game + if (WP == 66) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 64 | Game + if (WP == 67) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 65 | Game + if (WP == 68) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 66 | Game + if (WP == 69) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 67 | Game + if (WP == 70) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 68 | Game + if (WP == 71) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 69 | Game + if (WP == 72) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 70 | Game + if (WP == 73) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 71 | Game + if (WP == 74) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 72 | Game + if (WP == 75) + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 73 | Game + if (WP == 76) //DX 9 Temp Registers Limit + Weapon_Adjust = float3(0.0,0.0,0.0); //WP 74 | Game + + return Weapon_Adjust; +} +#elif WSM == 3 +float3 Weapon_Profiles(float WP ,float3 Weapon_Adjust) // MCC +{ + if (WP == 2) + Weapon_Adjust = float3(0,0,0); //WP 0 | Halo: Reach + if (WP == 3) + Weapon_Adjust = float3(1.5,26.25,0.2); //WP 1 | Halo: CE Anniversary + if (WP == 4) + Weapon_Adjust = float3(0.615,70.0,0.3955); //WP 2 | Halo 2: Anniversary + if (WP == 5) + Weapon_Adjust = float3(5.750,24.0,0); //WP 3 | Halo 3 + if (WP == 6) + Weapon_Adjust = float3(0,0,0); //WP 4 | Halo 3: ODST + if (WP == 7) + Weapon_Adjust = float3(0,0,0); //WP 5 | Halo 4 + + return Weapon_Adjust; +} +#elif WSM == 4 +float3 Weapon_Profiles(float WP ,float3 Weapon_Adjust) // Prey 2017 +{ + if (WP == 2) + Weapon_Adjust = float3(0.2832,31.25,0.8775); //WP 0 | Prey 2017 High Settings and < + if (WP == 3) + Weapon_Adjust = float3(0.2832,31.25,0.91875);//WP 1 | Prey 2017 Very High + + return Weapon_Adjust; +} +#elif WSM == 5 +float3 Weapon_Profiles(float WP ,float3 Weapon_Adjust) // Blood 2 +{ + if (WP == 2) + Weapon_Adjust = float3(0.4213,5.0,0.5); //WP 0 | Blood 2 All Weapons + if (WP == 3) + Weapon_Adjust = float3(0.484,5.0,0.5); //WP 1 | Blood 2 Bonus weapons + if (WP == 4) + Weapon_Adjust = float3(0.4213,5.0,0.8); //WP 2 | Blood 2 Former + + return Weapon_Adjust; +} +#endif diff --git a/data_from_portwine/Reshade/Shaders/PD80_00_Base_Effects.fxh b/data_from_portwine/Reshade/Shaders/PD80_00_Base_Effects.fxh new file mode 100644 index 00000000..c3aa7995 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_00_Base_Effects.fxh @@ -0,0 +1,52 @@ +/* + * Collection of simple base effects often used across shaders by prod80 + * Required for proper effect execution + * Includes [range]: exposure [-4, 4], contrast [-1, 1.5], brightness [-1, 1.5], saturation [-1, 1], vibrance[-1, 1] + */ + +float3 sl( float3 c, float3 b ) +{ + return b < 0.5f ? ( 2.0f * c * b + c * c * ( 1.0f - 2.0f * b )) : + ( sqrt( c ) * ( 2.0f * b - 1.0f ) + 2.0f * c * ( 1.0f - b )); +} + +float getLum( in float3 x ) +{ + return dot( x, float3( 0.212656, 0.715158, 0.072186 )); +} + +float3 exposure( float3 res, float x ) +{ + x = x < 0.0f ? x * 0.333f : x; + return saturate( res.xyz * ( x * ( 1.0f - res.xyz ) + 1.0f )); +} + +float3 con( float3 res, float x ) +{ + //softlight + float3 c = sl( res.xyz, res.xyz ); + x = ( x < 0.0f ) ? x * 0.5f : x; + return saturate( lerp( res.xyz, c.xyz, x )); +} + +float3 bri( float3 res, float x ) +{ + //screen + float3 c = 1.0f - ( 1.0f - res.xyz ) * ( 1.0f - res.xyz ); + x = ( x < 0.0f ) ? x * 0.5f : x; + return saturate( lerp( res.xyz, c.xyz, x )); +} + +float3 sat( float3 res, float x ) +{ + return saturate( lerp( getLum( res.xyz ), res.xyz, x + 1.0f )); +} + +float3 vib( float3 res, float x ) +{ + float4 sat = 0.0f; + sat.xy = float2( min( min( res.x, res.y ), res.z ), max( max( res.x, res.y ), res.z )); + sat.z = sat.y - sat.x; + sat.w = getLum( res.xyz ); + return saturate( lerp( sat.w, res.xyz, 1.0f + ( x * ( 1.0f - sat.z )))); +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_00_Blend_Modes.fxh b/data_from_portwine/Reshade/Shaders/PD80_00_Blend_Modes.fxh new file mode 100644 index 00000000..6cfa99bb --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_00_Blend_Modes.fxh @@ -0,0 +1,137 @@ +/* + * Blend functions across shaders by prod80 + * Required for proper effect execution + * These can be used by calling the function blendmode() taking input of base, blend, blendmode, opacity + * The effects only operate in LDR space + * UI elements + + uniform int blendmode < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Description"; + ui_category = "Category"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 0; + uniform float opacity < + ui_label = "Opacity"; + ui_tooltip = "Description"; + ui_category = "Category"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + + */ + +float getAvgColor( float3 col ) +{ + return dot( col.xyz, float3( 0.333333f, 0.333334f, 0.333333f )); +} + +// nVidia blend modes +// Source: https://www.khronos.org/registry/OpenGL/extensions/NV/NV_blend_equation_advanced.txt +float3 ClipColor( float3 color ) +{ + float lum = getAvgColor( color.xyz ); + float mincol = min( min( color.x, color.y ), color.z ); + float maxcol = max( max( color.x, color.y ), color.z ); + color.xyz = ( mincol < 0.0f ) ? lum + (( color.xyz - lum ) * lum ) / ( lum - mincol ) : color.xyz; + color.xyz = ( maxcol > 1.0f ) ? lum + (( color.xyz - lum ) * ( 1.0f - lum )) / ( maxcol - lum ) : color.xyz; + return color; +} + +// Luminosity: base, blend +// Color: blend, base +float3 blendLuma( float3 base, float3 blend ) +{ + float lumbase = getAvgColor( base.xyz ); + float lumblend = getAvgColor( blend.xyz ); + float ldiff = lumblend - lumbase; + float3 col = base.xyz + ldiff; + return ClipColor( col.xyz ); +} + +// Hue: blend, base, base +// Saturation: base, blend, base +float3 blendColor( float3 base, float3 blend, float3 lum ) +{ + float minbase = min( min( base.x, base.y ), base.z ); + float maxbase = max( max( base.x, base.y ), base.z ); + float satbase = maxbase - minbase; + float minblend = min( min( blend.x, blend.y ), blend.z ); + float maxblend = max( max( blend.x, blend.y ), blend.z ); + float satblend = maxblend - minblend; + float3 color = ( satbase > 0.0f ) ? ( base.xyz - minbase ) * satblend / satbase : 0.0f; + return blendLuma( color.xyz, lum.xyz ); +} + +float3 darken(float3 c, float3 b) { return min(c,b);} +float3 multiply(float3 c, float3 b) { return c*b;} +float3 linearburn(float3 c, float3 b) { return max(c+b-1.0f,0.0f);} +float3 colorburn(float3 c, float3 b) { return b<=0.0f ? b:saturate(1.0f-((1.0f-c)/b)); } +float3 lighten(float3 c, float3 b) { return max(b,c);} +float3 screen(float3 c, float3 b) { return 1.0f-(1.0f-c)*(1.0f-b);} +float3 colordodge(float3 c, float3 b) { return b>=1.0f ? b:saturate(c/(1.0f-b));} +float3 lineardodge(float3 c, float3 b) { return min(c+b,1.0f);} +float3 overlay(float3 c, float3 b) { return c<0.5f ? 2.0f*c*b:(1.0f-2.0f*(1.0f-c)*(1.0f-b));} +float3 softlight(float3 c, float3 b) { return b<0.5f ? (2.0f*c*b+c*c*(1.0f-2.0f*b)):(sqrt(c)*(2.0f*b-1.0f)+2.0f*c*(1.0f-b));} +float3 vividlight(float3 c, float3 b) { return b<0.5f ? colorburn(c,(2.0f*b)):colordodge(c,(2.0f*(b-0.5f)));} +float3 linearlight(float3 c, float3 b) { return b<0.5f ? linearburn(c,(2.0f*b)):lineardodge(c,(2.0f*(b-0.5f)));} +float3 pinlight(float3 c, float3 b) { return b<0.5f ? darken(c,(2.0f*b)):lighten(c, (2.0f*(b-0.5f)));} +float3 hardmix(float3 c, float3 b) { return vividlight(c,b)<0.5f ? float3(0.0,0.0,0.0):float3(1.0,1.0,1.0);} +float3 reflect(float3 c, float3 b) { return b>=1.0f ? b:saturate(c*c/(1.0f-b));} +float3 glow(float3 c, float3 b) { return reflect(b,c);} +float3 blendhue(float3 c, float3 b) { return blendColor(b,c,c);} +float3 blendsaturation(float3 c, float3 b) { return blendColor(c,b,c);} +float3 blendcolor(float3 c, float3 b) { return blendLuma(b,c);} +float3 blendluminosity(float3 c, float3 b) { return blendLuma(c,b);} + +float3 blendmode( float3 c, float3 b, int mode, float o ) +{ + float3 ret; + switch( mode ) + { + case 0: // Default + { ret.xyz = b.xyz; } break; + case 1: // Darken + { ret.xyz = darken( c, b ); } break; + case 2: // Multiply + { ret.xyz = multiply( c, b ); } break; + case 3: // Linearburn + { ret.xyz = linearburn( c, b ); } break; + case 4: // Colorburn + { ret.xyz = colorburn( c, b ); } break; + case 5: // Lighten + { ret.xyz = lighten( c, b ); } break; + case 6: // Screen + { ret.xyz = screen( c, b ); } break; + case 7: // Colordodge + { ret.xyz = colordodge( c, b ); } break; + case 8: // Lineardodge + { ret.xyz = lineardodge( c, b ); } break; + case 9: // Overlay + { ret.xyz = overlay( c, b ); } break; + case 10: // Softlight + { ret.xyz = softlight( c, b ); } break; + case 11: // Vividlight + { ret.xyz = vividlight( c, b ); } break; + case 12: // Linearlight + { ret.xyz = linearlight( c, b ); } break; + case 13: // Pinlight + { ret.xyz = pinlight( c, b ); } break; + case 14: // Hard Mix + { ret.xyz = hardmix( c, b ); } break; + case 15: // Reflect + { ret.xyz = reflect( c, b ); } break; + case 16: // Glow + { ret.xyz = glow( c, b ); } break; + case 17: // Hue + { ret.xyz = blendhue( c, b ); } break; + case 18: // Saturation + { ret.xyz = blendsaturation( c, b ); } break; + case 19: // Color + { ret.xyz = blendcolor( c, b ); } break; + case 20: // Luminosity + { ret.xyz = blendluminosity( c, b ); } break; + } + return saturate( lerp( c.xyz, ret.xyz, o )); +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_00_Color_Spaces.fxh b/data_from_portwine/Reshade/Shaders/PD80_00_Color_Spaces.fxh new file mode 100644 index 00000000..3a38c4c3 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_00_Color_Spaces.fxh @@ -0,0 +1,187 @@ +/* + * Color spaces shared across shaders by prod80 + * Required for proper effect execution + */ + +float3 HUEToRGB( in float H ) +{ + return saturate( float3( abs( H * 6.0f - 3.0f ) - 1.0f, + 2.0f - abs( H * 6.0f - 2.0f ), + 2.0f - abs( H * 6.0f - 4.0f ))); +} + +float3 RGBToHCV( in float3 RGB ) +{ + // Based on work by Sam Hocevar and Emil Persson + float4 P = ( RGB.g < RGB.b ) ? float4( RGB.bg, -1.0f, 2.0f/3.0f ) : float4( RGB.gb, 0.0f, -1.0f/3.0f ); + float4 Q1 = ( RGB.r < P.x ) ? float4( P.xyw, RGB.r ) : float4( RGB.r, P.yzx ); + float C = Q1.x - min( Q1.w, Q1.y ); + float H = abs(( Q1.w - Q1.y ) / ( 6.0f * C + 0.000001f ) + Q1.z ); + return float3( H, C, Q1.x ); +} + +float3 RGBToHSL( in float3 RGB ) +{ + RGB.xyz = max( RGB.xyz, 0.000001f ); + float3 HCV = RGBToHCV(RGB); + float L = HCV.z - HCV.y * 0.5f; + float S = HCV.y / ( 1.0f - abs( L * 2.0f - 1.0f ) + 0.000001f); + return float3( HCV.x, S, L ); +} + +float3 HSLToRGB( in float3 HSL ) +{ + float3 RGB = HUEToRGB(HSL.x); + float C = (1.0f - abs(2.0f * HSL.z - 1.0f)) * HSL.y; + return ( RGB - 0.5f ) * C + HSL.z; +} + +// Collected from +// http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl +float3 RGBToHSV(float3 c) +{ + float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + float4 p = c.g < c.b ? float4(c.bg, K.wz) : float4(c.gb, K.xy); + float4 q = c.r < p.x ? float4(p.xyw, c.r) : float4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +float3 HSVToRGB(float3 c) +{ + float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y); +} + +// Color temperature + +float3 KelvinToRGB( in float k ) +{ + float3 ret; + float kelvin = clamp( k, 1000.0f, 40000.0f ) / 100.0f; + if( kelvin <= 66.0f ) + { + ret.r = 1.0f; + ret.g = saturate( 0.39008157876901960784f * log( kelvin ) - 0.63184144378862745098f ); + } + else + { + float t = max( kelvin - 60.0f, 0.0f ); + ret.r = saturate( 1.29293618606274509804f * pow( t, -0.1332047592f )); + ret.g = saturate( 1.12989086089529411765f * pow( t, -0.0755148492f )); + } + if( kelvin >= 66.0f ) + ret.b = 1.0f; + else if( kelvin < 19.0f ) + ret.b = 0.0f; + else + ret.b = saturate( 0.54320678911019607843f * log( kelvin - 10.0f ) - 1.19625408914f ); + return ret; +} + +// sRGB to Linear RGB conversion + +float3 LinearTosRGB( float3 color ) +{ + float3 x = color * 12.92f; + float3 y = 1.055f * pow(saturate(color), 1.0f / 2.4f) - 0.055f; + + float3 clr = color; + clr.r = color.r < 0.0031308f ? x.r : y.r; + clr.g = color.g < 0.0031308f ? x.g : y.g; + clr.b = color.b < 0.0031308f ? x.b : y.b; + + return clr; +} + +float3 SRGBToLinear( float3 color ) +{ + float3 x = color / 12.92f; + float3 y = pow(max((color + 0.055f) / 1.055f, 0.0f), 2.4f); + + float3 clr = color; + clr.r = color.r <= 0.04045f ? x.r : y.r; + clr.g = color.g <= 0.04045f ? x.g : y.g; + clr.b = color.b <= 0.04045f ? x.b : y.b; + + return clr; +} + +// SRGB <--> CIELAB CONVERSIONS + +// Reference white D65 +#define reference_white float3( 0.95047, 1.0, 1.08883 ) + +// Source +// http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html + +#define K_val float( 24389.0 / 27.0 ) +#define E_val float( 216.0 / 24389.0 ) + +float3 pd80_xyz_to_lab( float3 c ) +{ + // .xyz output contains .lab + float3 w = max( c / reference_white, 0.0f ); + float3 v; + v.x = ( w.x > E_val ) ? pow( w.x, 1.0 / 3.0 ) : ( K_val * w.x + 16.0 ) / 116.0; + v.y = ( w.y > E_val ) ? pow( w.y, 1.0 / 3.0 ) : ( K_val * w.y + 16.0 ) / 116.0; + v.z = ( w.z > E_val ) ? pow( w.z, 1.0 / 3.0 ) : ( K_val * w.z + 16.0 ) / 116.0; + return float3( 116.0 * v.y - 16.0, + 500.0 * ( v.x - v.y ), + 200.0 * ( v.y - v.z )); +} + +float3 pd80_lab_to_xyz( float3 c ) +{ + float3 v; + v.y = ( c.x + 16.0 ) / 116.0; + v.x = c.y / 500.0 + v.y; + v.z = v.y - c.z / 200.0; + return float3(( v.x * v.x * v.x > E_val ) ? v.x * v.x * v.x : ( 116.0 * v.x - 16.0 ) / K_val, + ( c.x > K_val * E_val ) ? v.y * v.y * v.y : c.x / K_val, + ( v.z * v.z * v.z > E_val ) ? v.z * v.z * v.z : ( 116.0 * v.z - 16.0 ) / K_val ) * + reference_white; +} + +float3 pd80_srgb_to_xyz( float3 c ) +{ + // Source: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + // sRGB to XYZ (D65) - Standard sRGB reference white ( 0.95047, 1.0, 1.08883 ) + const float3x3 mat = float3x3( + 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041 + ); + return mul( mat, c ); +} + +float3 pd80_xyz_to_srgb( float3 c ) +{ + // Source: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + // XYZ to sRGB (D65) - Standard sRGB reference white ( 0.95047, 1.0, 1.08883 ) + const float3x3 mat = float3x3( + 3.2404542,-1.5371385,-0.4985314, + -0.9692660, 1.8760108, 0.0415560, + 0.0556434,-0.2040259, 1.0572252 + ); + return mul( mat, c ); +} + +// Maximum value in LAB, B channel is pure blue with 107.8602... divide by 108 to get 0..1 range values +// Maximum value in LAB, L channel is pure white with 100 +float3 pd80_srgb_to_lab( float3 c ) +{ + float3 lab = pd80_srgb_to_xyz( c ); + lab = pd80_xyz_to_lab( lab ); + return lab / float3( 100.0, 108.0, 108.0 ); +} + +float3 pd80_lab_to_srgb( float3 c ) +{ + float3 rgb = pd80_lab_to_xyz( c * float3( 100.0, 108.0, 108.0 )); + rgb = pd80_xyz_to_srgb( max( min( rgb, reference_white ), 0.0 )); + return saturate( rgb ); +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_00_Noise_Samplers.fxh b/data_from_portwine/Reshade/Shaders/PD80_00_Noise_Samplers.fxh new file mode 100644 index 00000000..d27c781f --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_00_Noise_Samplers.fxh @@ -0,0 +1,55 @@ +/* + * Shared textures across shaders by prod80 + * Required for proper effect execution + */ + +// Textures +texture texNoise < source = "pd80_bluenoise.png"; > { Width = 512; Height = 512; Format = RGBA8; }; +texture texNoiseRGB < source = "pd80_bluenoise_rgba.png"; > { Width = 512; Height = 512; Format = RGBA8; }; +texture texGaussNoise < source = "pd80_gaussnoise.png"; > { Width = 512; Height = 512; Format = RGBA8; }; + +// Samplers +sampler samplerNoise +{ + Texture = texNoise; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + AddressU = WRAP; + AddressV = WRAP; + AddressW = WRAP; +}; +sampler samplerRGBNoise +{ + Texture = texNoiseRGB; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + AddressU = WRAP; + AddressV = WRAP; + AddressW = WRAP; +}; +sampler samplerGaussNoise +{ + Texture = texGaussNoise; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + AddressU = WRAP; + AddressV = WRAP; + AddressW = WRAP; +}; + +// Functions +uniform float2 pp < source = "pingpong"; min = 0; max = 128; step = 1; >; +static const float2 dither_uv = float2( BUFFER_WIDTH, BUFFER_HEIGHT ) / 512.0f; + +float4 dither( sampler2D tex, float2 coords, int var, bool enabler, float str, bool motion, float swing ) +{ + coords.xy *= dither_uv.xy; + float4 noise = tex2D( tex, coords.xy ); + float mot = motion ? pp.x + var : 0.0f; + noise = frac( noise + 0.61803398875f * mot ); + noise = ( noise * 2.0f - 1.0f ) * swing; + return ( enabler ) ? noise * ( str / 255.0f ) : float4( 0.0f, 0.0f, 0.0f, 0.0f ); +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_01A_RT_Correct_Contrast.fx b/data_from_portwine/Reshade/Shaders/PD80_01A_RT_Correct_Contrast.fx new file mode 100644 index 00000000..409f9e5b --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_01A_RT_Correct_Contrast.fx @@ -0,0 +1,263 @@ +/* + Description : PD80 01A Correct Contrast for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +namespace pd80_correctcontrast +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool enable_fade < + ui_text = "----------------------------------------------"; + ui_label = "Enable Time Based Fade"; + ui_tooltip = "Enable Time Based Fade"; + ui_category = "Global: Correct Contrasts"; + > = true; + uniform bool freeze < + ui_label = "Freeze Correction"; + ui_tooltip = "Freeze Correction"; + ui_category = "Global: Correct Contrasts"; + > = false; + uniform float transition_speed < + ui_type = "slider"; + ui_label = "Time Based Fade Speed"; + ui_tooltip = "Time Based Fade Speed"; + ui_category = "Global: Correct Contrasts"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.5; + uniform bool rt_enable_whitepoint_correction < + ui_text = "----------------------------------------------"; + ui_label = "Enable Whitepoint Correction"; + ui_tooltip = "Enable Whitepoint Correction"; + ui_category = "Whitepoint Correction"; + > = false; + uniform float rt_wp_str < + ui_type = "slider"; + ui_label = "White Point Correction Strength"; + ui_tooltip = "White Point Correction Strength"; + ui_category = "Whitepoint Correction"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform bool rt_enable_blackpoint_correction < + ui_text = "----------------------------------------------"; + ui_label = "Enable Blackpoint Correction"; + ui_tooltip = "Enable Blackpoint Correction"; + ui_category = "Blackpoint Correction"; + > = true; + uniform float rt_bp_str < + ui_type = "slider"; + ui_label = "Black Point Correction Strength"; + ui_tooltip = "Black Point Correction Strength"; + ui_category = "Blackpoint Correction"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texDS_1_Max { Width = 32; Height = 32; Format = RGBA16F; }; + texture texDS_1_Min { Width = 32; Height = 32; Format = RGBA16F; }; + texture texPrevious { Width = 4; Height = 2; Format = RGBA16F; }; + texture texDS_1x1 { Width = 4; Height = 2; Format = RGBA16F; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerDS_1_Max + { + Texture = texDS_1_Max; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + sampler samplerDS_1_Min + { + Texture = texDS_1_Min; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + sampler samplerPrevious + { + Texture = texPrevious; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + sampler samplerDS_1x1 + { + Texture = texDS_1x1; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + uniform float frametime < source = "frametime"; >; + + float3 interpolate( float3 o, float3 n, float factor, float ft ) + { + return lerp( o.xyz, n.xyz, 1.0f - exp( -factor * ft )); + } + + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + //Downscale to 32x32 min/max color matrix + void PS_MinMax_1( float4 pos : SV_Position, float2 texcoord : TEXCOORD, out float4 minValue : SV_Target0, out float4 maxValue : SV_Target1 ) + { + float3 currColor; + minValue.xyz = 1.0f; + maxValue.xyz = 0.0f; + + // RenderTarget size is 32x32 + float pst = 0.03125f; // rcp( 32 ) + float hst = 0.5f * pst; // half size + + // Sample texture + float2 stexSize = float2( BUFFER_WIDTH, BUFFER_HEIGHT ); + float2 start = floor(( texcoord.xy - hst ) * stexSize.xy ); // sample block start position + float2 stop = floor(( texcoord.xy + hst ) * stexSize.xy ); // ... end position + + for( int y = start.y; y < stop.y; ++y ) + { + for( int x = start.x; x < stop.x; ++x ) + { + currColor = tex2Dfetch( ReShade::BackBuffer, int2( x, y ), 0 ).xyz; + // Dark color detection methods + minValue.xyz = min( minValue.xyz, currColor.xyz ); + // Light color detection methods + maxValue.xyz = max( currColor.xyz, maxValue.xyz ); + } + } + // Return + minValue = float4( minValue.xyz, 1.0f ); + maxValue = float4( maxValue.xyz, 1.0f ); + } + + //Downscale to 32x32 to 1x1 min/max colors + float4 PS_MinMax_1x1( float4 pos : SV_Position, float2 texcoord : TEXCOORD ) : SV_Target + { + float3 minColor; float3 maxColor; + float3 minValue = 1.0f; + float3 maxValue = 0.0f; + //Get texture resolution + uint SampleRes = 32; + float Sigma = 0.0f; + + for( int y = 0; y < SampleRes; ++y ) + { + for( int x = 0; x < SampleRes; ++x ) + { + // Dark color detection methods + minColor = tex2Dfetch( samplerDS_1_Min, int2( x, y), 0 ).xyz; + minValue.xyz = min( minValue.xyz, minColor.xyz ); + // Light color detection methods + maxColor = tex2Dfetch( samplerDS_1_Max, int2( x, y ), 0 ).xyz; + maxValue.xyz = max( maxColor.xyz, maxValue.xyz ); + } + } + + //Try and avoid some flickering + //Not really working, too radical changes in min values sometimes + float3 prevMin = tex2D( samplerPrevious, float2( texcoord.x / 4.0f, texcoord.y )).xyz; + float3 prevMax = tex2D( samplerPrevious, float2(( texcoord.x + 2.0f ) / 4.0, texcoord.y )).xyz; + float smoothf = transition_speed * 4.0f + 0.5f; + float time = frametime * 0.001f; + maxValue.xyz = enable_fade ? interpolate( prevMax.xyz, maxValue.xyz, smoothf, time ) : maxValue.xyz; + minValue.xyz = enable_fade ? interpolate( prevMin.xyz, minValue.xyz, smoothf, time ) : minValue.xyz; + // Freeze Correction + maxValue.xyz = freeze ? prevMax.xyz : maxValue.xyz; + minValue.xyz = freeze ? prevMin.xyz : minValue.xyz; + // Return + if( pos.x < 2 ) + return float4( minValue.xyz, 1.0f ); + else + return float4( maxValue.xyz, 1.0f ); + } + + float4 PS_CorrectContrast(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + float3 minValue = tex2D( samplerDS_1x1, float2( texcoord.x / 4.0f, texcoord.y )).xyz; + float3 maxValue = tex2D( samplerDS_1x1, float2(( texcoord.x + 2.0f ) / 4.0f, texcoord.y )).xyz; + // Black/White Point Change + float adjBlack = min( min( minValue.x, minValue.y ), minValue.z ); + float adjWhite = max( max( maxValue.x, maxValue.y ), maxValue.z ); + // Set min value + adjBlack = lerp( 0.0f, adjBlack, rt_bp_str ); + adjBlack = rt_enable_blackpoint_correction ? adjBlack : 0.0f; + // Set max value + adjWhite = lerp( 1.0f, adjWhite, rt_wp_str ); + adjWhite = rt_enable_whitepoint_correction ? adjWhite : 1.0f; + // Main color correction + color.xyz = saturate( color.xyz - adjBlack ) / saturate( adjWhite - adjBlack ); + //color.xyz = tex2D( samplerDS_1_Max, texcoord ).xyz; // Debug + //color.xyz = tex2D( samplerDS_1_Min, texcoord ).xyz; + return float4( color.xyz, 1.0f ); + } + + float4 PS_StorePrev( float4 pos : SV_Position, float2 texcoord : TEXCOORD ) : SV_Target + { + float3 minValue = tex2D( samplerDS_1x1, float2( texcoord.x / 4.0f, texcoord.y )).xyz; + float3 maxValue = tex2D( samplerDS_1x1, float2(( texcoord.x + 2.0f ) / 4.0f, texcoord.y )).xyz; + if( pos.x < 2 ) + return float4( minValue.xyz, 1.0f ); + else + return float4( maxValue.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_01A_RT_Correct_Contrast + { + pass prod80_pass1 + { + VertexShader = PostProcessVS; + PixelShader = PS_MinMax_1; + RenderTarget0 = texDS_1_Min; + RenderTarget1 = texDS_1_Max; + } + pass prod80_pass2 + { + VertexShader = PostProcessVS; + PixelShader = PS_MinMax_1x1; + RenderTarget = texDS_1x1; + } + pass prod80_pass3 + { + VertexShader = PostProcessVS; + PixelShader = PS_CorrectContrast; + } + pass prod80_pass4 + { + VertexShader = PostProcessVS; + PixelShader = PS_StorePrev; + RenderTarget = texPrevious; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_01B_RT_Correct_Color.fx b/data_from_portwine/Reshade/Shaders/PD80_01B_RT_Correct_Color.fx new file mode 100644 index 00000000..65cc570f --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_01B_RT_Correct_Color.fx @@ -0,0 +1,497 @@ +/* + Description : PD80 01B RT Correct Color for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" + +namespace pd80_correctcolor +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + #ifndef RT_PRECISION_LEVEL_0_TO_4 + #define RT_PRECISION_LEVEL_0_TO_4 0 + #endif + + #ifndef RT_ENABLE_HIGH_PERF_MODE + #define RT_ENABLE_HIGH_PERF_MODE 0 + #endif + + #if( RT_ENABLE_HIGH_PERF_MODE > 1 || RT_ENABLE_HIGH_PERF_MODE < 0 ) + #error "RT_ENABLE_HIGH_PERF_MODE has a range of 0 to 1" + #endif + + #if( RT_PRECISION_LEVEL_0_TO_4 > 4 || RT_PRECISION_LEVEL_0_TO_4 < 0 ) + #error "RT_PRECISION_LEVEL_0_TO_4 has a range of 0 to 4" + #endif + + //// DEFINES //////////////////////////////////////////////////////////////////// +#if( RT_PRECISION_LEVEL_0_TO_4 == 0 ) + #define RT_RES 1 + #define RT_MIPLVL 0 +#elif( RT_PRECISION_LEVEL_0_TO_4 == 1 ) + #define RT_RES 2 + #define RT_MIPLVL 1 +#elif( RT_PRECISION_LEVEL_0_TO_4 == 2 ) + #define RT_RES 4 + #define RT_MIPLVL 2 +#elif( RT_PRECISION_LEVEL_0_TO_4 == 3 ) + #define RT_RES 8 + #define RT_MIPLVL 3 +#else + #define RT_RES 16 + #define RT_MIPLVL 4 +#endif + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int debug_mode < __UNIFORM_COMBO_INT1 + ui_label = "Debug Mode"; + ui_tooltip = "Debug Mode"; + ui_category = "Debug Mode"; + ui_items = "Default\0Min Color Texture\0Max Color Texture\0Mid Color Texture\0"; + > = 0; + uniform bool enable_fade < + ui_text = "----------------------------------------------"; + ui_label = "Enable Time Based Fade"; + ui_tooltip = "Enable Time Based Fade"; + ui_category = "Global: Remove Tint"; + > = true; + uniform bool freeze < + ui_label = "Freeze Correction"; + ui_tooltip = "Freeze Correction"; + ui_category = "Global: Remove Tint"; + > = false; + uniform float transition_speed < + ui_type = "slider"; + ui_label = "Time Based Fade Speed"; + ui_tooltip = "Time Based Fade Speed"; + ui_category = "Global: Remove Tint"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.5; + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Global: Remove Tint"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Global: Remove Tint"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + uniform bool rt_enable_whitepoint_correction < + ui_text = "----------------------------------------------"; + ui_label = "Enable Whitepoint Correction"; + ui_tooltip = "Enable Whitepoint Correction"; + ui_category = "Whitepoint: Remove Tint"; + > = true; + uniform bool rt_whitepoint_respect_luma < + ui_label = "Respect Luma"; + ui_tooltip = "Whitepoint: Respect Luma"; + ui_category = "Whitepoint: Remove Tint"; + > = true; + uniform int rt_whitepoint_method < __UNIFORM_COMBO_INT1 + ui_label = "Color Detection Method"; + ui_category = "Whitepoint: Remove Tint"; + ui_items = "By Color Channel (auto-color)\0Find Light Color (auto-tone)\0"; + > = 0; + uniform float rt_wp_str < + ui_type = "slider"; + ui_label = "White Point Correction Strength"; + ui_tooltip = "Whitepoint: White Point Correction Strength"; + ui_category = "Whitepoint: Remove Tint"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform float rt_wp_rl_str < + ui_type = "slider"; + ui_label = "White Point Respect Luma Strength"; + ui_tooltip = "Whitepoint: White Point Respect Luma Strength"; + ui_category = "Whitepoint: Remove Tint"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform bool rt_enable_blackpoint_correction < + ui_text = "----------------------------------------------"; + ui_label = "Enable Blackpoint Correction"; + ui_tooltip = "Enable Blackpoint Correction"; + ui_category = "Blackpoint: Remove Tint"; + > = true; + uniform bool rt_blackpoint_respect_luma < + ui_label = "Respect Luma"; + ui_tooltip = "Blackpoint: Respect Luma"; + ui_category = "Blackpoint: Remove Tint"; + > = false; + uniform int rt_blackpoint_method < __UNIFORM_COMBO_INT1 + ui_label = "Color Detection Method"; + ui_category = "Blackpoint: Remove Tint"; + ui_items = "By Color Channel (auto-color)\0Find Dark Color (auto-tone)\0"; + > = 1; + uniform float rt_bp_str < + ui_type = "slider"; + ui_label = "Black Point Correction Strength"; + ui_tooltip = "Blackpoint: Black Point Correction Strength"; + ui_category = "Blackpoint: Remove Tint"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform float rt_bp_rl_str < + ui_type = "slider"; + ui_label = "Black Point Respect Luma Strength"; + ui_tooltip = "Blackpoint: Black Point Respect Luma Strength"; + ui_category = "Blackpoint: Remove Tint"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform bool rt_enable_midpoint_correction < + ui_text = "----------------------------------------------"; + ui_label = "Enable Midtone Correction"; + ui_tooltip = "Enable Midtone Correction"; + ui_category = "Midtone: Remove Tint"; + > = true; + uniform bool rt_midpoint_respect_luma < + ui_label = "Respect Luma"; + ui_tooltip = "Midtone: Respect Luma"; + ui_category = "Midtone: Remove Tint"; + > = true; + uniform bool mid_use_alt_method < + ui_label = "Use average Dark-Light as Mid"; + ui_tooltip = "Midtone: Use average Dark-Light as Mid"; + ui_category = "Midtone: Remove Tint"; + > = true; + uniform float midCC_scale < + ui_type = "slider"; + ui_label = "Midtone Correction Scale"; + ui_tooltip = "Midtone: Midtone Correction Scale"; + ui_category = "Midtone: Remove Tint"; + ui_min = 0.0f; + ui_max = 5.0f; + > = 0.5; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texColor { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; MipLevels = 5; }; + texture texDS_1_Max { Width = 32; Height = 32; Format = RGBA16F; }; + texture texDS_1_Min { Width = 32; Height = 32; Format = RGBA16F; }; + texture texDS_1_Mid { Width = 32; Height = 32; Format = RGBA16F; }; + texture texDS_1x1 { Width = 6; Height = 2; Format = RGBA16F; }; + texture texPrevious { Width = 6; Height = 2; Format = RGBA16F; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerColor { Texture = texColor; }; + sampler samplerDS_1_Max + { + Texture = texDS_1_Max; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + sampler samplerDS_1_Min + { + Texture = texDS_1_Min; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + sampler samplerDS_1_Mid + { + Texture = texDS_1_Mid; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + sampler samplerDS_1x1 + { + Texture = texDS_1x1; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + sampler samplerPrevious + { + Texture = texPrevious; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + uniform float frametime < source = "frametime"; >; + + float3 interpolate( float3 o, float3 n, float factor, float ft ) + { + return lerp( o.xyz, n.xyz, 1.0f - exp( -factor * ft )); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_WriteColor(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + return tex2D( ReShade::BackBuffer, texcoord ); + } + //Downscale to 32x32 min/max color matrix + void PS_MinMax_1( float4 pos : SV_Position, float2 texcoord : TEXCOORD, out float4 minValue : SV_Target0, out float4 maxValue : SV_Target1, out float4 midValue : SV_Target2 ) + { + float3 currColor; + float3 minMethod0 = 1.0f; + float3 minMethod1 = 1.0f; + float3 maxMethod0 = 0.0f; + float3 maxMethod1 = 0.0f; + midValue = 0.0f; + + float getMid; float getMid2; + float getMin; float getMin2; + float getMax; float getMax2; + + float3 prevMin = tex2D( samplerPrevious, float2( texcoord.x / 6.0f, texcoord.y )).xyz; + float3 prevMax = tex2D( samplerPrevious, float2(( texcoord.x + 4.0f ) / 6.0f, texcoord.y )).xyz; + float middle = dot( float2( dot( prevMin.xyz, 0.333333f ), dot( prevMax.xyz, 0.333333f )), 0.5f ); + middle = ( mid_use_alt_method ) ? middle : 0.5f; + + // RenderTarget size is 32x32 + float pst = 0.03125f; // rcp( 32 ) + float hst = 0.5f * pst; // half size + + // Sample texture + float2 stexSize = float2( BUFFER_WIDTH/RT_RES, BUFFER_HEIGHT/RT_RES ); + uint OFFSET = 1 + RT_ENABLE_HIGH_PERF_MODE * 3; + float2 start = floor(( texcoord.xy - hst ) * stexSize.xy ); // sample block start position + float2 stop = floor(( texcoord.xy + hst ) * stexSize.xy ); // ... end position + + [loop] + for( int y = start.y; y < stop.y && y < stexSize.y; y += OFFSET ) + { + for( int x = start.x; x < stop.x && x < stexSize.x; x += OFFSET ) + { + currColor = tex2Dfetch( samplerColor, int2( x, y ), RT_MIPLVL ).xyz; + // Dark color detection methods + // Per channel + minMethod0.xyz = min( minMethod0.xyz, currColor.xyz ); + // By color + getMin = max( max( currColor.x, currColor.y ), currColor.z ) + dot( currColor.xyz, 1.0f ); + getMin2 = max( max( minMethod1.x, minMethod1.y ), minMethod1.z ) + dot( minMethod1.xyz, 1.0f ); + minMethod1.xyz = ( getMin2 >= getMin ) ? currColor.xyz : minMethod1.xyz; + // Mid point detection + getMid = dot( abs( currColor.xyz - middle ), 1.0f ); + getMid2 = dot( abs( midValue.xyz - middle ), 1.0f ); + midValue.xyz = ( getMid2 >= getMid ) ? currColor.xyz : midValue.xyz; + // Light color detection methods + // Per channel + maxMethod0.xyz = max( currColor.xyz, maxMethod0.xyz ); + // By color + getMax = dot( currColor.xyz, 1.0f ); + getMax2 = dot( maxMethod1.xyz, 1.0f ); + maxMethod1.xyz = ( getMax >= getMax2 ) ? currColor.xyz : maxMethod1.xyz; + } + } + + minValue.xyz = rt_blackpoint_method ? minMethod1.xyz : minMethod0.xyz; + maxValue.xyz = rt_whitepoint_method ? maxMethod1.xyz : maxMethod0.xyz; + // Return + minValue = float4( minValue.xyz, 1.0f ); + maxValue = float4( maxValue.xyz, 1.0f ); + midValue = float4( midValue.xyz, 1.0f ); + } + + //Downscale to 32x32 to 1x1 min/max colors + float4 PS_MinMax_1x1( float4 pos : SV_Position, float2 texcoord : TEXCOORD ) : SV_Target + { + float3 minColor; float3 maxColor; float3 midColor; + float3 minValue; float3 maxValue; float3 midValue; + float getMin; float getMin2; + float getMax; float getMax2; + float3 minMethod0 = 1.0f; + float3 minMethod1 = 1.0f; + float3 maxMethod0 = 0.0f; + float3 maxMethod1 = 0.0f; + midValue = 0.0f; + //Get texture resolution + int2 SampleRes = 32; + float Sigma = 0.0f; + + for( int y = 0; y < SampleRes.y; ++y ) + { + for( int x = 0; x < SampleRes.x; ++x ) + { + // Dark color detection methods + minColor = tex2Dfetch( samplerDS_1_Min, int2( x, y ), 0 ).xyz; + // Per channel + minMethod0.xyz = min( minMethod0.xyz, minColor.xyz ); + // By color + getMin = max( max( minColor.x, minColor.y ), minColor.z ) + dot( minColor.xyz, 1.0f ); + getMin2 = max( max( minMethod1.x, minMethod1.y ), minMethod1.z ) + dot( minMethod1.xyz, 1.0f ); + minMethod1.xyz = ( getMin2 >= getMin ) ? minColor.xyz : minMethod1.xyz; + // Mid point detection + midColor += tex2Dfetch( samplerDS_1_Mid, int2( x, y ), 0 ).xyz; + Sigma += 1.0f; + // Light color detection methods + maxColor = tex2Dfetch( samplerDS_1_Max, int2( x, y ), 0 ).xyz; + // Per channel + maxMethod0.xyz = max( maxColor.xyz, maxMethod0.xyz ); + // By color + getMax = dot( maxColor.xyz, 1.0f ); + getMax2 = dot( maxMethod1.xyz, 1.0f ); + maxMethod1.xyz = ( getMax >= getMax2 ) ? maxColor.xyz : maxMethod1.xyz; + } + } + + minValue.xyz = rt_blackpoint_method ? minMethod1.xyz : minMethod0.xyz; + maxValue.xyz = rt_whitepoint_method ? maxMethod1.xyz : maxMethod0.xyz; + midValue.xyz = midColor.xyz / Sigma; + // When minValue = maxValue means the entire color is thrown out with correction + // This is correct behavior because this means that color component has the same fixed value on ALL pixels + // No game developer should ever make a coloring like that, but, you never know + maxValue.xyz = ( minValue.xyz >= maxValue.xyz ) ? float3( 1.0f, 1.0f, 1.0f ) : maxValue.xyz; + // Try and avoid some flickering + // Not really working consistently, too radical changes in min values sometimes + float3 prevMin = tex2D( samplerPrevious, float2( texcoord.x / 6.0f, texcoord.y )).xyz; + float3 prevMid = tex2D( samplerPrevious, float2(( texcoord.x + 2.0f ) / 6.0f, texcoord.y )).xyz; + float3 prevMax = tex2D( samplerPrevious, float2(( texcoord.x + 4.0f ) / 6.0f, texcoord.y )).xyz; + float smoothf = transition_speed * 4.0f + 1.0f; + float time = frametime * 0.001f; + maxValue.xyz = enable_fade ? interpolate( prevMax.xyz, maxValue.xyz, smoothf, time ) : maxValue.xyz; + minValue.xyz = enable_fade ? interpolate( prevMin.xyz, minValue.xyz, smoothf, time ) : minValue.xyz; + midValue.xyz = enable_fade ? interpolate( prevMid.xyz, midValue.xyz, smoothf, time ) : midValue.xyz; + // Freeze Correction + maxValue.xyz = freeze ? prevMax.xyz : maxValue.xyz; + minValue.xyz = freeze ? prevMin.xyz : minValue.xyz; + midValue.xyz = freeze ? prevMid.xyz : midValue.xyz; + // Return + if( pos.x < 2 ) + return float4( minValue.xyz, 1.0f ); + else if( pos.x >= 2 && pos.x < 4 ) + return float4( midValue.xyz, 1.0f ); + else + return float4( maxValue.xyz, 1.0f ); + return float4( 0.5, 0.5, 0.5, 1.0 ); + } + + float4 PS_RemoveTint(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( samplerColor, texcoord ); + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 0, enable_dither, dither_strength, 1, 0.5f ); + color.xyz = saturate( color.xyz + dnoise.xyz ); + // Grab min, max, mid values + float3 minValue = tex2D( samplerDS_1x1, float2( texcoord.x / 6.0f, texcoord.y )).xyz; + float3 midValue = tex2D( samplerDS_1x1, float2(( texcoord.x + 2.0f ) / 6.0f, texcoord.y )).xyz; + float3 maxValue = tex2D( samplerDS_1x1, float2(( texcoord.x + 4.0f ) / 6.0f, texcoord.y )).xyz; + // Get middle correction method + float middle = dot( float2( dot( minValue.xyz, 0.333333f ), dot( maxValue.xyz, 0.333333f )), 0.5f ); + middle = mid_use_alt_method ? middle : 0.5f; + // Set min value + minValue.xyz = lerp( 0.0f, minValue.xyz, rt_bp_str ); + minValue.xyz = rt_enable_blackpoint_correction ? minValue.xyz : 0.0f; + // Set max value + maxValue.xyz = lerp( 1.0f, maxValue.xyz, rt_wp_str ); + maxValue.xyz = rt_enable_whitepoint_correction ? maxValue.xyz : 1.0f; + // Set mid value + midValue.xyz = midValue.xyz - middle; + midValue.xyz *= midCC_scale; + midValue.xyz = rt_enable_midpoint_correction ? midValue.xyz : 0.0f; + // Main color correction + color.xyz = saturate( color.xyz - minValue.xyz ) / ( maxValue.xyz - minValue.xyz ); + // White Point luma preservation + float avgMax = dot( maxValue.xyz, 0.333333f ); + color.xyz = lerp( color.xyz, color.xyz * avgMax, rt_whitepoint_respect_luma * rt_wp_rl_str ); + // Black Point luma preservation + float avgMin = dot( minValue.xyz, 0.333333f ); + color.xyz = lerp( color.xyz, color.xyz * ( 1.0f - avgMin ) + avgMin, rt_blackpoint_respect_luma * rt_bp_rl_str ); + // Mid Point correction + float avgCol = dot( color.xyz, 0.333333f ); // Avg after main correction + float avgMid = dot( midValue.xyz, 0.333333f ); + avgCol = 1.0f - abs( avgCol * 2.0f - 1.0f ); + color.xyz = saturate( color.xyz - midValue.xyz * avgCol + avgMid * avgCol * rt_midpoint_respect_luma ); + // Debug + switch( debug_mode ) + { + case 0: { color.xyz = color.xyz; } break; + case 1: { color.xyz = tex2D( samplerDS_1_Min, texcoord ).xyz; } break; + case 2: { color.xyz = tex2D( samplerDS_1_Max, texcoord ).xyz; } break; + case 3: { color.xyz = tex2D( samplerDS_1_Mid, texcoord ).xyz; } break; + } + return float4( color.xyz, 1.0f ); + } + + float4 PS_StorePrev( float4 pos : SV_Position, float2 texcoord : TEXCOORD ) : SV_Target + { + float3 minValue = tex2D( samplerDS_1x1, float2( texcoord.x / 6.0f, texcoord.y )).xyz; + float3 midValue = tex2D( samplerDS_1x1, float2(( texcoord.x + 2.0f ) / 6.0f, texcoord.y )).xyz; + float3 maxValue = tex2D( samplerDS_1x1, float2(( texcoord.x + 4.0f ) / 6.0f, texcoord.y )).xyz; + if( pos.x < 2 ) + return float4( minValue.xyz, 1.0f ); + else if( pos.x >= 2 && pos.x < 4 ) + return float4( midValue.xyz, 1.0f ); + else + return float4( maxValue.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_01B_RT_Correct_Color + < ui_tooltip = "Remove Tint/Color Cast\n\n" + "Automatically adjust Blackpoint, Whitepoint, and remove color tints/casts while enhancing contrast.\n" + "Both correcting per individual channel, as well as Light/Dark colors are supported.\n" + "This shader will not adjust tinting applied in gamma, and this is considered out of scope.\n\n" + + "RT_PRECISION_LEVEL_0_TO_4\n" + "Sets the precision level in detecting the white and black points. Higher levels mean less precision and more color removal.\n" + "Too high values will remove significant amounts of color and may cause shifts in color, contrast, or banding artefacts.";> + { + pass prod80_pass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_WriteColor; + RenderTarget = texColor; + } + pass prod80_pass1 + { + VertexShader = PostProcessVS; + PixelShader = PS_MinMax_1; + RenderTarget0 = texDS_1_Min; + RenderTarget1 = texDS_1_Max; + RenderTarget2 = texDS_1_Mid; + } + pass prod80_pass2 + { + VertexShader = PostProcessVS; + PixelShader = PS_MinMax_1x1; + RenderTarget = texDS_1x1; + } + pass prod80_pass3 + { + VertexShader = PostProcessVS; + PixelShader = PS_RemoveTint; + } + pass prod80_pass4 + { + VertexShader = PostProcessVS; + PixelShader = PS_StorePrev; + RenderTarget = texPrevious; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_01_Color_Gamut.fx b/data_from_portwine/Reshade/Shaders/PD80_01_Color_Gamut.fx new file mode 100644 index 00000000..545be244 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_01_Color_Gamut.fx @@ -0,0 +1,248 @@ +/* + Description : PD80 01 Color Gamut for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +namespace pd80_colorconversion +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int colorgamut < + ui_type = "combo"; + ui_items= "No Change\0Adobe RGB\0Apple RGB\0Best RGB\0Beta RGB\0Bruce RGB\0CIE RGB\0Color Match\0Don\0ECI\0Ekta Space PS5\0NTSC\0PAL-SECAM\0ProPhoto\0SMPTE-C\0Wide Gamut RGB\0"; + ui_label = "Color Gamut Selection"; + ui_tooltip = "Color Gamut Selection"; + > = 0; + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //D65 + static const float3x3 sRGB_To_XYZ = float3x3( + 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041); + + //D65 (0) + static const float3x3 XYZ_To_sRGB = float3x3( + 3.2404542, -1.5371385, -0.4985314, + -0.9692660, 1.8760108, 0.0415560, + 0.0556434, -0.2040259, 1.0572252); + + //D65 (1) + static const float3x3 XYZ_To_AdobeRGB = float3x3( + 2.0413690, -0.5649464, -0.3446944, + -0.9692660, 1.8760108, 0.0415560, + 0.0134474, -0.1183897, 1.0154096); + + //D65 (2) + static const float3x3 XYZ_To_AppleRGB = float3x3( + 2.9515373, -1.2894116, -0.4738445, + -1.0851093, 1.9908566, 0.0372026, + 0.0854934, -0.2694964, 1.0912975); + + //D50 (3) + static const float3x3 XYZ_To_BestRGB = float3x3( + 1.7552599, -0.4836786, -0.2530000, + -0.5441336, 1.5068789, 0.0215528, + 0.0063467, -0.0175761, 1.2256959); + + //D50 (4) + static const float3x3 XYZ_To_BetaRGB = float3x3( + 1.6832270, -0.4282363, -0.2360185, + -0.7710229, 1.7065571, 0.0446900, + 0.0400013, -0.0885376, 1.2723640); + + //D65 (5) + static const float3x3 XYZ_To_BruceRGB = float3x3( + 2.7454669, -1.1358136, -0.4350269, + -0.9692660, 1.8760108, 0.0415560, + 0.0112723, -0.1139754, 1.0132541); + + //E (6) + static const float3x3 XYZ_To_CIERGB = float3x3( + 2.3706743, -0.9000405, -0.4706338, + -0.5138850, 1.4253036, 0.0885814, + 0.0052982, -0.0146949, 1.0093968); + + //D50 (7) + static const float3x3 XYZ_To_ColorMatch = float3x3( + 2.6422874, -1.2234270, -0.3930143, + -1.1119763, 2.0590183, 0.0159614, + 0.0821699, -0.2807254, 1.4559877); + + //D50 (8) + static const float3x3 XYZ_To_Don = float3x3( + 1.7603902, -0.4881198, -0.2536126, + -0.7126288, 1.6527432, 0.0416715, + 0.0078207, -0.0347411, 1.2447743); + + //D50 (9) + static const float3x3 XYZ_To_ECI = float3x3( + 1.7827618, -0.4969847, -0.2690101, + -0.9593623, 1.9477962, -0.0275807, + 0.0859317, -0.1744674, 1.3228273); + + //D50 (10) + static const float3x3 XYZ_To_EktaSpacePS5 = float3x3( + 2.0043819, -0.7304844, -0.2450052, + -0.7110285, 1.6202126, 0.0792227, + 0.0381263, -0.0868780, 1.2725438); + + //C (11) + static const float3x3 XYZ_To_NTSC = float3x3( + 1.9099961, -0.5324542, -0.2882091, + -0.9846663, 1.9991710, -0.0283082, + 0.0583056, -0.1183781, 0.8975535); + + //D65 (12) + static const float3x3 XYZ_To_PALSECAM = float3x3( + 3.0628971, -1.3931791, -0.4757517, + -0.9692660, 1.8760108, 0.0415560, + 0.0678775, -0.2288548, 1.0693490); + + //D50 (13) + static const float3x3 XYZ_To_ProPhoto = float3x3( + 1.3459433, -0.2556075, -0.0511118, + -0.5445989, 1.5081673, 0.0205351, + 0.0000000, 0.0000000, 1.2118128); + + //D65 (14) + static const float3x3 XYZ_To_SMPTEC = float3x3( + 3.5053960, -1.7394894, -0.5439640, + -1.0690722, 1.9778245, 0.0351722, + 0.0563200, -0.1970226, 1.0502026); + + //D50 (15) + static const float3x3 XYZ_To_WideGamutRGB = float3x3( + 1.4628067, -0.1840623, -0.2743606, + -0.5217933, 1.4472381, 0.0677227, + 0.0349342, -0.0968930, 1.2884099); + + //D65 to D50 + static const float3x3 D65_To_D50 = float3x3( + 1.0478112, 0.0228866, -0.0501270, + 0.0295424, 0.9904844, -0.0170491, + -0.0092345, 0.0150436, 0.7521316); + + //D65 to E + static const float3x3 D65_To_E = float3x3( + 1.0502616, 0.0270757, -0.0232523, + 0.0390650, 0.9729502, -0.0092579, + -0.0024047, 0.0026446, 0.918087); + + //D65 to C + static const float3x3 D65_To_C = float3x3( + 1.0097785, 0.0070419, 0.0127971, + 0.0123113, 0.9847094, 0.0032962, + 0.0038284, -0.0072331, 1.0891639); + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float3 LinearTosRGB( float3 color ) + { + float3 x = color * 12.92f; + float3 y = 1.055f * pow(saturate(color), 1.0f / 2.4f) - 0.055f; + + float3 clr = color; + clr.r = color.r < 0.0031308f ? x.r : y.r; + clr.g = color.g < 0.0031308f ? x.g : y.g; + clr.b = color.b < 0.0031308f ? x.b : y.b; + + return clr; + } + + float3 SRGBToLinear( float3 color ) + { + float3 x = color / 12.92f; + float3 y = pow(max((color + 0.055f) / 1.055f, 0.0f), 2.4f); + + float3 clr = color; + clr.r = color.r <= 0.04045f ? x.r : y.r; + clr.g = color.g <= 0.04045f ? x.g : y.g; + clr.b = color.b <= 0.04045f ? x.b : y.b; + + return clr; + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_ColorConversion(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + color.xyz = SRGBToLinear( color.xyz ); + color.xyz = mul( sRGB_To_XYZ, color.xyz ); + float3x3 gamut; + switch( colorgamut ) + { + case 0: { gamut = XYZ_To_sRGB; } break; + case 1: { gamut = XYZ_To_AdobeRGB; } break; + case 2: { gamut = XYZ_To_AppleRGB; } break; + case 3: { gamut = XYZ_To_BestRGB; } break; + case 4: { gamut = XYZ_To_BetaRGB; } break; + case 5: { gamut = XYZ_To_BruceRGB; } break; + case 6: { gamut = XYZ_To_CIERGB; } break; + case 7: { gamut = XYZ_To_ColorMatch; } break; + case 8: { gamut = XYZ_To_Don; } break; + case 9: { gamut = XYZ_To_ECI; } break; + case 10: { gamut = XYZ_To_EktaSpacePS5; } break; + case 11: { gamut = XYZ_To_NTSC; } break; + case 12: { gamut = XYZ_To_PALSECAM; } break; + case 13: { gamut = XYZ_To_ProPhoto; } break; + case 14: { gamut = XYZ_To_SMPTEC; } break; + case 15: { gamut = XYZ_To_WideGamutRGB; } break; + } + float3x3 refwhitemat = float3x3( + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0); + if( colorgamut == 3 ) refwhitemat = D65_To_D50; + if( colorgamut == 4 ) refwhitemat = D65_To_D50; + if( colorgamut == 6 ) refwhitemat = D65_To_E; + if( colorgamut == 7 ) refwhitemat = D65_To_D50; + if( colorgamut == 8 ) refwhitemat = D65_To_D50; + if( colorgamut == 9 ) refwhitemat = D65_To_D50; + if( colorgamut == 10 ) refwhitemat = D65_To_D50; + if( colorgamut == 11 ) refwhitemat = D65_To_C; + if( colorgamut == 13 ) refwhitemat = D65_To_D50; + if( colorgamut == 15 ) refwhitemat = D65_To_D50; + color.xyz = mul( gamut, mul( refwhitemat, color.xyz )); + color.xyz = LinearTosRGB( color.xyz ); + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_01_Color_Gamut + { + pass prod80_pass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_ColorConversion; + } + } +} + + diff --git a/data_from_portwine/Reshade/Shaders/PD80_02_Bloom.fx b/data_from_portwine/Reshade/Shaders/PD80_02_Bloom.fx new file mode 100644 index 00000000..d93511f1 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_02_Bloom.fx @@ -0,0 +1,813 @@ +/* + Description : PD80 01 HQ Bloom for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + 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 + + MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" +#include "PD80_00_Color_Spaces.fxh" +#include "PD80_00_Base_Effects.fxh" + +namespace pd80_hqbloom +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + // Funky stuff + #ifndef BLOOM_ENABLE_CA + #define BLOOM_ENABLE_CA 0 + #endif + + // Min: 0, Max: 3 | Bloom Quality, 0 is best quality (full screen) and values higher than that will progessively use lower resolution texture. Value 3 will use 1/4th screen resolution texture size + // 0 = Fullscreen - Ultra + // 1 = 1/4th size - High + // 2 = 1/16th size - Medium + // Default = High quality (1) as difference is nearly impossible to tell during gameplay, and performance 60% faster than Ultra (0) + // Using medium quality can show some artifacts because of the low resolution of texture upscaled to fullscreen when using CA, however it's very fast + #ifndef BLOOM_QUALITY_0_TO_2 + #define BLOOM_QUALITY_0_TO_2 1 + #endif + + #ifndef BLOOM_LOOPCOUNT + #define BLOOM_LOOPCOUNT 300 + #endif + + #ifndef BLOOM_LIMITER + #define BLOOM_LIMITER 0.0001 + #endif + + #ifndef BLOOM_USE_FOCUS_BLOOM + #define BLOOM_USE_FOCUS_BLOOM 0 + #endif + + // Dodgy code that should avoid some compilation errors that seem to happen sometimes for no particular reason + #if( BLOOM_QUALITY_0_TO_2 > 2 ) + #define BLOOM_MIPLVL 2 + #elif( BLOOM_QUALITY_0_TO_2 < 0 ) + #define BLOOM_MIPLVL 0 + #else + #define BLOOM_MIPLVL BLOOM_QUALITY_0_TO_2 + #endif + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool debugBloom < + ui_label = "Show only bloom on screen"; + ui_category = "Bloom debug"; + > = false; + uniform float dither_strength < + ui_label = "Bloom Dither Stength"; + ui_tooltip = "Bloom Dither Stength"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 10.0; + > = 2.0; + uniform float BloomMix < + ui_label = "Bloom Mix"; + ui_tooltip = "Bloom Mix"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.5; + uniform float BloomLimit < + ui_label = "Bloom Threshold"; + ui_tooltip = "Bloom Threshold"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.333; + uniform float GreyValue < + ui_label = "Bloom Exposure 50% Greyvalue"; + ui_tooltip = "Bloom Exposure 50% Greyvalue"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.333; + uniform float bExposure < + ui_label = "Bloom Exposure"; + ui_tooltip = "Bloom Exposure"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 5.0; + > = 0.0; +#if( BLOOM_USE_FOCUS_BLOOM ) + uniform float fBloomStrength < + ui_label = "Bloom Width (Focus Center) Bias"; + ui_tooltip = "Bloom Width (Focus Center) Bias"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.25; + uniform float BlurSigmaNarrow < + ui_label = "Bloom Width (Focus Center)"; + ui_tooltip = "Bloom Width (Focus Center)"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = 10.0; + ui_max = 40.0; + > = 15.0; +#endif + uniform float BlurSigma < + ui_label = "Bloom Width"; + ui_tooltip = "Bloom Width"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = 10.0; + ui_max = 300.0; + > = 30.0; + uniform float BloomSaturation < + ui_label = "Bloom Add Saturation"; + ui_tooltip = "Bloom Add Saturation"; + ui_category = "Bloom"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 2.0; + > = 0.0; + #if( BLOOM_ENABLE_CA == 0 ) + uniform bool enableBKelvin < + ui_label = "Enable Bloom Color Temp (K)"; + ui_tooltip = "Enable Bloom Color Temp (K)"; + ui_category = "Bloom Color Temperature"; + > = false; + uniform uint BKelvin < + ui_type = "slider"; + ui_label = "Bloom Color Temp (K)"; + ui_tooltip = "Bloom Color Temp (K)"; + ui_category = "Bloom Color Temperature"; + ui_min = 1000; + ui_max = 40000; + > = 6500; + #endif + #if( BLOOM_ENABLE_CA == 1 ) + uniform int CA_type < __UNIFORM_COMBO_INT1 + ui_label = "Chromatic Aberration Type"; + ui_tooltip = "Chromatic Aberration Type"; + ui_category = "Chromatic Aberration"; + ui_items = "Center Weighted Radial\0Center Weighted Longitudinal\0Full screen Radial\0Full screen Longitudinal\0"; + > = 0; + uniform bool use_only_ca < + ui_label = "Use only CA"; + ui_tooltip = "Use only CA"; + ui_category = "Chromatic Aberration"; + > = false; + uniform int degrees < + ui_type = "slider"; + ui_label = "CA Rotation Offset"; + ui_tooltip = "CA Rotation Offset"; + ui_category = "Chromatic Aberration"; + ui_min = 0; + ui_max = 360; + ui_step = 1; + > = 135; + uniform float CA < + ui_type = "slider"; + ui_label = "CA Global Width"; + ui_tooltip = "CA Global Width"; + ui_category = "Chromatic Aberration"; + ui_min = -150.0f; + ui_max = 150.0f; + > = 60.0; + uniform float CA_strength < + ui_type = "slider"; + ui_label = "CA Effect Strength"; + ui_tooltip = "CA Effect Strength"; + ui_category = "Chromatic Aberration"; + ui_min = 0.0f; + ui_max = 5.0f; + > = 0.5; + #endif + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texPrepLOD { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; MipLevels = 5; }; + texture texBLuma { Width = 256; Height = 256; Format = R16F; MipLevels = 9; }; + texture texBAvgLuma { Format = R16F; }; + texture texBPrevAvgLuma { Format = R16F; }; + #if( BLOOM_ENABLE_CA == 1 ) + texture texCABloom { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + #endif + #if( BLOOM_QUALITY_0_TO_2 == 0 ) + texture texBloomIn { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + texture texBloomH { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + texture texBloom { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + texture texBloomAll { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + #if( BLOOM_USE_FOCUS_BLOOM ) + texture texBloomHF { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + texture texBloomF { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + #endif + #define SWIDTH BUFFER_WIDTH + #define SHEIGHT BUFFER_HEIGHT + #elif( BLOOM_QUALITY_0_TO_2 == 1 ) + #define SWIDTH ( BUFFER_WIDTH / 2 ) + #define SHEIGHT ( BUFFER_HEIGHT / 2 ) + texture texBloomIn { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + texture texBloomH { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + texture texBloom { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + texture texBloomAll { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + #if( BLOOM_USE_FOCUS_BLOOM ) + texture texBloomF { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + texture texBloomHF { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + #endif + #else + #define SWIDTH ( BUFFER_WIDTH / 4 ) + #define SHEIGHT ( BUFFER_HEIGHT / 4 ) + texture texBloomIn { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + texture texBloomH { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + texture texBloom { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + texture texBloomAll { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + #if( BLOOM_USE_FOCUS_BLOOM ) + texture texBloomF { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + texture texBloomHF { Width = SWIDTH; Height = SHEIGHT; Format = RGBA16F; }; + #endif + #endif + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerLODColor { Texture = texPrepLOD; }; + sampler samplerLinColor { Texture = ReShade::BackBufferTex; SRGBTexture = true; }; + sampler samplerBLuma { Texture = texBLuma; }; + sampler samplerBAvgLuma { Texture = texBAvgLuma; }; + sampler samplerBPrevAvgLuma { Texture = texBPrevAvgLuma; }; + sampler samplerBloomIn + { + Texture = texBloomIn; + AddressU = BORDER; + AddressV = BORDER; + AddressW = BORDER; + }; + sampler samplerBloomH + { + Texture = texBloomH; + AddressU = BORDER; + AddressV = BORDER; + AddressW = BORDER; + }; + #if( BLOOM_USE_FOCUS_BLOOM ) + sampler samplerBloomHF + { + Texture = texBloomHF; + AddressU = BORDER; + AddressV = BORDER; + AddressW = BORDER; + }; + sampler samplerBloomF { Texture = texBloomF; }; + #endif + #if( BLOOM_ENABLE_CA == 1 ) + sampler samplerCABloom { Texture = texCABloom; }; + #endif + sampler samplerBloom { Texture = texBloom; }; + sampler samplerBloomAll { Texture = texBloomAll; }; + //// DEFINES //////////////////////////////////////////////////////////////////// + uniform float frametime < source = "frametime"; >; + #define LumCoeff float3(0.212656, 0.715158, 0.072186) + #define PI 3.141592f + #define LOOPCOUNT 500.0f + #define aspect float( BUFFER_WIDTH * BUFFER_RCP_HEIGHT ) + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float getLuminance( in float3 x ) + { + return dot( x, LumCoeff ); + } + + 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/ + // But more success using higher values >= 0.5 + float linExp = GreyValue / avgLuminance; + exposure = log2( linExp ); + return exposure; + } + + float3 CalcExposedColor( in float3 color, in float avgLuminance, in float offset, in float GreyValue ) + { + float exposure = Log2Exposure( avgLuminance, GreyValue ); + exposure += offset; //offset = exposure + return exp2( exposure ) * color; + } + + float3 screen( in float3 c, in float3 b ) + { + return 1.0f - ( 1.0f - c ) * ( 1.0f - b ); + } + + //// COMPUTE SHADERS //////////////////////////////////////////////////////////// + // Not supported in ReShade (?) + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float PS_WriteBLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( samplerLinColor, texcoord ); + float luma = getLuminance( color.xyz ); + luma = max( luma, BloomLimit ); // Bloom threshold + return log2( luma ); + } + + float PS_AvgBLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float luma = tex2Dlod( samplerBLuma, float4(0.5f, 0.5f, 0, 8 )).x; + luma = exp2( luma ); + float prevluma = tex2D( samplerBPrevAvgLuma, float2( 0.5f, 0.5f )).x; + float fps = max( 1000.0f / frametime, 0.001f ); + fps *= 0.5f; //approx. 1 second delay to change luma between bright and dark + float avgLuma = lerp( prevluma, luma, saturate( 1.0f / fps )); + return avgLuma; + } + + float4 PS_PrepLOD(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + return tex2D( ReShade::BackBuffer, texcoord ); + } + + float4 PS_BloomIn(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2Dlod( samplerLODColor, float4( texcoord.xy, 0, BLOOM_MIPLVL )); + float luma = tex2D( samplerBAvgLuma, float2( 0.5f, 0.5f )).x; + luma = clamp( luma, 0.000001f, 0.999999f ); + color.xyz = saturate( color.xyz - luma ) / saturate( 1.0f - luma ); + color.xyz = CalcExposedColor( color.xyz, luma, bExposure, GreyValue ); + return float4( color.xyz, 1.0f ); + } + + #if( !BLOOM_USE_FOCUS_BLOOM ) + float4 PS_GaussianH(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( samplerBloomIn, texcoord ); + float px = rcp( SWIDTH ); + float SigmaSum = 0.0f; + float pxlOffset = 1.5f; + float2 buffSigma = 0.0f; + #if( BLOOM_QUALITY_0_TO_2 == 0 ) + float bSigma = BlurSigma; + #elif( BLOOM_QUALITY_0_TO_2 == 1 ) + float bSigma = BlurSigma * 0.5f; + #else + float bSigma = BlurSigma * 0.25f; + #endif + //Gaussian Math + float3 Sigma; + Sigma.x = 1.0f / ( sqrt( 2.0f * PI ) * bSigma ); + Sigma.y = exp( -0.5f / ( bSigma * bSigma )); + Sigma.z = Sigma.y * Sigma.y; + + //Center Weight + color.xyz *= Sigma.x; + //Adding to total sum of distributed weights + SigmaSum += Sigma.x; + //Setup next weight + Sigma.xy *= Sigma.yz; + + [loop] + for( int i = 0; i < BLOOM_LOOPCOUNT && Sigma.x > BLOOM_LIMITER; ++i ) + { + buffSigma.x = Sigma.x * Sigma.y; + buffSigma.y = Sigma.x + buffSigma.x; + color += tex2Dlod( samplerBloomIn, float4( texcoord.xy + float2( pxlOffset * px, 0.0f ), 0, 0 )) * buffSigma.y; + color += tex2Dlod( samplerBloomIn, float4( texcoord.xy - float2( pxlOffset * px, 0.0f ), 0, 0 )) * buffSigma.y; + SigmaSum += ( 2.0f * Sigma.x + 2.0f * buffSigma.x ); + pxlOffset += 2.0f; + Sigma.xy *= Sigma.yz; + Sigma.xy *= Sigma.yz; + } + + color /= SigmaSum; + return color; + } + #endif + + #if( BLOOM_USE_FOCUS_BLOOM ) + void PS_GaussianH(float4 pos : SV_Position, float2 texcoord : TEXCOORD, out float4 bloom1 : SV_Target0, out float4 bloom2 : SV_Target1) + { + // This part of shader writes both wide and narrow gaussian horizontal during the same pass to avoid sampling same texture twice + // Bloom quality setting + #if( BLOOM_QUALITY_0_TO_2 == 0 ) + float Mult = 1.0f; + #elif( BLOOM_QUALITY_0_TO_2 == 1 ) + float Mult = 0.5f; + #else + float Mult = 0.25f; + #endif + + // Required variables + float px = rcp( SWIDTH ); + float pxlOffset = 1.5f; + + // Color + bloom1 = tex2D( samplerBloomIn, texcoord ); + bloom2 = bloom1; + + // Wide bloom + float b1_Sum = 0.0f; + float2 b1_tSigma = 0.0f; + float b1_Width = BlurSigma * Mult; + float3 b1_Sigma; + b1_Sigma.x = 1.0f / ( sqrt( 2.0f * PI ) * b1_Width ); + b1_Sigma.y = exp( -0.5f / ( b1_Width * b1_Width )); + b1_Sigma.z = b1_Sigma.y * b1_Sigma.y; + bloom1 *= b1_Sigma.x; + b1_Sum += b1_Sigma.x; + b1_Sigma.xy *= b1_Sigma.yz; + + // Narrow bloom + float b2_Sum = 0.0f; + float2 b2_tSigma = 0.0f; + float b2_Width = BlurSigmaNarrow * Mult; + float3 b2_Sigma; + b2_Sigma.x = 1.0f / ( sqrt( 2.0f * PI ) * b2_Width ); + b2_Sigma.y = exp( -0.5f / ( b2_Width * b2_Width )); + b2_Sigma.z = b2_Sigma.y * b2_Sigma.y; + bloom2 *= b2_Sigma.x; + b2_Sum += b2_Sigma.x; + b2_Sigma.xy *= b2_Sigma.yz; + + // Temp variables + float4 temp1; + float4 temp2; + + [loop] + for( int i = 0; i < BLOOM_LOOPCOUNT && b1_Sigma.x > BLOOM_LIMITER; ++i ) + { + // Setup weights (wide) + b1_tSigma.x = b1_Sigma.x * b1_Sigma.y; + b1_tSigma.y = b1_Sigma.x + b1_tSigma.x; + // Setup weights (narrow) + b2_tSigma.x = b2_Sigma.x * b2_Sigma.y; + b2_tSigma.y = b2_Sigma.x + b2_tSigma.x; + // Fetch + temp1 = tex2Dlod( samplerBloomIn, float4( texcoord.xy + float2( pxlOffset * px, 0.0f ), 0, 0 )); + temp2 = tex2Dlod( samplerBloomIn, float4( texcoord.xy - float2( pxlOffset * px, 0.0f ), 0, 0 )); + // Merge + bloom1 += temp1 * b1_tSigma.y; + bloom1 += temp2 * b1_tSigma.y; + bloom2 += temp1 * b2_tSigma.y; + bloom2 += temp2 * b2_tSigma.y; + // Sum + b1_Sum += 2.0f * b1_tSigma.y; + b2_Sum += 2.0f * b2_tSigma.y; + // Next offset + pxlOffset += 2.0f; + // Next weights + b1_Sigma.xy *= b1_Sigma.yz; + b1_Sigma.xy *= b1_Sigma.yz; + b2_Sigma.xy *= b2_Sigma.yz; + b2_Sigma.xy *= b2_Sigma.yz; + } + + bloom1 /= b1_Sum; + bloom2 /= b2_Sum; + } + #endif + + float4 PS_GaussianV(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( samplerBloomH, texcoord ); + float py = rcp( SHEIGHT ); + float SigmaSum = 0.0f; + float pxlOffset = 1.5f; + float2 buffSigma = 0.0f; + #if( BLOOM_QUALITY_0_TO_2 == 0 ) + float bSigma = BlurSigma; + #elif( BLOOM_QUALITY_0_TO_2 == 1 ) + float bSigma = BlurSigma * 0.5f; + #else + float bSigma = BlurSigma * 0.25f; + #endif + //Gaussian Math + float3 Sigma; + Sigma.x = 1.0f / ( sqrt( 2.0f * PI ) * bSigma ); + Sigma.y = exp( -0.5f / ( bSigma * bSigma )); + Sigma.z = Sigma.y * Sigma.y; + + //Center Weight + color.xyz *= Sigma.x; + //Adding to total sum of distributed weights + SigmaSum += Sigma.x; + //Setup next weight + Sigma.xy *= Sigma.yz; + + [loop] + for( int i = 0; i < BLOOM_LOOPCOUNT && Sigma.x > BLOOM_LIMITER; ++i ) + { + buffSigma.x = Sigma.x * Sigma.y; + buffSigma.y = Sigma.x + buffSigma.x; + color += tex2Dlod( samplerBloomH, float4( texcoord.xy + float2( 0.0f, pxlOffset * py ), 0, 0 )) * buffSigma.y; + color += tex2Dlod( samplerBloomH, float4( texcoord.xy - float2( 0.0f, pxlOffset * py ), 0, 0 )) * buffSigma.y; + SigmaSum += ( 2.0f * Sigma.x + 2.0f * buffSigma.x ); + pxlOffset += 2.0f; + Sigma.xy *= Sigma.yz; + Sigma.xy *= Sigma.yz; + } + + color /= SigmaSum; + return color; + } + + #if( BLOOM_USE_FOCUS_BLOOM ) + float4 PS_GaussianVF(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( samplerBloomHF, texcoord ); + float py = rcp( SHEIGHT ); + float SigmaSum = 0.0f; + float pxlOffset = 1.5f; + float2 buffSigma = 0.0f; + #if( BLOOM_QUALITY_0_TO_2 == 0 ) + float bSigma = BlurSigmaNarrow; + #elif( BLOOM_QUALITY_0_TO_2 == 1 ) + float bSigma = BlurSigmaNarrow * 0.5f; + #else + float bSigma = BlurSigmaNarrow * 0.25f; + #endif + //Gaussian Math + float3 Sigma; + Sigma.x = 1.0f / ( sqrt( 2.0f * PI ) * bSigma ); + Sigma.y = exp( -0.5f / ( bSigma * bSigma )); + Sigma.z = Sigma.y * Sigma.y; + + //Center Weight + color.xyz *= Sigma.x; + //Adding to total sum of distributed weights + SigmaSum += Sigma.x; + //Setup next weight + Sigma.xy *= Sigma.yz; + + [loop] + for( int i = 0; i < BLOOM_LOOPCOUNT && Sigma.x > BLOOM_LIMITER; ++i ) + { + buffSigma.x = Sigma.x * Sigma.y; + buffSigma.y = Sigma.x + buffSigma.x; + color += tex2Dlod( samplerBloomHF, float4( texcoord.xy + float2( 0.0f, pxlOffset * py ), 0, 0 )) * buffSigma.y; + color += tex2Dlod( samplerBloomHF, float4( texcoord.xy - float2( 0.0f, pxlOffset * py ), 0, 0 )) * buffSigma.y; + SigmaSum += ( 2.0f * Sigma.x + 2.0f * buffSigma.x ); + pxlOffset += 2.0f; + Sigma.xy *= Sigma.yz; + Sigma.xy *= Sigma.yz; + } + + color /= SigmaSum; + return color; + } + #endif + + float4 PS_Combine(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 widebloom = tex2D( samplerBloom, texcoord ); + #if( BLOOM_USE_FOCUS_BLOOM ) + float4 narrbloom = tex2D( samplerBloomF, texcoord ); + return saturate( widebloom * ( 1.0 - fBloomStrength ) + narrbloom * fBloomStrength ); + #else + return widebloom; + #endif + } + + #if( BLOOM_ENABLE_CA ) + float4 PS_CA(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = 0.0f; + float3 orig = tex2D( samplerBloomAll, texcoord ).xyz; + float px = BUFFER_RCP_WIDTH; + float py = BUFFER_RCP_HEIGHT; + + float2 coords = texcoord.xy * 2.0f - 1.0f; + float2 uv = coords.xy; + coords.xy /= float2( 1.0f / aspect, 1.0f ); + float2 caintensity= length( coords.xy ); // * 2.0f for higher weight in center + caintensity.y = caintensity.x * caintensity.x + 1.0f; + caintensity.x = 1.0f - ( 1.0f / ( caintensity.y * caintensity.y )); + + int degreesY = degrees; + float c = 0.0f; + float s = 0.0f; + switch( CA_type ) + { + // Radial: Y + 90 w/ multiplying with uv.xy + case 0: + { + degreesY = degrees + 90 > 360 ? degreesY = degrees + 90 - 360 : degrees + 90; + c = cos( radians( degrees )) * uv.x; + s = sin( radians( degreesY )) * uv.y; + } + break; + // Longitudinal: X = Y w/o multiplying with uv.xy + case 1: + { + c = cos( radians( degrees )); + s = sin( radians( degreesY )); + } + break; + // Full screen Radial + case 2: + { + degreesY = degrees + 90 > 360 ? degreesY = degrees + 90 - 360 : degrees + 90; + caintensity.x = 1.0f; + c = cos( radians( degrees )) * uv.x; + s = sin( radians( degreesY )) * uv.y; + } + break; + // Full screen Longitudinal + case 3: + { + caintensity.x = 1.0f; + c = cos( radians( degrees )); + s = sin( radians( degreesY )); + } + break; + } + + float3 huecolor = 0.0f; + float3 temp = 0.0f; + float o1 = 7.0f; + float o2 = 0.0f; + float3 d = 0.0f; + + // Scale CA (hackjob!) + float caWidth = CA * ( max( BUFFER_WIDTH, BUFFER_HEIGHT ) / 1920.0f ); // Scaled for 1920, raising resolution in X or Y should raise scale + + float offsetX = px * c * caintensity.x; + float offsetY = py * s * caintensity.x; + + for( float i = 0; i < 8; ++i ) + { + huecolor.xyz = HUEToRGB( i / 8.0f ); + o2 = lerp( -caWidth, caWidth, i / o1 ); + temp.xyz = tex2D( samplerBloomAll, texcoord.xy + float2( o2 * offsetX, o2 * offsetY )).xyz; + color.xyz += temp.xyz * huecolor.xyz; + d.xyz += huecolor.xyz; + } + color.xyz /= dot( d.xyz, 0.333333f ); // seems so-so OK + color.xyz = lerp( orig.xyz, color.xyz, CA_strength ); + color.xyz = lerp( color.xyz, color.xyz - orig.xyz, use_only_ca ); + return float4( color.xyz, 1.0f ); + } + #endif + + float4 PS_Gaussian(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + #if( !BLOOM_ENABLE_CA ) + float4 bloom = tex2D( samplerBloomAll, texcoord ); + #endif + #if( BLOOM_ENABLE_CA ) + float4 bloom = tex2D( samplerCABloom, texcoord ); + #endif + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + // Dither + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 0, 1, dither_strength, 1, 2.0f - ( 1.0f - BloomLimit ) ); + float3 steps = smoothstep( 0.0f, 0.012f, bloom.xyz ); + bloom.xyz = saturate( bloom.xyz + dnoise.xyz * steps.xyz ); + + #if( BLOOM_ENABLE_CA == 0 ) + if( enableBKelvin ) + { + float3 K = KelvinToRGB( BKelvin ); + float3 bLum = RGBToHSL( bloom.xyz ); + float3 retHSV = RGBToHSL( bloom.xyz * K.xyz ); + bloom.xyz = HSLToRGB( float3( retHSV.xy, bLum.z )); + } + #endif + // Vibrance + bloom.xyz = vib( bloom.xyz, BloomSaturation ); + float3 bcolor = screen( color.xyz, bloom.xyz ); + color.xyz = lerp( color.xyz, bcolor.xyz, BloomMix ); + color.xyz = debugBloom ? bloom.xyz : color.xyz; // render only bloom to screen + return float4( color.xyz, 1.0f ); + } + + float PS_PrevAvgBLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float avgLuma = tex2D( samplerBAvgLuma, float2( 0.5f, 0.5f )).x; + return avgLuma; + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_02_Bloom + < ui_tooltip = "Bloom\n\n" + "Bloom is an effect that causes diffraction of light around bright reflective or emittive sources\n\n" + "Preprocessor Settings\n\n" + "BLOOM_ENABLE_CA: Enables a chromatic aberration effect on bloom\n\n" + "BLOOM_QUALITY_0_TO_2: Sets the quality, 0 is full (and heavy!), 2 is low and very fast,\n" + "1 is high quality and best trade off between quality and performance\n\n" + "BLOOM_LOOPCOUNT: Limit to the amount of loops of the Width effect. Wider blooms may need higher\n" + "values (eg. max width is 300, this value should be 300)\n\n" + "BLOOM_LIMITER: Limiter to the bloom. Wider blooms may need lower values or the bloom starts to look\n" + "rectangular (eg. 0.0001 (default) is good to about width 100, after that start to decrease this value)\n\n" + "BLOOM_USE_FOCUS_BLOOM: Enables another pass to add a narrow bloom on top of the wide bloom";> + { + pass BLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_WriteBLuma; + RenderTarget = texBLuma; + } + pass AvgBLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_AvgBLuma; + RenderTarget = texBAvgLuma; + } + pass PrepLod + { + VertexShader = PostProcessVS; + PixelShader = PS_PrepLOD; + RenderTarget = texPrepLOD; + } + pass BloomIn + { + VertexShader = PostProcessVS; + PixelShader = PS_BloomIn; + RenderTarget = texBloomIn; + } + #if( BLOOM_USE_FOCUS_BLOOM ) + pass GaussianH + { + VertexShader = PostProcessVS; + PixelShader = PS_GaussianH; + RenderTarget0 = texBloomH; + RenderTarget1 = texBloomHF; + } + #endif + #if( !BLOOM_USE_FOCUS_BLOOM ) + pass GaussianH + { + VertexShader = PostProcessVS; + PixelShader = PS_GaussianH; + RenderTarget = texBloomH; + } + #endif + pass GaussianV + { + VertexShader = PostProcessVS; + PixelShader = PS_GaussianV; + RenderTarget = texBloom; + } + #if( BLOOM_USE_FOCUS_BLOOM ) + pass GaussianVF + { + VertexShader = PostProcessVS; + PixelShader = PS_GaussianVF; + RenderTarget = texBloomF; + } + #endif + pass Combine + { + VertexShader = PostProcessVS; + PixelShader = PS_Combine; + RenderTarget = texBloomAll; + } + #if( BLOOM_ENABLE_CA == 0 ) + pass GaussianBlur + { + VertexShader = PostProcessVS; + PixelShader = PS_Gaussian; + } + #endif + #if( BLOOM_ENABLE_CA == 1 ) + pass AddCA + { + VertexShader = PostProcessVS; + PixelShader = PS_CA; + RenderTarget = texCABloom; + } + pass GaussianBlur + { + VertexShader = PostProcessVS; + PixelShader = PS_Gaussian; + } + #endif + pass PreviousBLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_PrevAvgBLuma; + RenderTarget = texBPrevAvgLuma; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_02_Bonus_LUT_pack.fx b/data_from_portwine/Reshade/Shaders/PD80_02_Bonus_LUT_pack.fx new file mode 100644 index 00000000..90fe8906 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_02_Bonus_LUT_pack.fx @@ -0,0 +1,15 @@ +// Easy LUT config +// Name which will display in the UI. Should be without spaces +#define PD80_Technique_Name prod80_02_Bonus_LUT_pack + +// Texture name which contains the LUT(s) and the Tile Sizes, Amounts, etc. +#define PD80_LUT_File_Name "pd80_example-lut.png" +#define PD80_Tile_SizeXY 64 +#define PD80_Tile_Amount 64 +#define PD80_LUT_Amount 50 + +// Drop down menu which gives the names of the LUTs, each menu option should be followed by \0 +#define PD80_Drop_Down_Menu "PD80 Cinematic 01\0PD80 Cinematic 02\0PD80 Cinematic 03\0PD80 Cinematic 04\0PD80 Cinematic 05\0PD80 Cinematic 06\0PD80 Cinematic 07\0PD80 Cinematic 08\0PD80 Cinematic 09\0PD80 Cinematic 10\0PD80 Cinematic 11\0PD80 Cinematic 12\0PD80 Cinematic 13\0PD80 Cinematic 14\0PD80 Cinematic 15\0PD80 Cinematic 16\0PD80 Cinematic 17\0PD80 Cinematic 18\0PD80 Cinematic 19\0PD80 Cinematic 20\0PD80 Cinematic 21\0PD80 Cinematic 22\0PD80 Cinematic 23\0PD80 Cinematic 24\0PD80 Cinematic 25\0PD80 Cinematic 26\0PD80 Cinematic 27\0PD80 Cinematic 28\0PD80 Cinematic 29\0PD80 Cinematic 30\0PD80 Cinematic 31\0PD80 Cinematic 32\0PD80 Cinematic 33\0PD80 Cinematic 34\0PD80 Cinematic 35\0PD80 Cinematic 36\0PD80 Cinematic 37\0PD80 Cinematic 38\0PD80 Cinematic 39\0PD80 Cinematic 40\0PD80 Cinematic 41\0PD80 Cinematic 42\0PD80 Cinematic 43\0PD80 Cinematic 44\0PD80 Cinematic 45\0PD80 Cinematic 46\0PD80 Cinematic 47\0PD80 Cinematic 48\0PD80 Cinematic 49\0PD80 Cinematic 50\0" + +// Final pass to the shader +#include "PD80_LUT_v2.fxh" \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_02_Cinetools_LUT.fx b/data_from_portwine/Reshade/Shaders/PD80_02_Cinetools_LUT.fx new file mode 100644 index 00000000..0dc95998 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_02_Cinetools_LUT.fx @@ -0,0 +1,15 @@ +// Easy LUT config +// Name which will display in the UI. Should be without spaces +#define PD80_Technique_Name prod80_02_Cinetools_LUT + +// Texture name which contains the LUT(s) and the Tile Sizes, Amounts, etc. +#define PD80_LUT_File_Name "pd80_cinelut.png" +#define PD80_Tile_SizeXY 64 +#define PD80_Tile_Amount 64 +#define PD80_LUT_Amount 31 + +// Drop down menu which gives the names of the LUTs, each menu option should be followed by \0 +#define PD80_Drop_Down_Menu "FilmicGold\0FilmicGold_Contrast\0FilmicBlue\0FilmicBlue_Contrast\0TealOrangeNeutral\0TealOrangeYCSplit\0TealOrangeWarmMatte\0CinematicColors\0UltraWarmMatte\0UltraMatte\0BW-Max\0BW-MaxSepia\0BW-MatteLooks\0AlternativeProcess-01\0AlternativeProcess-02\0SuperGreens\0ColorHarmony-01\0ColorHarmony-02\0GoingBrownAgain\0Cyanolyte\0DustyOldMan\0DustyOldMatte\0DrankAllTheRedWine\0OldEleganceClean\0OldEleganceMatte\0HundredDollarStripper\0HundredDollarStripperMatte\0ClassicTealOrange\0ClassicTealOrangeMatte\0ClassicTealOrangeYHL\0ClassicTealOrangeYHLMatte\0" + +// Final pass to the shader +#include "PD80_LUT_v2.fxh" \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_02_LUT_Creator.fx b/data_from_portwine/Reshade/Shaders/PD80_02_LUT_Creator.fx new file mode 100644 index 00000000..30605e26 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_02_LUT_Creator.fx @@ -0,0 +1,118 @@ +/* + Description : PD80 02 LUT Creator for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +/* + This shader overlays the screen with a 512x512 high quality LUT. + One can run effects on this LUT using Reshade and export the results in a PNG + screenshot. You can take this screenshot into your favorite image editor and + make it into a 4096x64 LUT texture that can be read by Reshade's LUT shaders. + This way you can safe performance by using a texture to apply your favorite + effects instead of Reshade's color manipulation shaders. + + To use: + 1. Start game with Reshade + 2. Make sure PD80_03_LUT_Creator.fx is the first shader in your effect chain and any effects that shouldn't be enabled are disabled; Bloom, DoF, Noise/Grain, Dither, MXAO, SMAA, SSR, ... + 3. Adjust the game coloring, contrasts, brightness, gamma, etc. to taste using whatever Reshade effects you please. Once happy make a screenshot in .png format + 4. Exit game and load screenshot in Photoshop or your preferred image editing program + 5. Carefully cut and paste the individual rows into a 4096x64 size image + 6. Save the new image as a .png + 7. Back in the game open whatever LUT shader you have available (f.e. PD80_02_MultiLUT_2.0.fx) and load your new LUT file name with the correct parameters (Tile size 64, Number of tiles 64, Number of LUTs 1) + 8. Disable the effects used to make the LUT (or effects are applied twice) + + Profit. +*/ + +// "HALD_64.png" +// "pd80_neutral-lut.png" + +#include "ReShade.fxh" + +#ifndef PD80_LC_TEXTURE_NAME + #define PD80_LC_TEXTURE_NAME "pd80_neutral-lut.png" +#endif + +#ifndef PD80_LC_TEXTURE_WIDTH + #define PD80_LC_TEXTURE_WIDTH 512.0 +#endif + +#ifndef PD80_LC_TEXTURE_HEIGHT + #define PD80_LC_TEXTURE_HEIGHT 512.0 +#endif + +namespace pd80_lutoverlay +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texPicture < source = PD80_LC_TEXTURE_NAME; > { Width = PD80_LC_TEXTURE_WIDTH; Height = PD80_LC_TEXTURE_HEIGHT; Format = RGBA8; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerPicture { + Texture = texPicture; + AddressU = CLAMP; + AddressV = CLAMP; + AddressW = CLAMP; + }; + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_OverlayLUT(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float2 coords = float2( BUFFER_WIDTH, BUFFER_HEIGHT ) / float2( PD80_LC_TEXTURE_WIDTH, PD80_LC_TEXTURE_HEIGHT ); + coords.xy *= texcoord.xy; + float3 lut = tex2D( samplerPicture, coords ).xyz; + float3 color = tex2D( ReShade::BackBuffer, texcoord ).xyz; + float2 cutoff = float2( BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT ) * float2( PD80_LC_TEXTURE_WIDTH, PD80_LC_TEXTURE_HEIGHT ); + color = ( texcoord.y > cutoff.y || texcoord.x > cutoff.x ) ? color : lut; + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_02_LUT_Creator + < ui_tooltip = "This shader overlays the screen with a 512x512 high quality LUT.\n" + "One can run effects on this LUT using Reshade and export the results in a PNG\n" + "screenshot. You can take this screenshot into your favorite image editor and\n" + "make it into a 4096x64 LUT texture that can be read by Reshade's LUT shaders.\n" + "This way you can safe performance by using a texture to apply your favorite\n" + "effects instead of Reshade's color manipulation shaders.";> + { + pass prod80_pass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_OverlayLUT; + } + } +} + + diff --git a/data_from_portwine/Reshade/Shaders/PD80_03_Color_Space_Curves.fx b/data_from_portwine/Reshade/Shaders/PD80_03_Color_Space_Curves.fx new file mode 100644 index 00000000..b81d2670 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_03_Color_Space_Curves.fx @@ -0,0 +1,230 @@ +/* + Description : PD80 03 Color Space Curves for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + Additional Credits + http://technorgb.blogspot.com/2018/02/hyperbola-tone-mapping.html + + LAB Conversion adopted from + http://www.brucelindbloom.com/ + + For the curves code: + Copyright (c) 2018 ishiyama, MIT License + Please see https://www.shadertoy.com/view/4tjcD1 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" +#include "PD80_00_Color_Spaces.fxh" + +namespace pd80_cscurves +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Global"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Global"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + uniform int color_space < + ui_type = "combo"; + ui_category = "Global"; + ui_label = "Color Space"; + ui_tooltip = "Color Space"; + ui_items = "RGB-W\0L* a* b*\0HSL\0HSV\0"; + > = 1; + // Greys + uniform float pos0_shoulder_grey < + ui_type = "slider"; + ui_label = "Shoulder Position X"; + ui_tooltip = "Shoulder Position X"; + ui_category = "Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.8; + uniform float pos1_shoulder_grey < + ui_type = "slider"; + ui_label = "Shoulder Position Y"; + ui_tooltip = "Shoulder Position Y"; + ui_category = "Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.8; + uniform float pos0_toe_grey < + ui_type = "slider"; + ui_label = "Toe Position X"; + ui_tooltip = "Toe Position X"; + ui_category = "Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.2; + uniform float pos1_toe_grey < + ui_type = "slider"; + ui_label = "Toe Position Y"; + ui_tooltip = "Toe Position Y"; + ui_category = "Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.2; + // Saturation + uniform float colorsat < + ui_type = "slider"; + ui_category = "Color Control"; + ui_label = "Saturation"; + ui_tooltip = "Saturation"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// STRUCTURES ///////////////////////////////////////////////////////////////// + struct TonemapParams + { + float3 mToe; + float2 mMid; + float3 mShoulder; + float2 mBx; + }; + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float3 Tonemap(const TonemapParams tc, float3 x) + { + float3 toe = - tc.mToe.x / (x + tc.mToe.y) + tc.mToe.z; + float3 mid = tc.mMid.x * x + tc.mMid.y; + float3 shoulder = - tc.mShoulder.x / (x + tc.mShoulder.y) + tc.mShoulder.z; + float3 result = ( x >= tc.mBx.x ) ? mid : toe; + result = ( x >= tc.mBx.y ) ? shoulder : result; + return result; + } + + + float4 setBoundaries( float tx, float ty, float sx, float sy ) + { + if( tx > sx ) + tx = sx; + if( ty > sy ) + ty = sy; + return float4( tx, ty, sx, sy ); + } + + void PrepareTonemapParams(float2 p1, float2 p2, float2 p3, out TonemapParams tc) + { + float denom = p2.x - p1.x; + denom = abs(denom) > 1e-5 ? denom : 1e-5; + float slope = (p2.y - p1.y) / denom; + { + tc.mMid.x = slope; + tc.mMid.y = p1.y - slope * p1.x; + } + { + float denom = p1.y - slope * p1.x; + denom = abs(denom) > 1e-5 ? denom : 1e-5; + tc.mToe.x = slope * p1.x * p1.x * p1.y * p1.y / (denom * denom); + tc.mToe.y = slope * p1.x * p1.x / denom; + tc.mToe.z = p1.y * p1.y / denom; + } + { + float denom = slope * (p2.x - p3.x) - p2.y + p3.y; + denom = abs(denom) > 1e-5 ? denom : 1e-5; + tc.mShoulder.x = slope * pow(p2.x - p3.x, 2.0) * pow(p2.y - p3.y, 2.0) / (denom * denom); + tc.mShoulder.y = (slope * p2.x * (p3.x - p2.x) + p3.x * (p2.y - p3.y) ) / denom; + tc.mShoulder.z = (-p2.y * p2.y + p3.y * (slope * (p2.x - p3.x) + p2.y) ) / denom; + } + tc.mBx = float2(p1.x, p2.x); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_CSCurves(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 1, enable_dither, dither_strength, 1, 0.5f ); + color.xyz = saturate( color.xyz + dnoise.xyz ); + + // Prepare curves + float4 grey = setBoundaries( pos0_toe_grey, pos1_toe_grey, pos0_shoulder_grey, pos1_shoulder_grey ); + TonemapParams tc; + PrepareTonemapParams( grey.xy, grey.zw, float2( 1.0f, 1.0f ), tc ); + + // RGBW + float rgb_luma = min( min( color.x, color.y ), color.z ); + float temp_luma = rgb_luma; + float3 rgb_chroma = color.xyz - rgb_luma; + rgb_luma = Tonemap( tc, rgb_luma.xxx ).x; + rgb_chroma *= ( colorsat + 1.0f ); + + // LAB + float3 lab_color = pd80_srgb_to_lab( color.xyz ); + lab_color.x = Tonemap( tc, lab_color.xxx ).x; + lab_color.yz *= ( colorsat + 1.0f ); + + // HSL + float3 hsl_color = RGBToHSL( color.xyz ); + hsl_color.z = Tonemap( tc, hsl_color.zzz ).z; + hsl_color.y *= ( colorsat + 1.0f ); + + // HSV + float3 hsv_color = RGBToHSV( color.xyz ); + hsv_color.z = Tonemap( tc, hsv_color.zzz ).z; + hsv_color.y *= ( colorsat + 1.0f ); + + switch( color_space ) + { + case 0: { color.xyz = saturate( rgb_chroma.xyz + rgb_luma ); } break; + case 1: { color.xyz = pd80_lab_to_srgb( lab_color.xyz ); } break; + case 2: { color.xyz = HSLToRGB( saturate( hsl_color.xyz )); } break; + case 3: { color.xyz = HSVToRGB( saturate( hsv_color.xyz )); } break; + } + + color.xyz = saturate( color.xyz + dnoise.wxy ); + return float4(color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_03_Color_Space_Curves + { + pass prod80_CCpass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_CSCurves; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_03_Curved_Levels.fx b/data_from_portwine/Reshade/Shaders/PD80_03_Curved_Levels.fx new file mode 100644 index 00000000..dd46a0a0 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_03_Curved_Levels.fx @@ -0,0 +1,570 @@ +/* + Description : PD80 03 Contrast Curve for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + Additional Credits + http://technorgb.blogspot.com/2018/02/hyperbola-tone-mapping.html + + For the curves code: + Copyright (c) 2018 ishiyama, MIT License + Please see https://www.shadertoy.com/view/4tjcD1 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" + +namespace pd80_curvedlevels +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + #ifndef CURVEDCONTRASTS_ENABLE_RGB + #define CURVEDCONTRASTS_ENABLE_RGB 0 + #endif + + #ifndef CURVEDCONTRASTS_VISUALIZE + #define CURVEDCONTRASTS_VISUALIZE 0 // 0 = disabled, 1 = enabled + #endif + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Global"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Global"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + // Greys + uniform float black_in_grey < + ui_type = "slider"; + ui_label = "Grey: Black Point"; + ui_tooltip = "Grey: Black Point"; + ui_category = "Grey: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 0.0; + uniform float white_in_grey < + ui_type = "slider"; + ui_label = "Grey: White Point"; + ui_tooltip = "Grey: White Point"; + ui_category = "Grey: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 255.0; + uniform float pos0_shoulder_grey < + ui_type = "slider"; + ui_label = "Grey: Shoulder Position X"; + ui_tooltip = "Grey: Shoulder Position X"; + ui_category = "Grey: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.75; + uniform float pos1_shoulder_grey < + ui_type = "slider"; + ui_label = "Grey: Shoulder Position Y"; + ui_tooltip = "Grey: Shoulder Position Y"; + ui_category = "Grey: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.75; + uniform float pos0_toe_grey < + ui_type = "slider"; + ui_label = "Grey: Toe Position X"; + ui_tooltip = "Grey: Toe Position X"; + ui_category = "Grey: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.25; + uniform float pos1_toe_grey < + ui_type = "slider"; + ui_label = "Grey: Toe Position Y"; + ui_tooltip = "Grey: Toe Position Y"; + ui_category = "Grey: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.25; + uniform float black_out_grey < + ui_type = "slider"; + ui_label = "Grey: Black Point Offset"; + ui_tooltip = "Grey: Black Point Offset"; + ui_category = "Grey: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 0.0; + uniform float white_out_grey < + ui_type = "slider"; + ui_label = "Grey: White Point Offset"; + ui_tooltip = "Grey: White Point Offset"; + ui_category = "Grey: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 255.0; +#if( CURVEDCONTRASTS_ENABLE_RGB ) + // Reds + uniform float black_in_red < + ui_type = "slider"; + ui_label = "Red: Black Point"; + ui_tooltip = "Red: Black Point"; + ui_category = "Red: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 0.0; + uniform float white_in_red < + ui_type = "slider"; + ui_label = "Red: White Point"; + ui_tooltip = "Red: White Point"; + ui_category = "Red: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 255.0; + uniform float pos0_shoulder_red < + ui_type = "slider"; + ui_label = "Red: Shoulder Position X"; + ui_tooltip = "Red: Shoulder Position X"; + ui_category = "Red: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.75; + uniform float pos1_shoulder_red < + ui_type = "slider"; + ui_label = "Red: Shoulder Position Y"; + ui_tooltip = "Red: Shoulder Position Y"; + ui_category = "Red: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.75; + uniform float pos0_toe_red < + ui_type = "slider"; + ui_label = "Red: Toe Position X"; + ui_tooltip = "Red: Toe Position X"; + ui_category = "Red: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.25; + uniform float pos1_toe_red < + ui_type = "slider"; + ui_label = "Red: Toe Position Y"; + ui_tooltip = "Red: Toe Position Y"; + ui_category = "Red: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.25; + uniform float black_out_red < + ui_type = "slider"; + ui_label = "Red: Black Point Offset"; + ui_tooltip = "Red: Black Point Offset"; + ui_category = "Red: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 0.0; + uniform float white_out_red < + ui_type = "slider"; + ui_label = "Red: White Point Offset"; + ui_tooltip = "Red: White Point Offset"; + ui_category = "Red: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 255.0; + + // Greens + uniform float black_in_green < + ui_type = "slider"; + ui_label = "Green: Black Point"; + ui_tooltip = "Green: Black Point"; + ui_category = "Green: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 0.0; + uniform float white_in_green < + ui_type = "slider"; + ui_label = "Green: White Point"; + ui_tooltip = "Green: White Point"; + ui_category = "Green: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 255.0; + uniform float pos0_shoulder_green < + ui_type = "slider"; + ui_label = "Green: Shoulder Position X"; + ui_tooltip = "Green: Shoulder Position X"; + ui_category = "Green: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.75; + uniform float pos1_shoulder_green < + ui_type = "slider"; + ui_label = "Green: Shoulder Position Y"; + ui_tooltip = "Green: Shoulder Position Y"; + ui_category = "Green: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.75; + uniform float pos0_toe_green < + ui_type = "slider"; + ui_label = "Green: Toe Position X"; + ui_tooltip = "Green: Toe Position X"; + ui_category = "Green: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.25; + uniform float pos1_toe_green < + ui_type = "slider"; + ui_label = "Green: Toe Position Y"; + ui_tooltip = "Green: Toe Position Y"; + ui_category = "Green: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.25; + uniform float black_out_green < + ui_type = "slider"; + ui_label = "Green: Black Point Offset"; + ui_tooltip = "Green: Black Point Offset"; + ui_category = "Green: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 0.0; + uniform float white_out_green < + ui_type = "slider"; + ui_label = "Green: White Point Offset"; + ui_tooltip = "Green: White Point Offset"; + ui_category = "Green: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 255.0; + + // Blues + uniform float black_in_blue < + ui_type = "slider"; + ui_label = "Blue: Black Point"; + ui_tooltip = "Blue: Black Point"; + ui_category = "Blue: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 0.0; + uniform float white_in_blue < + ui_type = "slider"; + ui_label = "Blue: White Point"; + ui_tooltip = "Blue: White Point"; + ui_category = "Blue: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 255.0; + uniform float pos0_shoulder_blue < + ui_type = "slider"; + ui_label = "Blue: Shoulder Position X"; + ui_tooltip = "Blue: Shoulder Position X"; + ui_category = "Blue: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.75; + uniform float pos1_shoulder_blue < + ui_type = "slider"; + ui_label = "Blue: Shoulder Position Y"; + ui_tooltip = "Blue: Shoulder Position Y"; + ui_category = "Blue: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.75; + uniform float pos0_toe_blue < + ui_type = "slider"; + ui_label = "Blue: Toe Position X"; + ui_tooltip = "Blue: Toe Position X"; + ui_category = "Blue: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.25; + uniform float pos1_toe_blue < + ui_type = "slider"; + ui_label = "Blue: Toe Position Y"; + ui_tooltip = "Blue: Toe Position Y"; + ui_category = "Blue: Contrast Curves"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.25; + uniform float black_out_blue < + ui_type = "slider"; + ui_label = "Blue: Black Point Offset"; + ui_tooltip = "Blue: Black Point Offset"; + ui_category = "Blue: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 0.0; + uniform float white_out_blue < + ui_type = "slider"; + ui_label = "Blue: White Point Offset"; + ui_tooltip = "Blue: White Point Offset"; + ui_category = "Blue: Contrast Curves"; + ui_min = 0; + ui_max = 255; + ui_step = 1; + > = 255.0; +#endif + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// STRUCTURES ///////////////////////////////////////////////////////////////// + struct TonemapParams + { + float3 mToe; + float2 mMid; + float3 mShoulder; + float2 mBx; + }; + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float3 Tonemap(const TonemapParams tc, float3 x) + { + float3 toe = - tc.mToe.x / (x + tc.mToe.y) + tc.mToe.z; + float3 mid = tc.mMid.x * x + tc.mMid.y; + float3 shoulder = - tc.mShoulder.x / (x + tc.mShoulder.y) + tc.mShoulder.z; + float3 result = ( x >= tc.mBx.x ) ? mid : toe; + result = ( x >= tc.mBx.y ) ? shoulder : result; + return result; + } + + float blackwhiteIN( float c, float b, float w ) + { + return saturate( c - b )/max( w - b, 0.000001f ); + } + + float blackwhiteOUT( float c, float b, float w ) + { + return c * saturate( w - b ) + b; + } + + float3 blackwhiteIN( float3 c, float b, float w ) + { + return saturate( c.xyz - b )/max( w - b, 0.000001f ); + } + + float3 blackwhiteOUT( float3 c, float b, float w ) + { + return c.xyz * saturate( w - b ) + b; + } + + float4 setBoundaries( float tx, float ty, float sx, float sy ) + { + if( tx > sx ) + tx = sx; + if( ty > sy ) + ty = sy; + return float4( tx, ty, sx, sy ); + } + + void PrepareTonemapParams(float2 p1, float2 p2, float2 p3, out TonemapParams tc) + { + float denom = p2.x - p1.x; + denom = abs(denom) > 1e-5 ? denom : 1e-5; + float slope = (p2.y - p1.y) / denom; + { + tc.mMid.x = slope; + tc.mMid.y = p1.y - slope * p1.x; + } + { + float denom = p1.y - slope * p1.x; + denom = abs(denom) > 1e-5 ? denom : 1e-5; + tc.mToe.x = slope * p1.x * p1.x * p1.y * p1.y / (denom * denom); + tc.mToe.y = slope * p1.x * p1.x / denom; + tc.mToe.z = p1.y * p1.y / denom; + } + { + float denom = slope * (p2.x - p3.x) - p2.y + p3.y; + denom = abs(denom) > 1e-5 ? denom : 1e-5; + tc.mShoulder.x = slope * pow(p2.x - p3.x, 2.0) * pow(p2.y - p3.y, 2.0) / (denom * denom); + tc.mShoulder.y = (slope * p2.x * (p3.x - p2.x) + p3.x * (p2.y - p3.y) ) / denom; + tc.mShoulder.z = (-p2.y * p2.y + p3.y * (slope * (p2.x - p3.x) + p2.y) ) / denom; + } + tc.mBx = float2(p1.x, p2.x); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_CurvedLevels(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + float2 coords = float2(( texcoord.x - 0.75f ) * 4.0f, ( 1.0f - texcoord.y ) * 4.0f ); // For vizualization + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 1, enable_dither, dither_strength, 1, 0.5f ); + color.xyz = saturate( color.xyz + dnoise.yzx ); + + #if( CURVEDCONTRASTS_VISUALIZE == 1 ) + int def_bi = 0; + int def_wi = 255; + float def_toe0 = 0.25f; + float def_toe1 = 0.25f; + float def_sho0 = 0.75f; + float def_sho1 = 0.75f; + int def_bo = 0; + int def_wo = 255; + float3 showcurve = 0.0f; + #endif + + TonemapParams tc; + + // Grey apply black/white points and curves + float bigr = saturate( black_in_grey/255.0f + dnoise.w ); + float wigr = saturate( white_in_grey/255.0f + dnoise.w ); + float bogr = saturate( black_out_grey/255.0f + dnoise.w ); + float wogr = saturate( white_out_grey/255.0f + dnoise.w ); + + float4 grey = setBoundaries( pos0_toe_grey, pos1_toe_grey, pos0_shoulder_grey, pos1_shoulder_grey ); + PrepareTonemapParams( grey.xy, grey.zw, float2( 1.0f, 1.0f ), tc ); + color.xyz = blackwhiteIN( color.xyz, bigr, wigr ); + color.xyz = Tonemap( tc, color.xyz ); + color.xyz = blackwhiteOUT( color.xyz, bogr, wogr ); + // Visual +#if( CURVEDCONTRASTS_VISUALIZE ) + // Draw a bunch of lines + float4 bandwidth = float4( 0.002f, 0.002f, 0.0002f, 0.0002f ); + bandwidth.y *= ( BUFFER_WIDTH * BUFFER_RCP_HEIGHT ); + bandwidth.w *= ( BUFFER_WIDTH * BUFFER_RCP_HEIGHT ); + if( texcoord.x > 0.75 - bandwidth.x && texcoord.x < 0.75 && 1.0f - texcoord.y < 0.25 ) + color.xyz = float3( 0.7f, 0.7f, 0.7f ); + if( 1.0f - texcoord.y > 0.25 && 1.0f - texcoord.y < 0.25 + bandwidth.y && texcoord.x > 0.75 - bandwidth.x ) + color.xyz = float3( 0.7f, 0.7f, 0.7f ); + if( texcoord.x > 0.875 - bandwidth.z && texcoord.x < 0.875 + bandwidth.z && 1.0f - texcoord.y < 0.25 ) + color.xyz = float3( 1.4f, 1.4f, 1.4f ); + if( 1.0f - texcoord.y > 0.125f - bandwidth.w && 1.0f - texcoord.y < 0.125 + bandwidth.w && texcoord.x > 0.75 ) + color.xyz = float3( 1.4f, 1.4f, 1.4f ); + if( texcoord.x > 0.75 && texcoord.y > 0.75 ) + { + color.xyz *= 0.5f; + color.xyz = lerp( float3( 0.7f, 0.7f, 0.7f ), color.xyz, smoothstep( 0.0f, 10.0f * BUFFER_RCP_HEIGHT, abs( coords.y - coords.x ))); + showcurve.xyz = blackwhiteIN( coords.xxx, black_in_grey/255.0f, white_in_grey/255.0f ); + showcurve.xyz = Tonemap( tc, showcurve.xyz ); + showcurve.xyz = blackwhiteOUT( showcurve.xyz, black_out_grey/255.0f, white_out_grey/255.0f ); + color.xyz = lerp( float3( 1.0f, 1.0f, 1.0f ), color.xyz, smoothstep( 0.0f, 20.0f * BUFFER_RCP_HEIGHT, abs( coords.y - showcurve.x ))); + } +#endif +#if( CURVEDCONTRASTS_ENABLE_RGB ) + // Red + float bir = saturate( black_in_red/255.0f + dnoise.x ); + float wir = saturate( white_in_red/255.0f + dnoise.x ); + float bor = saturate( black_out_red/255.0f + dnoise.x ); + float wor = saturate( white_out_red/255.0f + dnoise.x ); + + float4 red = setBoundaries( pos0_toe_red, pos1_toe_red, pos0_shoulder_red, pos1_shoulder_red ); + PrepareTonemapParams( red.xy, red.zw, float2( 1.0f, 1.0f ), tc ); + color.x = blackwhiteIN( color.x, bir, wir ); + color.x = Tonemap( tc, color.xxx ).x; + color.x = blackwhiteOUT( color.x, bor, wor ); +#if( CURVEDCONTRASTS_VISUALIZE ) + if( any( float4( def_toe0 - pos0_toe_red, def_toe1 - pos1_toe_red, def_sho0 - pos0_shoulder_red, def_sho1 - pos1_shoulder_red )) || + any( int4( def_bi - black_in_red, def_wi - white_in_red, def_bo - black_out_red, def_wo - white_out_red ))) + { + if( texcoord.x > 0.75 && texcoord.y > 0.75 ) + { + showcurve.x = blackwhiteIN( showcurve.xxx, black_in_red/255.0f, white_in_red/255.0f ).x; + showcurve.x = Tonemap( tc, showcurve.xxx ).x; + showcurve.x = blackwhiteOUT( showcurve.xxx, black_out_red/255.0f, white_out_red/255.0f ).x; + color.xyz = lerp( float3( 1.0f, 0.0f, 0.0f ), color.xyz, smoothstep( 0.0f, 20.0f * BUFFER_RCP_HEIGHT, abs( coords.y - showcurve.x ))); + } + } +#endif + // Green + float big = saturate( black_in_green/255.0f + dnoise.y ); + float wig = saturate( white_in_green/255.0f + dnoise.y ); + float bog = saturate( black_out_green/255.0f + dnoise.y ); + float wog = saturate( white_out_green/255.0f + dnoise.y ); + + float4 green = setBoundaries( pos0_toe_green, pos1_toe_green, pos0_shoulder_green, pos1_shoulder_green ); + PrepareTonemapParams( green.xy, green.zw, float2( 1.0f, 1.0f ), tc ); + color.y = blackwhiteIN( color.y, big, wig ); + color.y = Tonemap( tc, color.yyy ).y; + color.y = blackwhiteOUT( color.y, bog, wog ); +#if( CURVEDCONTRASTS_VISUALIZE ) + if( any( float4( def_toe0 - pos0_toe_green, def_toe1 - pos1_toe_green, def_sho0 - pos0_shoulder_green, def_sho1 - pos1_shoulder_green )) || + any( int4( def_bi - black_in_green, def_wi - white_in_green, def_bo - black_out_green, def_wo - white_out_green ))) + { + if( texcoord.x > 0.75 && texcoord.y > 0.75 ) + { + showcurve.y = blackwhiteIN( showcurve.yyy, black_in_green/255.0f, white_in_green/255.0f ).y; + showcurve.y = Tonemap( tc, showcurve.yyy ).y; + showcurve.y = blackwhiteOUT( showcurve.yyy, black_out_green/255.0f, white_out_green/255.0f ).y; + color.xyz = lerp( float3( 0.0f, 1.0f, 0.0f ), color.xyz, smoothstep( 0.0f, 20.0f * BUFFER_RCP_HEIGHT, abs( coords.y - showcurve.y ))); + } + } +#endif + // Blue + float bib = saturate( black_in_blue/255.0f + dnoise.z ); + float wib = saturate( white_in_blue/255.0f + dnoise.z ); + float bob = saturate( black_out_blue/255.0f + dnoise.z ); + float wob = saturate( white_out_blue/255.0f + dnoise.z ); + + float4 blue = setBoundaries( pos0_toe_blue, pos1_toe_blue, pos0_shoulder_blue, pos1_shoulder_blue ); + PrepareTonemapParams( blue.xy, blue.zw, float2( 1.0f, 1.0f ), tc ); + color.z = blackwhiteIN( color.z, bib, wib ); + color.z = Tonemap( tc, color.zzz ).z; + color.z = blackwhiteOUT( color.z, bob, wob ); +#if( CURVEDCONTRASTS_VISUALIZE ) + if( any( float4( def_toe0 - pos0_toe_blue, def_toe1 - pos1_toe_blue, def_sho0 - pos0_shoulder_blue, def_sho1 - pos1_shoulder_blue )) || + any( int4( def_bi - black_in_blue, def_wi - white_in_blue, def_bo - black_out_blue, def_wo - white_out_blue ))) + { + if( texcoord.x > 0.75 && texcoord.y > 0.75 ) + { + showcurve.z = blackwhiteIN( showcurve.zzz, black_in_blue/255.0f, white_in_blue/255.0f ).z; + showcurve.z = Tonemap( tc, showcurve.zzz ).z; + showcurve.z = blackwhiteOUT( showcurve.zzz, black_out_blue/255.0f, white_out_blue/255.0f ).z; + color.xyz = lerp( float3( 0.0f, 0.0f, 1.0f ), color.xyz, smoothstep( 0.0f, 20.0f * BUFFER_RCP_HEIGHT, abs( coords.y - showcurve.z ))); + } + } +#endif +#endif + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_03_CurvedLevels + { + pass prod80_CCpass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_CurvedLevels; + } + } +} + + diff --git a/data_from_portwine/Reshade/Shaders/PD80_03_Filmic_Adaptation.fx b/data_from_portwine/Reshade/Shaders/PD80_03_Filmic_Adaptation.fx new file mode 100644 index 00000000..a1ba4d09 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_03_Filmic_Adaptation.fx @@ -0,0 +1,170 @@ +/* + Description : PD80 03 Filmic Adaptation for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + 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 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +namespace pd80_filmicadaptation +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform float adj_shoulder < + ui_label = "Adjust Highlights"; + ui_tooltip = "Adjust Highlights"; + ui_category = "Tonemapping"; + ui_type = "slider"; + ui_min = 1.0; + ui_max = 5.0; + > = 1.0; + uniform float adj_linear < + ui_label = "Adjust Linearity"; + ui_tooltip = "Adjust Linearity"; + ui_category = "Tonemapping"; + ui_type = "slider"; + ui_min = 1.0; + ui_max = 10.0; + > = 1.0; + uniform float adj_toe < + ui_label = "Adjust Shadows"; + ui_tooltip = "Adjust Shadows"; + ui_category = "Tonemapping"; + ui_type = "slider"; + ui_min = 1.0; + ui_max = 5.0; + > = 1.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texLuma { Width = 256; Height = 256; Format = R16F; MipLevels = 9; }; + texture texAvgLuma { Format = R16F; }; + texture texPrevAvgLuma { Format = R16F; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerLinColor { Texture = ReShade::BackBufferTex; SRGBTexture = true; }; + sampler samplerLuma { Texture = texLuma; }; + sampler samplerAvgLuma { Texture = texAvgLuma; }; + sampler samplerPrevAvgLuma { Texture = texPrevAvgLuma; }; + + //// DEFINES //////////////////////////////////////////////////////////////////// + #define LumCoeff float3(0.212656, 0.715158, 0.072186) + uniform float Frametime < source = "frametime"; >; + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float getLuminance( in float3 x ) + { + return dot( x, LumCoeff ); + } + + float3 Filmic( in float3 Fc, in float FA, in float FB, in float FC, in float FD, in float FE, in float FF, in float FWhite ) + { + float3 num = (( Fc * ( FA * Fc + FC * FB ) + FD * FE ) / ( Fc * ( FA * Fc + FB ) + FD * FF )) - FE / FF; + float3 denom = (( FWhite * ( FA * FWhite + FC * FB ) + FD * FE ) / ( FWhite * ( FA * FWhite + FB ) + FD * FF )) - FE / FF; + return num / denom; + //return num / denom; + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float PS_WriteLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( samplerLinColor, texcoord ); + float luma = getLuminance( color.xyz ); + luma = max( luma, 0.06f ); // give it a min value so that too dark scenes don't count too much against average + return log2( luma ); //writes to 256x256 texture + } + + float PS_AvgLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float luma = tex2Dlod( samplerLuma, float4(0.5f, 0.5f, 0, 8 )).x; + luma = exp2( luma ); + float prevluma = tex2D( samplerPrevAvgLuma, float2( 0.5f, 0.5f )).x; + float fps = 1000.0f / Frametime; + float delay = fps; //* 0.5f + float avgLuma = lerp( prevluma, luma, 1.0f / delay ); + return avgLuma; + } + + float4 PS_Tonemap(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + // Filmic operators, most fixed with no GUI + float A = 0.65f * adj_shoulder; + float B = 0.085f * adj_linear; + float C = 1.83f; + float D = 0.55f * adj_toe; + float E = 0.05f; + float F = 0.57f; + float W = 1.0f; // working in LDR space, white should be 1.0 + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + float luma = tex2D( samplerAvgLuma, float2( 0.5f, 0.5f )).x; + float exp = lerp( 1.0f, 8.0f, luma ); // Increase Toe when brightness goes up (increase contrast) + float toe = max( D * exp, D ); // Increase toe, effect is mild even though there's a potential 8x increase here + color.xyz = Filmic( color.xyz, A, B, C, toe, E, F, W ); + + return float4( color.xyz, 1.0f ); + } + + float PS_PrevAvgLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float avgLuma = tex2D( samplerAvgLuma, float2( 0.5f, 0.5f )).x; + return avgLuma; + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_03_FilmicTonemap + { + pass Luma + { + VertexShader = PostProcessVS; + PixelShader = PS_WriteLuma; + RenderTarget = texLuma; + } + pass AvgLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_AvgLuma; + RenderTarget = texAvgLuma; + } + pass Tonemapping + { + VertexShader = PostProcessVS; + PixelShader = PS_Tonemap; + } + pass PreviousLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_PrevAvgLuma; + RenderTarget = texPrevAvgLuma; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_03_Levels.fx b/data_from_portwine/Reshade/Shaders/PD80_03_Levels.fx new file mode 100644 index 00000000..c8039e13 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_03_Levels.fx @@ -0,0 +1,220 @@ +/* + Description : PD80 03 Levels for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" + +namespace pd80_levels +{ + + /* + Using depth texture to manipulate levels: + This feature is very dodgy, so hidden by default + It's added for people specilized in screenshots and able to understand + that using depth buffer can be odd on something like Levels + Uncomment ( remove "//" ) the line below to enable this feature + */ + #ifndef LEVELS_USE_DEPTH + #define LEVELS_USE_DEPTH 0 //0 = disable, 1 = enable + #endif + + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Global"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Global"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + uniform float3 ib < + ui_type = "color"; + ui_label = "Black IN Level"; + ui_tooltip = "Black IN Level"; + ui_category = "Levels"; + > = float3(0.0, 0.0, 0.0); + uniform float3 iw < + ui_type = "color"; + ui_label = "White IN Level"; + ui_tooltip = "White IN Level"; + ui_category = "Levels"; + > = float3(1.0, 1.0, 1.0); + uniform float3 ob < + ui_type = "color"; + ui_label = "Black OUT Level"; + ui_tooltip = "Black OUT Level"; + ui_category = "Levels"; + > = float3(0.0, 0.0, 0.0); + uniform float3 ow < + ui_type = "color"; + ui_label = "White OUT Level"; + ui_tooltip = "White OUT Level"; + ui_category = "Levels"; + > = float3(1.0, 1.0, 1.0); + uniform float ig < + ui_label = "Gamma Adjustment"; + ui_tooltip = "Gamma Adjustment"; + ui_category = "Levels"; + ui_type = "slider"; + ui_min = 0.05; + ui_max = 10.0; + > = 1.0; + #if( LEVELS_USE_DEPTH == 1 ) + uniform bool display_depth < + ui_label = "Show depth texture.\nThe below adjustments only apply to white areas.\0Make sure you have your depth texture setup correctly."; + ui_tooltip = "Show depth texture"; + ui_category = "Levels: Depth"; + > = false; + uniform float depthStart < + ui_type = "slider"; + ui_label = "Change Depth Start Plane"; + ui_tooltip = "Change Depth Start Plane"; + ui_category = "Levels: Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.0; + uniform float depthEnd < + ui_type = "slider"; + ui_label = "Change Depth End Plane"; + ui_tooltip = "Change Depth End Plane"; + ui_category = "Levels: Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.1; + uniform float depthCurve < + ui_label = "Depth Curve Adjustment"; + ui_tooltip = "Depth Curve Adjustment"; + ui_category = "Levels: Depth"; + ui_type = "slider"; + ui_min = 0.05; + ui_max = 8.0; + > = 1.0; + uniform float3 ibd < + ui_type = "color"; + ui_label = "Black IN Level Far"; + ui_tooltip = "Black IN Level Far"; + ui_category = "Levels: Far"; + > = float3(0.0, 0.0, 0.0); + uniform float3 iwd < + ui_type = "color"; + ui_label = "White IN Level Far"; + ui_tooltip = "White IN Level Far"; + ui_category = "Levels: Far"; + > = float3(1.0, 1.0, 1.0); + uniform float3 obd < + ui_type = "color"; + ui_label = "Black OUT Level Far"; + ui_tooltip = "Black OUT Level Far"; + ui_category = "Levels: Far"; + > = float3(0.0, 0.0, 0.0); + uniform float3 owd < + ui_type = "color"; + ui_label = "White OUT Level Far"; + ui_tooltip = "White OUT Level Far"; + ui_category = "Levels: Far"; + > = float3(1.0, 1.0, 1.0); + uniform float igd < + ui_label = "Gamma Adjustment Far"; + ui_tooltip = "Gamma Adjustment Far"; + ui_category = "Levels: Far"; + ui_type = "slider"; + ui_min = 0.05; + ui_max = 10.0; + > = 1.0; + #endif + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + uniform float2 pingpong < source = "pingpong"; min = 0; max = 128; step = 1; >; + + float3 levels( float3 color, float3 blackin, float3 whitein, float gamma, float3 outblack, float3 outwhite ) + { + float3 ret = saturate( color.xyz - blackin.xyz ) / max( whitein.xyz - blackin.xyz, 0.000001f ); + ret.xyz = pow( ret.xyz, gamma ); + ret.xyz = ret.xyz * saturate( outwhite.xyz - outblack.xyz ) + outblack.xyz; + return ret; + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_Levels(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 2, enable_dither, dither_strength, 1, 0.5f ); + + #if( LEVELS_USE_DEPTH == 1 ) + float depth = ReShade::GetLinearizedDepth( texcoord ).x; + depth = smoothstep( depthStart, depthEnd, depth ); + depth = pow( depth, depthCurve ); + depth = saturate( depth + dnoise.w ); + #endif + + color.xyz = saturate( color.xyz + dnoise.w ); + float3 dcolor = color.xyz; + color.xyz = levels( color.xyz, saturate( ib.xyz + dnoise.xyz ), + saturate( iw.xyz + dnoise.yzx ), + ig, + saturate( ob.xyz + dnoise.zxy ), + saturate( ow.xyz + dnoise.wxz )); + + #if( LEVELS_USE_DEPTH == 1 ) + dcolor.xyz = levels( dcolor.xyz, saturate( ibd.xyz + dnoise.xyz ), + saturate( iwd.xyz + dnoise.yzx ), + igd, + saturate( obd.xyz + dnoise.zxy ), + saturate( owd.xyz + dnoise.wxz )); + + color.xyz = lerp( color.xyz, dcolor.xyz, depth ); + color.xyz = lerp( color.xyz, depth.xxx, display_depth ); + #endif + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_03_Levels + { + pass DoLevels + { + VertexShader = PostProcessVS; + PixelShader = PS_Levels; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_03_Shadows_Midtones_Highlights.fx b/data_from_portwine/Reshade/Shaders/PD80_03_Shadows_Midtones_Highlights.fx new file mode 100644 index 00000000..7af6ec6f --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_03_Shadows_Midtones_Highlights.fx @@ -0,0 +1,412 @@ +/* + Description : PD80 03 Shadows Midtones Highlights for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" +#include "PD80_00_Blend_Modes.fxh" +#include "PD80_00_Base_Effects.fxh" + +namespace pd80_SMH +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int luma_mode < __UNIFORM_COMBO_INT1 + ui_label = "Luma Mode"; + ui_tooltip = "Luma Mode"; + ui_category = "Global"; + ui_items = "Use Average\0Use Perceived Luma\0Use Max Value\0"; + > = 2; + uniform int separation_mode < __UNIFORM_COMBO_INT1 + ui_label = "Luma Separation Mode"; + ui_tooltip = "Luma Separation Mode"; + ui_category = "Global"; + ui_items = "Harsh Separation\0Smooth Separation\0"; + > = 0; + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Global"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Global"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 2.0; + uniform float exposure_s < + ui_label = "Exposure"; + ui_tooltip = "Shadow Exposure"; + ui_category = "Shadow Adjustments"; + ui_type = "slider"; + ui_min = -4.0; + ui_max = 4.0; + > = 0.0; + uniform float contrast_s < + ui_label = "Contrast"; + ui_tooltip = "Shadow Contrast"; + ui_category = "Shadow Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float brightness_s < + ui_label = "Brightness"; + ui_tooltip = "Shadow Brightness"; + ui_category = "Shadow Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float3 blendcolor_s < + ui_type = "color"; + ui_label = "Color"; + ui_tooltip = "Shadow Color"; + ui_category = "Shadow Adjustments"; + > = float3( 0.0, 0.365, 1.0 ); + uniform int blendmode_s < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Shadow Blendmode"; + ui_category = "Shadow Adjustments"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 0; + uniform float opacity_s < + ui_label = "Opacity"; + ui_tooltip = "Shadow Opacity"; + ui_category = "Shadow Adjustments"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float tint_s < + ui_label = "Tint"; + ui_tooltip = "Shadow Tint"; + ui_category = "Shadow Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float saturation_s < + ui_label = "Saturation"; + ui_tooltip = "Shadow Saturation"; + ui_category = "Shadow Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float vibrance_s < + ui_label = "Vibrance"; + ui_tooltip = "Shadow Vibrance"; + ui_category = "Shadow Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float exposure_m < + ui_label = "Exposure"; + ui_tooltip = "Midtone Exposure"; + ui_category = "Midtone Adjustments"; + ui_type = "slider"; + ui_min = -4.0; + ui_max = 4.0; + > = 0.0; + uniform float contrast_m < + ui_label = "Contrast"; + ui_tooltip = "Midtone Contrast"; + ui_category = "Midtone Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float brightness_m < + ui_label = "Brightness"; + ui_tooltip = "Midtone Brightness"; + ui_category = "Midtone Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float3 blendcolor_m < + ui_type = "color"; + ui_label = "Color"; + ui_tooltip = "Midtone Color"; + ui_category = "Midtone Adjustments"; + > = float3( 0.98, 0.588, 0.0 ); + uniform int blendmode_m < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Midtone Blendmode"; + ui_category = "Midtone Adjustments"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 0; + uniform float opacity_m < + ui_label = "Opacity"; + ui_tooltip = "Midtone Opacity"; + ui_category = "Midtone Adjustments"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float tint_m < + ui_label = "Tint"; + ui_tooltip = "Midtone Tint"; + ui_category = "Midtone Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float saturation_m < + ui_label = "Saturation"; + ui_tooltip = "Midtone Saturation"; + ui_category = "Midtone Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float vibrance_m < + ui_label = "Vibrance"; + ui_tooltip = "Midtone Vibrance"; + ui_category = "Midtone Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float exposure_h < + ui_label = "Exposure"; + ui_tooltip = "Highlight Exposure"; + ui_category = "Highlight Adjustments"; + ui_type = "slider"; + ui_min = -4.0; + ui_max = 4.0; + > = 0.0; + uniform float contrast_h < + ui_label = "Contrast"; + ui_tooltip = "Highlight Contrast"; + ui_category = "Highlight Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float brightness_h < + ui_label = "Brightness"; + ui_tooltip = "Highlight Brightness"; + ui_category = "Highlight Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float3 blendcolor_h < + ui_type = "color"; + ui_label = "Color"; + ui_tooltip = "Highlight Color"; + ui_category = "Highlight Adjustments"; + > = float3( 1.0, 1.0, 1.0 ); + uniform int blendmode_h < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Highlight Blendmode"; + ui_category = "Highlight Adjustments"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 0; + uniform float opacity_h < + ui_label = "Opacity"; + ui_tooltip = "Highlight Opacity"; + ui_category = "Highlight Adjustments"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float tint_h < + ui_label = "Tint"; + ui_tooltip = "Highlight Tint"; + ui_category = "Highlight Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float saturation_h < + ui_label = "Saturation"; + ui_tooltip = "Highlight Saturation"; + ui_category = "Highlight Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float vibrance_h < + ui_label = "Vibrance"; + ui_tooltip = "Highlight Vibrance"; + ui_category = "Highlight Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + uniform float2 pingpong < source = "pingpong"; min = 0; max = 128; step = 1; >; + + float getLuminance( in float3 x ) + { + return dot( x, float3( 0.212656, 0.715158, 0.072186 )); + } + + float curve( float x ) + { + return x * x * x * ( x * ( x * 6.0f - 15.0f ) + 10.0f ); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_SMH(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + color.xyz = saturate( color.xyz ); + + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 3, enable_dither, dither_strength, 1, 0.5f ); + color.xyz = saturate( color.xyz + dnoise.xyz ); + + float pLuma = 0.0f; + switch( luma_mode ) + { + case 0: // Use average + { + pLuma = dot( color.xyz, float3( 0.333333f, 0.333334f, 0.333333f )); + } + break; + case 1: // Use perceived luma + { + pLuma = getLuminance( color.xyz ); + } + break; + case 2: // Use max + { + pLuma = max( max( color.x, color.y ), color.z ); + } + break; + } + + float weight_s; float weight_h; float weight_m; + + switch( separation_mode ) + { + /* + Clear cutoff between shadows and highlights + Maximizes precision at the loss of harsher transitions between contrasts + Curves look like: + + Shadows Highlights Midtones + ‾‾‾—_ _—‾‾‾ _——‾‾‾——_ + ‾‾——__________ __________——‾‾ ___—‾ ‾—___ + 0.0.....0.5.....1.0 0.0.....0.5.....1.0 0.0.....0.5.....1.0 + + */ + case 0: + { + weight_s = curve( max( 1.0f - pLuma * 2.0f, 0.0f )); + weight_h = curve( max(( pLuma - 0.5f ) * 2.0f, 0.0f )); + weight_m = saturate( 1.0f - weight_s - weight_h ); + } break; + + /* + Higher degree of blending between individual curves + F.e. shadows will still have a minimal weight all the way into highlight territory + Ensures smoother transition areas between contrasts + Curves look like: + + Shadows Highlights Midtones + ‾‾‾—_ _—‾‾‾ __---__ + ‾‾———————_____ _____———————‾‾ ___-‾‾ ‾‾-___ + 0.0.....0.5.....1.0 0.0.....0.5.....1.0 0.0.....0.5.....1.0 + + */ + case 1: + { + weight_s = pow( 1.0f - pLuma, 4.0f ); + weight_h = pow( pLuma, 4.0f ); + weight_m = saturate( 1.0f - weight_s - weight_h ); + } break; + } + + float3 cold = float3( 0.0f, 0.365f, 1.0f ); //LBB + float3 warm = float3( 0.98f, 0.588f, 0.0f ); //LBA + + // Shadows + color.xyz = exposure( color.xyz, exposure_s * weight_s ); + color.xyz = con( color.xyz, contrast_s * weight_s ); + color.xyz = bri( color.xyz, brightness_s * weight_s ); + color.xyz = blendmode( color.xyz, blendcolor_s.xyz, blendmode_s, opacity_s * weight_s ); + if( tint_s < 0.0f ) + color.xyz = lerp( color.xyz, softlight( color.xyz, cold.xyz ), abs( tint_s * weight_s )); + else + color.xyz = lerp( color.xyz, softlight( color.xyz, warm.xyz ), tint_s * weight_s ); + color.xyz = sat( color.xyz, saturation_s * weight_s ); + color.xyz = vib( color.xyz, vibrance_s * weight_s ); + + // Midtones + color.xyz = exposure( color.xyz, exposure_m * weight_m ); + color.xyz = con( color.xyz, contrast_m * weight_m ); + color.xyz = bri( color.xyz, brightness_m * weight_m ); + color.xyz = blendmode( color.xyz, blendcolor_m.xyz, blendmode_m, opacity_m * weight_m ); + if( tint_m < 0.0f ) + color.xyz = lerp( color.xyz, softlight( color.xyz, cold.xyz ), abs( tint_m * weight_m )); + else + color.xyz = lerp( color.xyz, softlight( color.xyz, warm.xyz ), tint_m * weight_m ); + color.xyz = sat( color.xyz, saturation_m * weight_m ); + color.xyz = vib( color.xyz, vibrance_m * weight_m ); + + // Highlights + color.xyz = exposure( color.xyz, exposure_h * weight_h ); + color.xyz = con( color.xyz, contrast_h * weight_h ); + color.xyz = bri( color.xyz, brightness_h * weight_h ); + color.xyz = blendmode( color.xyz, blendcolor_h.xyz, blendmode_h, opacity_h * weight_h ); + if( tint_h < 0.0f ) + color.xyz = lerp( color.xyz, softlight( color.xyz, cold.xyz ), abs( tint_h * weight_h )); + else + color.xyz = lerp( color.xyz, softlight( color.xyz, warm.xyz ), tint_h * weight_h ); + color.xyz = sat( color.xyz, saturation_h * weight_h ); + color.xyz = vib( color.xyz, vibrance_h * weight_h ); + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_03_Shadows_Midtones_Highlights + { + pass prod80_pass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_SMH; + } + } +} + + diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_BlacknWhite.fx b/data_from_portwine/Reshade/Shaders/PD80_04_BlacknWhite.fx new file mode 100644 index 00000000..58e04ff2 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_BlacknWhite.fx @@ -0,0 +1,378 @@ +/* + Description : PD80 04 Black & White for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" +#include "PD80_00_Color_Spaces.fxh" + +namespace pd80_blackandwhite +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Global"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Global"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + uniform float curve_str < + ui_type = "slider"; + ui_label = "Contrast Smoothness"; + ui_tooltip = "Contrast Smoothness"; + ui_category = "Global"; + ui_min = 1.0f; + ui_max = 4.0f; + > = 1.5f; + uniform bool show_clip < + ui_label = "Show Clipping Mask"; + ui_tooltip = "Show Clipping Mask"; + ui_category = "Global"; + > = false; + uniform int bw_mode < __UNIFORM_COMBO_INT1 + ui_label = "Black & White Conversion"; + ui_tooltip = "Black & White Conversion"; + ui_category = "Black & White Techniques"; + ui_items = "Red Filter\0Green Filter\0Blue Filter\0High Contrast Red Filter\0High Contrast Green Filter\0High Contrast Blue Filter\0Infrared\0Maximum Black\0Maximum White\0Preserve Luminosity\0Neutral Green Filter\0Maintain Contrasts\0High Contrast\0Custom\0"; + > = 13; + uniform float redchannel < + ui_type = "slider"; + ui_label = "Custom: Red Weight"; + ui_tooltip = "Custom: Red Weight"; + ui_category = "Black & White Techniques"; + ui_min = -2.0f; + ui_max = 3.0f; + > = 0.2f; + uniform float yellowchannel < + ui_type = "slider"; + ui_label = "Custom: Yellow Weight"; + ui_tooltip = "Custom: Yellow Weight"; + ui_category = "Black & White Techniques"; + ui_min = -2.0f; + ui_max = 3.0f; + > = 0.4f; + uniform float greenchannel < + ui_type = "slider"; + ui_label = "Custom: Green Weight"; + ui_tooltip = "Custom: Green Weight"; + ui_category = "Black & White Techniques"; + ui_min = -2.0f; + ui_max = 3.0f; + > = 0.6f; + uniform float cyanchannel < + ui_type = "slider"; + ui_label = "Custom: Cyan Weight"; + ui_tooltip = "Custom: Cyan Weight"; + ui_category = "Black & White Techniques"; + ui_min = -2.0f; + ui_max = 3.0f; + > = 0.0f; + uniform float bluechannel < + ui_type = "slider"; + ui_label = "Custom: Blue Weight"; + ui_tooltip = "Custom: Blue Weight"; + ui_category = "Black & White Techniques"; + ui_min = -2.0f; + ui_max = 3.0f; + > = -0.6f; + uniform float magentachannel < + ui_type = "slider"; + ui_label = "Custom: Magenta Weight"; + ui_tooltip = "Custom: Magenta Weight"; + ui_category = "Black & White Techniques"; + ui_min = -2.0f; + ui_max = 3.0f; + > = -0.2f; + uniform bool use_tint < + ui_label = "Enable Tinting"; + ui_tooltip = "Enable Tinting"; + ui_category = "Tint"; + > = false; + uniform float tinthue < + ui_type = "slider"; + ui_label = "Tint Hue"; + ui_tooltip = "Tint Hue"; + ui_category = "Tint"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.083f; + uniform float tintsat < + ui_type = "slider"; + ui_label = "Tint Saturation"; + ui_tooltip = "Tint Saturation"; + ui_category = "Tint"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.12f; + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + uniform float2 pingpong < source = "pingpong"; min = 0; max = 128; step = 1; >; + + // Credit to user 'iq' from shadertoy + // See https://www.shadertoy.com/view/MdBfR1 + float curve( float x, float k ) + { + float s = sign( x - 0.5f ); + float o = ( 1.0f + s ) / 2.0f; + return o - 0.5f * s * pow( max( 2.0f * ( o - s * x ), 0.0f ), k ); + } + + float3 ProcessBW( float3 col, float r, float y, float g, float c, float b, float m ) + { + float3 hsl = RGBToHSL( col.xyz ); + // Inverse of luma channel to no apply boosts to intensity on already intense brightness (and blow out easily) + float lum = 1.0f - hsl.z; + + // Calculate the individual weights per color component in RGB and CMY + // Sum of all the weights for a given hue is 1.0 + float weight_r = curve( max( 1.0f - abs( hsl.x * 6.0f ), 0.0f ), curve_str ) + + curve( max( 1.0f - abs(( hsl.x - 1.0f ) * 6.0f ), 0.0f ), curve_str ); + float weight_y = curve( max( 1.0f - abs(( hsl.x - 0.166667f ) * 6.0f ), 0.0f ), curve_str ); + float weight_g = curve( max( 1.0f - abs(( hsl.x - 0.333333f ) * 6.0f ), 0.0f ), curve_str ); + float weight_c = curve( max( 1.0f - abs(( hsl.x - 0.5f ) * 6.0f ), 0.0f ), curve_str ); + float weight_b = curve( max( 1.0f - abs(( hsl.x - 0.666667f ) * 6.0f ), 0.0f ), curve_str ); + float weight_m = curve( max( 1.0f - abs(( hsl.x - 0.833333f ) * 6.0f ), 0.0f ), curve_str ); + + // No saturation (greyscale) should not influence B&W image + float sat = hsl.y * ( 1.0f - hsl.y ) + hsl.y; + float ret = hsl.z; + ret += ( hsl.z * ( weight_r * r ) * sat * lum ); + ret += ( hsl.z * ( weight_y * y ) * sat * lum ); + ret += ( hsl.z * ( weight_g * g ) * sat * lum ); + ret += ( hsl.z * ( weight_c * c ) * sat * lum ); + ret += ( hsl.z * ( weight_b * b ) * sat * lum ); + ret += ( hsl.z * ( weight_m * m ) * sat * lum ); + + return saturate( ret ); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_BlackandWhite(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + color.xyz = saturate( color.xyz ); + + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 4, enable_dither, dither_strength, 1, 0.5f ); + color.xyz = saturate( color.xyz + dnoise.zyx ); + + float red; float yellow; float green; + float cyan; float blue; float magenta; + + switch( bw_mode ) + { + case 0: // Red Filter + { + red = 0.2f; + yellow = 0.5f; + green = -0.2f; + cyan = -0.6f; + blue = -1.0f; + magenta = -0.2f; + } + break; + case 1: // Green Filter + { + red = -0.5f; + yellow = 0.5f; + green = 1.2f; + cyan = -0.2f; + blue = -1.0f; + magenta = -0.5f; + } + break; + case 2: // Blue Filter + { + red = -0.2f; + yellow = 0.4f; + green = -0.6f; + cyan = 0.5f; + blue = 1.0f; + magenta = -0.2f; + } + break; + case 3: // High Contrast Red Filter + { + red = 0.5f; + yellow = 1.2f; + green = -0.5f; + cyan = -1.0f; + blue = -1.5f; + magenta = -1.0f; + } + break; + case 4: // High Contrast Green Filter + { + red = -1.0f; + yellow = 1.0f; + green = 1.2f; + cyan = -0.2f; + blue = -1.5f; + magenta = -1.0f; + } + break; + case 5: // High Contrast Blue Filter + { + red = -0.7f; + yellow = 0.4f; + green = -1.2f; + cyan = 0.7f; + blue = 1.2f; + magenta = -0.2f; + } + break; + case 6: // Infrared + { + red = -1.35f; + yellow = 2.35f; + green = 1.35f; + cyan = -1.35f; + blue = -1.6f; + magenta = -1.07f; + } + break; + case 7: // Maximum Black + { + red = -1.0f; + yellow = -1.0f; + green = -1.0f; + cyan = -1.0f; + blue = -1.0f; + magenta = -1.0f; + } + break; + case 8: // Maximum White + { + red = 1.0f; + yellow = 1.0f; + green = 1.0f; + cyan = 1.0f; + blue = 1.0f; + magenta = 1.0f; + } + break; + case 9: // Preserve Luminosity + { + red = -0.7f; + yellow = 0.9f; + green = 0.6f; + cyan = 0.1f; + blue = -0.4f; + magenta = -0.4f; + } + break; + case 10: // Neutral Green Filter + { + red = 0.2f; + yellow = 0.4f; + green = 0.6f; + cyan = 0.0f; + blue = -0.6f; + magenta = -0.2f; + } + break; + case 11: // Maintain Contrasts + { + red = -0.3f; + yellow = 1.0f; + green = -0.3f; + cyan = -0.6f; + blue = -1.0f; + magenta = -0.6f; + } + break; + case 12: // High Contrast + { + red = -0.3f; + yellow = 2.6f; + green = -0.3f; + cyan = -1.2f; + blue = -0.6f; + magenta = -0.4f; + } + break; + case 13: // Custom Filter + { + red = redchannel; + yellow = yellowchannel; + green = greenchannel; + cyan = cyanchannel; + blue = bluechannel; + magenta = magentachannel; + } + break; + default: + { + red = redchannel; + yellow = yellowchannel; + green = greenchannel; + cyan = cyanchannel; + blue = bluechannel; + magenta = magentachannel; + } + break; + } + // Do the Black & White + color.xyz = ProcessBW( color.xyz, red, yellow, green, cyan, blue, magenta ); + // Do the tinting + color.xyz = lerp( color.xyz, HSLToRGB( float3( tinthue, tintsat, color.x )), use_tint ); + if( show_clip ) + { + float h = 0.98f; + float l = 0.01f; + color.xyz = min( min( color.x, color.y ), color.z ) >= h ? lerp( color.xyz, float3( 1.0f, 0.0f, 0.0f ), smoothstep( h, 1.0f, min( min( color.x, color.y ), color.z ))) : color.xyz; + color.xyz = max( max( color.x, color.y ), color.z ) <= l ? lerp( float3( 0.0f, 0.0f, 1.0f ), color.xyz, smoothstep( 0.0f, l, max( max( color.x, color.y ), color.z ))) : color.xyz; + } + color.xyz = saturate( color.xyz + dnoise.xyz ); + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_Black_and_White + { + pass prod80_BlackandWhite + { + VertexShader = PostProcessVS; + PixelShader = PS_BlackandWhite; + } + } +} diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Color_Balance.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Color_Balance.fx new file mode 100644 index 00000000..f9e47b21 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Color_Balance.fx @@ -0,0 +1,221 @@ +/* + Description : PD80 04 Color Balance for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +namespace pd80_colorbalance +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENS ///////////////////////////////////////////////////////////////// + uniform bool preserve_luma < + ui_label = "Preserve Luminosity"; + ui_tooltip = "Preserve Luminosity"; + ui_category = "Color Balance"; + > = true; + uniform int separation_mode < __UNIFORM_COMBO_INT1 + ui_label = "Luma Separation Mode"; + ui_tooltip = "Luma Separation Mode"; + ui_category = "Color Balance"; + ui_items = "Harsh Separation\0Smooth Separation\0"; + > = 0; + uniform float s_RedShift < + ui_label = "Cyan <--> Red"; + ui_tooltip = "Shadows: Cyan <--> Red"; + ui_category = "Shadows"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float s_GreenShift < + ui_label = "Magenta <--> Green"; + ui_tooltip = "Shadows: Magenta <--> Green"; + ui_category = "Shadows"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float s_BlueShift < + ui_label = "Yellow <--> Blue"; + ui_tooltip = "Shadows: Yellow <--> Blue"; + ui_category = "Shadows"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float m_RedShift < + ui_label = "Cyan <--> Red"; + ui_tooltip = "Midtones: Cyan <--> Red"; + ui_category = "Midtones"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float m_GreenShift < + ui_label = "Magenta <--> Green"; + ui_tooltip = "Midtones: Magenta <--> Green"; + ui_category = "Midtones"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float m_BlueShift < + ui_label = "Yellow <--> Blue"; + ui_tooltip = "Midtones: Yellow <--> Blue"; + ui_category = "Midtones"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float h_RedShift < + ui_label = "Cyan <--> Red"; + ui_tooltip = "Highlights: Cyan <--> Red"; + ui_category = "Highlights"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float h_GreenShift < + ui_label = "Magenta <--> Green"; + ui_tooltip = "Highlights: Magenta <--> Green"; + ui_category = "Highlights"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float h_BlueShift < + ui_label = "Yellow <--> Blue"; + ui_tooltip = "Highlights: Yellow <--> Blue"; + ui_category = "Highlights"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + #define ES_RGB float3( 1.0 - float3( 0.299, 0.587, 0.114 )) + #define ES_CMY float3( dot( ES_RGB.yz, 0.5 ), dot( ES_RGB.xz, 0.5 ), dot( ES_RGB.xy, 0.5 )) + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float3 curve( float3 x ) + { + return x * x * ( 3.0f - 2.0f * x ); + } + + float3 ColorBalance( float3 c, float3 shadows, float3 midtones, float3 highlights ) + { + // For highlights + float luma = dot( c.xyz, float3( 0.333333f, 0.333334f, 0.333333f )); + + // Determine the distribution curves between shadows, midtones, and highlights + float3 dist_s; float3 dist_h; + + switch( separation_mode ) + { + /* + Clear cutoff between shadows and highlights + Maximizes precision at the loss of harsher transitions between contrasts + Curves look like: + + Shadows Highlights Midtones + ‾‾‾—_ _—‾‾‾ _——‾‾‾——_ + ‾‾——__________ __________——‾‾ ___—‾ ‾—___ + 0.0.....0.5.....1.0 0.0.....0.5.....1.0 0.0.....0.5.....1.0 + + */ + case 0: + { + dist_s.xyz = curve( max( 1.0f - c.xyz * 2.0f, 0.0f )); + dist_h.xyz = curve( max(( c.xyz - 0.5f ) * 2.0f, 0.0f )); + } break; + + /* + Higher degree of blending between individual curves + F.e. shadows will still have a minimal weight all the way into highlight territory + Ensures smoother transition areas between contrasts + Curves look like: + + Shadows Highlights Midtones + ‾‾‾—_ _—‾‾‾ __---__ + ‾‾———————_____ _____———————‾‾ ___-‾‾ ‾‾-___ + 0.0.....0.5.....1.0 0.0.....0.5.....1.0 0.0.....0.5.....1.0 + + */ + case 1: + { + dist_s.xyz = pow( 1.0f - c.xyz, 4.0f ); + dist_h.xyz = pow( c.xyz, 4.0f ); + } break; + } + + // Get luminosity offsets + // One could omit this whole code part in case no luma should be preserved + float3 s_rgb = 1.0f; + float3 m_rgb = 1.0f; + float3 h_rgb = 1.0f; + + if( preserve_luma ) + { + s_rgb = shadows > 0.0f ? ES_RGB * shadows : ES_CMY * abs( shadows ); + m_rgb = midtones > 0.0f ? ES_RGB * midtones : ES_CMY * abs( midtones ); + h_rgb = highlights > 0.0f ? ES_RGB * highlights : ES_CMY * abs( highlights ); + } + float3 mids = saturate( 1.0f - dist_s.xyz - dist_h.xyz ); + float3 highs = dist_h.xyz * ( highlights.xyz * h_rgb.xyz * ( 1.0f - luma )); + float3 newc = c.xyz * ( dist_s.xyz * shadows.xyz * s_rgb.xyz + mids.xyz * midtones.xyz * m_rgb.xyz ) * ( 1.0f - c.xyz ) + highs.xyz; + return saturate( c.xyz + newc.xyz ); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_ColorBalance(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + color.xyz = saturate( color.xyz ); + color.xyz = ColorBalance( color.xyz, float3( s_RedShift, s_GreenShift, s_BlueShift ), + float3( m_RedShift, m_GreenShift, m_BlueShift ), + float3( h_RedShift, h_GreenShift, h_BlueShift )); + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_ColorBalance + { + pass prod80_pass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_ColorBalance; + } + } +} + + diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Color_Gradients.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Color_Gradients.fx new file mode 100644 index 00000000..8c7aa476 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Color_Gradients.fx @@ -0,0 +1,362 @@ +/* + Description : PD80 04 Color Gradients for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" +#include "PD80_00_Blend_Modes.fxh" + +namespace pd80_ColorGradients +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int luma_mode < __UNIFORM_COMBO_INT1 + ui_label = "Luma Mode"; + ui_tooltip = "Luma Mode"; + ui_category = "Global"; + ui_items = "Use Average\0Use Perceived Luma\0Use Max Value\0"; + > = 0; + uniform int separation_mode < __UNIFORM_COMBO_INT1 + ui_label = "Luma Separation Mode"; + ui_tooltip = "Luma Separation Mode"; + ui_category = "Global"; + ui_items = "Harsh Separation\0Smooth Separation\0"; + > = 0; + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Global"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Global"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + uniform float CGdesat < + ui_label = "Desaturate Base Image"; + ui_tooltip = "Desaturate Base Image"; + ui_category = "Mixing Values"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float finalmix < + ui_label = "Mix with Original"; + ui_tooltip = "Mix with Original"; + ui_category = "Mixing Values"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.333; + // Light Scene + uniform float3 blendcolor_ls_m < + ui_type = "color"; + ui_label = "Color"; + ui_tooltip = "Light Scene: Midtone Color"; + ui_category = "Light Scene: Midtone Color"; + > = float3( 0.98, 0.588, 0.0 ); + uniform int blendmode_ls_m < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Light Scene: Midtone Color Blendmode"; + ui_category = "Light Scene: Midtone Color"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 10; + uniform float opacity_ls_m < + ui_label = "Opacity"; + ui_tooltip = "Light Scene: Midtone Color Opacity"; + ui_category = "Light Scene: Midtone Color"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + uniform float3 blendcolor_ls_s < + ui_type = "color"; + ui_label = "Color"; + ui_tooltip = "Light Scene: Shadow Color"; + ui_category = "Light Scene: Shadow Color"; + > = float3( 0.0, 0.365, 1.0 ); + uniform int blendmode_ls_s < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Light Scene: Shadow Color Blendmode"; + ui_category = "Light Scene: Shadow Color"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 5; + uniform float opacity_ls_s < + ui_label = "Opacity"; + ui_tooltip = "Light Scene: Shadow Color Opacity"; + ui_category = "Light Scene: Shadow Color"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.3; + // Dark Scene + uniform bool enable_ds < + ui_text = "-------------------------------------\n" + "Enables transitions of gradients\n" + "depending on average scene luminance.\n" + "To simulate Day-Night color grading.\n" + "-------------------------------------"; + ui_label = "Enable Color Transitions"; + ui_tooltip = "Enable Color Transitions"; + ui_category = "Enable Color Transitions"; + > = true; + uniform float3 blendcolor_ds_m < + ui_type = "color"; + ui_label = "Color"; + ui_tooltip = "Dark Scene: Midtone Color"; + ui_category = "Dark Scene: Midtone Color"; + > = float3( 0.0, 0.365, 1.0 ); + uniform int blendmode_ds_m < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Dark Scene: Midtone Color Blendmode"; + ui_category = "Dark Scene: Midtone Color"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 10; + uniform float opacity_ds_m < + ui_label = "Opacity"; + ui_tooltip = "Dark Scene: Midtone Color Opacity"; + ui_category = "Dark Scene: Midtone Color"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + uniform float3 blendcolor_ds_s < + ui_type = "color"; + ui_label = "Color"; + ui_tooltip = "Dark Scene: Shadow Color"; + ui_category = "Dark Scene: Shadow Color"; + > = float3( 0.0, 0.039, 0.588 ); + uniform int blendmode_ds_s < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Dark Scene: Shadow Color Blendmode"; + ui_category = "Dark Scene: Shadow Color"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 10; + uniform float opacity_ds_s < + ui_label = "Opacity"; + ui_tooltip = "Dark Scene: Shadow Color Opacity"; + ui_category = "Dark Scene: Shadow Color"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + uniform float minlevel < + ui_label = "Pure Dark Scene Level"; + ui_tooltip = "Pure Dark Scene Level"; + ui_category = "Scene Luminance Adaptation"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.125; + uniform float maxlevel < + ui_label = "Pure Light Scene Level"; + ui_tooltip = "Pure Light Scene Level"; + ui_category = "Scene Luminance Adaptation"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.3; + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texLuma { Width = 256; Height = 256; Format = R16F; MipLevels = 8; }; + texture texAvgLuma { Format = R16F; }; + texture texPrevAvgLuma { Format = R16F; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerLuma { Texture = texLuma; }; + sampler samplerAvgLuma { Texture = texAvgLuma; }; + sampler samplerPrevAvgLuma { Texture = texPrevAvgLuma; }; + + //// DEFINES //////////////////////////////////////////////////////////////////// + #define LumCoeff float3(0.212656, 0.715158, 0.072186) + uniform float Frametime < source = "frametime"; >; + uniform float2 pingpong < source = "pingpong"; min = 0; max = 128; step = 1; >; + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float getLuminance( in float3 x ) + { + return dot( x, LumCoeff ); + } + + float curve( float x ) + { + return x * x * ( 3.0f - 2.0f * x ); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float PS_WriteLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + float luma = max( max( color.x, color.y ), color.z ); + return luma; //writes to texLuma + } + + float PS_AvgLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float luma = tex2Dlod( samplerLuma, float4( 0.5f, 0.5f, 0, 8 )).x; + float prevluma = tex2D( samplerPrevAvgLuma, float2( 0.5f, 0.5f )).x; + float avgLuma = lerp( prevluma, luma, saturate( Frametime * 0.003f )); + return avgLuma; //writes to texAvgLuma + } + + float4 PS_ColorGradients(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + float sceneluma = tex2D( samplerAvgLuma, float2( 0.5f, 0.5f )).x; + float ml = ( minlevel >= maxlevel ) ? maxlevel - 0.01f : minlevel; + sceneluma = smoothstep( ml, maxlevel, sceneluma ); + color.xyz = saturate( color.xyz ); + + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 5, enable_dither, dither_strength, 1, 0.5f ); + color.xyz = saturate( color.xyz + dnoise.xyz ); + + // Weights + float cWeight; + switch( luma_mode ) + { + case 0: // Use average + { + cWeight = dot( color.xyz, float3( 0.333333f, 0.333334f, 0.333333f )); + } + break; + case 1: // Use perceived luma + { + cWeight = dot( color.xyz, float3( 0.212656f, 0.715158f, 0.072186f )); + } + break; + case 2: // Use max + { + cWeight = max( max( color.x, color.y ), color.z ); + } + break; + } + + float w_s; float w_h; float w_m; + switch( separation_mode ) + { + /* + Clear cutoff between shadows and highlights + Maximizes precision at the loss of harsher transitions between contrasts + Curves look like: + + Shadows Highlights Midtones + ‾‾‾—_ _—‾‾‾ _——‾‾‾——_ + ‾‾——__________ __________——‾‾ ___—‾ ‾—___ + 0.0.....0.5.....1.0 0.0.....0.5.....1.0 0.0.....0.5.....1.0 + + */ + case 0: + { + w_s = curve( max( 1.0f - cWeight * 2.0f, 0.0f )); + w_h = curve( max(( cWeight - 0.5f ) * 2.0f, 0.0f )); + w_m = saturate( 1.0f - w_s - w_h ); + } break; + + /* + Higher degree of blending between individual curves + F.e. shadows will still have a minimal weight all the way into highlight territory + Ensures smoother transition areas between contrasts + Curves look like: + + Shadows Highlights Midtones + ‾‾‾—_ _—‾‾‾ __---__ + ‾‾———————_____ _____———————‾‾ ___-‾‾ ‾‾-___ + 0.0.....0.5.....1.0 0.0.....0.5.....1.0 0.0.....0.5.....1.0 + + */ + case 1: + { + w_s = pow( 1.0f - cWeight, 4.0f ); + w_h = pow( cWeight, 4.0f ); + w_m = saturate( 1.0f - w_s - w_h ); + } break; + } + + // Desat original + // float pLuma = getLuminance( color.xyz ); + color.xyz = lerp( color.xyz, cWeight, CGdesat ); + + // Coloring + float3 LS_col; + float3 DS_col; + + // Light scene + float3 LS_b_s = blendmode( color.xyz, blendcolor_ls_s.xyz, blendmode_ls_s, opacity_ls_s ); + float3 LS_b_m = blendmode( color.xyz, blendcolor_ls_m.xyz, blendmode_ls_m, opacity_ls_m ); + LS_col.xyz = LS_b_s.xyz * w_s + LS_b_m.xyz * w_m + w_h; + + // Dark Scene + float3 DS_b_s = blendmode( color.xyz, blendcolor_ds_s.xyz, blendmode_ds_s, opacity_ds_s ); + float3 DS_b_m = blendmode( color.xyz, blendcolor_ds_m.xyz, blendmode_ds_m, opacity_ds_m ); + DS_col.xyz = DS_b_s.xyz * w_s + DS_b_m.xyz * w_m + w_h; + + // Mix + float3 new_c = lerp( DS_col.xyz, LS_col.xyz, sceneluma ); + new_c.xyz = ( enable_ds ) ? new_c.xyz : LS_col.xyz; + color.xyz = lerp( color.xyz, new_c.xyz, finalmix ); + + return float4( color.xyz, 1.0f ); + } + + float PS_PrevAvgLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float avgLuma = tex2D( samplerAvgLuma, float2( 0.5f, 0.5f )).x; + return avgLuma; //writes to texPrevAvgLuma + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_ColorGradient + { + pass Luma + { + VertexShader = PostProcessVS; + PixelShader = PS_WriteLuma; + RenderTarget = texLuma; + } + pass AvgLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_AvgLuma; + RenderTarget = texAvgLuma; + } + pass ColorGradients + { + VertexShader = PostProcessVS; + PixelShader = PS_ColorGradients; + } + pass PreviousLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_PrevAvgLuma; + RenderTarget = texPrevAvgLuma; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Color_Isolation.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Color_Isolation.fx new file mode 100644 index 00000000..3b396272 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Color_Isolation.fx @@ -0,0 +1,117 @@ +/* + Description : PD80 04 Color Isolation for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Color_Spaces.fxh" + +namespace pd80_ColorIsolation +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform float hueMid < + ui_label = "Hue Selection (Middle)"; + ui_category = "Color Isolation"; + ui_tooltip = "0 = Red, 0.167 = Yellow, 0.333 = Green, 0.5 = Cyan, 0.666 = Blue, 0.833 = Magenta"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float hueRange < + ui_label = "Hue Range Selection"; + ui_tooltip = "Hue Range Selection"; + ui_category = "Color Isolation"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.167; + uniform float satLimit < + ui_label = "Saturation Output"; + ui_tooltip = "Saturation Output"; + ui_category = "Color Isolation"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + uniform float fxcolorMix < + ui_label = "Mix with Original"; + ui_tooltip = "Mix with Original"; + ui_category = "Color Isolation"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + #define LumCoeff float3(0.212656, 0.715158, 0.072186) + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float getLuminance( in float3 x ) + { + return dot( x, LumCoeff ); + } + + float smootherstep( float x ) + { + return x * x * x * ( x * ( x * 6.0f - 15.0f ) + 10.0f ); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_ColorIso(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + color.xyz = saturate( color.xyz ); //Can't work with HDR + + float grey = getLuminance( color.xyz ); + float hue = RGBToHSV( color.xyz ).x; + + float r = rcp( hueRange ); + float3 w = max( 1.0f - abs(( hue - hueMid ) * r ), 0.0f ); + w.y = max( 1.0f - abs(( hue + 1.0f - hueMid ) * r ), 0.0f ); + w.z = max( 1.0f - abs(( hue - 1.0f - hueMid ) * r ), 0.0f ); + float weight = dot( w.xyz, 1.0f ); + + float3 newc = lerp( grey, color.xyz, smootherstep( weight ) * satLimit ); + color.xyz = lerp( color.xyz, newc.xyz, fxcolorMix ); + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_ColorIsolation + { + pass ColorIso + { + VertexShader = PostProcessVS; + PixelShader = PS_ColorIso; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Color_Temperature.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Color_Temperature.fx new file mode 100644 index 00000000..96cd61d5 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Color_Temperature.fx @@ -0,0 +1,95 @@ +/* + Description : PD80 04 Color Temperature for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + Additional credits + - Taller Helland + http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ + - Renaud Bédard https://www.shadertoy.com/view/lsSXW1 + License: https://creativecommons.org/licenses/by/3.0/ + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Color_Spaces.fxh" + +namespace pd80_colortemp +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform uint Kelvin < + ui_label = "Color Temp (K)"; + ui_tooltip = "Color Temp (K)"; + ui_category = "Kelvin"; + ui_type = "slider"; + ui_min = 1000; + ui_max = 40000; + > = 6500; + uniform float LumPreservation < + ui_label = "Luminance Preservation"; + ui_tooltip = "Luminance Preservation"; + ui_category = "Kelvin"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + uniform float kMix < + ui_label = "Mix with Original"; + ui_tooltip = "Mix with Original"; + ui_category = "Kelvin"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_ColorTemp(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + float3 kColor = KelvinToRGB( Kelvin ); + float3 oLum = RGBToHSL( color.xyz ); + float3 blended = lerp( color.xyz, color.xyz * kColor.xyz, kMix ); + float3 resHSV = RGBToHSL( blended.xyz ); + float3 resRGB = HSLToRGB( float3( resHSV.xy, oLum.z )); + color.xyz = lerp( blended.xyz, resRGB.xyz, LumPreservation ); + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_ColorTemperature + { + pass ColorTemp + { + VertexShader = PostProcessVS; + PixelShader = PS_ColorTemp; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Contrast_Brightness_Saturation.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Contrast_Brightness_Saturation.fx new file mode 100644 index 00000000..af9d6fa7 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Contrast_Brightness_Saturation.fx @@ -0,0 +1,371 @@ +/* + Description : PD80 04 Contrast Brightness Saturation for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" +#include "PD80_00_Color_Spaces.fxh" +#include "PD80_00_Blend_Modes.fxh" +#include "PD80_00_Base_Effects.fxh" + +namespace pd80_conbrisat +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Global"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Global"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + uniform float tint < + ui_label = "Tint"; + ui_tooltip = "Tint"; + ui_category = "Final Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float exposureN < + ui_label = "Exposure"; + ui_tooltip = "Exposure"; + ui_category = "Final Adjustments"; + ui_type = "slider"; + ui_min = -4.0; + ui_max = 4.0; + > = 0.0; + uniform float contrast < + ui_label = "Contrast"; + ui_tooltip = "Contrast"; + ui_category = "Final Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float brightness < + ui_label = "Brightness"; + ui_tooltip = "Brightness"; + ui_category = "Final Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float saturation < + ui_label = "Saturation"; + ui_tooltip = "Saturation"; + ui_category = "Final Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float vibrance < + ui_label = "Vibrance"; + ui_tooltip = "Vibrance"; + ui_category = "Final Adjustments"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float huemid < + ui_label = "Color Hue"; + ui_tooltip = "Custom Color Hue"; + ui_category = "Custom Saturation Adjustments"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float huerange < + ui_label = "Hue Range Selection"; + ui_tooltip = "Custom Hue Range Selection"; + ui_category = "Custom Saturation Adjustments"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.167; + uniform float sat_custom < + ui_label = "Custom Saturation Level"; + ui_tooltip = "Custom Saturation Level"; + ui_category = "Custom Saturation Adjustments"; + ui_type = "slider"; + ui_min = -2.0; + ui_max = 2.0; + > = 0.0; + uniform float sat_r < + ui_label = "Red Saturation"; + ui_tooltip = "Red Saturation"; + ui_category = "Color Saturation Adjustments"; + ui_type = "slider"; + ui_min = -2.0; + ui_max = 2.0; + > = 0.0; + uniform float sat_y < + ui_label = "Yellow Saturation"; + ui_tooltip = "Yellow Saturation"; + ui_category = "Color Saturation Adjustments"; + ui_type = "slider"; + ui_min = -2.0; + ui_max = 2.0; + > = 0.0; + uniform float sat_g < + ui_label = "Green Saturation"; + ui_tooltip = "Green Saturation"; + ui_category = "Color Saturation Adjustments"; + ui_type = "slider"; + ui_min = -2.0; + ui_max = 2.0; + > = 0.0; + uniform float sat_a < + ui_label = "Aqua Saturation"; + ui_tooltip = "Aqua Saturation"; + ui_category = "Color Saturation Adjustments"; + ui_type = "slider"; + ui_min = -2.0; + ui_max = 2.0; + > = 0.0; + uniform float sat_b < + ui_label = "Blue Saturation"; + ui_tooltip = "Blue Saturation"; + ui_category = "Color Saturation Adjustments"; + ui_type = "slider"; + ui_min = -2.0; + ui_max = 2.0; + > = 0.0; + uniform float sat_p < + ui_label = "Purple Saturation"; + ui_tooltip = "Purple Saturation"; + ui_category = "Color Saturation Adjustments"; + ui_type = "slider"; + ui_min = -2.0; + ui_max = 2.0; + > = 0.0; + uniform float sat_m < + ui_label = "Magenta Saturation"; + ui_tooltip = "Magenta Saturation"; + ui_category = "Color Saturation Adjustments"; + ui_type = "slider"; + ui_min = -2.0; + ui_max = 2.0; + > = 0.0; + uniform bool enable_depth < + ui_label = "Enable depth based adjustments.\nMake sure you have setup your depth buffer correctly."; + ui_tooltip = "Enable depth based adjustments"; + ui_category = "Final Adjustments: Depth"; + > = false; + uniform bool display_depth < + ui_label = "Show depth texture"; + ui_tooltip = "Show depth texture"; + ui_category = "Final Adjustments: Depth"; + > = false; + uniform float depthStart < + ui_type = "slider"; + ui_label = "Change Depth Start Plane"; + ui_tooltip = "Change Depth Start Plane"; + ui_category = "Final Adjustments: Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.0; + uniform float depthEnd < + ui_type = "slider"; + ui_label = "Change Depth End Plane"; + ui_tooltip = "Change Depth End Plane"; + ui_category = "Final Adjustments: Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.1; + uniform float depthCurve < + ui_label = "Depth Curve Adjustment"; + ui_tooltip = "Depth Curve Adjustment"; + ui_category = "Final Adjustments: Depth"; + ui_type = "slider"; + ui_min = 0.05; + ui_max = 8.0; + > = 1.0; + uniform float exposureD < + ui_label = "Exposure Far"; + ui_tooltip = "Exposure Far"; + ui_category = "Final Adjustments: Far"; + ui_type = "slider"; + ui_min = -4.0; + ui_max = 4.0; + > = 0.0; + uniform float contrastD < + ui_label = "Contrast Far"; + ui_tooltip = "Contrast Far"; + ui_category = "Final Adjustments: Far"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float brightnessD < + ui_label = "Brightness Far"; + ui_tooltip = "Brightness Far"; + ui_category = "Final Adjustments: Far"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.5; + > = 0.0; + uniform float saturationD < + ui_label = "Saturation Far"; + ui_tooltip = "Saturation Far"; + ui_category = "Final Adjustments: Far"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float vibranceD < + ui_label = "Vibrance Far"; + ui_tooltip = "Vibrance Far"; + ui_category = "Final Adjustments: Far"; + ui_type = "slider"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float getLuminance( in float3 x ) + { + return dot( x, float3( 0.212656, 0.715158, 0.072186 )); + } + + float curve( float x ) + { + return x * x * ( 3.0 - 2.0 * x ); + } + + float3 channelsat( float3 col, float r, float y, float g, float a, float b, float p, float m, float hue ) + { + float desat = getLuminance( col.xyz ); + + // Red : 0.0 + // Orange : 0.083 + // Yellow : 0.167 + // Green : 0.333 + // Cyan/Aqua : 0.5 + // Blue : 0.667 + // Purple : 0.75 + // Magenta : 0.833 + + float weight_r = curve( max( 1.0f - abs( hue * 6.0f ), 0.0f )) + + curve( max( 1.0f - abs(( hue - 1.0f ) * 6.0f ), 0.0f )); + float weight_y = curve( max( 1.0f - abs(( hue - 0.166667f ) * 6.0f ), 0.0f )); + float weight_g = curve( max( 1.0f - abs(( hue - 0.333333f ) * 6.0f ), 0.0f )); + float weight_a = curve( max( 1.0f - abs(( hue - 0.5f ) * 6.0f ), 0.0f )); + float weight_b = curve( max( 1.0f - abs(( hue - 0.666667f ) * 6.0f ), 0.0f )); + float weight_p = curve( max( 1.0f - abs(( hue - 0.75f ) * 6.0f ), 0.0f )); + float weight_m = curve( max( 1.0f - abs(( hue - 0.833333f ) * 6.0f ), 0.0f )); + + col.xyz = lerp( desat, col.xyz, clamp( 1.0f + r * weight_r, 0.0f, 2.0f )); + col.xyz = lerp( desat, col.xyz, clamp( 1.0f + y * weight_y, 0.0f, 2.0f )); + col.xyz = lerp( desat, col.xyz, clamp( 1.0f + g * weight_g, 0.0f, 2.0f )); + col.xyz = lerp( desat, col.xyz, clamp( 1.0f + a * weight_a, 0.0f, 2.0f )); + col.xyz = lerp( desat, col.xyz, clamp( 1.0f + b * weight_b, 0.0f, 2.0f )); + col.xyz = lerp( desat, col.xyz, clamp( 1.0f + p * weight_p, 0.0f, 2.0f )); + col.xyz = lerp( desat, col.xyz, clamp( 1.0f + m * weight_m, 0.0f, 2.0f )); + + return saturate( col.xyz ); + } + + float3 customsat( float3 col, float h, float range, float sat, float hue ) + { + float desat = getLuminance( col.xyz ); + float r = rcp( range ); + float3 w = max( 1.0f - abs(( hue - h ) * r ), 0.0f ); + w.y = max( 1.0f - abs(( hue + 1.0f - h ) * r ), 0.0f ); + w.z = max( 1.0f - abs(( hue - 1.0f - h ) * r ), 0.0f ); + float weight = curve( dot( w.xyz, 1.0f )) * sat; + col.xyz = lerp( desat, col.xyz, clamp( 1.0f + weight, 0.0f, 2.0f )); + return saturate( col.xyz ); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_CBS(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 6, enable_dither, dither_strength, 1, 0.5f ); + color.xyz = saturate( color.xyz + dnoise.xyz ); + + float depth = ReShade::GetLinearizedDepth( texcoord ).x; + depth = smoothstep( depthStart, depthEnd, depth ); + depth = pow( depth, depthCurve ); + float4 dnoise2 = dither( samplerGaussNoise, texcoord.xy, 0, 1, 1.0f, 0, 1.0f ); + depth = saturate( depth + dnoise2.x ); + + float3 cold = float3( 0.0f, 0.365f, 1.0f ); //LBB + float3 warm = float3( 0.98f, 0.588f, 0.0f ); //LBA + + color.xyz = ( tint < 0.0f ) ? lerp( color.xyz, blendLuma( cold.xyz, color.xyz ), abs( tint )) : + lerp( color.xyz, blendLuma( warm.xyz, color.xyz ), tint ); + + float3 dcolor = color.xyz; + color.xyz = exposure( color.xyz, exposureN ); + color.xyz = con( color.xyz, contrast ); + color.xyz = bri( color.xyz, brightness ); + color.xyz = sat( color.xyz, saturation ); + color.xyz = vib( color.xyz, vibrance ); + + dcolor.xyz = exposure( dcolor.xyz, exposureD ); + dcolor.xyz = con( dcolor.xyz, contrastD ); + dcolor.xyz = bri( dcolor.xyz, brightnessD ); + dcolor.xyz = sat( dcolor.xyz, saturationD ); + dcolor.xyz = vib( dcolor.xyz, vibranceD ); + + color.xyz = lerp( color.xyz, dcolor.xyz, enable_depth * depth ); // apply based on depth + + float chue = RGBToHSL( color.xyz ).x; + color.xyz = channelsat( color.xyz, sat_r, sat_y, sat_g, sat_a, sat_b, sat_p, sat_m, chue ); + color.xyz = customsat( color.xyz, huemid, huerange, sat_custom, chue ); + + color.xyz = display_depth ? depth.xxx : color.xyz; // show depth + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_ContrastBrightnessSaturation + { + pass ConBriSat + { + VertexShader = PostProcessVS; + PixelShader = PS_CBS; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Magical_Rectangle.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Magical_Rectangle.fx new file mode 100644 index 00000000..a2bb9135 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Magical_Rectangle.fx @@ -0,0 +1,364 @@ +/* + Description : PD80 04 Magical Rectangle for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" +#include "PD80_00_Blend_Modes.fxh" +#include "PD80_00_Color_Spaces.fxh" +#include "PD80_00_Base_Effects.fxh" + +namespace pd80_magicalrectangle +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int shape < __UNIFORM_COMBO_INT1 + ui_label = "Shape"; + ui_tooltip = "Shape"; + ui_category = "Shape Manipulation"; + ui_items = "Square\0Circle\0"; + > = 0; + uniform bool invert_shape < + ui_label = "Invert Shape"; + ui_tooltip = "Invert Shape"; + ui_category = "Shape Manipulation"; + > = false; + uniform uint rotation < + ui_type = "slider"; + ui_label = "Rotation Factor"; + ui_tooltip = "Rotation Factor"; + ui_category = "Shape Manipulation"; + ui_min = 0; + ui_max = 360; + > = 45; + uniform float2 center < + ui_type = "slider"; + ui_label = "Center"; + ui_tooltip = "Center"; + ui_category = "Shape Manipulation"; + ui_min = 0.0; + ui_max = 1.0; + > = float2( 0.5, 0.5 ); + uniform float ret_size_x < + ui_type = "slider"; + ui_label = "Horizontal Size"; + ui_tooltip = "Horizontal Size"; + ui_category = "Shape Manipulation"; + ui_min = 0.0; + ui_max = 0.5; + > = 0.125; + uniform float ret_size_y < + ui_type = "slider"; + ui_label = "Vertical Size"; + ui_tooltip = "Vertical Size"; + ui_category = "Shape Manipulation"; + ui_min = 0.0; + ui_max = 0.5; + > = 0.125; + uniform float depthpos < + ui_type = "slider"; + ui_label = "Depth Position"; + ui_tooltip = "Depth Position"; + ui_category = "Shape Manipulation"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float smoothing < + ui_type = "slider"; + ui_label = "Edge Smoothing"; + ui_tooltip = "Edge Smoothing"; + ui_category = "Shape Manipulation"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.01; + uniform float depth_smoothing < + ui_type = "slider"; + ui_label = "Depth Smoothing"; + ui_tooltip = "Depth Smoothing"; + ui_category = "Shape Manipulation"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.002; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Shape Manipulation"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 0.0; + uniform float3 reccolor < + ui_text = "-------------------------------------\n" + "Use Opacity and Blend Mode to adjust\n" + "Shape controls the Shape coloring\n" + "Image controls the underlying picture\n" + "-------------------------------------"; + ui_type = "color"; + ui_label = "Shape: Color"; + ui_tooltip = "Shape: Color"; + ui_category = "Shape Coloration"; + > = float3( 0.5, 0.5, 0.5 ); + uniform float mr_exposure < + ui_type = "slider"; + ui_label = "Image: Exposure"; + ui_tooltip = "Image: Exposure"; + ui_category = "Shape Coloration"; + ui_min = -4.0; + ui_max = 4.0; + > = 0.0; + uniform float mr_contrast < + ui_type = "slider"; + ui_label = "Image: Contrast"; + ui_tooltip = "Image: Contrast"; + ui_category = "Shape Coloration"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float mr_brightness < + ui_type = "slider"; + ui_label = "Image: Brightness"; + ui_tooltip = "Image: Brightness"; + ui_category = "Shape Coloration"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float mr_hue < + ui_type = "slider"; + ui_label = "Image: Hue"; + ui_tooltip = "Image: Hue"; + ui_category = "Shape Coloration"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float mr_saturation < + ui_type = "slider"; + ui_label = "Image: Saturation"; + ui_tooltip = "Image: Saturation"; + ui_category = "Shape Coloration"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform float mr_vibrance < + ui_type = "slider"; + ui_label = "Image: Vibrance"; + ui_tooltip = "Image: Vibrance"; + ui_category = "Shape Coloration"; + ui_min = -1.0; + ui_max = 1.0; + > = 0.0; + uniform bool enable_gradient < + ui_label = "Enable Gradient"; + ui_tooltip = "Enable Gradient"; + ui_category = "Shape Gradient"; + > = false; + uniform bool gradient_type < + ui_label = "Gradient Type"; + ui_tooltip = "Gradient Type"; + ui_category = "Shape Gradient"; + > = false; + uniform float gradient_curve < + ui_type = "slider"; + ui_label = "Gradient Curve"; + ui_tooltip = "Gradient Curve"; + ui_category = "Shape Gradient"; + ui_min = 0.001; + ui_max = 2.0; + > = 0.25; + uniform float intensity_boost < + ui_type = "slider"; + ui_label = "Intensity Boost"; + ui_tooltip = "Intensity Boost"; + ui_category = "Intensity Boost"; + ui_min = 1.0; + ui_max = 4.0; + > = 1.0; + uniform int blendmode_1 < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Blendmode"; + ui_category = "Shape Blending"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 0; + uniform float opacity < + ui_type = "slider"; + ui_label = "Opacity"; + ui_tooltip = "Opacity"; + ui_category = "Shape Blending"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texMagicRectangle { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerMagicRectangle { Texture = texMagicRectangle; }; + + //// DEFINES //////////////////////////////////////////////////////////////////// + #define ASPECT_RATIO float( BUFFER_WIDTH * BUFFER_RCP_HEIGHT ) + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + uniform bool hasdepth < source = "bufready_depth"; >; + + float3 hue( float3 res, float shift, float x ) + { + float3 hsl = RGBToHSL( res.xyz ); + hsl.x = frac( hsl.x + ( shift + 1.0f ) / 2.0f - 0.5f ); + hsl.xyz = HSLToRGB( hsl.xyz ); + return lerp( res.xyz, hsl.xyz, x ); + } + + float curve( float x ) + { + return x * x * x * ( x * ( x * 6.0f - 15.0f ) + 10.0f ); + } + + //// VERTEX SHADER ////////////////////////////////////////////////////////////// + /* + Adding texcoord2 in vextex shader which is a rotated texcoord + */ + void PPVS(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD, out float2 texcoord2 : TEXCOORD2) + { + PostProcessVS(id, position, texcoord); + float2 uv; + uv.x = ( id == 2 ) ? 2.0 : 0.0; + uv.y = ( id == 1 ) ? 2.0 : 0.0; + uv.xy -= center.xy; + uv.y /= ASPECT_RATIO; + float dim = ceil( sqrt( BUFFER_WIDTH * BUFFER_WIDTH + BUFFER_HEIGHT * BUFFER_HEIGHT )); // Diagonal size + float maxlen = min( BUFFER_WIDTH, BUFFER_HEIGHT ); + dim = dim / maxlen; // Scalar + uv.xy /= dim; + float sin = sin( radians( rotation )); + float cos = cos( radians( rotation )); + texcoord2.x = ( uv.x * cos ) + ( uv.y * (-sin)); + texcoord2.y = ( uv.x * sin ) + ( uv.y * cos ); + texcoord2.xy += float2( 0.5f, 0.5f ); // Transform back + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_Layer_1( float4 pos : SV_Position, float2 texcoord : TEXCOORD, float2 texcoord2 : TEXCOORD2 ) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + // Depth stuff + float depth = ReShade::GetLinearizedDepth( texcoord ).x; + // Sizing + float dim = ceil( sqrt( BUFFER_WIDTH * BUFFER_WIDTH + BUFFER_HEIGHT * BUFFER_HEIGHT )); // Diagonal size + float maxlen = max( BUFFER_WIDTH, BUFFER_HEIGHT ); + dim = dim / maxlen; // Scalar with screen diagonal + float2 uv = texcoord2.xy; + uv.xy = uv.xy * 2.0f - 1.0f; // rescale to -1..0..1 range + uv.xy /= ( float2( ret_size_x + ret_size_x * smoothing, ret_size_y + ret_size_y * smoothing ) * dim ); // scale rectangle + switch( shape ) + { + case 0: // square + { uv.xy = uv.xy; } break; + case 1: // circle + { uv.xy = lerp( dot( uv.xy, uv.xy ), dot( uv.xy, -uv.xy ), gradient_type ); } break; + } + uv.xy = ( uv.xy + 1.0f ) / 2.0f; // scale back to 0..1 range + + // Using smoothstep to create values from 0 to 1, 1 being the drawn shape around center + // First makes bottom and left side, then flips coord to make top and right side: x | 1 - x + // Do some funky stuff with gradients + // Finally make a depth fade + float2 bl = smoothstep( 0.0f, 0.0f + smoothing, uv.xy ); + float2 tr = smoothstep( 0.0f, 0.0f + smoothing, 1.0f - uv.xy ); + if( enable_gradient ) + { + if( gradient_type ) + { + bl = smoothstep( 0.0f, 0.0f + smoothing, uv.xy ) * pow( abs( uv.y ), gradient_curve ); + } + tr = smoothstep( 0.0f, 0.0f + smoothing, 1.0f - uv.xy ) * pow( abs( uv.x ), gradient_curve ); + } + float depthfade = smoothstep( depthpos - depth_smoothing, depthpos + depth_smoothing, depth ); + depthfade = lerp( 1.0f, depthfade, hasdepth ); + // Combine them all + float R = bl.x * bl.y * tr.x * tr.y * depthfade; + R = ( invert_shape ) ? 1.0f - R : R; + // Blend the borders + float intensity = RGBToHSV( reccolor.xyz ).z; + color.xyz = lerp( color.xyz, saturate( color.xyz * saturate( 1.0f - R ) + R * intensity ), R ); + // Add to color, use R for Alpha + return float4( color.xyz, R ); + } + + float4 PS_Blend(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 orig = tex2D( ReShade::BackBuffer, texcoord ); + float3 color; + float4 layer_1 = saturate( tex2D( samplerMagicRectangle, texcoord )); + // Dither + // Input: sampler, texcoord, variance(int), enable_dither(bool), dither_strength(float), motion(bool), swing(float) + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 7, 1, dither_strength, 1, 0.5f ); + layer_1.xyz = saturate( layer_1.xyz + dnoise.xyz ); + + orig.xyz = exposure( orig.xyz, mr_exposure * layer_1.w ); + orig.xyz = con( orig.xyz, mr_contrast * layer_1.w ); + orig.xyz = bri( orig.xyz, mr_brightness * layer_1.w ); + orig.xyz = hue( orig.xyz, mr_hue, layer_1.w ); + orig.xyz = sat( orig.xyz, mr_saturation * layer_1.w ); + orig.xyz = vib( orig.xyz, mr_vibrance * layer_1.w ); + orig.xyz = saturate( orig.xyz ); + // Doing some HSL color space conversions to colorize + layer_1.xyz = saturate( layer_1.xyz * intensity_boost ); + layer_1.xyz = RGBToHSV( layer_1.xyz ); + float2 huesat = RGBToHSV( reccolor.xyz ).xy; + layer_1.xyz = HSVToRGB( float3( huesat.xy, layer_1.z )); + layer_1.xyz = saturate( layer_1.xyz ); + // Blend mode with background + color.xyz = blendmode( orig.xyz, layer_1.xyz, blendmode_1, saturate( layer_1.w ) * opacity ); + // Output to screen + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_Magical_Rectangle + < ui_tooltip = "The Magical Rectangle\n\n" + "This shader gives you a rectangular shape on your screen that you can manipulate in 3D space.\n" + "It can blend on depth, blur edges, change color, change blending, change shape, and so on.\n" + "It will allow you to manipulate parts of the scene in various ways. Not withstanding; add mist,\n" + "remove mist, change clouds, create backgrounds, draw flares, add contrasts, change hues, etc. in ways\n" + "another shader will not be able to do.\n\n" + "This shader requires access to depth buffer for full functionality!";> + { + pass prod80_pass0 + { + VertexShader = PPVS; + PixelShader = PS_Layer_1; + RenderTarget = texMagicRectangle; + } + pass prod80_pass1 + { + VertexShader = PPVS; + PixelShader = PS_Blend; + } + } +} + + diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Saturation_Limit.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Saturation_Limit.fx new file mode 100644 index 00000000..26ee43e4 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Saturation_Limit.fx @@ -0,0 +1,71 @@ +/* + Description : PD80 04 Saturation Limit for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Color_Spaces.fxh" + +namespace pd80_satlimit +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform float saturation_limit < + ui_type = "slider"; + ui_label = "Saturation Limit"; + ui_tooltip = "Saturation Limit"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_Satlimit(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float3 color = tex2D( ReShade::BackBuffer, texcoord ).xyz; + color.xyz = RGBToHSL( color.xyz ); + color.y = min( color.y, saturation_limit ); + color.xyz = HSLToRGB( color.xyz ); + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_Saturation_Limiter + { + pass prod80_pass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_Satlimit; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Selective_Color.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Selective_Color.fx new file mode 100644 index 00000000..e2094713 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Selective_Color.fx @@ -0,0 +1,683 @@ +/* + Description : PD80 04 Selective Color for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + Additional credits + - Based on the mathematical analysis provided here + http://blog.pkh.me/p/22-understanding-selective-coloring-in-adobe-photoshop.html + + MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Base_Effects.fxh" + +namespace pd80_selectivecolor +{ + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int corr_method < __UNIFORM_COMBO_INT1 + ui_label = "Correction Method"; + ui_tooltip = "Correction Method"; + ui_category = "Selective Color"; + ui_items = "Absolute\0Relative\0"; //Do not change order; 0=Absolute, 1=Relative + > = 1; + uniform int corr_method2 < __UNIFORM_COMBO_INT1 + ui_label = "Correction Method Saturation"; + ui_tooltip = "Correction Method Saturation"; + ui_category = "Selective Color"; + ui_items = "Absolute\0Relative\0"; //Do not change order; 0=Absolute, 1=Relative + > = 1; + // Reds + uniform float r_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Reds: Cyan"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Reds: Magenta"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Reds: Yellow"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Reds: Black"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Reds: Saturation"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Reds: Vibrance"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Yellows + uniform float y_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Yellows: Cyan"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Yellows: Magenta"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Yellows: Yellow"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Yellows: Black"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Yellows: Saturation"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Yellows: Vibrance"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Greens + uniform float g_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Greens: Cyan"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Greens: Magenta"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Greens: Yellow"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Greens: Black"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Greens: Saturation"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Greens: Vibrance"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Cyans + uniform float c_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Cyans: Cyan"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Cyans: Magenta"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Cyans: Yellow"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Cyans: Black"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Cyans: Saturation"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Cyans: Vibrance"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Blues + uniform float b_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Blues: Cyan"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Blues: Magenta"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Blues: Yellow"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Blues: Black"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Blues: Saturation"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Blues: Vibrance"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Magentas + uniform float m_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Magentas: Cyan"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Magentas: Magenta"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Magentas: Yellow"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Magentas: Black"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Magentas: Saturation"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Magentas: Vibrance"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Whites + uniform float w_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Whites: Cyan"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Whites: Magenta"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Whites: Yellow"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Whites: Black"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Whites: Saturation"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Whites: Vibrance"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Neutrals + uniform float n_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Neutrals: Cyan"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Neutrals: Magenta"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Neutrals: Yellow"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Neutrals: Black"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Neutrals: Saturation"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Neutrals: Vibrance"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Blacks + uniform float bk_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Blacks: Cyan"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Blacks: Magenta"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Blacks: Yellow"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Blacks: Black"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Blacks: Saturation"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_vib < + ui_type = "slider"; + ui_label = "Vibrance"; + ui_tooltip = "Selective Color Blacks: Vibrance"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + + float mid( float3 c ) + { + float sum = c.x + c.y + c.z; + float mn = min( min( c.x, c.y ), c.z ); + float mx = max( max( c.x, c.y ), c.z ); + return sum - mn - mx; + } + + float adjustcolor( float scale, float colorvalue, float adjust, float bk, int method ) + { + /* + y(value, adjustment) = clamp((( -1 - adjustment ) * bk - adjustment ) * method, -value, 1 - value ) * scale + absolute: method = 1.0f - colorvalue * 0 + relative: method = 1.0f - colorvalue * 1 + */ + return clamp((( -1.0f - adjust ) * bk - adjust ) * ( 1.0f - colorvalue * method ), -colorvalue, 1.0f - colorvalue) * scale; + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_SelectiveColor(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + + // Clamp 0..1 + color.xyz = saturate( color.xyz ); + + // Need these a lot + float min_value = min( min( color.x, color.y ), color.z ); + float max_value = max( max( color.x, color.y ), color.z ); + float mid_value = mid( color.xyz ); + + // Used for determining which pixels to adjust regardless of prior changes to color + float3 orig = color.xyz; + + // Scales + float sRGB = max_value - mid_value; + float sCMY = mid_value - min_value; + float sNeutrals = 1.0f - ( abs( max_value - 0.5f ) + abs( min_value - 0.5f )); + float sWhites = ( min_value - 0.5f ) * 2.0f; + float sBlacks = ( 0.5f - max_value ) * 2.0f; + + /* + Create relative saturation levels. + For example when saturating red channel you will manipulate yellow and magenta channels. + So, to ensure there are no bugs and transitions are smooth, need to scale saturation with + relative saturation of nearest colors. If difference between red and green is low ( color nearly yellow ) + you use this info to scale back red saturation on those pixels. + This solution is not fool proof, but gives acceptable results almost always. + */ + + // Red is when maxvalue = x + float r_d_m = orig.x - orig.z; + float r_d_y = orig.x - orig.y; + // Yellow is when minvalue = z + float y_d = mid_value - orig.z; + // Green is when maxvalue = y + float g_d_y = orig.y - orig.x; + float g_d_c = orig.y - orig.z; + // Cyan is when minvalue = x + float c_d = mid_value - orig.x; + // Blue is when maxvalue = z + float b_d_c = orig.z - orig.y; + float b_d_m = orig.z - orig.x; + // Magenta is when minvalue = y + float m_d = mid_value - orig.y; + + float r_delta = 1.0f; + float y_delta = 1.0f; + float g_delta = 1.0f; + float c_delta = 1.0f; + float b_delta = 1.0f; + float m_delta = 1.0f; + + if( corr_method2 ) // Relative saturation + { + r_delta = min( r_d_m, r_d_y ); + y_delta = y_d; + g_delta = min( g_d_y, g_d_c ); + c_delta = c_d; + b_delta = min( b_d_c, b_d_m ); + m_delta = m_d; + } + + // Selective Color + if( max_value == orig.x ) + { + color.x = color.x + adjustcolor( sRGB, color.x, r_adj_cya, r_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sRGB, color.y, r_adj_mag, r_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sRGB, color.z, r_adj_yel, r_adj_bla, corr_method ); + color.xyz = sat( color.xyz, r_adj_sat * r_delta ); + color.xyz = vib( color.xyz, r_adj_vib * r_delta ); + } + + if( min_value == orig.z ) + { + color.x = color.x + adjustcolor( sCMY, color.x, y_adj_cya, y_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sCMY, color.y, y_adj_mag, y_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sCMY, color.z, y_adj_yel, y_adj_bla, corr_method ); + color.xyz = sat( color.xyz, y_adj_sat * y_delta ); + color.xyz = vib( color.xyz, y_adj_vib * y_delta ); + } + + if( max_value == orig.y ) + { + color.x = color.x + adjustcolor( sRGB, color.x, g_adj_cya, g_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sRGB, color.y, g_adj_mag, g_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sRGB, color.z, g_adj_yel, g_adj_bla, corr_method ); + color.xyz = sat( color.xyz, g_adj_sat * g_delta ); + color.xyz = vib( color.xyz, g_adj_vib * g_delta ); + } + + if( min_value == orig.x ) + { + color.x = color.x + adjustcolor( sCMY, color.x, c_adj_cya, c_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sCMY, color.y, c_adj_mag, c_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sCMY, color.z, c_adj_yel, c_adj_bla, corr_method ); + color.xyz = sat( color.xyz, c_adj_sat * c_delta ); + color.xyz = vib( color.xyz, c_adj_vib * c_delta ); + } + + if( max_value == orig.z ) + { + color.x = color.x + adjustcolor( sRGB, color.x, b_adj_cya, b_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sRGB, color.y, b_adj_mag, b_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sRGB, color.z, b_adj_yel, b_adj_bla, corr_method ); + color.xyz = sat( color.xyz, b_adj_sat * b_delta ); + color.xyz = vib( color.xyz, b_adj_vib * b_delta ); + } + + if( min_value == orig.y ) + { + color.x = color.x + adjustcolor( sCMY, color.x, m_adj_cya, m_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sCMY, color.y, m_adj_mag, m_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sCMY, color.z, m_adj_yel, m_adj_bla, corr_method ); + color.xyz = sat( color.xyz, m_adj_sat * m_delta ); + color.xyz = vib( color.xyz, m_adj_vib * m_delta ); + } + + if( min_value >= 0.5f ) + { + color.x = color.x + adjustcolor( sWhites, color.x, w_adj_cya, w_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sWhites, color.y, w_adj_mag, w_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sWhites, color.z, w_adj_yel, w_adj_bla, corr_method ); + color.xyz = sat( color.xyz, w_adj_sat * smoothstep( 0.5f, 1.0f, min_value )); + color.xyz = vib( color.xyz, w_adj_vib * smoothstep( 0.5f, 1.0f, min_value )); + } + + if( max_value > 0.0f && min_value < 1.0f ) + { + color.x = color.x + adjustcolor( sNeutrals, color.x, n_adj_cya, n_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sNeutrals, color.y, n_adj_mag, n_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sNeutrals, color.z, n_adj_yel, n_adj_bla, corr_method ); + color.xyz = sat( color.xyz, n_adj_sat ); + color.xyz = vib( color.xyz, n_adj_vib ); + } + + if( max_value < 0.5f ) + { + color.x = color.x + adjustcolor( sBlacks, color.x, bk_adj_cya, bk_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sBlacks, color.y, bk_adj_mag, bk_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sBlacks, color.z, bk_adj_yel, bk_adj_bla, corr_method ); + color.xyz = sat( color.xyz, bk_adj_sat * smoothstep( 0.5f, 0.0f, max_value )); + color.xyz = vib( color.xyz, bk_adj_vib * smoothstep( 0.5f, 0.0f, max_value )); + } + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_SelectiveColor + { + pass prod80_sc + { + VertexShader = PostProcessVS; + PixelShader = PS_SelectiveColor; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Selective_Color_v2.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Selective_Color_v2.fx new file mode 100644 index 00000000..132b9778 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Selective_Color_v2.fx @@ -0,0 +1,1182 @@ +/* + Description : PD80 04 Selective Color 2 for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + Additional credits + - Based on the mathematical analysis provided here + http://blog.pkh.me/p/22-understanding-selective-coloring-in-adobe-photoshop.html + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Color_Spaces.fxh" + +namespace pd80_selectivecolorv2 +{ + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int corr_method < __UNIFORM_COMBO_INT1 + ui_label = "Correction Method"; + ui_tooltip = "Correction Method"; + ui_category = "Selective Color"; + ui_items = "Absolute\0Relative\0"; //Do not change order; 0=Absolute, 1=Relative + > = 1; + // Reds + uniform float r_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Reds: Cyan"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Reds: Magenta"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Reds: Yellow"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Reds: Black"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Reds: Saturation"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Reds: Lightness Curve"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float r_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Reds: Lightness"; + ui_category = "Selective Color: Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Oranges + uniform float o_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Oranges: Cyan"; + ui_category = "Selective Color: Oranges"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float o_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Oranges: Magenta"; + ui_category = "Selective Color: Oranges"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float o_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Oranges: Yellow"; + ui_category = "Selective Color: Oranges"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float o_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Oranges: Black"; + ui_category = "Selective Color: Oranges"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float o_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Oranges: Saturation"; + ui_category = "Selective Color: Oranges"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float o_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Oranges: Lightness Curve"; + ui_category = "Selective Color: Oranges"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float o_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Oranges: Lightness"; + ui_category = "Selective Color: Oranges"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Yellows + uniform float y_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Yellows: Cyan"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Yellows: Magenta"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Yellows: Yellow"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Yellows: Black"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Yellows: Saturation"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Yellows: Lightness Curve"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float y_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Yellows: Lightness"; + ui_category = "Selective Color: Yellows"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Yellow-Greens + uniform float yg_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Yellow-Greens: Cyan"; + ui_category = "Selective Color: Yellow-Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float yg_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Yellow-Greens: Magenta"; + ui_category = "Selective Color: Yellow-Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float yg_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Yellow-Greens: Yellow"; + ui_category = "Selective Color: Yellow-Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float yg_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Yellow-Greens: Black"; + ui_category = "Selective Color: Yellow-Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float yg_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Yellow-Greens: Saturation"; + ui_category = "Selective Color: Yellow-Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float yg_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Yellow-Greens: Lightness Curve"; + ui_category = "Selective Color: Yellow-Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float yg_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Yellow-Greens: Lightness"; + ui_category = "Selective Color: Yellow-Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Greens + uniform float g_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Greens: Cyan"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Greens: Magenta"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Greens: Yellow"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Greens: Black"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Greens: Saturation"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Greens: Lightness Curve"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float g_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Greens: Lightness"; + ui_category = "Selective Color: Greens"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Green-Cyans + uniform float gc_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Green-Cyans: Cyan"; + ui_category = "Selective Color: Green-Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float gc_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Green-Cyans: Magenta"; + ui_category = "Selective Color: Green-Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float gc_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Green-Cyans: Yellow"; + ui_category = "Selective Color: Green-Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float gc_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Green-Cyans: Black"; + ui_category = "Selective Color: Green-Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float gc_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Green-Cyans: Saturation"; + ui_category = "Selective Color: Green-Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float gc_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Green-Cyans: Lightness Curve"; + ui_category = "Selective Color: Green-Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float gc_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Green-Cyans: Lightness"; + ui_category = "Selective Color: Green-Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Cyans + uniform float c_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Cyans: Cyan"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Cyans: Magenta"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Cyans: Yellow"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Cyans: Black"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Cyans: Saturation"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Cyans: Lightness Curve"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float c_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Cyans: Lightness"; + ui_category = "Selective Color: Cyans"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Cyan-Blues + uniform float cb_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Cyan-Blues: Cyan"; + ui_category = "Selective Color: Cyan-Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float cb_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Cyan-Blues: Magenta"; + ui_category = "Selective Color: Cyan-Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float cb_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Cyan-Blues: Yellow"; + ui_category = "Selective Color: Cyan-Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float cb_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Cyan-Blues: Black"; + ui_category = "Selective Color: Cyan-Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float cb_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Cyan-Blues: Saturation"; + ui_category = "Selective Color: Cyan-Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float cb_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Cyan-Blues: Lightness Curve"; + ui_category = "Selective Color: Cyan-Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float cb_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Cyan-Blues: Lightness"; + ui_category = "Selective Color: Cyan-Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Blues + uniform float b_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Blues: Cyan"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Blues: Magenta"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Blues: Yellow"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Blues: Black"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Blues: Saturation"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Blues: Lightness Curve"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float b_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Blues: Lightness"; + ui_category = "Selective Color: Blues"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Blue-Magentas + uniform float bm_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Blue-Magentas: Cyan"; + ui_category = "Selective Color: Blue-Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bm_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Blue-Magentas: Magenta"; + ui_category = "Selective Color: Blue-Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bm_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Blue-Magentas: Yellow"; + ui_category = "Selective Color: Blue-Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bm_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Blue-Magentas: Black"; + ui_category = "Selective Color: Blue-Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bm_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Blue-Magentas: Saturation"; + ui_category = "Selective Color: Blue-Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bm_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Blue-Magentas: Lightness Curve"; + ui_category = "Selective Color: Blue-Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bm_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Blue-Magentas: Lightness"; + ui_category = "Selective Color: Blue-Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Magentas + uniform float m_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Magentas: Cyan"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Magentas: Magenta"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Magentas: Yellow"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Magentas: Black"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Magentas: Saturation"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Magentas: Lightness Curve"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float m_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Magentas: Lightness"; + ui_category = "Selective Color: Magentas"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Magenta-Reds + uniform float mr_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Magenta-Reds: Cyan"; + ui_category = "Selective Color: Magenta-Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float mr_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Magenta-Reds: Magenta"; + ui_category = "Selective Color: Magenta-Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float mr_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Magenta-Reds: Yellow"; + ui_category = "Selective Color: Magenta-Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float mr_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Magenta-Reds: Black"; + ui_category = "Selective Color: Magenta-Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float mr_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Magenta-Reds: Saturation"; + ui_category = "Selective Color: Magenta-Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float mr_adj_lig_curve < + ui_type = "slider"; + ui_label = "Lightness Curve"; + ui_tooltip = "Selective Color Magenta-Reds: Lightness Curve"; + ui_category = "Selective Color: Magenta-Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float mr_adj_lig < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Selective Color Magenta-Reds: Lightness"; + ui_category = "Selective Color: Magenta-Reds"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Whites + uniform float w_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Whites: Cyan"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Whites: Magenta"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Whites: Yellow"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Whites: Black"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float w_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Whites: Saturation"; + ui_category = "Selective Color: Whites"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Neutrals + uniform float n_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Neutrals: Cyan"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Neutrals: Magenta"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Neutrals: Yellow"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Neutrals: Black"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float n_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Neutrals: Saturation"; + ui_category = "Selective Color: Neutrals"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + // Blacks + uniform float bk_adj_cya < + ui_type = "slider"; + ui_label = "Cyan"; + ui_tooltip = "Selective Color Blacks: Cyan"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_mag < + ui_type = "slider"; + ui_label = "Magenta"; + ui_tooltip = "Selective Color Blacks: Magenta"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_yel < + ui_type = "slider"; + ui_label = "Yellow"; + ui_tooltip = "Selective Color Blacks: Yellow"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_bla < + ui_type = "slider"; + ui_label = "Black"; + ui_tooltip = "Selective Color Blacks: Black"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float bk_adj_sat < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Selective Color Blacks: Saturation"; + ui_category = "Selective Color: Blacks"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float mid( float3 c ) + { + float sum = c.x + c.y + c.z; + float mn = min( min( c.x, c.y ), c.z ); + float mx = max( max( c.x, c.y ), c.z ); + return sum - mn - mx; + } + + // Credit to user 'iq' from shadertoy + // See https://www.shadertoy.com/view/MdBfR1 + float brightness_curve( float x, float k ) + { + float s = sign( x - 0.5f ); + float o = ( 1.0f + s ) / 2.0f; + return o - 0.5f * s * pow( max( 2.0f * ( o - s * x ), 0.0f ), k ); + } + + float curve( float x ) + { + return x * x * ( 3.0 - 2.0 * x ); + } + + float smooth( float x ) + { + return x * x * x * ( x * ( x * 6.0f - 15.0f ) + 10.0f ); + } + + float adjustcolor( float scale, float colorvalue, float adjust, float bk, int method ) + { + /* + y(value, adjustment) = clamp((( -1 - adjustment ) * bk - adjustment ) * method, -value, 1 - value ) * scale + absolute: method = 1.0f - colorvalue * 0 + relative: method = 1.0f - colorvalue * 1 + */ + return clamp((( -1.0f - adjust ) * bk - adjust ) * ( 1.0f - colorvalue * method ), -colorvalue, 1.0f - colorvalue) * scale; + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_SelectiveColor(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + + // Clamp 0..1 + color.xyz = saturate( color.xyz ); + + // Min Max Mid + float min_value = min( min( color.x, color.y ), color.z ); + float max_value = max( max( color.x, color.y ), color.z ); + float mid_value = mid( color.xyz ); + float scalar = max_value - min_value; + float alt_scalar = ( mid_value - min_value ) / 2.0f; + float cmy_scalar = scalar / 2.0f; + + // HSL + float3 hsl = RGBToHSL( color.xyz ).x; + + // Weights for Whites, Neutrals, Blacks + float sWhites = smooth( min_value ); + float sBlacks = 1.0f - smooth( max_value ); + float sNeutrals = 1.0f - smooth( max_value - min_value ); + + // Weights + float sw_r = curve( max( 1.0f - abs( hsl.x * 6.0f ), 0.0f )) + + curve( max( 1.0f - abs(( hsl.x - 1.0f ) * 6.0f ), 0.0f )); + float sw_o = curve( max( 1.0f - abs(( hsl.x - 1.0f / 12.0f ) * 6.0f ), 0.0f )) + + curve( max( 1.0f - abs(( hsl.x - 13.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_y = curve( max( 1.0f - abs(( hsl.x - 2.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_yg = curve( max( 1.0f - abs(( hsl.x - 3.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_g = curve( max( 1.0f - abs(( hsl.x - 4.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_gc = curve( max( 1.0f - abs(( hsl.x - 5.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_c = curve( max( 1.0f - abs(( hsl.x - 6.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_cb = curve( max( 1.0f - abs(( hsl.x - 7.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_b = curve( max( 1.0f - abs(( hsl.x - 8.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_bm = curve( max( 1.0f - abs(( hsl.x - 9.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_m = curve( max( 1.0f - abs(( hsl.x - 10.0f / 12.0f ) * 6.0f ), 0.0f )); + float sw_mr = curve( max( 1.0f - abs(( hsl.x - 11.0f / 12.0f ) * 6.0f ), 0.0f )) + + curve( max( 1.0f - abs(( hsl.x + 1.0f / 12.0f ) * 6.0f ), 0.0f )); + + float w_r = sw_r * scalar; + float w_o = sw_o * alt_scalar; + float w_y = sw_y * cmy_scalar; + float w_yg = sw_yg * alt_scalar; + float w_g = sw_g * scalar; + float w_gc = sw_gc * alt_scalar; + float w_c = sw_c * cmy_scalar; + float w_cb = sw_cb * alt_scalar; + float w_b = sw_b * scalar; + float w_bm = sw_bm * alt_scalar; + float w_m = sw_m * cmy_scalar; + float w_mr = sw_mr * alt_scalar; + + // Selective Color + // Reds + color.x = color.x + adjustcolor( w_r, color.x, r_adj_cya, r_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_r, color.y, r_adj_mag, r_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_r, color.z, r_adj_yel, r_adj_bla, corr_method ); + // Oranges + color.x = color.x + adjustcolor( w_o, color.x, o_adj_cya, o_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_o, color.y, o_adj_mag, o_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_o, color.z, o_adj_yel, o_adj_bla, corr_method ); + // Yellows + color.x = color.x + adjustcolor( w_y, color.x, y_adj_cya, y_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_y, color.y, y_adj_mag, y_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_y, color.z, y_adj_yel, y_adj_bla, corr_method ); + // Yellow-Greens + color.x = color.x + adjustcolor( w_yg, color.x, yg_adj_cya, yg_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_yg, color.y, yg_adj_mag, yg_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_yg, color.z, yg_adj_yel, yg_adj_bla, corr_method ); + // Greens + color.x = color.x + adjustcolor( w_g, color.x, g_adj_cya, g_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_g, color.y, g_adj_mag, g_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_g, color.z, g_adj_yel, g_adj_bla, corr_method ); + // Green-Cyans + color.x = color.x + adjustcolor( w_gc, color.x, gc_adj_cya, gc_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_gc, color.y, gc_adj_mag, gc_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_gc, color.z, gc_adj_yel, gc_adj_bla, corr_method ); + // Cyans + color.x = color.x + adjustcolor( w_c, color.x, c_adj_cya, c_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_c, color.y, c_adj_mag, c_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_c, color.z, c_adj_yel, c_adj_bla, corr_method ); + // Cyan-Blues + color.x = color.x + adjustcolor( w_cb, color.x, cb_adj_cya, cb_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_cb, color.y, cb_adj_mag, cb_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_cb, color.z, cb_adj_yel, cb_adj_bla, corr_method ); + // Blues + color.x = color.x + adjustcolor( w_b, color.x, b_adj_cya, b_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_b, color.y, b_adj_mag, b_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_b, color.z, b_adj_yel, b_adj_bla, corr_method ); + // Blue-Magentas + color.x = color.x + adjustcolor( w_bm, color.x, bm_adj_cya, bm_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_bm, color.y, bm_adj_mag, bm_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_bm, color.z, bm_adj_yel, bm_adj_bla, corr_method ); + // Magentas + color.x = color.x + adjustcolor( w_m, color.x, m_adj_cya, m_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_m, color.y, m_adj_mag, m_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_m, color.z, m_adj_yel, m_adj_bla, corr_method ); + // Magenta-Reds + color.x = color.x + adjustcolor( w_mr, color.x, mr_adj_cya, mr_adj_bla, corr_method ); + color.y = color.y + adjustcolor( w_mr, color.y, mr_adj_mag, mr_adj_bla, corr_method ); + color.z = color.z + adjustcolor( w_mr, color.z, mr_adj_yel, mr_adj_bla, corr_method ); + // Whites + color.x = color.x + adjustcolor( sWhites, color.x, w_adj_cya, w_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sWhites, color.y, w_adj_mag, w_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sWhites, color.z, w_adj_yel, w_adj_bla, corr_method ); + // Blacks + color.x = color.x + adjustcolor( sBlacks, color.x, bk_adj_cya, bk_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sBlacks, color.y, bk_adj_mag, bk_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sBlacks, color.z, bk_adj_yel, bk_adj_bla, corr_method ); + // Neutrals + color.x = color.x + adjustcolor( sNeutrals, color.x, n_adj_cya, n_adj_bla, corr_method ); + color.y = color.y + adjustcolor( sNeutrals, color.y, n_adj_mag, n_adj_bla, corr_method ); + color.z = color.z + adjustcolor( sNeutrals, color.z, n_adj_yel, n_adj_bla, corr_method ); + + // Saturation + // Have to get current saturation in between each adjustment as there are overlaps + float curr_sat = 0.0f; + + // Reds + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( r_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_r * r_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_r * r_adj_sat )); + // Oranges + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( o_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_o * o_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_o * o_adj_sat )); + // Yellows + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( y_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_y * y_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_y * y_adj_sat )); + // Yellow-Greens + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( yg_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_yg * yg_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_yg * yg_adj_sat )); + // Greens + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( g_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_g * g_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_g * g_adj_sat )); + // Green-Cyans + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( gc_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_gc * gc_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_gc * gc_adj_sat )); + // Cyans + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( c_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_c * c_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_c * c_adj_sat )); + // Cyan-Blues + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( cb_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_cb * cb_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_cb * cb_adj_sat )); + // Blues + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( b_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_b * b_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_b * b_adj_sat )); + // Blue-Magentas + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( bm_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_bm * bm_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_bm * bm_adj_sat )); + // Magentas + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( m_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_m * m_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_m * m_adj_sat )); + // Magenta-Reds + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( mr_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_mr * mr_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sw_mr * mr_adj_sat )); + // Whites + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( w_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sWhites * w_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sWhites * w_adj_sat )); + // Blacks + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( bk_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sBlacks * bk_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sBlacks * bk_adj_sat )); + // Neutrals + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + color.xyz = ( n_adj_sat > 0.0f ) ? saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sNeutrals * n_adj_sat * ( 1.0f - curr_sat ))) : + saturate( lerp( dot( color.xyz, 0.333333f ), color.xyz, 1.0f + sNeutrals * n_adj_sat )); + + // Lightness + float3 temp = 0.0f; + + // Reds + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + r_adj_lig )); + temp.z = brightness_curve( temp.z, max( r_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_r * smooth( curr_sat )); + // Oranges + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + o_adj_lig )); + temp.z = brightness_curve( temp.z, max( o_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_o * smooth( curr_sat )); + // Yellows + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + y_adj_lig )); + temp.z = brightness_curve( temp.z, max( y_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_y * smooth( curr_sat )); + // Yellow-Greens + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + yg_adj_lig )); + temp.z = brightness_curve( temp.z, max( yg_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_yg * smooth( curr_sat )); + // Greens + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + g_adj_lig )); + temp.z = brightness_curve( temp.z, max( g_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_g * smooth( curr_sat )); + // Green-Cyans + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + gc_adj_lig )); + temp.z = brightness_curve( temp.z, max( gc_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_gc * smooth( curr_sat )); + // Cyans + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + c_adj_lig )); + temp.z = brightness_curve( temp.z, max( c_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_c * smooth( curr_sat )); + // Cyan-Blues + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + cb_adj_lig )); + temp.z = brightness_curve( temp.z, max( cb_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_cb * smooth( curr_sat )); + // Blues + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + b_adj_lig )); + temp.z = brightness_curve( temp.z, max( b_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_b * smooth( curr_sat )); + // Blue-Magentas + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + bm_adj_lig )); + temp.z = brightness_curve( temp.z, max( bm_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_bm * smooth( curr_sat )); + // Magentas + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + m_adj_lig )); + temp.z = brightness_curve( temp.z, max( m_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_m * smooth( curr_sat )); + // Magenta-Reds + curr_sat = max( max( color.x, color.y ), color.z ) - min( min( color.x, color.y ), color.z ); + temp.xyz = RGBToHSL( color.xyz ); + temp.z = saturate( temp.z * ( 1.0f + mr_adj_lig )); + temp.z = brightness_curve( temp.z, max( mr_adj_lig_curve, 0.001f ) + 1.0f ); + color.xyz = lerp( color.xyz, HSLToRGB( temp.xyz ), sw_mr * smooth( curr_sat )); + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_SelectiveColor_v2 + { + pass prod80_sc + { + VertexShader = PostProcessVS; + PixelShader = PS_SelectiveColor; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_04_Technicolor.fx b/data_from_portwine/Reshade/Shaders/PD80_04_Technicolor.fx new file mode 100644 index 00000000..a525512f --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_04_Technicolor.fx @@ -0,0 +1,192 @@ +/* + Description : PD80 04 Technicolor for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + Additional credits + - Using Hue Shift algorythm from Vibhore Tanwer (stockexchange) + No particular reason, just found it interesting + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +namespace pd80_technicolor +{ + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform float3 Red2strip < + ui_type = "color"; + ui_label = "Red Dye Color"; + ui_tooltip = "Red Color used to create Cyan (contemporary)"; + ui_category = "Technicolor 2 strip"; + > = float3(1.0, 0.098, 0.0); + uniform float3 Cyan2strip < + ui_type = "color"; + ui_label = "Cyan Dye Color"; + ui_tooltip = "Cyan Color used to create Red (contemporary)"; + ui_category = "Technicolor 2 strip"; + > = float3(0.0, 0.988, 1.0); + uniform float3 colorKey < + ui_type = "color"; + ui_label = "Funky Color Adjustment"; + ui_tooltip = "3rd Layer for Fun, lower values increase contrast"; + ui_category = "Technicolor 2 strip"; + > = float3(1.0, 1.0, 1.0); + uniform float Saturation2 < + ui_min = 1.0; + ui_max = 2.0; + ui_type = "slider"; + ui_label = "Saturation Adjustment"; + ui_tooltip = "Additional saturation control as 2 Strip Process is not very saturated by itself"; + ui_category = "Technicolor 2 strip"; + > = 1.5; + uniform bool enable3strip < + ui_label = "Enable Technicolor 3 strip"; + ui_tooltip = "Enable Technicolor 3 strip"; + ui_category = "Technicolor 3 strip"; + > = false; + uniform float3 ColorStrength < + ui_type = "color"; + ui_tooltip = "Higher means darker and more intense colors."; + ui_category = "Technicolor 3 strip"; + > = float3(0.2, 0.2, 0.2); + uniform float Brightness < + ui_type = "slider"; + ui_label = "Brightness Adjustment"; + ui_min = 0.5; + ui_max = 1.5; + ui_tooltip = "Higher means brighter image."; + ui_category = "Technicolor 3 strip"; + > = 1.0; + uniform float Saturation < + ui_type = "slider"; + ui_label = "Saturation Adjustment"; + ui_min = 0.0; + ui_max = 1.5; + ui_tooltip = "Additional saturation control since this effect tends to oversaturate the image."; + ui_category = "Technicolor 3 strip"; + > = 1.0; + uniform float Strength < + ui_type = "slider"; + ui_label = "Effect Strength"; + ui_min = 0.0; + ui_max = 1.0; + ui_tooltip = "Adjust the strength of the effect."; + ui_category = "Technicolor 3 strip"; + > = 1.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float getLuminance( in float3 x ) + { + return dot( x, float3( 0.212656f, 0.715158f, 0.072186f )); + } + + // Code from Vibhore Tanwer + float3x3 QuaternionToMatrix( float4 quat ) + { + float3 cross = quat.yzx * quat.zxy; + float3 square= quat.xyz * quat.xyz; + float3 wimag = quat.w * quat.xyz; + + square = square.xyz + square.yzx; + + float3 diag = 0.5f - square; + float3 a = (cross + wimag); + float3 b = (cross - wimag); + + return float3x3( + 2.0f * float3(diag.x, b.z, a.y), + 2.0f * float3(a.z, diag.y, b.x), + 2.0f * float3(b.y, a.x, diag.z)); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_Technicolor(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + color.xyz = saturate( color.xyz ); + float3 root3 = 0.57735f; + float3 keyC = 0.0f; + float half_angle = 0.0f; + float4 rot_quat = 0.0f; + float3x3 rot_Mat; + float HueAdj = 0.52f; //0.5 is too strong in reds and doesn't work well with skin color + float3 orig = color.xyz; + float negR = 1.0f - color.x; + float negG = 1.0f - color.y; + float3 newR = 1.0f - negR * Cyan2strip; + float3 newC = 1.0f - negG * Red2strip; + half_angle = 0.5f * radians( 180.0f ); // Hue is radians of 0 to 360 degrees + rot_quat = float4(( root3 * sin( half_angle )), cos( half_angle )); + rot_Mat = QuaternionToMatrix( rot_quat ); + float3 key = colorKey.xyz; + key.xyz = mul( rot_Mat, key.xyz ); + key.xyz = max( color.yyy, key.xyz ); + color.xyz = newR.xyz * newC.xyz * key.xyz; // 2 strip image + // Fix hue + half_angle = 0.5f * radians( HueAdj * 360.0f ); // Hue is radians of 0 to 360 degrees + rot_quat = float4(( root3 * sin( half_angle )), cos( half_angle )); + rot_Mat = QuaternionToMatrix( rot_quat ); + color.xyz = mul( rot_Mat, color.xyz ); + // Add saturation to taste + color.xyz = lerp( getLuminance( color.xyz ), color.xyz, Saturation2 ); + + if( enable3strip ) { + float3 temp = 1.0 - orig.xyz; + float3 target = temp.grg; + float3 target2 = temp.bbr; + float3 temp2 = orig.xyz * target.xyz; + temp2.xyz *= target2.xyz; + temp.xyz = temp2.xyz * ColorStrength; + temp2.xyz *= Brightness; + target.xyz = temp.yxy; + target2.xyz = temp.zzx; + temp.xyz = orig.xyz - target.xyz; + temp.xyz += temp2.xyz; + temp2.xyz = temp.xyz - target2.xyz; + color.xyz = lerp( orig.xyz, temp2.xyz, Strength ); + color.xyz = lerp( getLuminance( color.xyz ), color.xyz, Saturation); + } + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_04_Technicolor + { + pass prod80_TC + { + VertexShader = PostProcessVS; + PixelShader = PS_Technicolor; + } + } +} + + diff --git a/data_from_portwine/Reshade/Shaders/PD80_05_Sharpening.fx b/data_from_portwine/Reshade/Shaders/PD80_05_Sharpening.fx new file mode 100644 index 00000000..388c3932 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_05_Sharpening.fx @@ -0,0 +1,276 @@ +/* + Description : PD80 05 Sharpening for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +namespace pd80_lumasharpen +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool enableShowEdges < + ui_label = "Show only Sharpening Texture"; + ui_tooltip = "Show only Sharpening Texture"; + ui_category = "Sharpening"; + > = false; + uniform float BlurSigma < + ui_label = "Sharpening Width"; + ui_tooltip = "Sharpening Width"; + ui_category = "Sharpening"; + ui_type = "slider"; + ui_min = 0.3; + ui_max = 1.2; + > = 0.45; + uniform float Sharpening < + ui_label = "Sharpening Strength"; + ui_tooltip = "Sharpening Strength"; + ui_category = "Sharpening"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 5.0; + > = 1.7; + uniform float Threshold < + ui_label = "Sharpening Threshold"; + ui_tooltip = "Sharpening Threshold"; + ui_category = "Sharpening"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float limiter < + ui_label = "Sharpening Highlight Limiter"; + ui_tooltip = "Sharpening Highlight Limiter"; + ui_category = "Sharpening"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.03; + uniform bool enable_depth < + ui_label = "Enable depth based adjustments.\nMake sure you have setup your depth buffer correctly."; + ui_tooltip = "Enable depth based adjustments"; + ui_category = "Sharpening: Depth"; + > = false; + uniform bool enable_reverse < + ui_label = "Reverses the effect (sharpen close, or sharpen far)"; + ui_tooltip = "Reverses the effect"; + ui_category = "Sharpening: Depth"; + > = false; + uniform bool display_depth < + ui_label = "Show depth texture"; + ui_tooltip = "Show depth texture"; + ui_category = "Sharpening: Depth"; + > = false; + uniform float depthStart < + ui_type = "slider"; + ui_label = "Change Depth Start Plane"; + ui_tooltip = "Change Depth Start Plane"; + ui_category = "Sharpening: Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.0; + uniform float depthEnd < + ui_type = "slider"; + ui_label = "Change Depth End Plane"; + ui_tooltip = "Change Depth End Plane"; + ui_category = "Sharpening: Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.1; + uniform float depthCurve < + ui_label = "Depth Curve Adjustment"; + ui_tooltip = "Depth Curve Adjustment"; + ui_category = "Sharpening: Depth"; + ui_type = "slider"; + ui_min = 0.05; + ui_max = 8.0; + > = 1.0; + + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texGaussianH { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; }; + texture texGaussian { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerGaussianH { Texture = texGaussianH; }; + sampler samplerGaussian { Texture = texGaussian; }; + + //// DEFINES //////////////////////////////////////////////////////////////////// + #define PI 3.141592f + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + + float getLuminance( in float3 x ) + { + return dot( x, float3( 0.212656, 0.715158, 0.072186 )); + } + + float getAvgColor( float3 col ) + { + return dot( col.xyz, float3( 0.333333f, 0.333334f, 0.333333f )); + } + + // nVidia blend modes + // Source: https://www.khronos.org/registry/OpenGL/extensions/NV/NV_blend_equation_advanced.txt + float3 ClipColor( float3 color ) + { + float lum = getAvgColor( color.xyz ); + float mincol = min( min( color.x, color.y ), color.z ); + float maxcol = max( max( color.x, color.y ), color.z ); + color.xyz = ( mincol < 0.0f ) ? lum + (( color.xyz - lum ) * lum ) / ( lum - mincol ) : color.xyz; + color.xyz = ( maxcol > 1.0f ) ? lum + (( color.xyz - lum ) * ( 1.0f - lum )) / ( maxcol - lum ) : color.xyz; + return color; + } + + // Luminosity: base, blend + // Color: blend, base + float3 blendLuma( float3 base, float3 blend ) + { + float lumbase = getAvgColor( base.xyz ); + float lumblend = getAvgColor( blend.xyz ); + float ldiff = lumblend - lumbase; + float3 col = base.xyz + ldiff; + return ClipColor( col.xyz ); + } + + float3 screen(float3 c, float3 b) { return 1.0f-(1.0f-c)*(1.0f-b);} + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_GaussianH(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + float px = BUFFER_RCP_WIDTH; + float SigmaSum = 0.0f; + float pxlOffset = 1.0f; + float loops = max( BUFFER_WIDTH, BUFFER_HEIGHT ) / 1920.0f * 4.0f; + + //Gaussian Math + float3 Sigma; + float bSigma = BlurSigma * ( max( BUFFER_WIDTH, BUFFER_HEIGHT ) / 1920.0f ); // Scalar + Sigma.x = 1.0f / ( sqrt( 2.0f * PI ) * bSigma ); + Sigma.y = exp( -0.5f / ( bSigma * bSigma )); + Sigma.z = Sigma.y * Sigma.y; + + //Center Weight + color.xyz *= Sigma.x; + //Adding to total sum of distributed weights + SigmaSum += Sigma.x; + //Setup next weight + Sigma.xy *= Sigma.yz; + + [loop] + for( int i = 0; i < loops; ++i ) + { + color += tex2Dlod( ReShade::BackBuffer, float4( texcoord.xy + float2( pxlOffset*px, 0.0f ), 0.0, 0.0 )) * Sigma.x; + color += tex2Dlod( ReShade::BackBuffer, float4( texcoord.xy - float2( pxlOffset*px, 0.0f ), 0.0, 0.0 )) * Sigma.x; + SigmaSum += ( 2.0f * Sigma.x ); + pxlOffset += 1.0f; + Sigma.xy *= Sigma.yz; + } + + color.xyz /= SigmaSum; + return float4( color.xyz, 1.0f ); + } + + float4 PS_GaussianV(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( samplerGaussianH, texcoord ); + float py = BUFFER_RCP_HEIGHT; + float SigmaSum = 0.0f; + float pxlOffset = 1.0f; + float loops = max( BUFFER_WIDTH, BUFFER_HEIGHT ) / 1920.0f * 4.0f; + + //Gaussian Math + float3 Sigma; + float bSigma = BlurSigma * ( max( BUFFER_WIDTH, BUFFER_HEIGHT ) / 1920.0f ); // Scalar + Sigma.x = 1.0f / ( sqrt( 2.0f * PI ) * bSigma ); + Sigma.y = exp( -0.5f / ( bSigma * bSigma )); + Sigma.z = Sigma.y * Sigma.y; + + //Center Weight + color.xyz *= Sigma.x; + //Adding to total sum of distributed weights + SigmaSum += Sigma.x; + //Setup next weight + Sigma.xy *= Sigma.yz; + + [loop] + for( int i = 0; i < loops; ++i ) + { + color += tex2Dlod( samplerGaussianH, float4( texcoord.xy + float2( 0.0f, pxlOffset*py ), 0.0, 0.0 )) * Sigma.x; + color += tex2Dlod( samplerGaussianH, float4( texcoord.xy - float2( 0.0f, pxlOffset*py ), 0.0, 0.0 )) * Sigma.x; + SigmaSum += ( 2.0f * Sigma.x ); + pxlOffset += 1.0f; + Sigma.xy *= Sigma.yz; + } + + color.xyz /= SigmaSum; + return float4( color.xyz, 1.0f ); + } + + float4 PS_LumaSharpen(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 orig = tex2D( ReShade::BackBuffer, texcoord ); + float4 gaussian = tex2D( samplerGaussian, texcoord ); + + float depth = ReShade::GetLinearizedDepth( texcoord ).x; + depth = smoothstep( depthStart, depthEnd, depth ); + depth = pow( depth, depthCurve ); + depth = enable_reverse ? 1.0f - depth : depth; + + float3 edges = max( saturate( orig.xyz - gaussian.xyz ) - Threshold, 0.0f ); + float3 invGauss = saturate( 1.0f - gaussian.xyz ); + float3 oInvGauss = saturate( orig.xyz + invGauss.xyz ); + float3 invOGauss = max( saturate( 1.0f - oInvGauss.xyz ) - Threshold, 0.0f ); + edges = max(( saturate( Sharpening * edges.xyz )) - ( saturate( Sharpening * invOGauss.xyz )), 0.0f ); + float3 blend = screen( orig.xyz, lerp( min( edges.xyz, limiter ), 0.0f, enable_depth * depth )); + float3 color = blendLuma( orig.xyz, blend.xyz ); + color.xyz = enableShowEdges ? lerp( min( edges.xyz, limiter ), min( edges.xyz, limiter ) * depth, enable_depth ) : color.xyz; + color.xyz = display_depth ? depth.xxx : color.xyz; + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_05_LumaSharpen + { + pass GaussianH + { + VertexShader = PostProcessVS; + PixelShader = PS_GaussianH; + RenderTarget = texGaussianH; + } + pass GaussianV + { + VertexShader = PostProcessVS; + PixelShader = PS_GaussianV; + RenderTarget = texGaussian; + } + pass LumaSharpen + { + VertexShader = PostProcessVS; + PixelShader = PS_LumaSharpen; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_06_Chromatic_Aberration.fx b/data_from_portwine/Reshade/Shaders/PD80_06_Chromatic_Aberration.fx new file mode 100644 index 00000000..145d2b77 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_06_Chromatic_Aberration.fx @@ -0,0 +1,306 @@ +/* + Description : PD80 06 Chromatic Aberration for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +#if __RENDERER__ == 0x9000 + #ifndef CA_sampleSTEPS + #define CA_sampleSTEPS 24 // [0 to 96] + #endif + #define CA_DX9_MODE 1 +#else + #define CA_DX9_MODE 0 +#endif + +namespace pd80_ca +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int CA_type < __UNIFORM_COMBO_INT1 + ui_label = "Chromatic Aberration Type"; + ui_tooltip = "Chromatic Aberration Type"; + ui_category = "Chromatic Aberration"; + ui_items = "Center Weighted Radial\0Center Weighted Longitudinal\0Full screen Radial\0Full screen Longitudinal\0"; + > = 0; + uniform int degrees < + ui_type = "slider"; + ui_label = "CA Rotation Offset"; + ui_tooltip = "CA Rotation Offset"; + ui_category = "Chromatic Aberration"; + ui_min = 0; + ui_max = 360; + ui_step = 1; + > = 135; + uniform float CA < + ui_type = "slider"; + ui_label = "CA Global Width"; + ui_tooltip = "CA Global Width"; + ui_category = "Chromatic Aberration"; + ui_min = -150.0f; + ui_max = 150.0f; + > = -12.0; +#if CA_DX9_MODE == 0 + uniform int sampleSTEPS < + ui_type = "slider"; + ui_label = "Number of Hues"; + ui_tooltip = "Number of Hues"; + ui_category = "Chromatic Aberration"; + ui_min = 8; + ui_max = 96; + ui_step = 1; + > = 24; +#endif + uniform float CA_strength < + ui_type = "slider"; + ui_label = "CA Effect Strength"; + ui_tooltip = "CA Effect Strength"; + ui_category = "Chromatic Aberration"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform bool show_CA < + ui_label = "CA Show Center / Vignette"; + ui_tooltip = "CA Show Center / Vignette"; + ui_category = "CA: Center Weighted"; + > = false; + uniform float3 vignetteColor < + ui_type = "color"; + ui_label = "Vignette Color"; + ui_tooltip = "Vignette Color"; + ui_category = "CA: Center Weighted"; + > = float3(0.0, 0.0, 0.0); + uniform float CA_width < + ui_type = "slider"; + ui_label = "CA Width"; + ui_tooltip = "CA Width"; + ui_category = "CA: Center Weighted"; + ui_min = 0.0f; + ui_max = 5.0f; + > = 1.0; + uniform float CA_curve < + ui_type = "slider"; + ui_label = "CA Curve"; + ui_tooltip = "CA Curve"; + ui_category = "CA: Center Weighted"; + ui_min = 0.1f; + ui_max = 12.0f; + > = 1.0; + uniform float oX < + ui_type = "slider"; + ui_label = "CA Center (X)"; + ui_tooltip = "CA Center (X)"; + ui_category = "CA: Center Weighted"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float oY < + ui_type = "slider"; + ui_label = "CA Center (Y)"; + ui_tooltip = "CA Center (Y)"; + ui_category = "CA: Center Weighted"; + ui_min = -1.0f; + ui_max = 1.0f; + > = 0.0; + uniform float CA_shapeX < + ui_type = "slider"; + ui_label = "CA Shape (X)"; + ui_tooltip = "CA Shape (X)"; + ui_category = "CA: Center Weighted"; + ui_min = 0.2f; + ui_max = 6.0f; + > = 1.0; + uniform float CA_shapeY < + ui_type = "slider"; + ui_label = "CA Shape (Y)"; + ui_tooltip = "CA Shape (Y)"; + ui_category = "CA: Center Weighted"; + ui_min = 0.2f; + ui_max = 6.0f; + > = 1.0; + uniform bool enable_depth_int < + ui_label = "Intensity: Enable depth based adjustments.\nMake sure you have setup your depth buffer correctly."; + ui_tooltip = "Intensity: Enable depth based adjustments"; + ui_category = "Final Adjustments: Depth"; + > = false; + uniform bool enable_depth_width < + ui_label = "Width: Enable depth based adjustments.\nMake sure you have setup your depth buffer correctly."; + ui_tooltip = "Width: Enable depth based adjustments"; + ui_category = "Final Adjustments: Depth"; + > = false; + uniform bool display_depth < + ui_label = "Show depth texture"; + ui_tooltip = "Show depth texture"; + ui_category = "Final Adjustments: Depth"; + > = false; + uniform float depthStart < + ui_type = "slider"; + ui_label = "Change Depth Start Plane"; + ui_tooltip = "Change Depth Start Plane"; + ui_category = "Final Adjustments: Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.0; + uniform float depthEnd < + ui_type = "slider"; + ui_label = "Change Depth End Plane"; + ui_tooltip = "Change Depth End Plane"; + ui_category = "Final Adjustments: Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.1; + uniform float depthCurve < + ui_label = "Depth Curve Adjustment"; + ui_tooltip = "Depth Curve Adjustment"; + ui_category = "Final Adjustments: Depth"; + ui_type = "slider"; + ui_min = 0.05; + ui_max = 8.0; + > = 1.0; + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float3 HUEToRGB( float H ) + { + return saturate( float3( abs( H * 6.0f - 3.0f ) - 1.0f, + 2.0f - abs( H * 6.0f - 2.0f ), + 2.0f - abs( H * 6.0f - 4.0f ))); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_CA(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = 0.0f; + float px = BUFFER_RCP_WIDTH; + float py = BUFFER_RCP_HEIGHT; + float aspect = float( BUFFER_WIDTH * BUFFER_RCP_HEIGHT ); + float3 orig = tex2D( ReShade::BackBuffer, texcoord ).xyz; + float depth = ReShade::GetLinearizedDepth( texcoord ).x; + depth = smoothstep( depthStart, depthEnd, depth ); + depth = pow( depth, depthCurve ); + float CA_width_n = CA_width; + if( enable_depth_width ) + CA_width_n *= depth; + + //float2 coords = clamp( texcoord.xy * 2.0f - float2( oX + 1.0f, oY + 1.0f ), -1.0f, 1.0f ); + float2 coords = texcoord.xy * 2.0f - float2( oX + 1.0f, oY + 1.0f ); // Let it ripp, and not clamp! + float2 uv = coords.xy; + coords.xy /= float2( CA_shapeX / aspect, CA_shapeY ); + float2 caintensity= length( coords.xy ) * CA_width_n; + caintensity.y = caintensity.x * caintensity.x + 1.0f; + caintensity.x = 1.0f - ( 1.0f / ( caintensity.y * caintensity.y )); + caintensity.x = pow( caintensity.x, CA_curve ); + + int degreesY = degrees; + float c = 0.0f; + float s = 0.0f; + switch( CA_type ) + { + // Radial: Y + 90 w/ multiplying with uv.xy + case 0: + { + degreesY = degrees + 90 > 360 ? degreesY = degrees + 90 - 360 : degrees + 90; + c = cos( radians( degrees )) * uv.x; + s = sin( radians( degreesY )) * uv.y; + } + break; + // Longitudinal: X = Y w/o multiplying with uv.xy + case 1: + { + c = cos( radians( degrees )); + s = sin( radians( degreesY )); + } + break; + // Full screen Radial + case 2: + { + degreesY = degrees + 90 > 360 ? degreesY = degrees + 90 - 360 : degrees + 90; + caintensity.x = 1.0f; + c = cos( radians( degrees )) * uv.x; + s = sin( radians( degreesY )) * uv.y; + } + break; + // Full screen Longitudinal + case 3: + { + caintensity.x = 1.0f; + c = cos( radians( degrees )); + s = sin( radians( degreesY )); + } + break; + } + + //Apply based on scene depth + if( enable_depth_int ) + caintensity.x *= depth; + + float3 huecolor = 0.0f; + float3 temp = 0.0f; +#if CA_DX9_MODE == 1 + float o1 = CA_sampleSTEPS - 1.0f; +#else + float o1 = sampleSTEPS - 1.0f; +#endif + float o2 = 0.0f; + float3 d = 0.0f; + + // Scale CA (hackjob!) + float caWidth = CA * ( max( BUFFER_WIDTH, BUFFER_HEIGHT ) / 1920.0f ); // Scaled for 1920, raising resolution in X or Y should raise scale + + float offsetX = px * c * caintensity.x; + float offsetY = py * s * caintensity.x; +#if CA_DX9_MODE == 1 + float sampst = CA_sampleSTEPS; + for( float i = 0; i < CA_sampleSTEPS; i++ ) +#else + float sampst = sampleSTEPS; + for( float i = 0; i < sampleSTEPS; i++ ) +#endif + { + huecolor.xyz = HUEToRGB( i / sampst ); + o2 = lerp( -caWidth, caWidth, i / o1 ); + temp.xyz = tex2D( ReShade::BackBuffer, texcoord.xy + float2( o2 * offsetX, o2 * offsetY )).xyz; + color.xyz += temp.xyz * huecolor.xyz; + d.xyz += huecolor.xyz; + } + //color.xyz /= ( sampleSTEPS / 3.0f * 2.0f ); // Too crude and doesn't work with low sampleSTEPS ( too dim ) + color.xyz /= dot( d.xyz, 0.333333f ); // seems so-so OK + color.xyz = lerp( orig.xyz, color.xyz, CA_strength ); + color.xyz = lerp( color.xyz, vignetteColor.xyz * caintensity.x + ( 1.0f - caintensity.x ) * color.xyz, show_CA ); + color.xyz = display_depth ? depth.xxx : color.xyz; + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_06_ChromaticAberration + { + pass prod80_CA + { + VertexShader = PostProcessVS; + PixelShader = PS_CA; + } + } +} diff --git a/data_from_portwine/Reshade/Shaders/PD80_06_Depth_Slicer.fx b/data_from_portwine/Reshade/Shaders/PD80_06_Depth_Slicer.fx new file mode 100644 index 00000000..02e97b7a --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_06_Depth_Slicer.fx @@ -0,0 +1,149 @@ +/* + Description : PD80 04 Magical Rectangle for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Blend_Modes.fxh" +#include "PD80_00_Color_Spaces.fxh" + +namespace pd80_depthslicer +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform float depth_near < + ui_type = "slider"; + ui_label = "Depth Near Plane"; + ui_tooltip = "Depth Near Plane"; + ui_category = "Depth Slicer"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float depthpos < + ui_type = "slider"; + ui_label = "Depth Position"; + ui_tooltip = "Depth Position"; + ui_category = "Depth Slicer"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.015; + uniform float depth_far < + ui_type = "slider"; + ui_label = "Depth Far Plane"; + ui_tooltip = "Depth Far Plane"; + ui_category = "Depth Slicer"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float depth_smoothing < + ui_type = "slider"; + ui_label = "Depth Smoothing"; + ui_tooltip = "Depth Smoothing"; + ui_category = "Depth Slicer"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.005; + uniform float intensity < + ui_type = "slider"; + ui_label = "Lightness"; + ui_tooltip = "Lightness"; + ui_category = "Depth Slicer"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform float hue < + ui_type = "slider"; + ui_label = "Hue"; + ui_tooltip = "Hue"; + ui_category = "Depth Slicer"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.083; + uniform float saturation < + ui_type = "slider"; + ui_label = "Saturation"; + ui_tooltip = "Saturation"; + ui_category = "Depth Slicer"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.0; + uniform int blendmode_1 < __UNIFORM_COMBO_INT1 + ui_label = "Blendmode"; + ui_tooltip = "Blendmode"; + ui_category = "Depth Slicer"; + ui_items = "Default\0Darken\0Multiply\0Linearburn\0Colorburn\0Lighten\0Screen\0Colordodge\0Lineardodge\0Overlay\0Softlight\0Vividlight\0Linearlight\0Pinlight\0Hardmix\0Reflect\0Glow\0Hue\0Saturation\0Color\0Luminosity\0"; + > = 0; + uniform float opacity < + ui_type = "slider"; + ui_label = "Opacity"; + ui_tooltip = "Opacity"; + ui_category = "Depth Slicer"; + ui_min = 0.0; + ui_max = 1.0; + > = 1.0; + //// TEXTURES /////////////////////////////////////////////////////////////////// + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + + //// DEFINES //////////////////////////////////////////////////////////////////// + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_DepthSlice(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + float depth = ReShade::GetLinearizedDepth( texcoord ).x; + + float depth_np = depthpos - depth_near; + float depth_fp = depthpos + depth_far; + + float dn = smoothstep( depth_np - depth_smoothing, depth_np, depth ); + float df = 1.0f - smoothstep( depth_fp, depth_fp + depth_smoothing, depth ); + + float colorize = 1.0f - ( dn * df ); + float a = colorize; + colorize *= intensity; + float3 b = HSVToRGB( float3( hue, saturation, colorize )); + color.xyz = blendmode( color.xyz, b.xyz, blendmode_1, opacity * a ); + + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_06_Depth_Slicer + { + pass prod80_pass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_DepthSlice; + } + } +} + + diff --git a/data_from_portwine/Reshade/Shaders/PD80_06_Film_Grain.fx b/data_from_portwine/Reshade/Shaders/PD80_06_Film_Grain.fx new file mode 100644 index 00000000..110ce8c8 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_06_Film_Grain.fx @@ -0,0 +1,474 @@ +/* + Description : PD80 06 Film Grain for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + Additional credits + - Noise/Grain code adopted, modified, and adjusted from Stefan Gustavson. + License: MIT, Copyright (c) 2011 stegu + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Color_Spaces.fxh" + +#ifndef FG_GRAIN_SMOOTHING + #define FG_GRAIN_SMOOTHING 0 +#endif + +namespace pd80_filmgrain +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform bool enable_test < + ui_label = "Enable Setup Mode"; + ui_tooltip = "Enable Setup Mode"; + ui_category = "Film Grain (simplex)"; + > = false; + uniform int grainMotion < __UNIFORM_COMBO_INT1 + ui_label = "Grain Motion"; + ui_tooltip = "Grain Motion"; + ui_category = "Film Grain (simplex)"; + ui_items = "Disabled\0Enabled\0"; + > = 1; + uniform float grainAdjust < + ui_type = "slider"; + ui_label = "Grain Pattern Adjust (for still noise)"; + ui_tooltip = "Grain Pattern Adjust (for still noise)"; + ui_category = "Film Grain (simplex)"; + ui_min = 1.0f; + ui_max = 2.0f; + > = 1.0; + uniform int grainSize < + ui_type = "slider"; + ui_label = "Grain Size"; + ui_tooltip = "Grain Size"; + ui_category = "Film Grain (simplex)"; + ui_min = 1; + ui_max = 4; + > = 1; +#if( FG_GRAIN_SMOOTHING ) + uniform float grainBlur < + ui_type = "slider"; + ui_label = "Grain Smoothness"; + ui_tooltip = "Grain Smoothness"; + ui_category = "Film Grain (simplex)"; + ui_min = 0.005f; + ui_max = 0.7f; + > = 0.5; +#endif + uniform int grainOrigColor < __UNIFORM_COMBO_INT1 + ui_label = "Use Original Color"; + ui_tooltip = "Use Original Color"; + ui_category = "Film Grain (simplex)"; + ui_items = "Use Random Color\0Use Original Color\0"; + > = 1; + uniform bool use_negnoise < + ui_label = "Use Negative Noise (highlights)"; + ui_tooltip = "Use Negative Noise (highlights)"; + ui_category = "Film Grain (simplex)"; + > = false; + uniform float grainColor < + ui_type = "slider"; + ui_label = "Grain Color Amount"; + ui_tooltip = "Grain Color Amount"; + ui_category = "Film Grain (simplex)"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform float grainAmount < + ui_type = "slider"; + ui_label = "Grain Amount"; + ui_tooltip = "Grain Amount"; + ui_category = "Film Grain (simplex)"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.333; + uniform float grainIntensity < + ui_type = "slider"; + ui_label = "Grain Intensity"; + ui_tooltip = "Grain Intensity"; + ui_category = "Film Grain (simplex)"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.65; + uniform float grainDensity < + ui_type = "slider"; + ui_label = "Grain Density"; + ui_tooltip = "Grain Density"; + ui_category = "Film Grain (simplex)"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 10.0; + uniform float grainIntHigh < + ui_type = "slider"; + ui_label = "Grain Intensity Highlights"; + ui_tooltip = "Grain Intensity Highlights"; + ui_category = "Film Grain (simplex)"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform float grainIntLow < + ui_type = "slider"; + ui_label = "Grain Intensity Shadows"; + ui_tooltip = "Grain Intensity Shadows"; + ui_category = "Film Grain (simplex)"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform bool enable_depth < + ui_label = "Enable depth based adjustments.\nMake sure you have setup your depth buffer correctly."; + ui_tooltip = "Enable depth based adjustments"; + ui_category = "Film Grain (simplex): Depth"; + > = false; + uniform bool display_depth < + ui_label = "Show depth texture"; + ui_tooltip = "Show depth texture"; + ui_category = "Film Grain (simplex): Depth"; + > = false; + uniform float depthStart < + ui_type = "slider"; + ui_label = "Change Depth Start Plane"; + ui_tooltip = "Change Depth Start Plane"; + ui_category = "Film Grain (simplex): Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.0; + uniform float depthEnd < + ui_type = "slider"; + ui_label = "Change Depth End Plane"; + ui_tooltip = "Change Depth End Plane"; + ui_category = "Film Grain (simplex): Depth"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.1; + uniform float depthCurve < + ui_label = "Depth Curve Adjustment"; + ui_tooltip = "Depth Curve Adjustment"; + ui_category = "Film Grain (simplex): Depth"; + ui_type = "slider"; + ui_min = 0.05; + ui_max = 8.0; + > = 1.0; + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texPerm < source = "pd80_permtexture.png"; > { Width = 256; Height = 256; Format = RGBA8; }; + texture texNoise { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; +#if( FG_GRAIN_SMOOTHING ) + texture texNoiseH { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; + texture texNoiseV { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; +#endif + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerPermTex { Texture = texPerm; }; + sampler samplerNoise { Texture = texNoise; }; +#if( FG_GRAIN_SMOOTHING ) + sampler samplerNoiseH { Texture = texNoiseH; }; + sampler samplerNoiseV { Texture = texNoiseV; }; +#endif + + //// DEFINES //////////////////////////////////////////////////////////////////// + #define permTexSize 256 + #define permONE 1.0f / 256.0f + #define permHALF 0.5f * permONE + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + uniform float Timer < source = "timer"; >; + + float4 rnm( float2 tc, float t ) + { + float noise = sin( dot( tc, float2( 12.9898, 78.233 ))) * ( 43758.5453 + t ); + float noiseR = frac( noise * grainAdjust ) * 2.0 - 1.0; + float noiseG = frac( noise * 1.2154 * grainAdjust ) * 2.0 - 1.0; + float noiseB = frac( noise * 1.3453 * grainAdjust ) * 2.0 - 1.0; + float noiseA = frac( noise * 1.3647 * grainAdjust ) * 2.0 - 1.0; + return float4( noiseR, noiseG, noiseB, noiseA ); + } + + float fade( float t ) + { + return t * t * t * ( t * ( t * 6.0 - 15.0 ) + 10.0 ); + } + + float curve( float x ) + { + return x * x * ( 3.0 - 2.0 * x ); + } + + float pnoise3D( float3 p, float t ) + { + float3 pi = permONE * floor( p ) + permHALF; + pi.xy *= permTexSize; + pi.xy = round(( pi.xy - permHALF ) / grainSize ) * grainSize; + pi.xy /= permTexSize; + float3 pf = frac( p ); + // Noise contributions from (x=0, y=0), z=0 and z=1 + float perm00 = rnm( pi.xy, t ).x; + float3 grad000 = tex2D( samplerPermTex, float2( perm00, pi.z )).xyz * 4.0 - 1.0; + float n000 = dot( grad000, pf ); + float3 grad001 = tex2D( samplerPermTex, float2( perm00, pi.z + permONE )).xyz * 4.0 - 1.0; + float n001 = dot( grad001, pf - float3( 0.0, 0.0, 1.0 )); + // Noise contributions from (x=0, y=1), z=0 and z=1 + float perm01 = rnm( pi.xy + float2( 0.0, permONE ), t ).y ; + float3 grad010 = tex2D( samplerPermTex, float2( perm01, pi.z )).xyz * 4.0 - 1.0; + float n010 = dot( grad010, pf - float3( 0.0, 1.0, 0.0 )); + float3 grad011 = tex2D( samplerPermTex, float2( perm01, pi.z + permONE )).xyz * 4.0 - 1.0; + float n011 = dot( grad011, pf - float3( 0.0, 1.0, 1.0 )); + // Noise contributions from (x=1, y=0), z=0 and z=1 + float perm10 = rnm( pi.xy + float2( permONE, 0.0 ), t ).z ; + float3 grad100 = tex2D( samplerPermTex, float2( perm10, pi.z )).xyz * 4.0 - 1.0; + float n100 = dot( grad100, pf - float3( 1.0, 0.0, 0.0 )); + float3 grad101 = tex2D( samplerPermTex, float2( perm10, pi.z + permONE )).xyz * 4.0 - 1.0; + float n101 = dot( grad101, pf - float3( 1.0, 0.0, 1.0 )); + // Noise contributions from (x=1, y=1), z=0 and z=1 + float perm11 = rnm( pi.xy + float2( permONE, permONE ), t ).w ; + float3 grad110 = tex2D( samplerPermTex, float2( perm11, pi.z )).xyz * 4.0 - 1.0; + float n110 = dot( grad110, pf - float3( 1.0, 1.0, 0.0 )); + float3 grad111 = tex2D( samplerPermTex, float2( perm11, pi.z + permONE )).xyz * 4.0 - 1.0; + float n111 = dot( grad111, pf - float3( 1.0, 1.0, 1.0 )); + // Blend contributions along x + float4 n_x = lerp( float4( n000, n001, n010, n011 ), float4( n100, n101, n110, n111 ), fade( pf.x )); + // Blend contributions along y + float2 n_xy = lerp( n_x.xy, n_x.zw, fade( pf.y )); + // Blend contributions along z + float n_xyz = lerp( n_xy.x, n_xy.y, fade( pf.z )); + // We're done, return the final noise value + return n_xyz; + } + + float getAvgColor( float3 col ) + { + return dot( col.xyz, float3( 0.333333f, 0.333334f, 0.333333f )); + } + + // nVidia blend modes + // Source: https://www.khronos.org/registry/OpenGL/extensions/NV/NV_blend_equation_advanced.txt + float3 ClipColor( float3 color ) + { + float lum = getAvgColor( color.xyz ); + float mincol = min( min( color.x, color.y ), color.z ); + float maxcol = max( max( color.x, color.y ), color.z ); + color.xyz = ( mincol < 0.0f ) ? lum + (( color.xyz - lum ) * lum ) / ( lum - mincol ) : color.xyz; + color.xyz = ( maxcol > 1.0f ) ? lum + (( color.xyz - lum ) * ( 1.0f - lum )) / ( maxcol - lum ) : color.xyz; + return color; + } + + // Luminosity: base, blend + // Color: blend, base + float3 blendLuma( float3 base, float3 blend ) + { + float lumbase = getAvgColor( base.xyz ); + float lumblend = getAvgColor( blend.xyz ); + float ldiff = lumblend - lumbase; + float3 col = base.xyz + ldiff; + return ClipColor( col.xyz ); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_FilmGrain(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + // Noise + float timer = 1.0f; + if( grainMotion ) + timer = Timer % 1000.0f; + float2 uv = texcoord.xy * float2( BUFFER_WIDTH, BUFFER_HEIGHT ); + float3 noise = pnoise3D( float3( uv.xy, 1 ), timer ); + noise.y = pnoise3D( float3( uv.xy, 2 ), timer ); + noise.z = pnoise3D( float3( uv.xy, 3 ), timer ); + + // Intensity + noise.xyz *= grainIntensity; + + // Noise color + noise.xyz = lerp( noise.xxx, noise.xyz, grainColor ); + + // Control noise density + noise.xyz = pow( abs( noise.xyz ), max( 11.0f - grainDensity, 0.1f )) * sign( noise.xyz ); + + // Pack noise that has range -1..0..1 into 0..1 range for blurring passes + // After blurring passes unpack again noise * 2 - 1 + noise.xyz = saturate(( noise.xyz + 1.0f ) * 0.5f ); + + return float4( noise.xyz, 1.0f ); + } +#if( FG_GRAIN_SMOOTHING ) + float4 PS_BlurH(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 noise = tex2D( samplerNoise, texcoord ); + // Blur + float SigmaSum = 0.0f; + float pxlOffset = 1.0f; + float Blur = grainBlur * grainSize; + float3 Sigma; + Sigma.x = 1.0f / ( sqrt( 6.283184f ) * Blur ); + Sigma.y = exp( -0.5f / ( Blur * Blur )); + Sigma.z = Sigma.y * Sigma.y; + noise.xyz *= Sigma.x; + SigmaSum += Sigma.x; + Sigma.xy *= Sigma.yz; + float px = BUFFER_RCP_WIDTH; + + [loop] + for( int i = 0; i < 5 && Sigma.x > 0.001f; ++i ) + { + noise += tex2Dlod( samplerNoise, float4( texcoord.xy + float2( pxlOffset * px, 0.0f ), 0.0, 0.0 )) * Sigma.x; + noise += tex2Dlod( samplerNoise, float4( texcoord.xy - float2( pxlOffset * px, 0.0f ), 0.0, 0.0 )) * Sigma.x; + SigmaSum += ( 2.0f * Sigma.x ); + pxlOffset += 1.0f; + Sigma.xy *= Sigma.yz; + } + + noise.xyz /= SigmaSum; + return float4( noise.xyz, 1.0f ); + } + + float4 PS_BlurV(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 noise = tex2D( samplerNoiseH, texcoord ); + // Blur + float SigmaSum = 0.0f; + float pxlOffset = 1.0f; + float Blur = grainBlur * grainSize; + float3 Sigma; + Sigma.x = 1.0f / ( sqrt( 6.283184f ) * Blur ); + Sigma.y = exp( -0.5f / ( Blur * Blur )); + Sigma.z = Sigma.y * Sigma.y; + noise.xyz *= Sigma.x; + SigmaSum += Sigma.x; + Sigma.xy *= Sigma.yz; + float py = BUFFER_RCP_HEIGHT; + + [loop] + for( int i = 0; i < 5 && Sigma.x > 0.001f; ++i ) + { + noise += tex2Dlod( samplerNoiseH, float4( texcoord.xy + float2( 0.0f, pxlOffset * py ), 0.0, 0.0 )) * Sigma.x; + noise += tex2Dlod( samplerNoiseH, float4( texcoord.xy - float2( 0.0f, pxlOffset * py ), 0.0, 0.0 )) * Sigma.x; + SigmaSum += ( 2.0f * Sigma.x ); + pxlOffset += 1.0f; + Sigma.xy *= Sigma.yz; + } + + noise.xyz /= SigmaSum; + return float4( noise.xyz, 1.0f ); + } +#endif + float4 PS_MergeNoise(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { +#if( FG_GRAIN_SMOOTHING ) + float4 noise = tex2D( samplerNoiseV, texcoord ); +#else + float4 noise = tex2D( samplerNoise, texcoord ); +#endif + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + + // Unpack noise + noise.xyz = noise.xyz * 2.0f - 1.0f; + + // Depth + float depth = ReShade::GetLinearizedDepth( texcoord ).x; + depth = smoothstep( depthStart, depthEnd, depth ); + depth = pow( depth, depthCurve ); + float d = enable_depth ? depth : 1.0f; + + // Test setup + float3 testenv = ( texcoord.y < 0.25f ) ? texcoord.xxx : ( texcoord.y < 0.5f ) ? float3( texcoord.x, 0.0f, 0.0f ) : + ( texcoord.y < 0.75f ) ? float3( 0.0f, texcoord.x, 0.0f ) : float3( 0.0f, 0.0f, texcoord.x ); + color.xyz = enable_test ? testenv.xyz : color.xyz; + + // Store some values + float3 origHSV = RGBToHSV( color.xyz ); + float3 orig = color.xyz; + float maxc = max( max( color.x, color.y ), color.z ); + float minc = min( min( color.x, color.y ), color.z ); + + // Mixing options + float lum = maxc; + noise.xyz = lerp( noise.xyz * grainIntLow, noise.xyz * grainIntHigh, fade( lum )); // Noise adjustments based on average intensity + float3 negnoise = -abs( noise.xyz ); + lum *= lum; + // Apply only negative noise in highlights/whites as positive will be clipped out + // Swizzle the components of negnoise to avoid middle intensity regions of no noise ( x - x = 0 ) + negnoise.xyz = lerp( noise.xyz, negnoise.zxy * 0.5f, lum ); + noise.xyz = use_negnoise ? negnoise.xyz : noise.xyz; + + // Noise coloring + // Issue, when changing hue to original Red, Bblue channels work fine, but humans more sensitive to Yellow/Green + // In perceived luminosity R and B channel are very close, will assume they are equal as they are close enough + // "weight" is my poor attemp to match human vision, bit heavier on the yellow-green than green + float factor = 1.2f; + float weight = max( 1.0f - abs(( origHSV.x - 0.166667f ) * 6.0f ), 0.0f ) * factor; + weight += max( 1.0f - abs(( origHSV.x - 0.333333f ) * 6.0f ), 0.0f ) / factor; + weight = saturate( curve( weight / factor )); + + // Account for saturation + weight *= saturate(( maxc + 1.0e-10 - minc ) / maxc + 1.0e-10 ); + // Account for intensity. Highest reduction at 0.2 intensity + // No change in blacks and brights + float adj = saturate(( maxc - 0.2f ) * 1.25f ) + saturate( 1.0f - maxc * 5.0f ); + adj = 1.0f - curve( adj ); + weight *= adj; + + // Create a factor to adjust noise intensity based on weight + float adjNoise = lerp( 1.0f, 0.5f, grainOrigColor * weight ); + + color.xyz = lerp( color.xyz, color.xyz + ( noise.xyz * d ), grainAmount * adjNoise ); + color.xyz = saturate( color.xyz ); + + // Use original hue and saturation mixed with lightness channel of noise + float3 col = blendLuma( orig.xyz, color.xyz ); + color.xyz = grainOrigColor ? col.xyz : color.xyz; + + color.xyz = display_depth ? depth.xxx : color.xyz; + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_06_FilmGrain + { + pass prod80_WriteNoise + { + VertexShader = PostProcessVS; + PixelShader = PS_FilmGrain; + RenderTarget = texNoise; + } +#if( FG_GRAIN_SMOOTHING ) + pass prod80_BlurH + { + VertexShader = PostProcessVS; + PixelShader = PS_BlurH; + RenderTarget = texNoiseH; + } + pass prod80_BlurV + { + VertexShader = PostProcessVS; + PixelShader = PS_BlurV; + RenderTarget = texNoiseV; + } +#endif + pass prod80_MixNoise + { + VertexShader = PostProcessVS; + PixelShader = PS_MergeNoise; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_06_Luma_Fade.fx b/data_from_portwine/Reshade/Shaders/PD80_06_Luma_Fade.fx new file mode 100644 index 00000000..7a43249b --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_06_Luma_Fade.fx @@ -0,0 +1,153 @@ +/* + Description : PD80 06 Luma Fade for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +namespace pd80_lumafade +{ + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform float transition_speed < + ui_type = "slider"; + ui_label = "Time Based Fade Speed"; + ui_tooltip = "Time Based Fade Speed"; + ui_category = "Scene Luminance Adaptation"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.5; + uniform float minlevel < + ui_label = "Pure Dark Scene Level"; + ui_tooltip = "Pure Dark Scene Level"; + ui_category = "Scene Luminance Adaptation"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.125; + uniform float maxlevel < + ui_label = "Pure Light Scene Level"; + ui_tooltip = "Pure Light Scene Level"; + ui_category = "Scene Luminance Adaptation"; + ui_type = "slider"; + ui_min = 0.0; + ui_max = 1.0; + > = 0.3; + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texLuma { Width = 256; Height = 256; Format = R16F; MipLevels = 8; }; + texture texAvgLuma { Format = R16F; }; + texture texPrevAvgLuma { Format = R16F; }; + texture texPrevColor { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerLuma { Texture = texLuma; }; + sampler samplerAvgLuma { Texture = texAvgLuma; }; + sampler samplerPrevAvgLuma { Texture = texPrevAvgLuma; }; + sampler samplerPrevColor { Texture = texPrevColor; }; + + //// DEFINES //////////////////////////////////////////////////////////////////// + uniform float Frametime < source = "frametime"; >; + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + float interpolate( float o, float n, float factor, float ft ) + { + return lerp( o, n, 1.0f - exp( -factor * ft )); + } + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float PS_WriteLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 color = tex2D( ReShade::BackBuffer, texcoord ); + return dot( color.xyz, 0.333333f ); + } + + float PS_AvgLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float luma = tex2Dlod( samplerLuma, float4( 0.5f, 0.5f, 0, 8 )).x; + float prevluma = tex2D( samplerPrevAvgLuma, float2( 0.5f, 0.5f )).x; + float factor = transition_speed * 4.0f + 1.0f; + return interpolate( prevluma, luma, factor, Frametime * 0.001f ); + } + + float4 PS_StorePrev(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + return tex2D( ReShade::BackBuffer, texcoord ); + } + + float PS_PrevAvgLuma(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + return tex2D( samplerAvgLuma, float2( 0.5f, 0.5f )).x; + } + + float4 PS_LumaInterpolation(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float4 newcol = tex2D( ReShade::BackBuffer, texcoord ); + float4 oldcol = tex2D( samplerPrevColor, texcoord ); + float luma = tex2D( samplerAvgLuma, float2( 0.5f, 0.5f )).x; + return lerp( oldcol, newcol, smoothstep( minlevel, maxlevel, luma )); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_06_LumaFade_Start + < ui_tooltip = "Luma Fading Effects\n\n" + "This shader allows you to fade in and out ReShade effects based on scene luminance.\n" + "To use: put the Start technque before the shaders you want to enable in a BRIGHT scene and\n" + "put the End technique after those shaders. Then use the UI settings to manipulate the fading.";> + { + pass Luma + { + VertexShader = PostProcessVS; + PixelShader = PS_WriteLuma; + RenderTarget = texLuma; + } + pass AvgLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_AvgLuma; + RenderTarget = texAvgLuma; + } + pass StoreColor + { + VertexShader = PostProcessVS; + PixelShader = PS_StorePrev; + RenderTarget = texPrevColor; + } + pass PreviousLuma + { + VertexShader = PostProcessVS; + PixelShader = PS_PrevAvgLuma; + RenderTarget = texPrevAvgLuma; + } + } + technique prod80_06_LumaFade_End + { + pass Combine + { + VertexShader = PostProcessVS; + PixelShader = PS_LumaInterpolation; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_06_Posterize_Pixelate.fx b/data_from_portwine/Reshade/Shaders/PD80_06_Posterize_Pixelate.fx new file mode 100644 index 00000000..bf667165 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_06_Posterize_Pixelate.fx @@ -0,0 +1,152 @@ +/* + Description : PD80 06 Posterize Pixelate for Reshade https://reshade.me/ + Author : prod80 (Bas Veth) + License : MIT, Copyright (c) 2020 prod80 + + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" +#include "PD80_00_Noise_Samplers.fxh" + +namespace pd80_posterizepixelate +{ + //// PREPROCESSOR DEFINITIONS /////////////////////////////////////////////////// + + //// UI ELEMENTS //////////////////////////////////////////////////////////////// + uniform int number_of_levels < + ui_label = "Number of Levels"; + ui_tooltip = "Number of Levels"; + ui_category = "Posterize"; + ui_type = "slider"; + ui_min = 2; + ui_max = 255; + > = 255; + uniform int pixel_size < + ui_label = "Pixel Size"; + ui_tooltip = "Pixel Size"; + ui_category = "Pixelate"; + ui_type = "slider"; + ui_min = 1; + ui_max = 9; + > = 1; + uniform float effect_strength < + ui_type = "slider"; + ui_label = "Effect Strength"; + ui_tooltip = "Effect Strength"; + ui_category = "Posterize Pixelate"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 1.0; + uniform float border_str < + ui_type = "slider"; + ui_label = "Border Strength"; + ui_tooltip = "Border Strength"; + ui_category = "Posterize Pixelate"; + ui_min = 0.0f; + ui_max = 1.0f; + > = 0.0; + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + ui_category = "Posterize Pixelate"; + > = false; + uniform bool dither_motion < + ui_label = "Dither Motion"; + ui_tooltip = "Dither Motion"; + ui_category = "Posterize Pixelate"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_category = "Posterize Pixelate"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + //// TEXTURES /////////////////////////////////////////////////////////////////// + texture texMipMe { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; MipLevels = 9; }; + + //// SAMPLERS /////////////////////////////////////////////////////////////////// + sampler samplerMipMe + { + Texture = texMipMe; + MipFilter = POINT; + MinFilter = POINT; + MagFilter = POINT; + }; + + //// DEFINES //////////////////////////////////////////////////////////////////// + #define aspect float( BUFFER_WIDTH * BUFFER_RCP_HEIGHT ) + + //// FUNCTIONS ////////////////////////////////////////////////////////////////// + uniform float2 pingpong < source = "pingpong"; min = 0; max = 128; step = 1; >; + + //// PIXEL SHADERS ////////////////////////////////////////////////////////////// + float4 PS_MipMe(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + return tex2D( ReShade::BackBuffer, texcoord ); + } + + float4 PS_Posterize(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target + { + float3 color = tex2Dlod( samplerMipMe, float4( texcoord.xy, 0.0f, pixel_size - 1 )).xyz; + float exp = exp2( pixel_size - 1 ); + float rcp_exp = max( rcp( exp ) - 0.00001f, 0.0f ); // - 0.00001f because fp precision comes into play + float2 bwbh = float2( floor( BUFFER_WIDTH / exp ), floor( BUFFER_HEIGHT / exp )); + // Dither + float2 tx = bwbh.xy / 512.0f; + tx.xy *= texcoord.xy; + float3 dnoise = tex2D( samplerRGBNoise, tx ).xyz; + float mot = dither_motion ? pingpong.x + 9 : 1.0f; + dnoise.xyz = frac( dnoise + 0.61803398875f * mot ); + dnoise.xyz = dnoise * 2.0f - 1.0f; + color.xyz = enable_dither ? saturate( color.xyz + dnoise.xyz * ( dither_strength / number_of_levels )) : color.xyz; + // Dither end + float3 orig = color.xyz; + color.xyz = floor( color.xyz * number_of_levels ) / ( number_of_levels - 1 ); + float2 uv = frac( texcoord.xy * bwbh.xy ); + float grade = ( uv.x <= rcp_exp ) ? 1.0 : 0.0; + grade += ( uv.y <= rcp_exp ) ? 1.0 : 0.0; + color.xyz = lerp( color.xyz, lerp( color.xyz, 0.0f, border_str * saturate( pixel_size - 1 )), saturate( grade )); + color.xyz = lerp( orig.xyz, color.xyz, effect_strength ); + return float4( color.xyz, 1.0f ); + } + + //// TECHNIQUES ///////////////////////////////////////////////////////////////// + technique prod80_06_Posterize_Pixelate + { + pass prod80_pass0 + { + VertexShader = PostProcessVS; + PixelShader = PS_MipMe; + RenderTarget = texMipMe; + } + pass prod80_pass1 + { + VertexShader = PostProcessVS; + PixelShader = PS_Posterize; + } + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/PD80_LUT_v2.fxh b/data_from_portwine/Reshade/Shaders/PD80_LUT_v2.fxh new file mode 100644 index 00000000..13256153 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/PD80_LUT_v2.fxh @@ -0,0 +1,148 @@ +/* + * Original shader by Ganossa + * + * ReShade Community edits by: + * - MartyMcFly + * - Otis_Inf + * - prod80 + */ + +// Input +#define _CONCAT(a, b) a##b +#define _MERGE(a, b) _CONCAT(a, b) +#define PD80_TexName _MERGE( PD80_Technique_Name, Tex ) +#define PD80_Sampler _MERGE( PD80_Technique_Name, Samp ) +#define PD80_NameSpace _MERGE( PD80_Technique_Name, Name ) + +#include "ReShade.fxh" +#include "PD80_00_Noise_Samplers.fxh" +#include "PD80_00_Color_Spaces.fxh" + +namespace PD80_NameSpace +{ + + //// UI Elements ///////////////////////////////////////////////// + uniform bool enable_dither < + ui_label = "Enable Dithering"; + ui_tooltip = "Enable Dithering"; + > = true; + uniform float dither_strength < + ui_type = "slider"; + ui_label = "Dither Strength"; + ui_tooltip = "Dither Strength"; + ui_min = 0.0f; + ui_max = 10.0f; + > = 1.0; + uniform int PD80_LutSelector < + ui_type = "combo"; + ui_items= PD80_Drop_Down_Menu; + ui_label = "LUT Selection"; + ui_tooltip = "The LUT to use for color transformation."; + > = 0; + uniform float PD80_MixChroma < + ui_type = "slider"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "LUT Chroma"; + ui_tooltip = "LUT Chroma"; + > = 1.00; + uniform float PD80_MixLuma < + ui_type = "slider"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "LUT Luma"; + ui_tooltip = "LUT Luma"; + > = 1.00; + uniform float PD80_Intensity < + ui_type = "slider"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "LUT Intensity"; + ui_tooltip = "Intensity of LUT effect"; + > = 1.00; + uniform float3 ib < + ui_type = "color"; + ui_label = "LUT Black IN Level"; + ui_tooltip = "LUT Black IN Level"; + ui_category = "LUT Levels"; + > = float3(0.0, 0.0, 0.0); + uniform float3 iw < + ui_type = "color"; + ui_label = "LUT White IN Level"; + ui_tooltip = "LUT White IN Level"; + ui_category = "LUT Levels"; + > = float3(1.0, 1.0, 1.0); + uniform float3 ob < + ui_type = "color"; + ui_label = "LUT Black OUT Level"; + ui_tooltip = "LUT Black OUT Level"; + ui_category = "LUT Levels"; + > = float3(0.0, 0.0, 0.0); + uniform float3 ow < + ui_type = "color"; + ui_label = "LUT White OUT Level"; + ui_tooltip = "LUT White OUT Level"; + ui_category = "LUT Levels"; + > = float3(1.0, 1.0, 1.0); + uniform float ig < + ui_label = "LUT Gamma Adjustment"; + ui_tooltip = "LUT Gamma Adjustment"; + ui_category = "LUT Levels"; + ui_type = "slider"; + ui_min = 0.05; + ui_max = 10.0; + > = 1.0; + + //// Textures Samplers /////////////////////////////////////////// + texture PD80_TexName < source = PD80_LUT_File_Name; > + { + Width = PD80_Tile_SizeXY * PD80_Tile_Amount; + Height = PD80_Tile_SizeXY * PD80_LUT_Amount; + }; + sampler PD80_Sampler { Texture = PD80_TexName; }; + + //// Functions /////////////////////////////////////////////////// + float3 levels( float3 color, float3 blackin, float3 whitein, float gamma, float3 outblack, float3 outwhite ) + { + float3 ret = saturate( color.xyz - blackin.xyz ) / max( whitein.xyz - blackin.xyz, 0.000001f ); + ret.xyz = pow( ret.xyz, gamma ); + ret.xyz = ret.xyz * saturate( outwhite.xyz - outblack.xyz ) + outblack.xyz; + return ret; + } + + //// Pixel Shader //////////////////////////////////////////////// + void PS_MultiLUT_v2( float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 color : SV_Target0 ) + { + color = tex2D( ReShade::BackBuffer, texcoord.xy ); + float4 dnoise = dither( samplerRGBNoise, texcoord.xy, 10, enable_dither, dither_strength, 1, 0.5f ); + + float2 texelsize = rcp( PD80_Tile_SizeXY ); + texelsize.x /= PD80_Tile_Amount; + + float3 lutcoord = float3(( color.xy * PD80_Tile_SizeXY - color.xy + 0.5f ) * texelsize.xy, color.z * PD80_Tile_SizeXY - color.z ); + lutcoord.y /= PD80_LUT_Amount; + lutcoord.y += ( float( PD80_LutSelector ) / PD80_LUT_Amount ); + float lerpfact = frac( lutcoord.z ); + lutcoord.x += ( lutcoord.z - lerpfact ) * texelsize.y; + + float3 lutcolor = lerp( tex2D( PD80_Sampler, lutcoord.xy ).xyz, tex2D( PD80_Sampler, float2( lutcoord.x + texelsize.y, lutcoord.y )).xyz, lerpfact ); + lutcolor.xyz = levels( lutcolor.xyz, saturate( ib.xyz + dnoise.xyz ), + saturate( iw.xyz + dnoise.yzx ), + ig, + saturate( ob.xyz + dnoise.zxy ), + saturate( ow.xyz + dnoise.wxz )); + float3 lablut = pd80_srgb_to_lab( lutcolor.xyz ); + float3 labcol = pd80_srgb_to_lab( color.xyz ); + float newluma = lerp( labcol.x, lablut.x, PD80_MixLuma ); + float2 newAB = lerp( labcol.yz, lablut.yz, PD80_MixChroma ); + lutcolor.xyz = pd80_lab_to_srgb( float3( newluma, newAB )); + color.xyz = lerp( color.xyz, saturate( lutcolor.xyz + dnoise.wzx ), PD80_Intensity ); + } + + //// Technique /////////////////////////////////////////////////// + technique PD80_Technique_Name + { + pass MultiLUT_Apply + { + VertexShader = PostProcessVS; + PixelShader = PS_MultiLUT_v2; + } + } +} diff --git a/data_from_portwine/Reshade/Shaders/RadiantGI.fx b/data_from_portwine/Reshade/Shaders/RadiantGI.fx new file mode 100644 index 00000000..4f777b17 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/RadiantGI.fx @@ -0,0 +1,2354 @@ +////-------------// +///**RadiantGI**/// +//-------------//// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// *// +//For Reshade 3.0+ PCGI Ver 3.0.9 +//----------------------------- +// Radiant Global Illumination +// + +// Subsurface Scattering +// Due Diligence +// Michael Bunnell Disk Screen Space Ambient Occlusion or Disk to Disk SSAO 14.3 +// https://developer.nvidia.com/gpugems/gpugems2/part-ii-shading-lighting-and-shadows/chapter-14-dynamic-ambient-occlusion-and +// - Arkano22 +// https://www.gamedev.net/topic/550699-ssao-no-halo-artifacts/ +// - Martinsh +// http://devlog-martinsh.blogspot.com/2011/10/nicer-ssao.html +// - Boulotaur2024 +// https://github.com/PeterTh/gedosato/blob/master/pack/assets/dx9/martinsh_ssao.fx +// Nayar and Oren Simple Scattering Approximations 16.2 +// https://developer.nvidia.com/gpugems/gpugems/part-iii-materials/chapter-16-real-time-approximations-subsurface-scattering +// GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look +// https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ +// Computer graphics & visualization Global Illumination Effects. +// - Christian A. Wiesner +// https://slideplayer.com/slide/3533454/ +//Improved Normal Reconstruction From Depth +// - Turanszkij +// https://wickedengine.net/2019/09/22/improved-normal-reconstruction-from-depth/ +// Upsample Code +// - PETER KL "I think" +// https://frictionalgames.blogspot.com/2014/01/tech-feature-ssao-and-temporal-blur.html#Code +// TAA Based on my own port of Epics Temporal AA +// https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf +// Joined Bilateral Upsampling Filtering +// - Bart Wronski +// https://bartwronski.com/2019/09/22/local-linear-models-guided-filter/ +// - Johannes Kopf | Michael F. Cohen | Dani Lischinski | Matt Uyttendaele +// https://johanneskopf.de/publications/jbu/paper/FinalPaper_0185.pdf +// Reinhard by Tom Madams +// http://imdoingitwrong.wordpress.com/2010/08/19/why-reinhard-desaturates-my-blacks-3/ +// Generate Noise is Based on this implamentation +// https://www.shadertoy.com/view/wtsSW4 +// Poisson-Disc Sampling Evenly distributed points on a rotated 2D Disk +// https://www.jasondavies.com/poisson-disc/ +// Text rendering code by Hamneggs +// https://www.shadertoy.com/view/4dtGD2 +// A slightly faster buffer-less vertex shader trick by CeeJay.dk +// https://www.reddit.com/r/gamedev/comments/2j17wk/a_slightly_faster_bufferless_vertex_shader_trick/ +// Origina LUT algorithm by Ganossa edited by | MartyMcFly | Otis_Inf | prod80 | - Base LUT texture made by Prod80 Thank you. +// https://github.com/prod80/prod80-ReShade-Repository/blob/master/Shaders/PD80_LUT_v2.fxh +// SRGB <--> CIELAB CONVERSIONS Ported by Prod80. Also More Stuff From Prod80 +// http://www.brucelindbloom.com/index.html +// Explicit Image Detection using YCbCr Space Color Model for basic Skin Detection +// - JORGE ALBERTO MARCIAL BASILI | GUALBERTO AGUILAR TORRES | GABRIEL SÁNCHEZ PÉREZ3 | L. KARINA TOSCANO MEDINA4 | HÉCTOR M. PÉREZ MEANA +// http://www.wseas.us/e-library/conferences/2011/Mexico/CEMATH/CEMATH-20.pdf +// Unlimited Blur Filter +// - Paul Dang +// http://blog.marmakoide.org/?p=1 +// https://github.com/spite/Wagner/blob/master/fragment-shaders/box-blur-fs.glsl [MIT] +// https://github.com/Brimson/reshaders/blob/master/shaders/cBlur.fx +// +// If I missed any please tell me. +// +// Special Thank You to CeeJay.dk & Dorinte. May the Pineapple Kringle lead you too happiness. +// +// LICENSE +// ============ +// Overwatch & Code out side the work of people mention above is licenses under: Attribution-NoDerivatives 4.0 International +// +// 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. +// +// NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. +// +// 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-nd/4.0 +// +// Have fun, +// Written by Jose Negrete AKA BlueSkyDefender , October 2020 +// https://github.com/BlueSkyDefender/Depth3D +// +// Notes to the other developers: https://github.com/BlueSkyDefender/AstrayFX +// +// I welcome almost any help that seems to improve the code. But, The changes need to be approved by myself. So feel free to submit changes to me personally. +// Things to work on are listed here. Oh if you feel your code changes too much. Just add a preprocessor to section off your code. Thank you. +// +// Write your name and changes/notes below thank you. +// __________________________________________________________________________________________________________________________________________________________________________________ +// -------------------------------------------------------------------Around Line 1390--------------------------------------------------------------------------------------- +// Lord of Lunacy - https://github.com/LordOfLunacy +// Reveil DeHaze Masking was inserted around GI Creation. +// __________________________________________________________________________________________________________________________________________________________________________________ +// -------------------------------------------------------------------Around Line 0000--------------------------------------------------------------------------------------- +// Dev Name - Repo +// Notes from Dev. +// +// Upcoming Updates.............................................no guarantee +// Need Past Edge Brightness storage. +// +// Radiant GI Update Notes are at the bottom +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if exists "Overwatch.fxh" //Overwatch Interceptor// + #include "Overwatch.fxh" + #define OS 0 +#else// DA_Y = [Depth Adjust] DA_Z = [Offset] DA_W = [Depth Linearization] DB_X = [Depth Flip] + static const float DA_Y = 7.5, DA_Z = 0.0, DA_W = 0.0, DB_X = 0; + // DC_X = [Barrel Distortion K1] DC_Y = [Barrel Distortion K2] DC_Z = [Barrel Distortion K3] DC_W = [Barrel Distortion Zoom] + static const float DC_X = 0, DC_Y = 0, DC_Z = 0, DC_W = 0; + // DD_X = [Horizontal Size] DD_Y = [Vertical Size] DD_Z = [Horizontal Position] DD_W = [Vertical Position] + static const float DD_X = 1, DD_Y = 1, DD_Z = 0.0, DD_W = 0.0; + //Triggers + static const int RE = 0, NC = 0, RH = 0, NP = 0, ID = 0, SP = 0, DC = 0, HM = 0, DF = 0, NF = 0, DS = 0, LBC = 0, LBM = 0, DA = 0, NW = 0, PE = 0, FV = 0, ED = 0; + //Overwatch.fxh State + #define OS 1 +#endif + +//Keep in mind you are not licenced to redistribute this shader with setting modified below. Please Read the Licence. +//This GI shader is free and shouldn't sit behind a paywall. If you paid for this shader ask for a refund right away. + +//Depth Buffer Adjustments +#define DB_Size_Position 0 //[Off | On] This is used to reposition and adjusts the size of the depth buffer. +#define BD_Correction 0 //[Off | On] Barrel Distortion Correction for non conforming BackBuffer. + +//TAA Quality Level +#define TAA_Clamping 0.2 //[0.0 - 1.0] Use this to adjust TAA clamping. + +//Other Settings +#define Controlled_Blend 0 //[Off | On] Use this if you want control over blending GI in to the final +#define Dark_Mode 0 //[Off | On] Instead of using a 50% gray it displays Black for the absence of information. +#define Text_Info_Key 93 //Menu Key Text Information Key Default 93 is the Menu Key. You can use this site https://keycode.info to pick your own. +#define Disable_Debug_Info 0 //[Off | On] Use this to disable help information that gives you hints for fixing many games with Overwatch.fxh. +#define Minimize_Web_Info 0 //[Off | On] Use this to minimize the website logo on startup. +#define ForcePool 0 //[Off | On] Force Pooled Textures in versions 4.9.0+ If you get a black screen turn this too off. Seems to be a ReShade Issue. +#define Force_Texture_Details 1//[Off | On] This is used to add Texture Detail AO into PCGI output. + + +//RadiantGI In menu Options +#ifndef MaxDepth_CutOff + #define MaxDepth_CutOff 0.999 //[0.1 - 1.0] Used to cutout the sky with depth buffer masking. This lets the shader save on performance by limiting what is used in GI. +#endif + +//RadiantGI In menu Options +#ifndef Simple_Mode + #define Simple_Mode 1 //[0 - 1] Used this to enable or disable Simple User Mode. +#endif +#define Simp_Mode Simple_Mode + +//Keep in mind you are not licenced to redistribute this shader with setting modified below. Please Read the Licence. +//This GI shader is free and shouldn't sit behind a paywall. If you paid for this shader ask for a refund right away. + +//--------------------------------------------------------------------------------------// +// Common Intercept Code +// (Copy and paste this code into your shader to help with interception of it) +//--------------------------------------------------------------------------------------// +#define __SUPPORTED_VRS_MAP_COMPATIBILITY__ 11 + +#if exists "VRS_Map.fxh" + #include "VRS_Map.fxh" + #ifndef VRS_MAP + #define VRS_MAP 1 + #endif +#else + #define VRS_MAP 0 +#endif + +//Define the necessary functions and constants so the code can't break when the .fxh isn't present +#if VRS_MAP == 0 +static const uint VRS_RATE1D_1X = 0x0; +static const uint VRS_RATE1D_2X = 0x1; +static const uint VRS_RATE1D_4X = 0x2; +#define VRS_MAKE_SHADING_RATE(x,y) ((x << 2) | (y)) + +static const uint VRS_RATE_1X1 = VRS_MAKE_SHADING_RATE(VRS_RATE1D_1X, VRS_RATE1D_1X); // 0; +static const uint VRS_RATE_1X2 = VRS_MAKE_SHADING_RATE(VRS_RATE1D_1X, VRS_RATE1D_2X); // 0x1; +static const uint VRS_RATE_2X1 = VRS_MAKE_SHADING_RATE(VRS_RATE1D_2X, VRS_RATE1D_1X); // 0x4; +static const uint VRS_RATE_2X2 = VRS_MAKE_SHADING_RATE(VRS_RATE1D_2X, VRS_RATE1D_2X); // 0x5; +//Only up to 2X2 is implemented currently +static const uint VRS_RATE_2X4 = VRS_MAKE_SHADING_RATE(VRS_RATE1D_2X, VRS_RATE1D_4X); // 0x6; +static const uint VRS_RATE_4X2 = VRS_MAKE_SHADING_RATE(VRS_RATE1D_4X, VRS_RATE1D_2X); // 0x9; +static const uint VRS_RATE_4X4 = VRS_MAKE_SHADING_RATE(VRS_RATE1D_4X, VRS_RATE1D_4X); // 0xa; + +namespace VRS_Map +{ + uint ShadingRate(float2 texcoord, bool UseVRS, uint offRate) + { + return offRate; + } + uint ShadingRate(float2 texcoord, float VarianceCutoff, bool UseVRS, uint offRate) + { + return offRate; + } + float3 DebugImage(float3 originalImage, float2 texcoord, float VarianceCutoff, bool DebugView) + { + return originalImage; + } +} +#endif //VRS_MAP + +#if exists "IsolateSkintones.png" //Look Up Table Interceptor// + #define LUT_File_Name "IsolateSkintones.png" //Base Texture also made by Prod80 + #define Tile_SizeXY 64 + #define Tile_Amount 64 + #define LutSD 1 +#else // Texture name which contains the LUT(s) and the Tile Sizes, Amounts, etc. by Prod80 + #define LutSD 0 +#endif +static const float MixChroma = 2.0; //LUT Chroma 0-1 +static const float MixLuma = 1.0; //LUT Luma 0-1 +static const float Intensity = 1.5; //LUT Intensity 0-1 +static const float3 ib = float3(0.0,0.0,0.0);//LUT Black IN Level +static const float3 iw = float3(1.0,1.0,1.0);//LUT White IN Level +static const float3 ob = float3(0.0,0.0,0.0);//LUT Black OUT Level +static const float3 ow = float3(1.0,1.0,1.0);//LUT White OUT Level +static const float ig = 1.0; //LUT Gamma Adjustment 0.05 - 10.0 +//Use for real HDR. //Do not Use. +#define HDR_Toggle 0 //For HDR //Do not Use. +//Pooled Texture Issue for 4.8.0 +#if __RESHADE__ >= 40910 && ForcePool + #define PoolTex < pooled = true; > +#else + #define PoolTex +#endif +//Older ReShade Compatibility +#if __RESHADE__ >= 40300 + #define Compatibility_TF 1 +#else + #define Compatibility_TF 0 +#endif +//Check DX9 Game +#if __RENDERER__ == 0x9000 + #define DX9 1 +#else + #define DX9 0 +#endif +//This GI shader is free and shouldn't sit behind a paywall. If you paid for this shader ask for a refund right away. +//Automatic Adjustment based on Resolutionsup to 4k considered. LOL good luck with 8k in 2020 +#if (BUFFER_HEIGHT <= 720) + #define RSRes 1.0 +#elif (BUFFER_HEIGHT <= 1080) + #define RSRes 0.8 +#elif (BUFFER_HEIGHT <= 1440) + #define RSRes 0.7 +#elif (BUFFER_HEIGHT <= 2160) + #define RSRes 0.6 +#else + #define RSRes 0.5 //??? 8k Mystery meat +#endif + +//Help / Guide Information stub uniform a idea from LucasM +uniform int RadiantGI < + ui_text = "RadiantGI is an indirect lighting algorithm based on the disk-to-disk radiance transfer by Michael Bunnell.\n" + "As you can tell its name is a play on words and it radiates the kind of feeling I want from it one Ray Bounce at a time.\n" + "This GI shader is free and shouldn't sit behind a paywall. If you paid for this shader ask for a refund right away.\n" + "As for my self I do want to provide the community with free shaders and any donations will help keep that motivation alive.\n" + "For more information and help please feel free to visit http://www.Depth3D.info or https://blueskydefender.github.io/AstrayFX\n " + "Help with this shader fuctions specifically visit the WIki @ https://github.com/BlueSkyDefender/AstrayFX/wiki/RadiantGI\n" + "Please enjoy this shader and Thank You for using RadiantGI."; + ui_category = "RadiantGI"; + ui_category_closed = true; + ui_label = " "; + ui_type = "radio"; +>; +//uniform float TEST < ui_type = "slider"; ui_min = 0.0; ui_max = 1; ui_label = "TEST"; > = 1; +uniform float samples < + ui_type = "slider"; + ui_min = 4; ui_max = 12; ui_step = 1; + ui_label = "Samples"; + ui_tooltip = "GI Sample Quantity is used to increase samples amount as a side effect this reduces noise."; + ui_category = "Global Illumination"; +> = 6; + +uniform float GI_Ray_Length < + ui_type = "drag"; + ui_min = 1.0; ui_max = 500; ui_step = 1; + ui_label = "General Ray Length"; + ui_tooltip = "General GI Ray Length is used to increase the Sampling Radius.\n" //Marty didn't want me using Ray Length. But, this is easyer for normies to understand. + "The byproduc of this causes the ray casting distance to extend.\n" //So I opted for keeping the name and explaining it for the user. + "This scales automatically with multi level detail."; // So the name not 100% correct. But, it's close enough. + ui_category = "Global Illumination"; +> = 250; + +uniform float Target_Lighting < + ui_type = "slider"; + ui_min = -1.0; ui_max = 1.0; + ui_label = "Targeted Lighting"; + ui_tooltip = "Lets you target the Direct Lighting and/or Indirect Lighting specifically, so the shader can use your adjustment for its own GI calculations.\n" + "Negative values target Indirect lighting and positive values target direct lighting in the image./n" + "Defaults is [0.05] and Zero is full image sampling."; + ui_category = "Global Illumination"; +> = 0.05; + +uniform float2 NCD < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Near Details"; + ui_tooltip = "Lets you adjust detail of objects near the cam and or like weapon hand GI.\n" + "The 2nd Option is for Weapon Hands in game that fall out of range.\n" + "Defaults are [Near Details X 0.125] [Weapon Hand Y 0.0]"; + ui_category = "Global Illumination"; +> = float2(0.125,0.0); + +uniform float PCGI_Fade < //Blame the pineapple for this option. + ui_type = "slider"; + ui_min = -1.0; ui_max = 1.0; //Still need to make this better...... + ui_label = "Depth Fade-Out"; + ui_tooltip = "GI Application Power that is based on Depth scaling for controlled fade In-N-Out.\n" //That's What A Hamburger's All About + "Can be set from 0 to 1 and is Set to Zero for No Culling.\n" + "Default is 0.0."; + ui_category = "Global Illumination"; +> = 1.0; + +uniform float2 Reflectivness < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Diffusion Amount"; + ui_tooltip = "This basicly adds control for how defused the lighting should look on the ground.\n" + "Default is [1.0 | 0.5]. One is Max Diffusion and the value is length."; + ui_category = "Global Illumination"; +> = float2(1.0,0.5); + +uniform bool Scattering< + ui_label = "Subsurface Light Transport"; + ui_tooltip = "Enable The Subsurface Light Transport Function to create a Subsurface Scattering effect.\n" + "Default is Off."; + ui_category = "Subsurface Scattering"; +> = false; + +uniform float Wrap < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Upper Scattering"; + ui_tooltip = "Control the Light Wrap Form Factor to adjust the Subsurface Scattering effect.\n" + "Default is [0.5]."; + ui_category = "Subsurface Scattering"; +> = 0.5; +/* +uniform float User_SSS_Luma < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Subsurface Brightness"; + ui_tooltip = "This is used to fine tune the automatic brightness of the upper layer scattering.\n" + "Can be set from Zero to One.\n" + "Default is [0.5]."; + ui_category = "SSLT"; +> = 0.5; +*/ +uniform float Deep_Scattering < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Deep Scattering"; + ui_tooltip = "Control Thickness Estimation Form Factor to create a Deep Tissue Scattering effect.\n" + "Default is [0.1]."; + ui_category = "Subsurface Scattering"; +> = 0.1; + +uniform float Luma_Map < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Tissue Luma Map"; + ui_tooltip = "Controls the Luma Map that lets bright lights approximate deep penotration of the tissue.\n" //So Deep.... + "Default is [0.5]."; + ui_category = "Subsurface Scattering"; +> = 0.5; +uniform float3 Internals < // We are all pink and fleshy on the inside? + ui_type = "color"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Internal Flesh Color"; + ui_tooltip = "Since I can't tell what the internal color of the Deep Tissue you need to set this your self for RGB.\n" + "Defaults are [R 0.25] [B 0.0] [G 0.0] [L 0.5]."; + ui_category = "Subsurface Scattering"; +> = float3(0.54,0.01,0.01); + +uniform float2 Diffusion_Saturation_Power < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Subsurface Blur & Flesh Saturation"; + ui_tooltip = "Diffusion Blur is used too softens the lighting and makes the person a little more realistic by mimicking this effect skin has on light.\n" + "Simulate light diffusion favor red blurring over other colors.\n" + "Default are [0.5] [0.5]."; + ui_category = "Subsurface Scattering"; +> = float2(0.25,0.5); + +#if LutSD //Man............................................ +uniform float2 SSS_Seek < +#else +uniform float SSS_Seek < +#endif + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; +#if LutSD + ui_label = "Skin Detect Distance & Seeking"; +#else + ui_label = "Skin Detect Distance"; +#endif + ui_tooltip = "Lets you control how far we need to search and seek with the human skin tone detection algorithm for SSLT.\n" +#if LutSD + "Defaults are [0.25] and [0.5]."; +#else + "The 2nd option only shows if you use the special LUT for custom and or more accurate skin tone detection.\n" + "You can get this LUT @ https://github.com/BlueSkyDefender/AstrayFX/wiki/Subsurface-Light-Transport\n" + "Default is [0.25]."; +#endif + ui_category = "Subsurface Scattering"; +#if LutSD +> = float2(0.25,0.5); +#else +> = 0.25; +#endif + +uniform int Sky_Emissive_Selection < //Emissive_Mode //Sky_Contribution + ui_type = "combo"; + ui_label = "Directional Sky & Emissive Mode"; + ui_tooltip = "Use this to add Directional Sky and or Emissive Mode.\n" + "\n" + "Directional Sky Color:\n" + "Allows for the use of Sky Color Contribution to effect the world directly.\n" + "\n" + "Emissive Mode:\n" + "Make all bright objects''Emissive Objects,'' based on approximated information from the emitter.\n" + "\n" + "Default is Off."; + ui_items = "Off\0Directional Sky Color\0Emissive Mode\0Sky & Emissive Mode\0"; + ui_category = "Supplemental Contributions"; + > = 0; + +uniform float GI_Sky_Saturation < + ui_type = "slider"; + ui_min = 0.0; ui_max = 5.0; + ui_label = "Sky Saturation"; + ui_tooltip = "Sky Color Saturation.\n" + "Default is [Power 1.0]."; + ui_category = "Supplemental Contributions"; +> = 1.0; + +uniform int Sky_Adustment < + ui_type = "slider"; + ui_min = 0; ui_max = 6; + ui_label = "Sky Color Averaging"; + ui_tooltip = "This lets you Average the sky color so you can have general color."; + ui_category = "Supplemental Contributions"; +> = 3; + +uniform float D_Irradiance < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Distance Irradiance"; + ui_tooltip = "Distance Irradiance Lets you control Irradiance that comes from the Refracted Light from distant ground.\n" + "Default is [0.0] and Zero is Off."; + ui_category = "Supplemental Contributions"; +> = 0.0; + +#if Force_Texture_Details +uniform float2 PCGI_2DTexture_Detail < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Texture Details & Falloff"; + ui_tooltip = "Lets you add Texture Details to PCGI so you can have added 2D texture information applyed to the GI.\n" + "Turn this on by adjusting the first slider and then adjusting it's falloff with the second.\n" + "Defaults are [0.0,0.5] and Zero is Off"; + ui_category = "Supplemental Contributions"; +> = float2(0.0,1.0); +#else +static const int2 PCGI_2DTexture_Detail = 0; +#endif + +uniform float Trim < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Trim"; + ui_tooltip = "Trim GI by limiting how far the GI is able to effect the objects around them.\n" + "Directional Sky Color is negatively impacted by this option.\n" + "Use this mostly for Emissive Mode.\n" + "Default is [0.0] and Zero is Off."; + ui_category = "Supplemental Contributions"; +> = 0.0; + +#if Controlled_Blend +uniform float Blend < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Blend"; + ui_tooltip = "Use this to change the look of GI when applied to the final image."; + ui_category = "Image"; +> = 0.5; +#else +uniform int Blend < + ui_type = "combo"; + ui_label = "Blend Mode"; + ui_tooltip = "Use this to change the look of GI when applied to the final image."; + ui_items = "Mix\0Overlay\0Softlight\0Add\0"; + ui_category = "Image"; + > = 0; +#endif + +uniform float GI_Power < + ui_type = "slider"; + ui_min = 0.0; ui_max = 2.5; + ui_label = "Power"; + ui_tooltip = "Main overall GI application power control.\n" + "Default is [Power 1.0]."; + ui_category = "Image"; +> = 1.0; + +uniform float GI_Saturation < + ui_type = "slider"; + ui_min = 0.0; ui_max = 5.0; + ui_label = "GI Saturation"; + ui_tooltip = "Irradiance Map Saturation.\n" + "Default is [Power 1.0]."; + ui_category = "Image"; +> = 1.0; +/* +uniform float shadows < + ui_type = "slider"; + ui_min = -2.5; ui_max = 0.0; + ui_label = "Enhance Shadows."; + ui_tooltip = "Boost The Shadows in the image."; + ui_category = "Image"; +> = 0.0; +*/ +uniform float HDR_BP < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "HDR Extraction Power"; + ui_tooltip = "Use This to adjust the HDR Power, You can override this value and set it to like 1.5 or something.\n" + "Dedault is [0.5] and Zero and is Off.";//Because new HDR extraction works well now. + ui_category = "Image"; +> = 0.5; + +uniform int Depth_Map < + ui_type = "combo"; + ui_items = "DM0 Normal\0DM1 Reversed\0"; + ui_label = "Depth Map Selection"; + ui_tooltip = "Linearization for the zBuffer also known as Depth Map.\n" + "DM0 is Z-Normal and DM1 is Z-Reversed.\n"; + ui_category = "Depth Map"; +> = DA_W; + +uniform float Depth_Map_Adjust < + ui_type = "drag"; + ui_min = 1.0; ui_max = 500.0; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "This allows for you to adjust the DM precision.\n" + "Adjust this to keep it as low as possible.\n" + "Default is 7.5"; + ui_category = "Depth Map"; +> = DA_Y; + +uniform float Offset < + ui_type = "drag"; + ui_min = -1.0; ui_max = 1.0; + ui_label = "Depth Map Offset"; + ui_tooltip = "Depth Map Offset is for non conforming ZBuffer.\n" + "It is rare that you would need to use this option.\n" + "Use this to make adjustments to DM 0 or DM 1.\n" + "Default and starts at Zero and it is Off."; + ui_category = "Depth Map"; +> = DA_Z; + +uniform bool Depth_Map_Flip < + ui_label = "Depth Map Flip"; + ui_tooltip = "Flip the depth map if it is upside down."; + ui_category = "Depth Map"; +> = DB_X; +uniform int Debug < + ui_type = "combo"; + ui_items = "RadiantGI\0Irradiance Map\0Light Source Map\0Depth & Normals\0"; + ui_label = "Debug View"; + ui_tooltip = "View Debug Buffers."; + ui_category = "Extra Options"; +> = 0; + +uniform int SamplesXY < + ui_type = "slider"; + ui_min = 0; ui_max = 20; + ui_label = "Denoise Power";//Ya CeeJay.dk you got your way.. + ui_tooltip = "This raises or lowers Samples used for the Final DeNoisers which in turn affects Performance.\n" + "This also has the side effect of smoothing out the image so you get that Normal Like Smoothing.\n" + "Default is 7 and you can override this a bit."; + ui_category = "Extra Options"; +> = 6; + +uniform float GI_Res < + ui_type = "slider"; + ui_min = 0.5; ui_max = 1;// ui_step = 0.1; + ui_label = "Resolution"; + ui_tooltip = "GI Resolution is used too increase performance at the cost of quality.\n" + "Larger adjustments from default will reduce noise and vice versa.\n" + "Default is automaticly adjusted based on current resolution."; + ui_category = "Extra Options"; +> = RSRes; + +uniform bool IGN_Toggle < + ui_label = "Interleaved Gradient Noise"; + ui_tooltip = "In the on position it uses Interleaved Gradient Noise in stead of Regular Noise."; + ui_category = "Extra Options"; +> = true; + +#if DB_Size_Position || SP == 2 +uniform float2 Horizontal_and_Vertical < + ui_type = "drag"; + ui_min = 0.0; ui_max = 2; + ui_label = "Horizontal & Vertical Size"; + ui_tooltip = "Adjust Horizontal and Vertical Resize. Default is 1.0."; + ui_category = "Depth Corrections"; +> = float2(DD_X,DD_Y); +uniform float2 Image_Position_Adjust< + ui_type = "drag"; + ui_min = -1.0; ui_max = 1.0; + ui_label = "Horizontal & Vertical Position"; + ui_tooltip = "Adjust the Image Position if it's off by a bit. Default is Zero."; + ui_category = "Depth Corrections"; +> = float2(DD_Z,DD_W); +#else +static const float2 Horizontal_and_Vertical = float2(DD_X,DD_Y); +static const float2 Image_Position_Adjust = float2(DD_Z,DD_W); +#endif +#if BD_Correction +uniform int BD_Options < + ui_type = "combo"; + ui_items = "On\0Off\0"; + ui_label = "Distortion Options"; + ui_tooltip = "Use this to Turn BD Off or On.\n" + "Default is ON."; + ui_category = "Depth Corrections"; +> = 0; + +uniform float3 Colors_K1_K2_K3 < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = -2.0; ui_max = 2.0; + ui_tooltip = "Adjust the Distortion K1, K2, & K3.\n" + "Default is 0.0"; + ui_label = "BD K1 K2 K3"; + ui_category = "Depth Corrections"; +> = float3(DC_X,DC_Y,DC_Z); + +uniform float Zoom < + ui_type = "drag"; + ui_min = -0.5; ui_max = 0.5; + ui_label = "BD Zoom"; + ui_category = "Depth Corrections"; +> = DC_W; +#else + #if DC + uniform bool BD_Options < + ui_label = "Toggle Barrel Distortion"; + ui_tooltip = "Use this if you modded the game to remove Barrel Distortion."; + ui_category = "Depth Corrections"; + > = !true; + #else + static const int BD_Options = 1; + #endif +static const float3 Colors_K1_K2_K3 = float3(DC_X,DC_Y,DC_Z); +static const float Zoom = DC_W; +#endif +#if BD_Correction || DB_Size_Position + uniform bool Depth_Guide < + ui_label = "Alinement Guide"; + ui_tooltip = "Use this for a guide for alinement."; + ui_category = "Depth Corrections"; + > = !true; +#else + static const int Depth_Guide = 0; +#endif +uniform int PP_Options < // Yes I am a Grown Man.... + ui_text = "Max Depth Cutoff: Sets cutoff point for depth in RadiantGI. \n" +#if !VRS_MAP + " Affects masking for Directional Sky Color.\n" + " DEFAULT [0.999] RANGE [0.5] - [0.999] "; +#else + " Affects masking for Directional Sky Color.\n" + " DEFAULT [0.999] RANGE [0.5] - [0.999] " + "\n" + "VRS Optical Flow: Is used to turn on this feature in the VRS_Map.fx\n" + " shader by Lord of Lunacy a Shader Dev.\n" + " DEFAULT [0] TOGGLE [0] - [1] "; +#endif + ui_category = "Preprocessor Options Information"; + ui_category_closed = false; + ui_label = " "; + ui_type = "radio"; +>; + +//This GI shader is free and shouldn't sit behind a paywall. If you paid for this shader ask for a refund right away. +uniform bool Text_Info < source = "key"; keycode = Text_Info_Key; toggle = true; mode = "toggle";>; +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +uniform float frametime < source = "frametime"; >; // Time in milliseconds it took for the last frame to complete. +uniform int framecount < source = "framecount"; >; // Total amount of frames since the game started. +uniform float clock < source = "timer"; >; // A timer that starts when the Game starts. +#define Alternate framecount % 2.0 == 0 // Alternate per frame +#define PI 3.14159265358979323846264 // PI +#if LutSD //Extracted Look Up Table +texture TexName < source = LUT_File_Name; > { Width = Tile_SizeXY * Tile_Amount; Height = Tile_SizeXY ; }; +sampler Sampler { Texture = TexName; }; +#endif + +int2 Sky_Emissive_Bool() +{ + int Sky_Bool = Sky_Emissive_Selection == 1 || Sky_Emissive_Selection == 3 ? 1 : 0; + int Emissive_Bool = Sky_Emissive_Selection == 2 || Sky_Emissive_Selection == 3 ? 1 : 0; + return int2(Sky_Bool,Emissive_Bool); +} + +float Scale_PCGI_Fade() +{ + return lerp(0,2,saturate(abs(PCGI_Fade)) ); +} + +float Offset_Switch() +{ + return Offset >= -0.0015 && Offset <= 0.0015 ? 0 : Offset; +} + +float2 Saturation() +{ + return float2(GI_Saturation,GI_Sky_Saturation); +} + +float Reflect() +{ + return Reflectivness.x == 0 ? -0.001 : Reflectivness.x; +} + +float2 GIRL() +{ + return float2(GI_Ray_Length,250); +} +static const float EvenSteven[21] = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 , 22, 24, 26, 28, 30, 32, 34, 36, 38, 40}; // It's not odd... +/////////////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// +static const float2 XYoffset[8] = { float2( 0,+pix.y ), float2( 0,-pix.y), float2(+pix.x, 0), float2(-pix.x, 0), float2(-pix.x,-pix.y), float2(+pix.x,-pix.y), float2(-pix.x,+pix.y), float2(+pix.x,+pix.y) }; +static const float DBoffsets[7] = { -5.5, -3.5, -1.5, 0.0, 1.5, 3.5, 5.5 }; +static const float SkyMipLeves[7] = { 0, 5, 6, 7, 8, 9, 10}; +//Diffusion Blur weights to blur red channel more than green and blue SSS +static const float3 DBweight[7] = { float3( 0.006, 0.00, 0.00), + float3( 0.061, 0.00, 0.00), + float3( 0.242, 0.25, 0.25), + float3( 0.383, 0.50, 0.50), + float3( 0.242, 0.25, 0.25), + float3( 0.061, 0.00, 0.00), + float3( 0.006, 0.00, 0.00) }; +//Poisson Disk Precompute +static const float2 PoissonTaps[13] = { float2(-0.326,-0.406), //This Distribution seems faster..... + float2(-0.840,-0.074), //Tried many from https://github.com/bartwronski/PoissonSamplingGenerator + float2(-0.696, 0.457), //But they seems slower then this one I found online..... WTF + float2(-0.203, 0.621), + float2( 0.962,-0.195), + float2( 0.473,-0.480), + float2( 0.519, 0.767), + float2( 0.185,-0.893), + float2( 0.507, 0.064), + float2( 0.896, 0.412), + float2(-0.322,-0.933), + float2(-0.792,-0.598), + float2(-0.255, 0.464) }; + +float fmod(float a, float b) +{ + float c = frac(abs(a / b)) * abs(b); + return a < 0 ? -c : c; +} + +float Scale(float val,float max,float min) //Scale to 0 - 1 +{ + return (val - min) / (max - min); +} + +int useVRS(float2 texcoord, int UseVRS) +{ + return VRS_Map::ShadingRate(texcoord, UseVRS, VRS_RATE_1X1 ) == VRS_RATE_2X2; +} + +float MCNoise(float FC ,float2 TC,float seed) +{ //This is the noise I used for rendering + float motion = FC, a = 12.9898, b = 78.233, c = 43758.5453, dt = dot(TC.xy + 0.5, float2(a,b)), sn = fmod(dt,PI + seed); + return frac(frac(sin(sn) * c) + 0.71803398875f * motion); +} int T_01() { return 12500; } + +float Interleaved_Gradient_Noise(float2 TC) +{ //Magic Numbers + float3 MNums = float3(0.06711056, 0.00583715, 52.9829189); + return frac( MNums.z * frac(dot(TC,MNums.xy)) ); +} + +float gaussian(float x, float sigma) +{ + return (rsqrt( PI * pow(sigma,2))) * exp(-(pow(x,2) / (2.0 * pow(sigma,2)))); +} +//Color Mixing +float3 overlay(float3 c, float3 b) { return c<0.5f ? 2.0f*c*b:(1.0f-2.0f*(1.0f-c)*(1.0f-b));} +float3 softlight(float3 c, float3 b) { return b<0.5f ? (2.0f*c*b+c*c*(1.0f-2.0f*b)):(sqrt(c)*(2.0f*b-1.0f)+2.0f*c*(1.0f-b));} +float3 add(float3 c, float3 b) { return c + (b * 0.5);} +//Enhace Shadows +//float3 Shadows( float3 color ) +//{ +// float3 distribution = pow( 1.0f - color.rgb, 4.0f ), SH = color.rgb * ( distribution * shadows ) * ( 1.0f - color.rgb ); +// return saturate( color.rgb + SH ); +//} +#if BD_Correction || DC +float2 D(float2 p, float k1, float k2, float k3) //Lens + Radial lens undistort filtering Left & Right +{ // Normalize the u,v coordinates in the range [-1;+1] + p = (2. * p - 1.); + // Calculate Zoom + p *= 1 + Zoom; + // Calculate l2 norm + float r2 = p.x*p.x + p.y*p.y; + float r4 = r2 * r2; + float r6 = r4 * r2; + // Forward transform + float x2 = p.x * (1. + k1 * r2 + k2 * r4 + k3 * r6); + float y2 = p.y * (1. + k1 * r2 + k2 * r4 + k3 * r6); + // De-normalize to the original range + p.x = (x2 + 1.) * 1. * 0.5; + p.y = (y2 + 1.) * 1. * 0.5; + +return p; +} +#endif +float3 RGBtoYCbCr(float3 rgb) +{ float C[1];//The Chronicles of Riddick: Assault on Dark Athena FIX I don't know why it works....... + float Y = .299 * rgb.x + .587 * rgb.y + .114 * rgb.z; // Luminance + float Cb = -.169 * rgb.x - .331 * rgb.y + .500 * rgb.z; // Chrominance Blue + float Cr = .500 * rgb.x - .419 * rgb.y - .081 * rgb.z; // Chrominance Red + return float3(Y,Cb + 128./255.,Cr + 128./255.); +} + +float3 YCbCrtoRGB(float3 ycc) +{ + float3 c = ycc - float3(0., 128./255., 128./255.); + + float R = c.x + 1.400 * c.z; + float G = c.x - 0.343 * c.y - 0.711 * c.z; + float B = c.x + 1.765 * c.y; + return float3(R,G,B); +} +//----------------------------------Inverse ToneMappers-------------------------------------------- +float Luma(float3 C) +{ + float3 Luma; + + if (HDR_Toggle == 0) + Luma = float3(0.2126, 0.7152, 0.0722); // (HD video) https://en.wikipedia.org/wiki/Luma_(video) + else + Luma = float3(0.2627, 0.6780, 0.0593); // (HDR video) https://en.wikipedia.org/wiki/Rec._2100 + + return dot(C,Luma); +} + +float max3(float x, float y, float z) +{ + return max(x, max(y, z)); +} + +float3 inv_Tonemapper(float4 color) +{ //Timothy Lottes fast_reversible + return color.rgb * rcp((1.0 + max(color.w,0.001)) - max3(color.r, color.g, color.b)); +} + +float3 HUEToRGB( in float H ) +{ + return saturate( float3( abs( H * 6.0f - 3.0f ) - 1.0f, + 2.0f - abs( H * 6.0f - 2.0f ), + 2.0f - abs( H * 6.0f - 4.0f ))); +} + +float3 RGBToHCV( in float3 RGB ) +{ + // Based on work by Sam Hocevar and Emil Persson + float4 P = ( RGB.g < RGB.b ) ? float4( RGB.bg, -1.0f, 2.0f/3.0f ) : float4( RGB.gb, 0.0f, -1.0f/3.0f ); + float4 Q1 = ( RGB.r < P.x ) ? float4( P.xyw, RGB.r ) : float4( RGB.r, P.yzx ); + float C = Q1.x - min( Q1.w, Q1.y ); + float H = abs(( Q1.w - Q1.y ) / ( 6.0f * C + 0.000001f ) + Q1.z ); + return float3( H, C, Q1.x ); +} + +float3 RGBToHSL( in float3 RGB ) +{ + RGB.xyz = max( RGB.xyz, 0.000001f ); + float3 HCV = RGBToHCV(RGB); + float L = HCV.z - HCV.y * 0.5f; + float S = HCV.y / ( 1.0f - abs( L * 2.0f - 1.0f ) + 0.000001f); + return float3( HCV.x, S, L ); +} + +float3 HSLToRGB( in float3 HSL ) +{ + float3 RGB = HUEToRGB(HSL.x); + float C = (1.0f - abs(2.0f * HSL.z - 1.0f)) * HSL.y; + return ( RGB - 0.5f ) * C + HSL.z; +} + +float3 Saturator_A(float3 C, float Depth_Mask,float DD)//DD is Distance Dimming so that Sky irradiance has prefrence. +{ float Mask = 1-Depth_Mask, Sat = Debug == 2 ? 0.0 : Saturation().x, Distance_Irradiance = lerp(0.5,1.0,saturate(D_Irradiance)), DDMasked = lerp(1-saturate((DD-Distance_Irradiance)/(1-Distance_Irradiance)),1,DD * Depth_Mask); + C.rgb *= DDMasked; + C.rgb *= lerp(1,lerp(1,6,Trim),Depth_Mask);//Used to keep trimming from effecting Sky color too...much.... + C.rgb = RGBToHSL(lerp(C.rgb, C.rgb * 1.25,Depth_Mask));// Can boost the sky color irradiance here. + C.y *= (Sat * Mask) + lerp(1,Saturation().y,Depth_Mask); + return HSLToRGB(C.rgb); +} + +float3 Saturator_B(float3 C) // for SSS +{ + C.rgb = RGBToHSL(C.rgb); + C.y *= saturate(Diffusion_Saturation_Power.y) * 2; + return HSLToRGB(C.rgb); +} + +float3 Saturator_C(float3 C) // for SSS +{ + C.rgb = RGBToHSL(C.rgb); + //C.y *= 1.+ saturate(GI_LumaPower-0.625) ; + return HSLToRGB(C.rgb); +} + +float3 InternalFleshColor(float3 SSS, float Density, float3 Internal, float LumProfile) +{ float3 D = saturate(Density) * LumProfile; + return SSS + lerp(D * Internal,0,saturate(SSS)); +} +//// Skin Functions /////////////////////////////////////////////////// -- Ported by BSD from 02_Isolate_SkinTones.fx +#if LutSD +float3 levels( float3 color, float3 blackin, float3 whitein, float gamma, float3 outblack, float3 outwhite ) +{ + float3 ret = saturate( color.xyz - blackin.xyz ) / max( whitein.xyz - blackin.xyz, 0.000001f ); + ret.xyz = pow( ret.xyz, gamma ); + ret.xyz = ret.xyz * saturate( outwhite.xyz - outblack.xyz ) + outblack.xyz; + return ret; +} +// SRGB <--> CIELAB CONVERSIONS Ported by Prod80. + +// Reference white D65 +#define reference_white float3( 0.95047, 1.0, 1.08883 ) +// Source +// http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html +#define K_val float( 24389.0 / 27.0 ) +#define E_val float( 216.0 / 24389.0 ) + +float3 xyz_to_lab( float3 c ) +{ + // .xyz output contains .lab + float3 w = c / reference_white; + float3 v; + v.x = ( w.x > E_val ) ? pow( abs(w.x), 1.0 / 3.0 ) : ( K_val * w.x + 16.0 ) / 116.0; + v.y = ( w.y > E_val ) ? pow( abs(w.y), 1.0 / 3.0 ) : ( K_val * w.y + 16.0 ) / 116.0; + v.z = ( w.z > E_val ) ? pow( abs(w.z), 1.0 / 3.0 ) : ( K_val * w.z + 16.0 ) / 116.0; + return float3( 116.0 * v.y - 16.0, + 500.0 * ( v.x - v.y ), + 200.0 * ( v.y - v.z )); +} + +float3 lab_to_xyz( float3 c ) +{ + float3 v; + v.y = ( c.x + 16.0 ) / 116.0; + v.x = c.y / 500.0 + v.y; + v.z = v.y - c.z / 200.0; + return float3(( v.x * v.x * v.x > E_val ) ? v.x * v.x * v.x : ( 116.0 * v.x - 16.0 ) / K_val, + ( c.x > K_val * E_val ) ? v.y * v.y * v.y : c.x / K_val, + ( v.z * v.z * v.z > E_val ) ? v.z * v.z * v.z : ( 116.0 * v.z - 16.0 ) / K_val ) * + reference_white; +} + +float3 srgb_to_xyz( float3 c ) +{ + // Source: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + // sRGB to XYZ (D65) - Standard sRGB reference white ( 0.95047, 1.0, 1.08883 ) + const float3x3 mat = float3x3( + 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041 + ); + return mul( mat, c ); +} + +float3 xyz_to_srgb( float3 c ) +{ + // Source: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html + // XYZ to sRGB (D65) - Standard sRGB reference white ( 0.95047, 1.0, 1.08883 ) + const float3x3 mat = float3x3( + 3.2404542,-1.5371385,-0.4985314, + -0.9692660, 1.8760108, 0.0415560, + 0.0556434,-0.2040259, 1.0572252 + ); + return mul( mat, c ); +} +// Maximum value in LAB, B channel is pure blue with 107.8602... divide by 108 to get 0..1 range values + +// Maximum value in LAB, L channel is pure white with 100 +float3 srgb_to_lab( float3 c ) +{ + float3 lab = srgb_to_xyz( c ); + lab = xyz_to_lab( lab ); + return lab / float3( 100.0, 108.0, 108.0 ); +} + +float3 lab_to_srgb( float3 c ) +{ + float3 rgb = lab_to_xyz( c * float3( 100.0, 108.0, 108.0 )); + rgb = xyz_to_srgb( max( min( rgb, reference_white ), 0.0 )); + return saturate( rgb ); +} +#endif +float SkinDetection(float4 color) +{ //Can Also mask out the sky or things that are too far....... + float3 YCbCr = RGBtoYCbCr(color.rgb) * 255.0; + //So after exhaustive image histogram analysis, the optimal range threshold is.... + #if LutSD + //Prod80 Port of Skin Isolation for RadiantGI + float2 texelsize = rcp( Tile_SizeXY ); + texelsize.x /= Tile_Amount; + + float3 lutcoord = float3(( color.xy * Tile_SizeXY - color.xy + 0.5f ) * texelsize.xy, color.z * Tile_SizeXY - color.z ); + float lerpfact = frac( lutcoord.z ); + lutcoord.x += ( lutcoord.z - lerpfact ) * texelsize.y; + + float3 lutcolor = lerp( tex2D( Sampler, lutcoord.xy ).xyz, tex2D( Sampler, float2( lutcoord.x + texelsize.y, lutcoord.y )).xyz, lerpfact ); + lutcolor.xyz = levels( lutcolor.xyz, saturate( ib.xyz ), + saturate( iw.xyz ), + ig, + saturate( ob.xyz ), + saturate( ow.xyz )); + float3 lablut = srgb_to_lab( lutcolor.xyz ); + float3 labcol = srgb_to_lab( color.xyz ); + float newluma = lerp( labcol.x, lablut.x, MixLuma ); + float2 newAB = lerp( labcol.yz, lablut.yz, MixChroma ); + lutcolor.xyz = lab_to_srgb( float3( newluma, newAB )); + color.xyz = lerp( color.xyz, saturate( lutcolor.xyz ), Intensity ); + float Fin = dot(color.xyz,color.xyz); + if(Fin > SSS_Seek.y) + return 1.0; + else + return 0.0; + #else + if (YCbCr.y > 80 && YCbCr.y < 118 && YCbCr.z > 133 && YCbCr.z < 173) + return 0.0; + else + return 1.0; + #endif +} int T_02() { return 25000; } +/////////////////////////////////////////////////////Texture Samplers//////////////////////////////////////////////////////////////// +#if Compatibility_TF + #define RGBAC RGB10A2 +#else + #define RGBAC RGBA8 +#endif +texture DepthBufferTex : DEPTH; + +sampler ZBuffer + { + Texture = DepthBufferTex; + }; + +texture BackBufferTex : COLOR; + +sampler BackBufferPCGI + { + Texture = BackBufferTex; + }; + +texture2D PCGIpastTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16f; MipLevels = 5;}; //Has to 16bit min +sampler2D PCGIpastFrame { Texture = PCGIpastTex; + MagFilter = POINT; + MinFilter = POINT; + MipFilter = POINT; +}; + +texture2D PCGIaccuTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT ; Format = RGBAC; }; +sampler2D PCGIaccuFrames { Texture = PCGIaccuTex; }; +//Seen issues with pooling this texture.. Workaround for 4.8.0- +texture2D PCGIcurrColorTex PoolTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16f; MipLevels = 11;}; //Cant use RGB10A2 // must be RGBA8 or RGBA16f since I store information on A +sampler2D PCGIcurrColor { Texture = PCGIcurrColorTex; }; + +texture2D PCGIcurrNormalsDepthTex < pooled = true; > { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16f; MipLevels = 11;}; +sampler2D PCGIcurrNormalsDepth { Texture = PCGIcurrNormalsDepthTex; }; + +texture2D RadiantGITex { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT ; Format = RGBAC; }; +sampler2D PCGI_Info { Texture = RadiantGITex; + MagFilter = POINT; + MinFilter = POINT; + MipFilter = POINT; +}; + +texture2D RadiantSSTex { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT ; Format = RGBA16f;}; +sampler2D PCSS_Info { Texture = RadiantSSTex; + MagFilter = POINT; + MinFilter = POINT; + MipFilter = POINT; +}; + +texture2D PCGIReconstructionTex < pooled = true; > { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT ; Format = RGBAC; MipLevels = 8;}; +sampler2D PCGIReconstruction_Info { Texture = PCGIReconstructionTex; + MagFilter = POINT; + MinFilter = POINT; + MipFilter = POINT; +}; +//Seen issues with pooling this texture.. Workaround for 4.8.0- +texture2D PCGIHorizontalTex PoolTex { Width = BUFFER_WIDTH / 2; Height = BUFFER_HEIGHT / 2; Format = RGBAC; }; +sampler2D PCGI_BGUHorizontal_Sample { Texture = PCGIHorizontalTex;}; +//Seen issues with pooling this texture.. Workaround for 4.8.0- +texture2D PCGIVerticalTex PoolTex { Width = BUFFER_WIDTH ; Height = BUFFER_HEIGHT ; Format = RGBAC; }; +sampler2D PCGI_BGUVertical_Sample { Texture = PCGIVerticalTex; +}; + +//texture2D StorageTex < pooled = true; > { Width = 256 ; Height = 256 ; Format = R8; }; +//sampler2D Storage { Texture = StroageTex; }; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Depth_Info(float2 texcoord) +{ + #if BD_Correction || DC + if(BD_Options == 0) + { + float3 K123 = Colors_K1_K2_K3 * 0.1; + texcoord = D(texcoord.xy,K123.x,K123.y,K123.z); + } + #endif + #if DB_Size_Position || SP || LBC || LB_Correction + texcoord.xy += float2(-Image_Position_Adjust.x,Image_Position_Adjust.y)*0.5; + #if LBC || LB_Correction + float2 H_V = Horizontal_and_Vertical * float2(1,LBDetection() ? 1.315 : 1 ); + #else + float2 H_V = Horizontal_and_Vertical; + #endif + float2 midHV = (H_V-1) * float2(BUFFER_WIDTH * 0.5,BUFFER_HEIGHT * 0.5) * pix; + texcoord = float2((texcoord.x*H_V.x)-midHV.x,(texcoord.y*H_V.y)-midHV.y); + #endif + + if (Depth_Map_Flip) + texcoord.y = 1 - texcoord.y; + + //Conversions to linear space..... + float zBuffer = tex2Dlod(ZBuffer, float4(texcoord,0,0)).x, zBufferWH = zBuffer, Far = 1.0, Near = 0.125/(0.00000001+Depth_Map_Adjust), NearWH = 0.125/(0.00000001+(Depth_Map ? NCD.y : 10*NCD.y)), OtherSettings = Depth_Map ? NCD.y : 100 * NCD.y ; //Near & Far Adjustment + //Man Why can't depth buffers Just Be Normal + float2 C = float2( Far / Near, 1.0 - Far / Near ), Z = Offset_Switch() < 0 ? min( 1.0, zBuffer * ( 1.0 + abs(Offset_Switch()) ) ) : float2( zBuffer, 1.0 - zBuffer ), Offsets = float2(1 + OtherSettings,1 - OtherSettings), zB = float2( zBufferWH, 1-zBufferWH ); + + if(Offset_Switch() > 0 || Offset_Switch() < 0) + Z = Offset_Switch() < 0 ? float2( Z.x, 1.0 - Z.y ) : min( 1.0, float2( Z.x * (1.0 + Offset_Switch()) , Z.y / (1.0 - Offset_Switch()) ) ); + + if (NCD.y > 0) + zB = min( 1, float2( zB.x * Offsets.x , zB.y / Offsets.y )); + + if (Depth_Map == 0) + { //DM0 Normal + zBuffer = rcp(Z.x * C.y + C.x); + zBufferWH = Far * NearWH / (Far + zB.x * (NearWH - Far)); + } + else if (Depth_Map == 1) + { //DM1 Reverse + zBuffer = rcp(Z.y * C.y + C.x); + zBufferWH = Far * NearWH / (Far + zB.y * (NearWH - Far)); + } + + return saturate( lerp(NCD.y > 0 ? zBufferWH : zBuffer,zBuffer,0.925) ); +} + +float SUMTexture_lookup(float2 TC, float dx, float dy) +{ float Depth = 1-Depth_Info( TC ); + Depth = (Depth - 0)/ (lerp(1,10,saturate(1-PCGI_2DTexture_Detail.x)) - 0); + float2 uv = (TC.xy + float2(dx , dy ) * pix); + float3 c = tex2Dlod( BackBufferPCGI, float4(uv.xy,0, 0) ).rgb * 0.5; + + // return as luma + return (0.2126*c.r + 0.7152*c.g + 0.0722*c.b) * Depth * 0.00666f; +} + +float3 TextureNormals(float2 UV, float Depth ) +{ + if(saturate(PCGI_2DTexture_Detail.x) > 0) + { + // simple sobel edge detection + float dx = 0.0; + dx += -1.0 * SUMTexture_lookup(UV, -1.5, -1.5); + dx += -2.0 * SUMTexture_lookup(UV, -1.5, 0.0); + dx += -1.0 * SUMTexture_lookup(UV, -1.5, 1.5); + dx += SUMTexture_lookup(UV, 1.5, -1.5); + dx += 2.0 * SUMTexture_lookup(UV, 1.5, 0.0); + dx += SUMTexture_lookup(UV, 1.5, 1.5); + + float dy = 0.0; + dy += -1.0 * SUMTexture_lookup(UV, -1.5, -1.5); + dy += -2.0 * SUMTexture_lookup(UV, 0.0, -1.5); + dy += -1.0 * SUMTexture_lookup(UV, 1.5, -1.5); + dy += SUMTexture_lookup(UV, -1.5, 1.5); + dy += 2.0 * SUMTexture_lookup(UV, 0.0, 1.5); + dy += SUMTexture_lookup(UV, 1.5, 1.5); + + float edge = sqrt(dx*dx + dy*dy); + edge *= edge; + + float angle = atan2(dx,dy); + + float X = edge * sin(angle); //X= -X; + float Y = edge * sin(angle + 7.5 * PI / 3.);// Adjust me to rotate Normals + float Z = edge * (X - Y); + + return min(1,lerp(float3(X,Y,Z) * lerp(1,Depth,PCGI_2DTexture_Detail.y), 0, float3(X,Y,Z) == 0.5) ); + } + else + return 0; + +} +//Improved Normal reconstruction from Depth +float3 DepthNormals(float2 texcoord) +{ + float2 Pix_Offset = pix.xy; + //A 2x2 Taps is done here. You can also do 4x4 tap + float2 uv0 = texcoord; // center + float2 uv1 = texcoord + float2( Pix_Offset.x, 0); // right + float2 uv2 = texcoord + float2(-Pix_Offset.x, 0); // left + float2 uv3 = texcoord + float2( 0, Pix_Offset.y); // down + float2 uv4 = texcoord + float2( 0,-Pix_Offset.y); // up + + float depth = Depth_Info( uv0 ); + + float depthR = Depth_Info( uv1 ); + float depthL = Depth_Info( uv2 ); + float depthD = Depth_Info( uv3 ); + float depthU = Depth_Info( uv4 ); + + float3 P0, P1, P2; + + int best_Z_horizontal = abs(depthR - depth) < abs(depthL - depth) ? 1 : 2; + int best_Z_vertical = abs(depthD - depth) < abs(depthU - depth) ? 3 : 4; + + if (best_Z_horizontal == 1 && best_Z_vertical == 4) + { //triangle 0 = P0: center, P1: right, P2: up + P1 = float3(uv1 - 0.5, 1) * depthR; + P2 = float3(uv4 - 0.5, 1) * depthU; + } + if (best_Z_horizontal == 1 && best_Z_vertical == 3) + { //triangle 1 = P0: center, P1: down, P2: right + P1 = float3(uv3 - 0.5, 1) * depthD; + P2 = float3(uv1 - 0.5, 1) * depthR; + } + if (best_Z_horizontal == 2 && best_Z_vertical == 4) + { //triangle 2 = P0: center, P1: up, P2: left + P1 = float3(uv4 - 0.5, 1) * depthU; + P2 = float3(uv2 - 0.5, 1) * depthL; + } + if (best_Z_horizontal == 2 && best_Z_vertical == 3) + { //triangle 3 = P0: center, P1: left, P2: down + P1 = float3(uv2 - 0.5, 1) * depthL; + P2 = float3(uv3 - 0.5, 1) * depthD; + } + + P0 = float3(uv0 - 0.5, 1) * depth; + //Not the best way to do it be it had to be fast. + float3 Normals_XYZ = cross(P2 - P0, P1 - P0); + + float3 Norm_XYZ = abs(normalize(Normals_XYZ) * 0.5 + 0.5); + + float3 DX = ddx(Norm_XYZ); + float3 DY = ddy(Norm_XYZ); + + float DDX, DDY; + DDX += depthD; + DDX += depthL; + DDX += depth; + + DDY += depth; + DDY += depthR; + DDY += depthU; + + float N_Mask = 1-saturate(distance(DX * DX , DY * DY ) > 0.006), D_Mask = 1-saturate(distance(DDX * DDX , DDY * DDY ) > 0.029); + + return normalize( Normals_XYZ + lerp(0, TextureNormals(texcoord, depth ), saturate(D_Mask + D_Mask) ) ); +} + +float3 UnpackNormals(float2 enc) +{ + float2 fenc = enc*4-2; + float f = dot(fenc,fenc), g = sqrt(1-f/4); + float3 n; + n.xy = fenc*g; + n.z = 1-f/2; + return n; +} + +float4 Normals_Depth(float2 texcoords, float Mips) +{ + float Depth = tex2Dlod(PCGIcurrNormalsDepth,float4(texcoords,0,Mips)).z; + float3 Normals = UnpackNormals(tex2Dlod(PCGIcurrNormalsDepth,float4(texcoords,0,Mips)).xy); + return float4(Normals,Depth); +} + +float DepthMDC(float2 texcoords, float Mips) +{ + return smoothstep(0,1,Normals_Depth(texcoords, Mips).w) > MaxDepth_CutOff; +} +/////////////////////////////////////////////////////Blur Shaders//////////////////////////////////////////////////////////////// +//Unlimited Blur +float2 Vogel2D(int uIndex, int nTaps, float phi) +{ + const float GoldenAngle = PI * (3.0 - sqrt(5.0)); + const float r = sqrt(uIndex + 0.5f) / sqrt(nTaps); + float theta = uIndex * GoldenAngle + phi; + + float2 sc; + sincos(theta, sc.x, sc.y); + return r * sc.yx; +} + +float4 Ublur(sampler2D Tex,in float2 TC,int Mip, float Radius) +{ + const int uTaps = 8;//went from 16 to 8 saves a little + //float uBoard = fmod(dot(pos, 1.0), 2.0); + float2 ps = pix * Radius; + float urand = MCNoise( 1, TC, 1 ) * (PI*2);//nrand(pos * uBoard) * (PI*2); + float4 uImage; + + [fastopt] + for (int i = 0; i < uTaps; i++) + { + float2 ofs = Vogel2D(i, uTaps, urand); + float4 uColor = tex2Dlod(Tex,float4(TC + ofs * ps,0,Mip)).rgba; + uImage = lerp(uImage, uColor, rcp(i + 1)); + } + + return uImage; +} +//Custom Edge Avoiding Gaussian Denoiser +float4 Denoise(sampler Tex, float2 texcoords, int SXY, int Dir , float R ) +{ + float4 StoredNormals_Depth = Normals_Depth( texcoords, 0); + float4 center = tex2D(Tex,texcoords), color = 0.0;//Like why do SmoothNormals when 2nd Level Denoiser is like Got you B#*@!........ + float total = 0.0, NormalBlurFactor = Debug == 1 ? 0.25f : 1.0f, DepthBlurFactor = 0.011f, DM = smoothstep(0,1,StoredNormals_Depth.w) > MaxDepth_CutOff; + R += 1-tex2Dlod( PCGIcurrNormalsDepth,float4(texcoords,0,0)).w ; + #if VRS_MAP + R += useVRS(texcoords, 1); + #endif + if(SXY > 0) // Who would win Raw Boi or Gaussian Boi + { [fastopt] + for (int i = -SXY * 0.5; i <= SXY * 0.5; ++i) + { + float2 D = Dir ? float2( i, 0) : float2( 0, i), TC = texcoords + D * R * pix; + + float4 ModifiedNormals_Depth = Normals_Depth( TC, 2);//Use lower mip level here on finnished product. + float ModN = length(StoredNormals_Depth.xyz - ModifiedNormals_Depth.xyz), ModD = saturate( StoredNormals_Depth.w - ModifiedNormals_Depth.w); + + float D_Dist2 = max(ModD, 0.0), d_w = min(exp(-(D_Dist2)/DepthBlurFactor), 1.0); + float N_Dist2 = max(ModN, 0.0), n_w = min(exp(-(N_Dist2)/NormalBlurFactor), 1.0); + + + float Weight = gaussian(i, sqrt(SXY));//Looks better + Weight *= d_w;// Removed Depth Weighting because it was not really needed. + Weight *= n_w; + color += tex2Dlod(Tex, float4(TC ,0, 0)) * Weight; + total += Weight; + } + } + return SamplesXY > 0 ? lerp(color / total,center,DM) : center; +} +//Diffusion Blur not moved here.... will do this some other time. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +float4 BBColor(float2 texcoords, int Mips) +{ float LL_Comp = 0.5; //Wanted to automate this but it's really not need. + float4 BBC = tex2Dlod(PCGIcurrColor,float4(texcoords,0,Mips)).rgba;//PrepColor(texcoords, 0, Mips); + BBC.rgb = Sky_Emissive_Bool().x ? BBC.rgb : BBC.rgb * ( 1-DepthMDC(texcoords, 0) ); + // BBC.rgb = (BBC.rgb - 0.5) * (LL_Comp + 1.0) + 0.5; + // return BBC + (LL_Comp * 0.5625); + return BBC; +} + +float4 DirectLighting(float2 texcoords , int Mips) +{ float MDC = DepthMDC(texcoords, 0), Sky_Quality = lerp(Mips,SkyMipLeves[min(6,Sky_Adustment)],MDC); + float4 BC = BBColor(texcoords, Sky_Quality); + if(HDR_BP > 0) + BC.rgb = inv_Tonemapper(float4(BC.rgb,1-HDR_BP)); + float GS = Luma(BC.rgb), Boost = 1; + + if(Target_Lighting >= 0) + { + BC.rgb /= GS; + BC.rgb *= saturate(GS - lerp(0.0,0.5,saturate(Target_Lighting))); + } + else + { + BC.rgb /= 1-GS; + BC.rgb *= 1-saturate(GS + lerp(0.0,0.5,saturate(abs(Target_Lighting)))); + } + + Boost = lerp(1.0,2.5,saturate(abs(Target_Lighting))); + + return float4(Saturator_A(BC.rgb * Boost, DepthMDC(texcoords, 0) , Normals_Depth(texcoords, 0).w),BC.a); +} + +float3 GetPosition(float2 texcoord) +{ + float3 DM = -Normals_Depth(texcoord, 0 ).www; + return float3(texcoord.xy*2-1,1.0)*DM; +} float GetPos() { float Postional_Information = T_02() == 25000 ? 0 : 1 ; return Postional_Information;} + +float2 MultiPattern(float2 TC) +{ //const int Images = 6, Levels[Images] = { 0, 1, 2, 3, 4, 5} ; //OrderedMixing = Levels[int(fmod(Grid.x+Grid.y*(Images*0.5),Images))]; + //float2 Grid = floor( TC * float2(BUFFER_WIDTH, BUFFER_HEIGHT ) ); + //float CheckerBoard = fmod(Grid.x+Grid.y,2.0);//, V_Interlaced = fmod(Grid.x,2.0), BayerLike = V_Interlaced ? CheckerBoard ? 0 : 1 : CheckerBoard ? 2 : 3; + float2 Grid = floor( float2(TC.x * BUFFER_WIDTH, TC.y * BUFFER_HEIGHT) ); + return float2(fmod(Grid.x+Grid.y, 2.0),fmod(Grid.x, 2.0)); +} + +float2 Rotate2D_A( float2 r, float l , float2 TC) +{ float Reflective_Diffusion = lerp(saturate(abs(Reflect())),1.0,smoothstep(0,0.25,1-dot(float3(0,1,0) ,Normals_Depth(TC,0).xyz))); + float2 Directions; + sincos(l,Directions[0],Directions[1]);//same as float2(cos(l),sin(l)) + Reflective_Diffusion = Reflect() < 0 ? Reflective_Diffusion : MultiPattern(TC.xy * GI_Res).y ? 1 : Reflective_Diffusion; + return float2( dot( r * Reflective_Diffusion, float2(Directions[1], -Directions[0]) ), dot( r, Directions.xy ) ); +} + +float2 Rotate2D_B( float2 r, float l ) +{ float2 Directions; + sincos(l,Directions[0],Directions[1]);//same as float2(cos(l),sin(l)) + return float2( dot( r, float2(Directions[1], -Directions[0]) ), dot( r, Directions.xy ) ); +} + +float SSSMasking(float2 TC) +{ + float SSSD = lerp(0,1, saturate(1-Normals_Depth(TC, 0 ).w * lerp(1,10,SSS_Seek.x)) ); + return SSSD * smoothstep(0,0.25,1-dot(float3(0,1,0) ,Normals_Depth(TC,0).xyz) * saturate(dot(float3(0,1,0) ,Normals_Depth(TC,0).xyz)) );// || dot(float3(0,1,0) ,NormalsMap(TC,0)) +} +//Form Factor Approximations +float RadianceFF(in float2 texcoord,in float3 ddiff,in float3 normals, in float2 AB,in float STDepth) +{ //So normal and the vector between "Element to Element - Radiance Transfer." + float4 v = float4(normalize(ddiff), length(ddiff)); + float Mnormals = abs(Reflect()) < 1 ? lerp(3,0,saturate(dot(float3(0,1,0),normals))) : 3, Trimming = lerp(1,5000,saturate(Trim)) ; + //Emitter & Recever [With emulated Back-Face lighting.] + float giE_Selection = Sky_Emissive_Bool().y ? dot( 1-v.xyz , 1-Normals_Depth(texcoord+AB, Mnormals ).xyz ) : dot( -v.xyz , Normals_Depth(texcoord+AB, Mnormals ).xyz ); + float2 giE_R = max(float2( step( 0.0, giE_Selection ), dot( v.xyz, normals ) ) ,0); + float FF_Dampen = Sky_Emissive_Bool().y ? PI*20 : PI*10; //Emulated Back-Face lighting Adjustment. + return saturate((100 * giE_R.x * giE_R.y) / ( lerp(Trimming,1,STDepth * Sky_Emissive_Bool().x) * (v.w*v.w) + FF_Dampen) ); +} +/* //This Code is Disabled Not going to use in RadiantGI +float AmbientOcclusionFF(in float2 texcoord,in float3 ddiff,in float3 normals, in float2 AB) +{ //So normal and the vector between "Element to Element - Occlusion." + float4 v = float4(normalize(ddiff), length(ddiff)); + //Emitter & Recever - Clamped Values are used for self Shadowing. + float2 aoE_R = 1.0*float2(1-clamp(dot(-v.xyz,NormalsMap(texcoord+AB,0)),-1,0), saturate(dot( v.xyz, normals ))); + return saturate(aoE_R.x * aoE_R.y * (1.0 - (1*8) / sqrt(1/(v.w*v.w) + PI ))); +} +//This Code is Disabled Not going to use in RadiantGI +float GlossyFF(in float2 texcoord,in float3 ddiff,in float3 normals, in float2 AB, float PassD) +{ //So normal and the vector between "Element to Element - Specular Effect." + float4 v = float4(normalize(ddiff), length(ddiff)); + //Emitter & Recever + float2 E_R = max(float2(dot(-v.xyz,NormalsMap(texcoord+AB,3)), dot( v.xyz, reflect(normalize(float3(texcoord.xy*2-1,2)),normals) )),0.); + //E_R = pow(E_R,Roughness); + float Global_Illumination = saturate(100.0 * E_R.x * E_R.y / ( PI * v.w * v.w + 100.0) ); + return Global_Illumination; +} +*/ +float SubsurfaceScatteringFF(in float2 texcoord,in float3 ddiff,in float3 normals, in float2 AB) +{ //So normal and the vector between "Element to Element - Wrap Lighting." + float4 v = float4(normalize(ddiff), length(ddiff)); + float LW = Wrap; //Emitter & Recever + float2 ssE_R = saturate(float2(max(0, dot(-v.xyz,Normals_Depth(texcoord+AB,0).xyz)), max(0, dot( v.xyz, normals ) + LW) / (1 + LW))); + float Scatter = saturate(100.0 * ssE_R.x * ssE_R.y / ( PI * v.w * v.w + 1.0) ); + return Scatter; +} + +float ThiccnessFF(in float2 texcoord,in float3 ddiff,in float3 normals, in float2 AB) +{ //So normal and the vector between "Element to Element - Thiccness Approximation." + float4 v = float4(normalize(ddiff), length(ddiff)); + //Emitter & Recever + float2 fE_R = float2(1.0 - dot(-Normals_Depth(texcoord+AB, 1).xyz,v.xyz), dot( normals, -v.xyz ) ); //flipped face is needed for generate local thiccness map. + float Thicc = min(1.0,fE_R.x * fE_R.y * (1.0 - 1.0 / sqrt(rcp(v.w*v.w) + PI))); + return Thicc; +} int nonplus() { return T_01() == 0 || T_02() == 0 ? 1 : 0;} + +void PCGI(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, out float4 GlobalIllumination : SV_Target0, out float4 SubsurfaceScattering : SV_Target1) +{ float2 stexcoords = texcoords; + texcoords /= GI_Res; int Samples = lerp(samples,4,1-tex2Dlod( PCGIcurrNormalsDepth,float4(texcoords,0,0)).w ); + #if VRS_MAP + Samples = lerp(Samples,4,useVRS(texcoords, 1)); + #endif + //Global Illumination Ray Length & Depth // * 0.125 + float depth = Normals_Depth( texcoords, 0 ).w, D = depth;// * 0.9992; + float4 Noise = float4( MCNoise( framecount, stexcoords, 1 ), MCNoise( framecount, stexcoords, 2 ), MCNoise( framecount, stexcoords, 3 ), MCNoise( framecount, stexcoords, 4 )); //Smoothing for AO not needed since this shader not going to use AO code above.//for GetPos * 0.990 + float4 random = normalize(Noise.xyzw * 2 - 1), GI, SS, PWH;//!Smooth ? 0 : 9 // sn = lerp(NormalsMap(texcoords,0),lerp(NormalsMap(texcoords,0),NormalsMap(texcoords,9),lerp(1.0,0.5,D)),0.9) + float3 n = Normals_Depth( texcoords,0).xyz, p = GetPosition( texcoords) * 0.990, ddiff, ddiff_tc, ddiff_gi ,ddiff_gd, ddiff_ss, II_gi, II_gd, II_ss; + float4 rl_gi_sss = float4( GIRL().x, GIRL().y, 75,lerp(1,125, Deep_Scattering )); + //CheckerBoard Pattern Grab to save Perf + float CB0 = MultiPattern( stexcoords.xy ).x, CB1 = Scattering ? CB0 || SkinDetection(tex2Dlod(PCGIcurrColor,float4(texcoords,0,2))) : 1; //|| SkinDetection(tex2D(BackBufferPCGI,texcoords)) + //Interlaced Scaling + rl_gi_sss.xy *= MultiPattern(stexcoords.xy).y ? Alternate ? 1.0 : 0.5 : Alternate ? 0.05 : 0.10 ; + float MaskDir = saturate( dot(float3(0,1,0),Normals_Depth(texcoords, 0).xyz) ), Diffusion = lerp(1.0,lerp(Reflectivness.y * 2,1.0,abs(Reflect())), MaskDir ); + rl_gi_sss.xy *= Reflect() < 0 ? Diffusion : MultiPattern(stexcoords.xy).y ? 1 : Diffusion; + //Basic depth rescaling from Near to Far + float D0 = smoothstep(-NCD.x,1, depth ), D1 = smoothstep(-1,1, depth ), D_Fade = PCGI_Fade < 0 ? lerp(1-Scale_PCGI_Fade() * 2,0, 1-D ) : smoothstep(0,2,D / Scale_PCGI_Fade()), MDCutOff = smoothstep(0,1,D) > MaxDepth_CutOff;//smoothstep(0,saturate(GI_Fade),D); + float4 IGN = IGN_Toggle ? Interleaved_Gradient_Noise(stexcoords / pix / 2) * 2 - 1 : random; + //SSS, GI, Gloss, and AO Form Factor code look above + [fastopt] // Dose this even do anything better vs unroll? Compile times seem the same too me. Maybe this will work better if I use the souls I collect of the users that use this shader? + for (int i = 0; i <= Samples; i++) + { + #if DX9 //DX 9 issues...... + if( clock == 0 || texcoords.x > 1.0 || texcoords.y > 1.0 ) + discard; + #else //VRS and Max Depth Exclusion...... every ms counts......... + if( MDCutOff || clock == 0 || texcoords.x > 1.0 || texcoords.y > 1.0 ) + break; + #endif + //Evenly distributed points on Poisson Disk.... But, with High Frequency noise. + float2 GIWH = (pix * rl_gi_sss[0]) * IGN[0] * Rotate2D_A( PoissonTaps[i], random[3], texcoords) / D0, + //GDWH = (pix * rl_gi_sss[1]) * IGN[1] * Rotate2D_B( PoissonTaps[i], random[2]) / D0, + SSWH = (pix * rl_gi_sss[2]) * IGN[2] * Rotate2D_B( PoissonTaps[i], random[1]) / D1, + TCWH = (pix * rl_gi_sss[3]) * IGN[3] * Rotate2D_B( PoissonTaps[i], random[0]) / D1; + //Recever to Emitter vector + ddiff_tc = GetPosition( texcoords + TCWH) - p; + //Thiccness Form Factor + if(!CB1) + SS.w += lerp(0,ThiccnessFF(texcoords, ddiff_tc, n, TCWH), SSSMasking( texcoords )); + + if(CB0) + { + //Recever to Emitter vector + ddiff_gi = GetPosition( texcoords + GIWH) - p; + //Irradiance Information + II_gi = DirectLighting( texcoords + GIWH, 3 ).rgb * 1.125; + //Radiance Form Factor + GI.rgb += lerp(II_gi, 0, D_Fade) * RadianceFF(texcoords, ddiff_gi, n, GIWH, smoothstep(1,0,D)); + } + + if(!CB1) + { //Recever to Emitter vector + ddiff_ss = GetPosition( texcoords + SSWH) - p; + //Irradiance Information + II_ss = BBColor( texcoords + SSWH, 3).rgb; + //SubsurfaceScattering Form Factor + //lerp( 0,lerp(II_ss, 0, N_F), SSSMasking( texcoords)) + SS.rgb += lerp( 0,lerp(II_ss, 0, D_Fade), SSSMasking( texcoords)) * SubsurfaceScatteringFF( texcoords, ddiff_ss, n, SSWH); + } + } + float Samp = rcp(Samples); + GI *= Samp; SS *= Samp; + + GlobalIllumination = float4( min( 1.0 , GI.rgb ) , GI.w); + SubsurfaceScattering = min( 1.0 , float4(SS.rgb, SS.w * 2.0)); +} + +float4 GI_Adjusted(float2 TC, int Mip) +{ + float4 ConvertGI = tex2Dlod( PCGI_Info, float4( TC , 0, Mip)) , ConvertSS = tex2Dlod( PCSS_Info, float4( TC , 0, Mip)); + + ConvertGI.xyz = RGBtoYCbCr(ConvertGI.xyz); + ConvertGI.x *= 0.75;//GI_LumaPower.x; + ConvertGI.xyz = Saturator_C(YCbCrtoRGB( ConvertGI.xyz)); + + float DTMip = lerp(3,5,dot(BBColor(TC / GI_Res, 6.0).rgb,0.333)),DT = BBColor(TC / GI_Res, DTMip ).w * 2.0, SSL = 1;//clamp(dot(BBColor(TC / GI_Res, 2.0).rgb,0.333) * lerp(1.0,4.0,User_SSS_Luma),1,2); + float3 SSS = InternalFleshColor(ConvertSS.xyz * SSL, ConvertSS.w , lerp(0,lerp(0,10,Luma_Map),saturate(Internals.xyz)), DT ); + + ConvertGI.xyz = MultiPattern( TC ).x ? ConvertGI.xyz * min( GI_Power.x, 5.0) : Saturator_B(SSS) ; + + return float4( ConvertGI.xyz , 0) ; +} + +void CBReconstruction(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, out float4 UpGI : SV_Target0) +{ int MipLevel = 0; + float4 tl = GI_Adjusted(texcoords,MipLevel); + float4 tr = GI_Adjusted(texcoords + float2( pix.x, 0.0 ),MipLevel); + float4 bl = GI_Adjusted(texcoords + float2( 0.0 , pix.y),MipLevel); + float4 br = GI_Adjusted(texcoords + float2( pix.x, pix.y),MipLevel); + + float2 f = frac( texcoords * float2(BUFFER_WIDTH, BUFFER_HEIGHT ) ); + + float4 tA = lerp( tl, tr, f.x ); + float4 tB = lerp( bl, br, f.x ); + + UpGI = lerp( tA, tB, f.y ) * 1.25;//GI_Adjusted(texcoords,0); +} + +float3 GI(float2 TC, float Mips) +{ + #line 4 "For the latest version go https://blueskydefender.github.io/AstrayFX/ or http://www.Depth3D.info " + #warning " T A M P E R E D " + float3 GI_Out = tex2Dlod( PCGIReconstruction_Info, float4( TC * GI_Res , 0, Mips)).xyz ; + return GetPos() ? GI_Out * TC.xyx : GI_Out; +} float Helper() { float Temp_Location = T_01() == 12500 ? 0 : 1 ; return Temp_Location;} + +float4 GI_TAA(float4 vpos : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ //Depth Similarity + float M_Similarity = 0.5, D_Similarity = saturate(pow(abs(tex2D(PCGIpastFrame,texcoords).x/Normals_Depth(texcoords, 0).w), 10) + M_Similarity); + //Velocity Scaler + //float S_Velocity = 12.5 * lerp( 1, 80,TAA_Clamping), V_Buffer = saturate(abs(DepthMap(texcoords, 0)-tex2D(PCGIpastFrame,texcoords).w )* S_Velocity); + //Accumulation buffer Start + //Resolution Scale & GI_Power + float ReSRes = Scale(GI_Res,1.0,0.5), power = GI_Power >= 1 ? Scale(GI_Power,1.0,2.5) : 1, Res_Scale = lerp(1.0,0.0,ReSRes); + float3 GISamples, CurrAOGI = GI( texcoords, Debug == 1 ? 0 : Res_Scale).rgb, MB = 0; + float3 minColor = CurrAOGI - MB; + float3 maxColor = CurrAOGI + MB; + [unroll] + for(int i = 0; i < 8; ++i) + { + float2 Offset = XYoffset[i] * 4;//Use this on color image first. + GISamples = GI( texcoords + Offset , Res_Scale ).rgb; + minColor = min( minColor, GISamples) - MB; + maxColor = max( maxColor, GISamples) + MB; + } + //Insert your motion buffer here...... Also leaving this here so when ReShade or a cleaver Dev can make his own. + //float2 Motion_Buffer = tex2D(OpticalFlow::sMotion5, texcoords).xy / float2(BUFFER_WIDTH, BUFFER_HEIGHT); + + float2 PastTexcoords = texcoords;// + Motion_Buffer; + // this is done with a ACC Buffer in reshade. But, you may want to create your own PastFrames + //Min Max neighbourhood clamping. + float3 Past = clamp( tex2Dlod( PCGIaccuFrames, float4(PastTexcoords, 0, 0) ).rgb, minColor, maxColor); + //float mixRate = min( tex2Dlod( PCGIaccuFrames, float4(texcoords, 0, 0) ).w, 0.5); + + // Simple AB clamping used for mixing + //float2 A = PastTexcoords > 1., B = PastTexcoords < 0.; + //TAA Mixing for real motion buffer....... + // float Mixing = any(float2(any(A), any(B))) ? 1 : 0; + + //float diff = length(antialiased - preclamping) * 4;//Alternet way of doing it + //Added Velocity Clamping....... + float3 clampAmount = abs(Past - CurrAOGI); //V_Buffer;//For AO But,I Droped this and use MixRate; + clampAmount.x = saturate(dot(clampAmount, clampAmount)); + + float Mixing = saturate(lerp( lerp(0.02,0.2,ReSRes) , lerp(0.2,0.5, power ) , clampAmount.x));// Use mixRate or AB Clamping for Mixing..... + //Simple Blending + float3 AA = lerp(Past, CurrAOGI, Mixing ); + //Sample from Accumulation buffer, with mix rate clamping. + AA = lerp( 0 , AA, D_Similarity); + return float4( AA, 1.0) ; +} + +void AccumulatedFramesGI(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, out float4 acc : SV_Target) +{ + acc = tex2D(BackBufferPCGI,texcoords).rgba; +} +//Horizontal Denoising Upscaling +float4 BGU_Hoz(float4 position : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + return float4( Denoise( PCGIaccuFrames , texcoords, EvenSteven[clamp(SamplesXY,0,20)], 0, 2.5 ).rgb, 0); +} +//Vertical Denoising Upscaling +float4 BGU_Ver(float4 position : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + return float4( Denoise( PCGI_BGUHorizontal_Sample, texcoords, EvenSteven[clamp(SamplesXY,0,20)], 1, 2.5).rgb, 0); +} + +float3 ControlledBlend(float3 Color, float3 Cloud) +{ + float3 FiftyGray = Cloud + 0.490; + #if Controlled_Blend + return add( lerp( overlay( Color, FiftyGray), softlight( Color, FiftyGray),Blend),Cloud * 0.1875); + #else + return add( lerp( overlay( Color, FiftyGray), softlight( Color, FiftyGray), 0.5 ),Cloud * 0.1875); + #endif +} + +float3 Composite(float3 Color, float3 Cloud) +{ + float3 FiftyGray = Cloud + 0.490; + //Left for Rework + //FiftyGray = Shadows(FiftyGray); + + if(Blend == 0) + return ControlledBlend( Color, Cloud); + else if(Blend == 1) + return overlay( Color, FiftyGray); + else if(Blend == 2) + return softlight( Color, FiftyGray); + else + return add( Color, Cloud ); +} + +float3 Mix(float2 texcoords) +{ + return Composite(tex2Dlod(PCGIcurrColor,float4(texcoords,0,0)).rgb , tex2Dlod(PCGI_BGUVertical_Sample,float4(texcoords,0,0)).rgb) ; +} float Text_Info_Plus() { return nonplus() ? Alternate : Text_Info; } +//Diffusion Blur - Man....... Talk about strange.... +float3 DiffusionBlur(float2 texcoords) +{ + float3 Layer,total; + float ML = SSSMasking(texcoords).x, + SD = 1-SkinDetection(tex2Dlod(PCGIcurrColor,float4(texcoords,0,2)) ), + NormalBlurFactor = 1.0f, + DepthBlurFactor = 0.009f; + + float4 StoredNormals_Depth = Normals_Depth( texcoords, 0); + + if(SD && Scattering && ML && Diffusion_Saturation_Power.x > 0 ) + { + [loop] + for(int i = 0; i < 7; ++i) + { + if(i > 7 || smoothstep( 0, 1, DepthMDC(texcoords, 0))) + break; + + float2 offsetxy = texcoords + float2( DBoffsets[i], 0) * pix * lerp( 0.0, 2.0,saturate(Diffusion_Saturation_Power.x)); + float3 CMix = Mix( offsetxy ).rgb; + + float4 ModifiedNormals_Depth = Normals_Depth( offsetxy, 2);//Use lower mip level here on finnished product. + float ModN = length(StoredNormals_Depth.xyz - ModifiedNormals_Depth.xyz), ModD = saturate( StoredNormals_Depth.w - ModifiedNormals_Depth.w); + + float D_Dist2 = max(ModD, 0.0), d_w = min(exp(-(D_Dist2)/DepthBlurFactor), 1.0); + float N_Dist2 = max(ModN, 0.0), n_w = min(exp(-(N_Dist2)/NormalBlurFactor), 1.0); + + + float3 Weight = DBweight[i]; + Weight *= d_w; + Weight *= n_w; + Layer += CMix * Weight; + total += Weight; + } + return Layer / total; + } + else + return Mix(texcoords).rgb; +} + +#define DScale -1 +float D_Scale(float Input) +{ + return (Input-DScale)/(1-DScale); +} + +float4 MixOut(float2 texcoords) +{ + //float2 Grid = floor( texcoords * float2(BUFFER_WIDTH, BUFFER_HEIGHT ) * pix * 125);//125 lines + float Depth = D_Scale(Normals_Depth(texcoords,0).w), AO_Scale = 0.5,FakeAO = Debug == 1 ? ( + Normals_Depth(texcoords ,1).w + + Normals_Depth(texcoords ,2).w + + Normals_Depth(texcoords ,3).w + + Normals_Depth(texcoords ,4).w + + Normals_Depth(texcoords ,5).w + + Normals_Depth(texcoords ,6).w + + Normals_Depth(texcoords ,7).w + + Normals_Depth(texcoords ,8).w + + Normals_Depth(texcoords ,9).w + + Normals_Depth(texcoords ,10).w + ) * 0.1: 0.00000001; + FakeAO = (1-Depth/D_Scale(FakeAO) * AO_Scale ) * (1+AO_Scale); + + float Guide = Depth_Guide ? ( Depth + + Normals_Depth(texcoords + float2( pix.x * 2.5, 0), 1 ).w + + Normals_Depth(texcoords + float2(-pix.x * 2.5, 0), 2 ).w + + Normals_Depth(texcoords + float2( 0, pix.y * 2.5), 3 ).w + + Normals_Depth(texcoords + float2( 0,-pix.y * 2.5), 4 ).w ) * 0.2 : 0.00000001; + + float3 Output = tex2D( PCGI_BGUVertical_Sample, texcoords).rgb, Layer = DiffusionBlur( texcoords ); float4 Done = float4(Layer,0.5); + + if(Debug == 0) + Done.rgb = Depth_Guide ? Layer.rgb * float3((Depth/Guide> 0.998),1,(Depth/Guide > 0.998)) : Layer.rgb; + else if(Debug == 1)//(1-Depth/FakeAO * 0.75) ; + Done.rgb = lerp(lerp(smoothstep(0.5,1,(Output * 0.5) + FakeAO),1,smoothstep(0,1,Depth) == 1),Output,Dark_Mode); //This fake AO is a lie.......... + else if(Debug == 2) + Done.rgb = DirectLighting( texcoords, 0).rgb; + else + Done.rgb = texcoords.x + texcoords.y < 1 ? Normals_Depth(texcoords, 0 ).w : Normals_Depth(texcoords,0).xyz * 0.5 + 0.5; + + return Done; +} +////////////////////////////////////////////////////////////////Overwatch//////////////////////////////////////////////////////////////////////////// +float Text_Switch() { return RH || NC || NP || NF || PE || DS || OS || DA || NW || FV ? 0 : 1; } +static const float CH_A = float(0x69f99), CH_B = float(0x79797), CH_C = float(0xe111e), + CH_D = float(0x79997), CH_E = float(0xf171f), CH_F = float(0xf1711), + CH_G = float(0xe1d96), CH_H = float(0x99f99), CH_I = float(0xf444f), + CH_J = float(0x88996), CH_K = float(0x95159), CH_L = float(0x1111f), + CH_M = float(0x9fd99), CH_N = float(0x9bd99), CH_O = float(0x69996), + CH_P = float(0x79971), CH_Q = float(0x69b5a), CH_R = float(0x79759), + CH_S = float(0xe1687), CH_T = float(0xf4444), CH_U = float(0x99996), + CH_V = float(0x999a4), CH_W = float(0x999f9), CH_X = float(0x99699), + CH_Y = float(0x99e8e), CH_Z = float(0xf843f), CH_0 = float(0x6bd96), + CH_1 = float(0x46444), CH_2 = float(0x6942f), CH_3 = float(0x69496), + CH_4 = float(0x99f88), CH_5 = float(0xf1687), CH_6 = float(0x61796), + CH_7 = float(0xf8421), CH_8 = float(0x69696), CH_9 = float(0x69e84), + CH_APST = float(0x66400), CH_PI = float(0x0faa9), CH_UNDS = float(0x0000f), + CH_HYPH = float(0x00600), CH_TILD = float(0x0a500), CH_PLUS = float(0x02720), + CH_EQUL = float(0x0f0f0), CH_SLSH = float(0x08421), CH_EXCL = float(0x33303), + CH_QUES = float(0x69404), CH_COMM = float(0x00032), CH_FSTP = float(0x00002), + CH_QUOT = float(0x55000), CH_BLNK = float(0x00000), CH_COLN = float(0x00202), + CH_LPAR = float(0x42224), CH_RPAR = float(0x24442); +#define MAP_SIZE float2(4,5) +//returns the status of a bit in a bitmap. This is done value-wise, so the exact representation of the float doesn't really matter. +float getBit( float map, float index ) +{ // Ooh -index takes out that divide :) + return fmod( floor( map * exp2(-index) ), 2.0 ); +} float DT_Information(){ float DT_Text = Text_Switch() ? T_02() : T_01(); return clock <= DT_Text; } + +float drawChar( float Char, float2 pos, float2 size, float2 TC ) +{ // Subtract our position from the current TC so that we can know if we're inside the bounding box or not. + TC -= pos; + // Divide the screen space by the size, so our bounding box is 1x1. + TC /= size; + // Create a place to store the result & Branchless bounding box check. + float res = step(0.0,min( TC.x, TC.y)) - step(1.0,max( TC.x, TC.y)); + // Go ahead and multiply the TC by the bitmap size so we can work in bitmap space coordinates. + TC *= MAP_SIZE; + // Get the appropriate bit and return it. + res*=getBit( Char, 4.0 * floor( TC.y) + floor( TC.x) ); + return saturate( res); +} + +float4 Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float2 TC = float2(texcoord.x,1-texcoord.y); + float Gradient = (1-texcoord.y*50.0+48.85)*texcoord.y-0.500, BT = smoothstep(0,1,sin(clock*(3.75/1000))), Size = 1.1, Depth3D, Read_Help, Supported, SetFoV, FoV, Post, Effect, NoPro, NotCom, Mod, Needs, Net, Over, Set, AA, Emu, Not, No, Help, Fix, Need, State, SetAA, SetWP, Work; + float4 Color = MixOut(texcoord); + + [branch] if(DT_Information() || Text_Info_Plus()) + { // Set a general character size... + float2 charSize = float2(.00875, .0125) * Size; + // Starting position. + float2 charPos = float2( 0.009, 0.9725); + //Needs Copy Depth and/or Depth Selection + Needs += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_Y, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Needs += drawChar( CH_N, charPos, charSize, TC); + //Network Play May Need Modded DLL + charPos = float2( 0.009, 0.955); + Work += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_W, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_K, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_Y, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_Y, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Work += drawChar( CH_L, charPos, charSize, TC); + //Disable CA/MB/Dof/Grain + charPos = float2( 0.009, 0.9375); + Effect += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_B, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_B, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_G, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + Effect += drawChar( CH_N, charPos, charSize, TC); + //Disable TAA/MSAA/AA + charPos = float2( 0.009, 0.920); + SetAA += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_B, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + SetAA += drawChar( CH_A, charPos, charSize, TC); + //Set FoV + charPos = float2( 0.009, 0.9025); + SetFoV += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + SetFoV += drawChar( CH_V, charPos, charSize, TC); + //Read Help + charPos = float2( 0.894, 0.9725); + Read_Help += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + Read_Help += drawChar( CH_P, charPos, charSize, TC); + //New Start + charPos = float2( 0.009, 0.018); + // No Profile + NoPro += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + NoPro += drawChar( CH_E, charPos, charSize, TC); charPos.x = 0.009; + //Not Compatible + NotCom += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_P, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_B, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_L, charPos, charSize, TC); charPos.x += .01 * Size; + NotCom += drawChar( CH_E, charPos, charSize, TC); charPos.x = 0.009; + //Needs Fix/Mod + Mod += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_D, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_X, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_SLSH, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + Mod += drawChar( CH_D, charPos, charSize, TC); charPos.x = 0.009; + //Overwatch.fxh Missing + State += drawChar( CH_O, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_V, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_E, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_R, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_W, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_A, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_T, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_C, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_FSTP, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_F, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_X, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_H, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_BLNK, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_M, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_S, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_I, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_N, charPos, charSize, TC); charPos.x += .01 * Size; + State += drawChar( CH_G, charPos, charSize, TC); + //New Size + float D3D_Size_A = 1.375,D3D_Size_B = 0.75; + float2 charSize_A = float2(.00875, .0125) * D3D_Size_A, charSize_B = float2(.00875, .0125) * D3D_Size_B; + //New Start Pos + charPos = float2( 0.862, 0.018); + //Depth3D.Info Logo/Website + Depth3D += drawChar( CH_D, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_E, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_P, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_T, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_H, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_3, charPos, charSize_A, TC); charPos.x += .01 * D3D_Size_A; + Depth3D += drawChar( CH_D, charPos, charSize_A, TC); charPos.x += 0.008 * D3D_Size_A; + Depth3D += drawChar( CH_FSTP, charPos, charSize_A, TC); charPos.x += 0.01 * D3D_Size_A; + charPos = float2( 0.963, 0.018); + Depth3D += drawChar( CH_I, charPos, charSize_B, TC); charPos.x += .01 * D3D_Size_B; + Depth3D += drawChar( CH_N, charPos, charSize_B, TC); charPos.x += .01 * D3D_Size_B; + Depth3D += drawChar( CH_F, charPos, charSize_B, TC); charPos.x += .01 * D3D_Size_B; + Depth3D += drawChar( CH_O, charPos, charSize_B, TC); + //Text Information + if(DS) + Need = Needs; + if(RH) + Help = Read_Help; + if(NW) + Net = Work; + if(PE) + Post = Effect; + if(DA) + AA = SetAA; + if(FV) + FoV = SetFoV; + //Blinking Text Warnings + if(NP) + No = NoPro * BT; + if(NC) + Not = NotCom * BT; + if(NF) + Fix = Mod * BT; + if(OS) + Over = State * BT; + //Website + return Depth3D+(Disable_Debug_Info ? 0 : Help+Post+No+Not+Net+Fix+Need+Over+AA+Set+FoV+Emu) ? Minimize_Web_Info ? lerp(Gradient + Depth3D,Color,saturate(Depth3D*0.98)) : Gradient : Color; + } + else + return Helper() ? 0 : Color; +} + +float4 BackBufferCG(float2 texcoords) +{ float4 C = tex2D(BackBufferPCGI,texcoords); + float GS = dot(C.rgb,0.333); + return float4(C.rgb,GS); +} + +float2 PackNormals(float3 n) +{ + float f = rsqrt(8*n.z+8); + return n.xy * f + 0.5; +} + +void CurrentFrame(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, out float4 Color : SV_Target0, out float4 NormalsDepth : SV_Target1) +{ + float4 BBCG = BackBufferCG(texcoords); + float DI = Depth_Info(texcoords), LRBLM = saturate( dot( Ublur( PCGIcurrColor, texcoords, 5, 100) ,0.333) ); + Color = float4(BBCG.rgb,max(0.0, BBCG.w - lerp(0,1,saturate(Luma_Map))));//,0, smoothstep(0,1,DI) > MaxDepth_CutOff ) ; + //Packed Normals / Depth / Large Radius Blured Luma Mask + NormalsDepth = float4(PackNormals(DepthNormals(texcoords)),DI,LRBLM); +} + +void PreviousFrame(float4 vpos : SV_Position, float2 texcoords : TEXCOORD, out float4 prev : SV_Target) +{ //float PD = dot(tex2D(PCGI_BGUVertical_Sample ,texcoords).rgb,0.333); + prev = Normals_Depth(texcoords, 0).w;//float4(0,0,0,Normals_Depth(texcoords, 0).w); +} +/* // Saved for Next Release +float4 GI_Storage(float4 position : SV_Position, float2 texcoords : TEXCOORD) : SV_Target +{ + return (tex2D(BackBufferPCGI,0.5).w * 255) == 127 ? 1.0 : 0; +} +*/ +//////////////////////////////////////////////////////////Reshade.fxh///////////////////////////////////////////////////////////// +// 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) +{ + 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*// +#if Simp_Mode +technique PCGI_One +< togglectrl = true; toggle = 0x2E; ui_label = "RadiantGI"; +ui_tooltip = "RadiantGI: Point Cloud Global Illumination."; > +#else +technique PCGI_One +< togglectrl = true; toggle = 0x2E; ui_label = "PCGI¹"; +ui_tooltip = "Alpha: Global Illumination Primary Generator.¹"; > +#endif +{ + pass PastFrame + { + VertexShader = PostProcessVS; + PixelShader = PreviousFrame; + RenderTarget = PCGIpastTex; + } + pass CopyFrame + { + VertexShader = PostProcessVS; + PixelShader = CurrentFrame; + RenderTarget0 = PCGIcurrColorTex; + RenderTarget1 = PCGIcurrNormalsDepthTex; + } + pass SSGI + { + VertexShader = PostProcessVS; + PixelShader = PCGI; + RenderTarget0 = RadiantGITex; + RenderTarget1 = RadiantSSTex; + } + pass Reconstruction + { + VertexShader = PostProcessVS; + PixelShader = CBReconstruction; + RenderTarget = PCGIReconstructionTex; + } + pass TAA + { + VertexShader = PostProcessVS; + PixelShader = GI_TAA; + } + pass AccumilateFrames + { + VertexShader = PostProcessVS; + PixelShader = AccumulatedFramesGI; + RenderTarget = PCGIaccuTex; + } +#if Simp_Mode +// Simple Mode +#else +} + +technique PCGI_Two +< togglectrl = true; toggle = 0x2E; ui_label = "PCGI²"; +ui_tooltip = "Beta: Global Illumination Secondary Output.²"; > +{ + +#endif + pass Edge_Avoiding_Denoiser_H + { + VertexShader = PostProcessVS; + PixelShader = BGU_Hoz; + RenderTarget = PCGIHorizontalTex; + } + pass Edge_Avoiding_Denoiser_V + { + VertexShader = PostProcessVS; + PixelShader = BGU_Ver; + RenderTarget = PCGIVerticalTex; + } + pass Done + { + VertexShader = PostProcessVS; + PixelShader = Out; + } + /* // Saved for next release + pass GIStorage + { + VertexShader = PostProcessVS; + PixelShader = GI_Storage; + //RenderTarget = GI_StoredTex; + } + */ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Update Notes +// +// Update 1.2 +// This update did change a few things here and there like PCGI_Alpha and PCGI_Beta are now PCGI_One and PCGI_Two. +// Error Code edited so it does not show the warning anymore. But, it's still shows the shader name as yellow.¯\_('_')_/¯ +// This version has a small perf loss. Also removed some extra code that was not mine. Forgot to replace it my bad..... +// TAA now gives The JBGU shader motion information to blur in motion so there is less noise in motion. :) +// +// Update 2.0 +// So reworked the Joint Bilateral Gaussian Upscaling for sharper Debug and fewer artifacts in motion. Now I am using a plain +// old box blur it seems to run faster and look sharper at masking high frequency noise. Also reworked how to sample the GI. +// Radiant Global Illumination now uses a proper Poisson Disk Sampling. This kind of sampling should improve the accuracy of GI displayed. +// Shader motion information removed for now to get this out by the deadline around Xmas time. Some Defaults and max setting were changed. +// Subsurface Scattering AKA Subsurface Light Transport Added. This feature is heavy. But, should be doable to find/look for Flesh in an image. +// Once found it will try to add SSS with Diffusion Blur to give skin that soft look to it. This was a lot harder than expected............... +// It Just works well most of the time...... Just issues come up with some games with earthy tones. I will allow an option to apply SSS to everything later. +// I was also able to do thickness estimation this lets things like ears and other thin/dangly parts to allow Deep Tissue Scattering. So Deep..... +// So all in all this was capable of being done. The Thickness estimation may cause issues on White objects that trigger the Skin Detection so be warned. +// This shader not done. But, it is close. +// +// Update 2.1 +// Small changes to help guide the user a bit more with SSLT. +// +// Update 2.2 +// More Pooled Texture issues. Black screen is shown when Pooling some textures. Issue now is that this shader uses around 605.0 MiB at 4k...... +// Need to talk to the main man about this. When time allows. +// +// Update 2.3 +// Added a way to control the Subsurface Scattering Brightness. +// +// Update 2.4 +// Added a way to control Diffusion profile for added Reflectivness. Notices a bad bug with TAA not working in some game I need to find out why. +// +// Update 2.5 +// Changed the way I am doing my 2nd Denoiser. Also reworked the Saturation system and the HDR extraction. +// Targeted lighting works as intended now. Indirect and Direct world color sampling. +// RadiantGI now has a pure GI mode that runs 2x times as slow but, gives 2x times more control. +// This mode disables SSLT. So keep that in mind. +// +// Update 2.6 +// Added a way to force pooling off for 4.9.0+ and small perf boost. +// +// Update 2.7 +// +// Improved Normal smoothing on my 2nd Denoiser and looser setting on my TAA solution should get most of the noise in motion. +// Tested an Edge-Avoiding À-Trous Wavelet Transform Denoiser that was "Fast." But, My own solution was faster and got rid of more noise. +// All I can say is that I learned a lot about 2nd level Denoisers. I think I will be ready to may my own AO shader now. +// For now enjoy this update. +// +// TLDR: Better Normal smoothing and noise removal in motion. +// +// Update 2.8 +// +// I targeted Diffusion to work on the floors only. Because having it affect everything was not correct to me. I also Made the Debug View a bit cleaner. +// With The cleaner Debug you will see more detail. But, It will not cause the final output to show normal edges even if you see them in the Debug View. +// I also made the De-Noiser go up to 20 now so........ Ya...... At any rate it better now!!!!! +// +// Update 2.9 +// +// So Small Performance Boost over old way by taking in to account Depth Fade. Also, some other code adjustments and moved the Update Notes section down to the +// bottom of the shader. Now I am using a extra Buffer for SSS and allow for RadiantGI Internal Resolution to be changed in UI so no more need to go into the +// PreProcessors to-do it. Fixed the Blue hue Bug in SSLT should more accurately portray skin color. Cleaned up the Noise a bit better this time around so that +// nothing short of reworking my TAA will help now. Sill would not mind help on that BTW. +// +// Sub-Update 2.9.1 +// +// Bug fix Low light issue. Shader will no longer generate rays in low light situations. Rays went Burrrrrrrrrrrrr too much needed and to cap it. +// Ya,too much Burrrrrrr. +// +// Sub-Update 2.9.2 +// +// Light Source Map was added a Debug mode for Targeted Lighting. This is so you can see what is getting used as lighting information. +// Change use Transmission from ReVeil to default to "False" also changed Default End toggle = 0x23 from to Delete toggle = 0x2E For the next version of ReShade +// +// Sub-Update 2.9.3 +// +// Targeted Lighting now allows for Direct Lighting and Indirect Lighitng calibrations. +// +// Sub-Update 2.9.4 +// +// Fixed a small issue with the shader. Swizzle me this......... +// +// Sub-Update 2.9.5 +// +// Default Key Change for debug menu from F11 to the Menu Key......... +// +// Update 2.9.6 +// +// Rewrote my TAA implementation so if there is a update for ReShade that can give us real motion buffer It can be easy addition to the current TAA. +// +// Update 2.9.7 +// +// So Made every thing a little faster. But, also changed many default setting and added correct staturation control.I also changed the way denoise works with the image. +// Added support for Lord of Lunacy VRS "Variable Rate Shading." VRS works better the more samples you use.Sadly VRS auto lower res areas don't work due to the newly added +// checkerboard reconstruction.This Preping it rework for next release. Removed Pure GI mode since it complicated things.Added Sky Color Contribution. Lets the sky scatter +// on to the world based on Direction. I do hope this update make things better to use. I also tried to make SSS easier by automating luminace clipping. +// +// For the next release I will be reworking the Denoiser / TAA 100% Thank you Robloxian AKA Clown Comp AKA Brimsion on GitHubs on the interwebs. +// +// Update 2.9.7 +// +// Mini Update Adjusting the Denoiser so it gives a sharper image out.Thank you Lord of Lunacy. +// +// Update 2.9.8 +// +// Perf update based on a blured Luma Map. This uses lower samples in areas that are darker. Temporal Mask was also added to TAA. It replace the old Mixing system. +// This was done too reduce the noise in the final image. I also made it sample from Lower MipLeves when lowering Resolution. This seems to reduce noise overall. +// I also adjusted the color system and the Luma Power options too automaticly increase the TAA accumulation. This seems to be at the veary limit of what +// my TAA filter can do. I got to admit my 2nd Level Denoiser needs work. But, for now I leave it be. A option was added to adjust for distance irradiance. +// +// Update 2.9.9 +// +// Perf update Texture format change and removed render target. Also added simple mode for new users as an default setting. This change comes after seeing new users struggle +// too use my shader for the first time. I also changed the tag PCGI_One and PCGI_Two too PCGI¹ and PCGI². Also in simple mode the tag is changed too RadiantGI. I do hope +// that this change helps users with lower end hardware as well. Shout out to lelfarian moral support and Gordinho for being there I think. +// +// Update 3.0.0 +// +// Emissive Mode added! It lets the shader make all objects emissive based on approximated information from the emitter's luminace information. This adjusted Form Factor can +// be used to allow emissive light mirror what on the opposite side. Simple and effective option for older games. Also added back Trimming that was removed back in an later update. +// The two options do effect Directional Sky Color. But, mitagations where added to help prevent this. +// +// Update 3.0.2 +// +// DX 9 workaround................ it works.... I think. +// +// Update 3.0.3 +// +// DX 9 Sky fixed: No More Ghosts +// Added Interleaved Gradient Noise as default on option. Gives the GI a smoother look when denoising. Because of this I lowered default Defnoise power to 6... +// Also added an Experimental Texture Details option. +// Now even your crevices can have GI................ +// +// Update 3.0.4 +// +// Simplified RadiantGI setting and recategorized many of them to make the shader easier to use. This update also makes Enhanced Texture Details a standard for this shader. +// Supplemental contributions has the extra setting needed for enhanced features. +// Moved Resolution scaling to the Extra Options area. +// +// Update 3.0.5 +// +// Simplified RadiantGI setting even more and tried to make the lighting more accurate. I removed luma power and left normal power there since was almost the same thing. +// +// Update 3.0.6 +// +// Made the sampling radius change every other frame to grab a larger sample base. So that the TAA can blend them and provide a more accurate / better GI output. +// It been fun learning on this shader. I do hope you enjoy this update. +// +// Update 3.0.7 +// +// Simple HDR adjustment. Made sure it works with HDR output. PCGI Fade now works the same as GloomAO. Since I need the shaders to have parity. +// +// Update 3.0.8 +// +// Set the default for Trim to off and adjusted a few things. Changed the UI a little bit to make it easier on new users. +// +// Update 3.0.9 +// +// To be honest, this update was made under duress. I was not ready to make this update, nor did I want to do it so soon. I was not asked to do this; it was demanded of me. I had intended to +// wait for a proper update for this shader, addressing all my own users requests. I apologize if I got your hopes up by making promises about the next update. This update is not a happy one, +// and if it brings you joy, I must express my disapproval. I know your going justify it to yourself and cope. But, in the grand scheme of things, this issue was minor, and it boggles the mind +// that a few people hyper-focused on it. All of It is rather petty. Despite demands to remove the key, I have only added a modifier. Until a proper solution is devised, I'll refrain from updates. +// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/data_from_portwine/Reshade/Shaders/ReShade.fxh b/data_from_portwine/Reshade/Shaders/ReShade.fxh new file mode 100644 index 00000000..bb734819 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/ReShade.fxh @@ -0,0 +1,118 @@ +/* + * SPDX-License-Identifier: CC0-1.0 + */ + +#pragma once + +#if !defined(__RESHADE__) || __RESHADE__ < 30000 + #error "ReShade 3.0+ is required to use this header file" +#endif + +#ifndef RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN + #define RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 0 +#endif +#ifndef RESHADE_DEPTH_INPUT_IS_REVERSED + #define RESHADE_DEPTH_INPUT_IS_REVERSED 1 +#endif +#ifndef RESHADE_DEPTH_INPUT_IS_LOGARITHMIC + #define RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 0 +#endif + +#ifndef RESHADE_DEPTH_MULTIPLIER + #define RESHADE_DEPTH_MULTIPLIER 1 +#endif +#ifndef RESHADE_DEPTH_LINEARIZATION_FAR_PLANE + #define RESHADE_DEPTH_LINEARIZATION_FAR_PLANE 1000.0 +#endif + +// Above 1 expands coordinates, below 1 contracts and 1 is equal to no scaling on any axis +#ifndef RESHADE_DEPTH_INPUT_Y_SCALE + #define RESHADE_DEPTH_INPUT_Y_SCALE 1 +#endif +#ifndef RESHADE_DEPTH_INPUT_X_SCALE + #define RESHADE_DEPTH_INPUT_X_SCALE 1 +#endif +// An offset to add to the Y coordinate, (+) = move up, (-) = move down +#ifndef RESHADE_DEPTH_INPUT_Y_OFFSET + #define RESHADE_DEPTH_INPUT_Y_OFFSET 0 +#endif +#ifndef RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET + #define RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET 0 +#endif +// An offset to add to the X coordinate, (+) = move right, (-) = move left +#ifndef RESHADE_DEPTH_INPUT_X_OFFSET + #define RESHADE_DEPTH_INPUT_X_OFFSET 0 +#endif +#ifndef RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET + #define RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET 0 +#endif + +#define BUFFER_PIXEL_SIZE float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +#define BUFFER_SCREEN_SIZE float2(BUFFER_WIDTH, BUFFER_HEIGHT) +#define BUFFER_ASPECT_RATIO (BUFFER_WIDTH * BUFFER_RCP_HEIGHT) + +namespace ReShade +{ +#if defined(__RESHADE_FXC__) + float GetAspectRatio() { return BUFFER_WIDTH * BUFFER_RCP_HEIGHT; } + float2 GetPixelSize() { return float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); } + float2 GetScreenSize() { return float2(BUFFER_WIDTH, BUFFER_HEIGHT); } + #define AspectRatio GetAspectRatio() + #define PixelSize GetPixelSize() + #define ScreenSize GetScreenSize() +#else + // These are deprecated and will be removed eventually. + static const float AspectRatio = BUFFER_WIDTH * BUFFER_RCP_HEIGHT; + static const float2 PixelSize = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); + static const float2 ScreenSize = float2(BUFFER_WIDTH, BUFFER_HEIGHT); +#endif + + // Global textures and samplers + texture BackBufferTex : COLOR; + texture DepthBufferTex : DEPTH; + + sampler BackBuffer { Texture = BackBufferTex; }; + sampler DepthBuffer { Texture = DepthBufferTex; }; + + // Helper functions + float GetLinearizedDepth(float2 texcoord) + { +#if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN + texcoord.y = 1.0 - texcoord.y; +#endif + texcoord.x /= RESHADE_DEPTH_INPUT_X_SCALE; + texcoord.y /= RESHADE_DEPTH_INPUT_Y_SCALE; +#if RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET + texcoord.x -= RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET * BUFFER_RCP_WIDTH; +#else // Do not check RESHADE_DEPTH_INPUT_X_OFFSET, since it may be a decimal number, which the preprocessor cannot handle + texcoord.x -= RESHADE_DEPTH_INPUT_X_OFFSET / 2.000000001; +#endif +#if RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET + texcoord.y += RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET * BUFFER_RCP_HEIGHT; +#else + texcoord.y += RESHADE_DEPTH_INPUT_Y_OFFSET / 2.000000001; +#endif + float depth = tex2Dlod(DepthBuffer, float4(texcoord, 0, 0)).x * RESHADE_DEPTH_MULTIPLIER; + +#if RESHADE_DEPTH_INPUT_IS_LOGARITHMIC + const float C = 0.01; + depth = (exp(depth * log(C + 1.0)) - 1.0) / C; +#endif +#if RESHADE_DEPTH_INPUT_IS_REVERSED + depth = 1.0 - depth; +#endif + const float N = 1.0; + depth /= RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - depth * (RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - N); + + return depth; + } +} + +// Vertex shader generating a triangle covering the entire screen +// See also https://www.reddit.com/r/gamedev/comments/2j17wk/a_slightly_faster_bufferless_vertex_shader_trick/ +void PostProcessVS(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD) +{ + 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); +} diff --git a/data_from_portwine/Reshade/Shaders/ReShadeUI.fxh b/data_from_portwine/Reshade/Shaders/ReShadeUI.fxh new file mode 100644 index 00000000..6f3a4118 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/ReShadeUI.fxh @@ -0,0 +1,216 @@ +#pragma once + +#if !defined(__RESHADE__) || __RESHADE__ < 30000 +#error "ReShade 3.0+ is required to use this header file" +#endif + +#define RESHADE_VERSION(major,minor,build) (10000 * (major) + 100 * (minor) + (build)) +#define SUPPORTED_VERSION(major,minor,build) (__RESHADE__ >= RESHADE_VERSION(major,minor,build)) + +// Since 3.0.0 +// Commit current in-game user interface status +// https://github.com/crosire/reshade/commit/302bacc49ae394faedc2e29a296c1cebf6da6bb2#diff-82cf230afdb2a0d5174111e6f17548a5R1183 +// Added various GUI related uniform variable annotations +// https://reshade.me/forum/releases/2341-3-0 +#define __UNIFORM_INPUT_ANY ui_type = "input"; + +#define __UNIFORM_INPUT_BOOL1 __UNIFORM_INPUT_ANY // It is unsupported on all version +#define __UNIFORM_INPUT_BOOL2 __UNIFORM_INPUT_ANY // It is unsupported on all version +#define __UNIFORM_INPUT_BOOL3 __UNIFORM_INPUT_ANY // It is unsupported on all version +#define __UNIFORM_INPUT_BOOL4 __UNIFORM_INPUT_ANY // It is unsupported on all version +#define __UNIFORM_INPUT_INT1 __UNIFORM_INPUT_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_INPUT_INT2 __UNIFORM_INPUT_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_INPUT_INT3 __UNIFORM_INPUT_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_INPUT_INT4 __UNIFORM_INPUT_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_INPUT_FLOAT1 __UNIFORM_INPUT_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_INPUT_FLOAT2 __UNIFORM_INPUT_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_INPUT_FLOAT3 __UNIFORM_INPUT_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_INPUT_FLOAT4 __UNIFORM_INPUT_ANY // If it was not supported in someday or now, please add information + +// Since 4.0.1 +// Change slider widget to be used with new "slider" instead of a "drag" type annotation +// https://github.com/crosire/reshade/commit/746229f31cd6f311a3e72a543e4f1f23faa23f11#diff-59405a313bd8cbfb0ca6dd633230e504R1701 +// Changed slider widget to be used with < ui_type = "slider"; > instead of < ui_type = "drag"; > +// https://reshade.me/forum/releases/4772-4-0 +#if SUPPORTED_VERSION(4,0,1) +#define __UNIFORM_DRAG_ANY ui_type = "drag"; + +// Since 4.0.0 +// Rework statistics tab and add drag widgets back +// https://github.com/crosire/reshade/commit/1b2c38795f00efd66c007da1f483f1441b230309 +// Changed drag widget to a slider widget (old one is still available via < ui_type = "drag2"; >) +// https://reshade.me/forum/releases/4772-4-0 +#elif SUPPORTED_VERSION(4,0,0) +#define __UNIFORM_DRAG_ANY ui_type = "drag2"; + +// Since 3.0.0 +// Commit current in-game user interface status +// https://github.com/crosire/reshade/commit/302bacc49ae394faedc2e29a296c1cebf6da6bb2#diff-82cf230afdb2a0d5174111e6f17548a5R1187 +// Added various GUI related uniform variable annotations +// https://reshade.me/forum/releases/2341-3-0 +#else +#define __UNIFORM_DRAG_ANY ui_type = "drag"; +#endif + +#define __UNIFORM_DRAG_BOOL1 __UNIFORM_DRAG_ANY // It is unsupported on all version +#define __UNIFORM_DRAG_BOOL2 __UNIFORM_DRAG_ANY // It is unsupported on all version +#define __UNIFORM_DRAG_BOOL3 __UNIFORM_DRAG_ANY // It is unsupported on all version +#define __UNIFORM_DRAG_BOOL4 __UNIFORM_DRAG_ANY // It is unsupported on all version +#define __UNIFORM_DRAG_INT1 __UNIFORM_DRAG_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_DRAG_INT2 __UNIFORM_DRAG_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_DRAG_INT3 __UNIFORM_DRAG_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_DRAG_INT4 __UNIFORM_DRAG_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_DRAG_FLOAT1 __UNIFORM_DRAG_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_DRAG_FLOAT2 __UNIFORM_DRAG_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_DRAG_FLOAT3 __UNIFORM_DRAG_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_DRAG_FLOAT4 __UNIFORM_DRAG_ANY // If it was not supported in someday or now, please add information + +// Since 4.0.1 +// Change slider widget to be used with new "slider" instead of a "drag" type annotation +// https://github.com/crosire/reshade/commit/746229f31cd6f311a3e72a543e4f1f23faa23f11#diff-59405a313bd8cbfb0ca6dd633230e504R1699 +// Changed slider widget to be used with < ui_type = "slider"; > instead of < ui_type = "drag"; > +// https://reshade.me/forum/releases/4772-4-0 +#if SUPPORTED_VERSION(4,0,1) +#define __UNIFORM_SLIDER_ANY ui_type = "slider"; + +// Since 4.0.0 +// Rework statistics tab and add drag widgets back +// https://github.com/crosire/reshade/commit/1b2c38795f00efd66c007da1f483f1441b230309 +// Changed drag widget to a slider widget (old one is still available via < ui_type = "drag2"; >) +// https://reshade.me/forum/releases/4772-4-0 +#elif SUPPORTED_VERSION(4,0,0) +#define __UNIFORM_SLIDER_ANY ui_type = "drag"; +#else +#define __UNIFORM_SLIDER_ANY __UNIFORM_DRAG_ANY +#endif + +#define __UNIFORM_SLIDER_BOOL1 __UNIFORM_SLIDER_ANY // It is unsupported on all version +#define __UNIFORM_SLIDER_BOOL2 __UNIFORM_SLIDER_ANY // It is unsupported on all version +#define __UNIFORM_SLIDER_BOOL3 __UNIFORM_SLIDER_ANY // It is unsupported on all version +#define __UNIFORM_SLIDER_BOOL4 __UNIFORM_SLIDER_ANY // It is unsupported on all version +#define __UNIFORM_SLIDER_INT1 __UNIFORM_SLIDER_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_SLIDER_INT2 __UNIFORM_SLIDER_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_SLIDER_INT3 __UNIFORM_SLIDER_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_SLIDER_INT4 __UNIFORM_SLIDER_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_SLIDER_FLOAT1 __UNIFORM_SLIDER_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_SLIDER_FLOAT2 __UNIFORM_SLIDER_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_SLIDER_FLOAT3 __UNIFORM_SLIDER_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_SLIDER_FLOAT4 __UNIFORM_SLIDER_ANY // If it was not supported in someday or now, please add information + +// Since 3.0.0 +// Add combo box display type for uniform variables and fix displaying of integer variable under Direct3D 9 +// https://github.com/crosire/reshade/commit/b025bfae5f7343509ec0cacf6df0cff537c499f2#diff-82cf230afdb2a0d5174111e6f17548a5R1631 +// Added various GUI related uniform variable annotations +// https://reshade.me/forum/releases/2341-3-0 +#define __UNIFORM_COMBO_ANY ui_type = "combo"; + +// __UNIFORM_COMBO_BOOL1 +#define __UNIFORM_COMBO_BOOL2 __UNIFORM_COMBO_ANY // It is unsupported on all version +#define __UNIFORM_COMBO_BOOL3 __UNIFORM_COMBO_ANY // It is unsupported on all version +#define __UNIFORM_COMBO_BOOL4 __UNIFORM_COMBO_ANY // It is unsupported on all version +#define __UNIFORM_COMBO_INT1 __UNIFORM_COMBO_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_COMBO_INT2 __UNIFORM_COMBO_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_COMBO_INT3 __UNIFORM_COMBO_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_COMBO_INT4 __UNIFORM_COMBO_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_COMBO_FLOAT1 __UNIFORM_COMBO_ANY // It is unsupported on all version +#define __UNIFORM_COMBO_FLOAT2 __UNIFORM_COMBO_ANY // It is unsupported on all version +#define __UNIFORM_COMBO_FLOAT3 __UNIFORM_COMBO_ANY // It is unsupported on all version +#define __UNIFORM_COMBO_FLOAT4 __UNIFORM_COMBO_ANY // It is unsupported on all version + +// Since 4.0.0 (but the ui_items force set "Off\0On\0"), and if less than it force converted to checkbox +// Add option to display boolean values as combo box instead of checkbox +// https://github.com/crosire/reshade/commit/aecb757c864c9679e77edd6f85a1521c49e489c1#diff-59405a313bd8cbfb0ca6dd633230e504R1147 +// https://github.com/crosire/reshade/blob/v4.0.0/source/gui.cpp +// Added option to display boolean values as combo box instead of checkbox (via < ui_type = "combo"; >) +// https://reshade.me/forum/releases/4772-4-0 +#define __UNIFORM_COMBO_BOOL1 __UNIFORM_COMBO_ANY + +// Since 4.0.0 +// Cleanup GUI code and rearrange some widgets +// https://github.com/crosire/reshade/commit/6751f7bd50ea7c0556cf0670f10a4b4ba912ee7d#diff-59405a313bd8cbfb0ca6dd633230e504R1711 +// Added radio button widget (via < ui_type = "radio"; ui_items = "Button 1\0Button 2\0...\0"; >) +// https://reshade.me/forum/releases/4772-4-0 +#if SUPPORTED_VERSION(4,0,0) +#define __UNIFORM_RADIO_ANY ui_type = "radio"; +#else +#define __UNIFORM_RADIO_ANY __UNIFORM_COMBO_ANY +#endif + +#define __UNIFORM_RADIO_BOOL1 __UNIFORM_RADIO_ANY // It is unsupported on all version +#define __UNIFORM_RADIO_BOOL2 __UNIFORM_RADIO_ANY // It is unsupported on all version +#define __UNIFORM_RADIO_BOOL3 __UNIFORM_RADIO_ANY // It is unsupported on all version +#define __UNIFORM_RADIO_BOOL4 __UNIFORM_RADIO_ANY // It is unsupported on all version +#define __UNIFORM_RADIO_INT1 __UNIFORM_RADIO_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_RADIO_INT2 __UNIFORM_RADIO_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_RADIO_INT3 __UNIFORM_RADIO_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_RADIO_INT4 __UNIFORM_RADIO_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_RADIO_FLOAT1 __UNIFORM_RADIO_ANY // It is unsupported on all version +#define __UNIFORM_RADIO_FLOAT2 __UNIFORM_RADIO_ANY // It is unsupported on all version +#define __UNIFORM_RADIO_FLOAT3 __UNIFORM_RADIO_ANY // It is unsupported on all version +#define __UNIFORM_RADIO_FLOAT4 __UNIFORM_RADIO_ANY // It is unsupported on all version + +// Since 4.1.0 +// Fix floating point uniforms with unknown "ui_type" not showing up in UI +// https://github.com/crosire/reshade/commit/50e5bf44dfc84bc4220c2b9f19d5f50c7a0fda66#diff-59405a313bd8cbfb0ca6dd633230e504R1788 +// Fixed floating point uniforms with unknown "ui_type" not showing up in UI +// https://reshade.me/forum/releases/5021-4-1 +#define __UNIFORM_COLOR_ANY ui_type = "color"; + +// Since 3.0.0 +// Move technique list to preset configuration file +// https://github.com/crosire/reshade/blob/84bba3aa934c1ebe4c6419b69dfe1690d9ab9d34/source/runtime.cpp#L1328 +// Added various GUI related uniform variable annotations +// https://reshade.me/forum/releases/2341-3-0 + +// If empty, these versions before 4.1.0 are decide that the type is color from the number of components + +#define __UNIFORM_COLOR_BOOL1 __UNIFORM_COLOR_ANY // It is unsupported on all version +#define __UNIFORM_COLOR_BOOL2 __UNIFORM_COLOR_ANY // It is unsupported on all version +#define __UNIFORM_COLOR_BOOL3 __UNIFORM_COLOR_ANY // It is unsupported on all version +#define __UNIFORM_COLOR_BOOL4 __UNIFORM_COLOR_ANY // It is unsupported on all version +#define __UNIFORM_COLOR_INT1 __UNIFORM_COLOR_ANY // It is unsupported on all version +#define __UNIFORM_COLOR_INT2 __UNIFORM_COLOR_ANY // It is unsupported on all version +#define __UNIFORM_COLOR_INT3 __UNIFORM_COLOR_ANY // It is unsupported on all version +#define __UNIFORM_COLOR_INT4 __UNIFORM_COLOR_ANY // It is unsupported on all version +// __UNIFORM_COLOR_FLOAT1 +#define __UNIFORM_COLOR_FLOAT2 __UNIFORM_COLOR_ANY // It is unsupported on all version +#define __UNIFORM_COLOR_FLOAT3 __UNIFORM_COLOR_ANY // If it was not supported in someday or now, please add information +#define __UNIFORM_COLOR_FLOAT4 __UNIFORM_COLOR_ANY // If it was not supported in someday or now, please add information + +// Since 4.2.0 +// Add alpha slider widget for single component uniform variables (#86) +// https://github.com/crosire/reshade/commit/87a740a8e3c4dcda1dd4eeec8d5cff7fa35fe829#diff-59405a313bd8cbfb0ca6dd633230e504R1820 +// Added alpha slider widget for single component uniform variables +// https://reshade.me/forum/releases/5150-4-2 +#if SUPPORTED_VERSION(4,2,0) +#define __UNIFORM_COLOR_FLOAT1 __UNIFORM_COLOR_ANY +#else +#define __UNIFORM_COLOR_FLOAT1 __UNIFORM_SLIDER_ANY +#endif + +// Since 4.3.0 +// Add new "list" GUI widget (#103) +// https://github.com/crosire/reshade/commit/515287d20ce615c19cf3d4c21b49f83896f04ddc#diff-59405a313bd8cbfb0ca6dd633230e504R1894 +// Added new "list" GUI widget +// https://reshade.me/forum/releases/5417-4-3 +#if SUPPORTED_VERSION(4,3,0) +#define __UNIFORM_LIST_ANY ui_type = "list"; +#else +#define __UNIFORM_LIST_ANY __UNIFORM_COMBO_ANY +#endif + +// __UNIFORM_LIST_BOOL1 +#define __UNIFORM_LIST_BOOL2 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_BOOL3 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_BOOL4 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_INT1 __UNIFORM_LIST_ANY // Supported in 4.3.0 +#define __UNIFORM_LIST_INT2 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_INT3 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_INT4 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_FLOAT1 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_FLOAT2 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_FLOAT3 __UNIFORM_LIST_ANY // Not supported in all versions +#define __UNIFORM_LIST_FLOAT4 __UNIFORM_LIST_ANY // Not supported in all versions + +// For compatible with ComboBox +#define __UNIFORM_LIST_BOOL1 __UNIFORM_COMBO_ANY diff --git a/data_from_portwine/Reshade/Shaders/SMAA.fx b/data_from_portwine/Reshade/Shaders/SMAA.fx new file mode 100644 index 00000000..59f460d1 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/SMAA.fx @@ -0,0 +1,325 @@ +/** + * _______ ___ ___ ___ ___ + * / || \/ | / \ / \ + * | (---- | \ / | / ^ \ / ^ \ + * \ \ | |\/| | / /_\ \ / /_\ \ + * ----) | | | | | / _____ \ / _____ \ + * |_______/ |__| |__| /__/ \__\ /__/ \__\ + * + * E N H A N C E D + * S U B P I X E L M O R P H O L O G I C A L A N T I A L I A S I N G + * + * for ReShade 3.0+ + */ + +//------------------- Preprocessor Settings ------------------- + +#if !defined(SMAA_PRESET_LOW) && !defined(SMAA_PRESET_MEDIUM) && !defined(SMAA_PRESET_HIGH) && !defined(SMAA_PRESET_ULTRA) +#define SMAA_PRESET_CUSTOM // Do not use a quality preset by default +#endif + +//----------------------- UI Variables ------------------------ + +#include "ReShadeUI.fxh" + +uniform int EdgeDetectionType < __UNIFORM_COMBO_INT1 + ui_items = "Luminance edge detection\0Color edge detection\0Depth edge detection\0"; + ui_label = "Edge Detection Type"; +> = 1; + +#ifdef SMAA_PRESET_CUSTOM +uniform float EdgeDetectionThreshold < __UNIFORM_DRAG_FLOAT1 + ui_min = 0.05; ui_max = 0.20; ui_step = 0.001; + ui_tooltip = "Edge detection threshold. If SMAA misses some edges try lowering this slightly."; + ui_label = "Edge Detection Threshold"; +> = 0.10; + +uniform float DepthEdgeDetectionThreshold < __UNIFORM_DRAG_FLOAT1 + ui_min = 0.001; ui_max = 0.10; ui_step = 0.001; + ui_tooltip = "Depth Edge detection threshold. If SMAA misses some edges try lowering this slightly."; + ui_label = "Depth Edge Detection Threshold"; +> = 0.01; + +uniform int MaxSearchSteps < __UNIFORM_SLIDER_INT1 + ui_min = 0; ui_max = 112; + ui_label = "Max Search Steps"; + ui_tooltip = "Determines the radius SMAA will search for aliased edges."; +> = 32; + +uniform int MaxSearchStepsDiagonal < __UNIFORM_SLIDER_INT1 + ui_min = 0; ui_max = 20; + ui_label = "Max Search Steps Diagonal"; + ui_tooltip = "Determines the radius SMAA will search for diagonal aliased edges"; +> = 16; + +uniform int CornerRounding < __UNIFORM_SLIDER_INT1 + ui_min = 0; ui_max = 100; + ui_label = "Corner Rounding"; + ui_tooltip = "Determines the percent of anti-aliasing to apply to corners."; +> = 25; + +uniform bool PredicationEnabled < __UNIFORM_INPUT_BOOL1 + ui_label = "Enable Predicated Thresholding"; +> = false; + +uniform float PredicationThreshold < __UNIFORM_DRAG_FLOAT1 + ui_min = 0.005; ui_max = 1.00; ui_step = 0.01; + ui_tooltip = "Threshold to be used in the additional predication buffer."; + ui_label = "Predication Threshold"; +> = 0.01; + +uniform float PredicationScale < __UNIFORM_SLIDER_FLOAT1 + ui_min = 1; ui_max = 8; + ui_tooltip = "How much to scale the global threshold used for luma or color edge."; + ui_label = "Predication Scale"; +> = 2.0; + +uniform float PredicationStrength < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0; ui_max = 4; + ui_tooltip = "How much to locally decrease the threshold."; + ui_label = "Predication Strength"; +> = 0.4; +#endif + +uniform int DebugOutput < __UNIFORM_COMBO_INT1 + ui_items = "None\0View edges\0View weights\0"; + ui_label = "Debug Output"; +> = false; + +#ifdef SMAA_PRESET_CUSTOM + #define SMAA_PREDICATION PredicationEnabled + #define SMAA_THRESHOLD EdgeDetectionThreshold + #define SMAA_DEPTH_THRESHOLD DepthEdgeDetectionThreshold + #define SMAA_MAX_SEARCH_STEPS MaxSearchSteps + #define SMAA_MAX_SEARCH_STEPS_DIAG MaxSearchStepsDiagonal + #define SMAA_CORNER_ROUNDING CornerRounding + #define SMAA_PREDICATION_THRESHOLD PredicationThreshold + #define SMAA_PREDICATION_SCALE PredicationScale + #define SMAA_PREDICATION_STRENGTH PredicationStrength +#endif + +#define SMAA_RT_METRICS float4(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT, BUFFER_WIDTH, BUFFER_HEIGHT) +#define SMAA_CUSTOM_SL 1 + +#define SMAATexture2D(tex) sampler tex +#define SMAATexturePass2D(tex) tex +#define SMAASampleLevelZero(tex, coord) tex2Dlod(tex, float4(coord, coord)) +#define SMAASampleLevelZeroPoint(tex, coord) SMAASampleLevelZero(tex, coord) +#define SMAASampleLevelZeroOffset(tex, coord, offset) tex2Dlodoffset(tex, float4(coord, coord), offset) +#define SMAASample(tex, coord) tex2D(tex, coord) +#define SMAASamplePoint(tex, coord) SMAASample(tex, coord) +#define SMAASampleOffset(tex, coord, offset) tex2Doffset(tex, coord, offset) +#define SMAA_BRANCH [branch] +#define SMAA_FLATTEN [flatten] + +#if (__RENDERER__ == 0xb000 || __RENDERER__ == 0xb100) + #define SMAAGather(tex, coord) tex2Dgather(tex, coord, 0) +#endif + +#include "SMAA.fxh" +#include "ReShade.fxh" + +// Textures + +texture depthTex < pooled = true; > +{ + Width = BUFFER_WIDTH; + Height = BUFFER_HEIGHT; + Format = R16F; +}; + +texture edgesTex < pooled = true; > +{ + Width = BUFFER_WIDTH; + Height = BUFFER_HEIGHT; + Format = RG8; +}; +texture blendTex < pooled = true; > +{ + Width = BUFFER_WIDTH; + Height = BUFFER_HEIGHT; + Format = RGBA8; +}; + +texture areaTex < source = "AreaTex.png"; > +{ + Width = 160; + Height = 560; + Format = RG8; +}; +texture searchTex < source = "SearchTex.png"; > +{ + Width = 64; + Height = 16; + Format = R8; +}; + +// Samplers + +sampler depthLinearSampler +{ + Texture = depthTex; +}; + +sampler colorGammaSampler +{ + Texture = ReShade::BackBufferTex; + AddressU = Clamp; AddressV = Clamp; + MipFilter = Point; MinFilter = Linear; MagFilter = Linear; + SRGBTexture = false; +}; +sampler colorLinearSampler +{ + Texture = ReShade::BackBufferTex; + AddressU = Clamp; AddressV = Clamp; + MipFilter = Point; MinFilter = Linear; MagFilter = Linear; + SRGBTexture = true; +}; +sampler edgesSampler +{ + Texture = edgesTex; + AddressU = Clamp; AddressV = Clamp; + MipFilter = Linear; MinFilter = Linear; MagFilter = Linear; + SRGBTexture = false; +}; +sampler blendSampler +{ + Texture = blendTex; + AddressU = Clamp; AddressV = Clamp; + MipFilter = Linear; MinFilter = Linear; MagFilter = Linear; + SRGBTexture = false; +}; +sampler areaSampler +{ + Texture = areaTex; + AddressU = Clamp; AddressV = Clamp; AddressW = Clamp; + MipFilter = Linear; MinFilter = Linear; MagFilter = Linear; + SRGBTexture = false; +}; +sampler searchSampler +{ + Texture = searchTex; + AddressU = Clamp; AddressV = Clamp; AddressW = Clamp; + MipFilter = Point; MinFilter = Point; MagFilter = Point; + SRGBTexture = false; +}; + +// Vertex shaders + +void SMAAEdgeDetectionWrapVS( + in uint id : SV_VertexID, + out float4 position : SV_Position, + out float2 texcoord : TEXCOORD0, + out float4 offset[3] : TEXCOORD1) +{ + PostProcessVS(id, position, texcoord); + SMAAEdgeDetectionVS(texcoord, offset); +} +void SMAABlendingWeightCalculationWrapVS( + in uint id : SV_VertexID, + out float4 position : SV_Position, + out float2 texcoord : TEXCOORD0, + out float2 pixcoord : TEXCOORD1, + out float4 offset[3] : TEXCOORD2) +{ + PostProcessVS(id, position, texcoord); + SMAABlendingWeightCalculationVS(texcoord, pixcoord, offset); +} +void SMAANeighborhoodBlendingWrapVS( + in uint id : SV_VertexID, + out float4 position : SV_Position, + out float2 texcoord : TEXCOORD0, + out float4 offset : TEXCOORD1) +{ + PostProcessVS(id, position, texcoord); + SMAANeighborhoodBlendingVS(texcoord, offset); +} + +// Pixel shaders + +float SMAADepthLinearizationPS( + float4 position : SV_Position, + float2 texcoord : TEXCOORD) : SV_Target +{ + return ReShade::GetLinearizedDepth(texcoord); +} + +float2 SMAAEdgeDetectionWrapPS( + float4 position : SV_Position, + float2 texcoord : TEXCOORD0, + float4 offset[3] : TEXCOORD1) : SV_Target +{ + if (EdgeDetectionType == 0 && SMAA_PREDICATION == true) + return SMAALumaEdgePredicationDetectionPS(texcoord, offset, colorGammaSampler, depthLinearSampler); + else if (EdgeDetectionType == 0) + return SMAALumaEdgeDetectionPS(texcoord, offset, colorGammaSampler); + + if (EdgeDetectionType == 2) + return SMAADepthEdgeDetectionPS(texcoord, offset, depthLinearSampler); + + if (SMAA_PREDICATION) + return SMAAColorEdgePredicationDetectionPS(texcoord, offset, colorGammaSampler, depthLinearSampler); + else + return SMAAColorEdgeDetectionPS(texcoord, offset, colorGammaSampler); +} +float4 SMAABlendingWeightCalculationWrapPS( + float4 position : SV_Position, + float2 texcoord : TEXCOORD0, + float2 pixcoord : TEXCOORD1, + float4 offset[3] : TEXCOORD2) : SV_Target +{ + return SMAABlendingWeightCalculationPS(texcoord, pixcoord, offset, edgesSampler, areaSampler, searchSampler, 0.0); +} + +float3 SMAANeighborhoodBlendingWrapPS( + float4 position : SV_Position, + float2 texcoord : TEXCOORD0, + float4 offset : TEXCOORD1) : SV_Target +{ + if (DebugOutput == 1) + return tex2D(edgesSampler, texcoord).rgb; + if (DebugOutput == 2) + return tex2D(blendSampler, texcoord).rgb; + + return SMAANeighborhoodBlendingPS(texcoord, offset, colorLinearSampler, blendSampler).rgb; +} + +// Rendering passes + +technique SMAA +{ + pass LinearizeDepthPass + { + VertexShader = PostProcessVS; + PixelShader = SMAADepthLinearizationPS; + RenderTarget = depthTex; + } + pass EdgeDetectionPass + { + VertexShader = SMAAEdgeDetectionWrapVS; + PixelShader = SMAAEdgeDetectionWrapPS; + RenderTarget = edgesTex; + ClearRenderTargets = true; + StencilEnable = true; + StencilPass = REPLACE; + StencilRef = 1; + } + pass BlendWeightCalculationPass + { + VertexShader = SMAABlendingWeightCalculationWrapVS; + PixelShader = SMAABlendingWeightCalculationWrapPS; + RenderTarget = blendTex; + ClearRenderTargets = true; + StencilEnable = true; + StencilPass = KEEP; + StencilFunc = EQUAL; + StencilRef = 1; + } + pass NeighborhoodBlendingPass + { + VertexShader = SMAANeighborhoodBlendingWrapVS; + PixelShader = SMAANeighborhoodBlendingWrapPS; + StencilEnable = false; + SRGBWriteEnable = true; + } +} diff --git a/data_from_portwine/Reshade/Shaders/SMAA.fxh b/data_from_portwine/Reshade/Shaders/SMAA.fxh new file mode 100644 index 00000000..0b449780 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/SMAA.fxh @@ -0,0 +1,1452 @@ +/** + * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) + * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) + * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) + * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to + * do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. As clarification, there + * is no requirement that the copyright notice and permission be included in + * binary distributions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +/** + * _______ ___ ___ ___ ___ + * / || \/ | / \ / \ + * | (---- | \ / | / ^ \ / ^ \ + * \ \ | |\/| | / /_\ \ / /_\ \ + * ----) | | | | | / _____ \ / _____ \ + * |_______/ |__| |__| /__/ \__\ /__/ \__\ + * + * E N H A N C E D + * S U B P I X E L M O R P H O L O G I C A L A N T I A L I A S I N G + * + * http://www.iryoku.com/smaa/ + * + * Hi, welcome aboard! + * + * Here you'll find instructions to get the shader up and running as fast as + * possible. + * + * IMPORTANTE NOTICE: when updating, remember to update both this file and the + * precomputed textures! They may change from version to version. + * + * The shader has three passes, chained together as follows: + * + * |input|------------------+ + * v | + * [ SMAA*EdgeDetection ] | + * v | + * |edgesTex| | + * v | + * [ SMAABlendingWeightCalculation ] | + * v | + * |blendTex| | + * v | + * [ SMAANeighborhoodBlending ] <------+ + * v + * |output| + * + * Note that each [pass] has its own vertex and pixel shader. Remember to use + * oversized triangles instead of quads to avoid overshading along the + * diagonal. + * + * You've three edge detection methods to choose from: luma, color or depth. + * They represent different quality/performance and anti-aliasing/sharpness + * tradeoffs, so our recommendation is for you to choose the one that best + * suits your particular scenario: + * + * - Depth edge detection is usually the fastest but it may miss some edges. + * + * - Luma edge detection is usually more expensive than depth edge detection, + * but catches visible edges that depth edge detection can miss. + * + * - Color edge detection is usually the most expensive one but catches + * chroma-only edges. + * + * For quickstarters: just use luma edge detection. + * + * The general advice is to not rush the integration process and ensure each + * step is done correctly (don't try to integrate SMAA T2x with predicated edge + * detection from the start!). Ok then, let's go! + * + * 1. The first step is to create two RGBA temporal render targets for holding + * |edgesTex| and |blendTex|. + * + * In DX10 or DX11, you can use a RG render target for the edges texture. + * In the case of NVIDIA GPUs, using RG render targets seems to actually be + * slower. + * + * On the Xbox 360, you can use the same render target for resolving both + * |edgesTex| and |blendTex|, as they aren't needed simultaneously. + * + * 2. Both temporal render targets |edgesTex| and |blendTex| must be cleared + * each frame. Do not forget to clear the alpha channel! + * + * 3. The next step is loading the two supporting precalculated textures, + * 'areaTex' and 'searchTex'. You'll find them in the 'Textures' folder as + * C++ headers, and also as regular DDS files. They'll be needed for the + * 'SMAABlendingWeightCalculation' pass. + * + * If you use the C++ headers, be sure to load them in the format specified + * inside of them. + * + * You can also compress 'areaTex' and 'searchTex' using BC5 and BC4 + * respectively, if you have that option in your content processor pipeline. + * When compressing then, you get a non-perceptible quality decrease, and a + * marginal performance increase. + * + * 4. All samplers must be set to linear filtering and clamp. + * + * After you get the technique working, remember that 64-bit inputs have + * half-rate linear filtering on GCN. + * + * If SMAA is applied to 64-bit color buffers, switching to point filtering + * when accesing them will increase the performance. Search for + * 'SMAASamplePoint' to see which textures may benefit from point + * filtering, and where (which is basically the color input in the edge + * detection and resolve passes). + * + * 5. All texture reads and buffer writes must be non-sRGB, with the exception + * of the input read and the output write in + * 'SMAANeighborhoodBlending' (and only in this pass!). If sRGB reads in + * this last pass are not possible, the technique will work anyway, but + * will perform antialiasing in gamma space. + * + * IMPORTANT: for best results the input read for the color/luma edge + * detection should *NOT* be sRGB. + * + * 6. Before including SMAA.h you'll have to setup the render target metrics, + * the target and any optional configuration defines. Optionally you can + * use a preset. + * + * You have the following targets available: + * SMAA_HLSL_3 + * SMAA_HLSL_4 + * SMAA_HLSL_4_1 + * SMAA_GLSL_3 * + * SMAA_GLSL_4 * + * + * * (See SMAA_INCLUDE_VS and SMAA_INCLUDE_PS below). + * + * And four presets: + * SMAA_PRESET_LOW (%60 of the quality) + * SMAA_PRESET_MEDIUM (%80 of the quality) + * SMAA_PRESET_HIGH (%95 of the quality) + * SMAA_PRESET_ULTRA (%99 of the quality) + * + * For example: + * #define SMAA_RT_METRICS float4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0) + * #define SMAA_HLSL_4 + * #define SMAA_PRESET_HIGH + * #include "SMAA.h" + * + * Note that SMAA_RT_METRICS doesn't need to be a macro, it can be a + * uniform variable. The code is designed to minimize the impact of not + * using a constant value, but it is still better to hardcode it. + * + * Depending on how you encoded 'areaTex' and 'searchTex', you may have to + * add (and customize) the following defines before including SMAA.h: + * #define SMAA_AREATEX_SELECT(sample) sample.rg + * #define SMAA_SEARCHTEX_SELECT(sample) sample.r + * + * If your engine is already using porting macros, you can define + * SMAA_CUSTOM_SL, and define the porting functions by yourself. + * + * 7. Then, you'll have to setup the passes as indicated in the scheme above. + * You can take a look into SMAA.fx, to see how we did it for our demo. + * Checkout the function wrappers, you may want to copy-paste them! + * + * 8. It's recommended to validate the produced |edgesTex| and |blendTex|. + * You can use a screenshot from your engine to compare the |edgesTex| + * and |blendTex| produced inside of the engine with the results obtained + * with the reference demo. + * + * 9. After you get the last pass to work, it's time to optimize. You'll have + * to initialize a stencil buffer in the first pass (discard is already in + * the code), then mask execution by using it the second pass. The last + * pass should be executed in all pixels. + * + * + * After this point you can choose to enable predicated thresholding, + * temporal supersampling and motion blur integration: + * + * a) If you want to use predicated thresholding, take a look into + * SMAA_PREDICATION; you'll need to pass an extra texture in the edge + * detection pass. + * + * b) If you want to enable temporal supersampling (SMAA T2x): + * + * 1. The first step is to render using subpixel jitters. I won't go into + * detail, but it's as simple as moving each vertex position in the + * vertex shader, you can check how we do it in our DX10 demo. + * + * 2. Then, you must setup the temporal resolve. You may want to take a look + * into SMAAResolve for resolving 2x modes. After you get it working, you'll + * probably see ghosting everywhere. But fear not, you can enable the + * CryENGINE temporal reprojection by setting the SMAA_REPROJECTION macro. + * Check out SMAA_DECODE_VELOCITY if your velocity buffer is encoded. + * + * 3. The next step is to apply SMAA to each subpixel jittered frame, just as + * done for 1x. + * + * 4. At this point you should already have something usable, but for best + * results the proper area textures must be set depending on current jitter. + * For this, the parameter 'subsampleIndices' of + * 'SMAABlendingWeightCalculationPS' must be set as follows, for our T2x + * mode: + * + * @SUBSAMPLE_INDICES + * + * | S# | Camera Jitter | subsampleIndices | + * +----+------------------+---------------------+ + * | 0 | ( 0.25, -0.25) | float4(1, 1, 1, 0) | + * | 1 | (-0.25, 0.25) | float4(2, 2, 2, 0) | + * + * These jitter positions assume a bottom-to-top y axis. S# stands for the + * sample number. + * + * More information about temporal supersampling here: + * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf + * + * c) If you want to enable spatial multisampling (SMAA S2x): + * + * 1. The scene must be rendered using MSAA 2x. The MSAA 2x buffer must be + * created with: + * - DX10: see below (*) + * - DX10.1: D3D10_STANDARD_MULTISAMPLE_PATTERN or + * - DX11: D3D11_STANDARD_MULTISAMPLE_PATTERN + * + * This allows to ensure that the subsample order matches the table in + * @SUBSAMPLE_INDICES. + * + * (*) In the case of DX10, we refer the reader to: + * - SMAA::detectMSAAOrder and + * - SMAA::msaaReorder + * + * These functions allow to match the standard multisample patterns by + * detecting the subsample order for a specific GPU, and reordering + * them appropriately. + * + * 2. A shader must be run to output each subsample into a separate buffer + * (DX10 is required). You can use SMAASeparate for this purpose, or just do + * it in an existing pass (for example, in the tone mapping pass, which has + * the advantage of feeding tone mapped subsamples to SMAA, which will yield + * better results). + * + * 3. The full SMAA 1x pipeline must be run for each separated buffer, storing + * the results in the final buffer. The second run should alpha blend with + * the existing final buffer using a blending factor of 0.5. + * 'subsampleIndices' must be adjusted as in the SMAA T2x case (see point + * b). + * + * d) If you want to enable temporal supersampling on top of SMAA S2x + * (which actually is SMAA 4x): + * + * 1. SMAA 4x consists on temporally jittering SMAA S2x, so the first step is + * to calculate SMAA S2x for current frame. In this case, 'subsampleIndices' + * must be set as follows: + * + * | F# | S# | Camera Jitter | Net Jitter | subsampleIndices | + * +----+----+--------------------+-------------------+----------------------+ + * | 0 | 0 | ( 0.125, 0.125) | ( 0.375, -0.125) | float4(5, 3, 1, 3) | + * | 0 | 1 | ( 0.125, 0.125) | (-0.125, 0.375) | float4(4, 6, 2, 3) | + * +----+----+--------------------+-------------------+----------------------+ + * | 1 | 2 | (-0.125, -0.125) | ( 0.125, -0.375) | float4(3, 5, 1, 4) | + * | 1 | 3 | (-0.125, -0.125) | (-0.375, 0.125) | float4(6, 4, 2, 4) | + * + * These jitter positions assume a bottom-to-top y axis. F# stands for the + * frame number. S# stands for the sample number. + * + * 2. After calculating SMAA S2x for current frame (with the new subsample + * indices), previous frame must be reprojected as in SMAA T2x mode (see + * point b). + * + * e) If motion blur is used, you may want to do the edge detection pass + * together with motion blur. This has two advantages: + * + * 1. Pixels under heavy motion can be omitted from the edge detection process. + * For these pixels we can just store "no edge", as motion blur will take + * care of them. + * 2. The center pixel tap is reused. + * + * Note that in this case depth testing should be used instead of stenciling, + * as we have to write all the pixels in the motion blur pass. + * + * That's it! + */ + +//----------------------------------------------------------------------------- +// SMAA Presets + +/** + * Note that if you use one of these presets, the following configuration + * macros will be ignored if set in the "Configurable Defines" section. + */ + +#if defined(SMAA_PRESET_LOW) +#define SMAA_THRESHOLD 0.15 +#define SMAA_MAX_SEARCH_STEPS 4 +#define SMAA_DISABLE_DIAG_DETECTION +#define SMAA_DISABLE_CORNER_DETECTION +#elif defined(SMAA_PRESET_MEDIUM) +#define SMAA_THRESHOLD 0.1 +#define SMAA_MAX_SEARCH_STEPS 8 +#define SMAA_DISABLE_DIAG_DETECTION +#define SMAA_DISABLE_CORNER_DETECTION +#elif defined(SMAA_PRESET_HIGH) +#define SMAA_THRESHOLD 0.1 +#define SMAA_MAX_SEARCH_STEPS 16 +#define SMAA_MAX_SEARCH_STEPS_DIAG 8 +#define SMAA_CORNER_ROUNDING 25 +#elif defined(SMAA_PRESET_ULTRA) +#define SMAA_THRESHOLD 0.05 +#define SMAA_MAX_SEARCH_STEPS 32 +#define SMAA_MAX_SEARCH_STEPS_DIAG 16 +#define SMAA_CORNER_ROUNDING 25 +#endif + +//----------------------------------------------------------------------------- +// Configurable Defines + +/** + * SMAA_THRESHOLD specifies the threshold or sensitivity to edges. + * Lowering this value you will be able to detect more edges at the expense of + * performance. + * + * Range: [0, 0.5] + * 0.1 is a reasonable value, and allows to catch most visible edges. + * 0.05 is a rather overkill value, that allows to catch 'em all. + * + * If temporal supersampling is used, 0.2 could be a reasonable value, as low + * contrast edges are properly filtered by just 2x. + */ +#ifndef SMAA_THRESHOLD +#define SMAA_THRESHOLD 0.1 +#endif + +/** + * SMAA_DEPTH_THRESHOLD specifies the threshold for depth edge detection. + * + * Range: depends on the depth range of the scene. + */ +#ifndef SMAA_DEPTH_THRESHOLD +#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) +#endif + +/** + * SMAA_MAX_SEARCH_STEPS specifies the maximum steps performed in the + * horizontal/vertical pattern searches, at each side of the pixel. + * + * In number of pixels, it's actually the double. So the maximum line length + * perfectly handled by, for example 16, is 64 (by perfectly, we meant that + * longer lines won't look as good, but still antialiased). + * + * Range: [0, 112] + */ +#ifndef SMAA_MAX_SEARCH_STEPS +#define SMAA_MAX_SEARCH_STEPS 16 +#endif + +/** + * SMAA_MAX_SEARCH_STEPS_DIAG specifies the maximum steps performed in the + * diagonal pattern searches, at each side of the pixel. In this case we jump + * one pixel at time, instead of two. + * + * Range: [0, 20] + * + * On high-end machines it is cheap (between a 0.8x and 0.9x slower for 16 + * steps), but it can have a significant impact on older machines. + * + * Define SMAA_DISABLE_DIAG_DETECTION to disable diagonal processing. + */ +#ifndef SMAA_MAX_SEARCH_STEPS_DIAG +#define SMAA_MAX_SEARCH_STEPS_DIAG 8 +#endif + +/** + * SMAA_CORNER_ROUNDING specifies how much sharp corners will be rounded. + * + * Range: [0, 100] + * + * Define SMAA_DISABLE_CORNER_DETECTION to disable corner processing. + */ +#ifndef SMAA_CORNER_ROUNDING +#define SMAA_CORNER_ROUNDING 25 +#endif + +/** + * If there is an neighbor edge that has SMAA_LOCAL_CONTRAST_FACTOR times + * bigger contrast than current edge, current edge will be discarded. + * + * This allows to eliminate spurious crossing edges, and is based on the fact + * that, if there is too much contrast in a direction, that will hide + * perceptually contrast in the other neighbors. + */ +#ifndef SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR +#define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0 +#endif + +/** + * Predicated thresholding allows to better preserve texture details and to + * improve performance, by decreasing the number of detected edges using an + * additional buffer like the light accumulation buffer, object ids or even the + * depth buffer (the depth buffer usage may be limited to indoor or short range + * scenes). + * + * It locally decreases the luma or color threshold if an edge is found in an + * additional buffer (so the global threshold can be higher). + * + * This method was developed by Playstation EDGE MLAA team, and used in + * Killzone 3, by using the light accumulation buffer. More information here: + * http://iryoku.com/aacourse/downloads/06-MLAA-on-PS3.pptx + */ +#ifndef SMAA_PREDICATION +#define SMAA_PREDICATION 0 +#endif + +/** + * Threshold to be used in the additional predication buffer. + * + * Range: depends on the input, so you'll have to find the magic number that + * works for you. + */ +#ifndef SMAA_PREDICATION_THRESHOLD +#define SMAA_PREDICATION_THRESHOLD 0.01 +#endif + +/** + * How much to scale the global threshold used for luma or color edge + * detection when using predication. + * + * Range: [1, 16] + */ +#ifndef SMAA_PREDICATION_SCALE +#define SMAA_PREDICATION_SCALE 2.0 +#endif + +/** + * How much to locally decrease the threshold. + * + * Range: [0, 4] + */ +#ifndef SMAA_PREDICATION_STRENGTH +#define SMAA_PREDICATION_STRENGTH 0.4 +#endif + +/** + * Temporal reprojection allows to remove ghosting artifacts when using + * temporal supersampling. We use the CryEngine 3 method which also introduces + * velocity weighting. This feature is of extreme importance for totally + * removing ghosting. More information here: + * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf + * + * Note that you'll need to setup a velocity buffer for enabling reprojection. + * For static geometry, saving the previous depth buffer is a viable + * alternative. + */ +#ifndef SMAA_REPROJECTION +#define SMAA_REPROJECTION 0 +#endif + +/** + * SMAA_REPROJECTION_WEIGHT_SCALE controls the velocity weighting. It allows to + * remove ghosting trails behind the moving object, which are not removed by + * just using reprojection. Using low values will exhibit ghosting, while using + * high values will disable temporal supersampling under motion. + * + * Behind the scenes, velocity weighting removes temporal supersampling when + * the velocity of the subsamples differs (meaning they are different objects). + * + * Range: [0, 80] + */ +#ifndef SMAA_REPROJECTION_WEIGHT_SCALE +#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 +#endif + +/** + * On some compilers, discard cannot be used in vertex shaders. Thus, they need + * to be compiled separately. + */ +#ifndef SMAA_INCLUDE_VS +#define SMAA_INCLUDE_VS 1 +#endif +#ifndef SMAA_INCLUDE_PS +#define SMAA_INCLUDE_PS 1 +#endif + +//----------------------------------------------------------------------------- +// Texture Access Defines + +#ifndef SMAA_AREATEX_SELECT +#if defined(SMAA_HLSL_3) +#define SMAA_AREATEX_SELECT(sample) sample.ra +#else +#define SMAA_AREATEX_SELECT(sample) sample.rg +#endif +#endif + +#ifndef SMAA_SEARCHTEX_SELECT +#define SMAA_SEARCHTEX_SELECT(sample) sample.r +#endif + +#ifndef SMAA_DECODE_VELOCITY +#define SMAA_DECODE_VELOCITY(sample) sample.rg +#endif + +//----------------------------------------------------------------------------- +// Non-Configurable Defines + +#define SMAA_AREATEX_MAX_DISTANCE 16 +#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 +#define SMAA_AREATEX_PIXEL_SIZE (1.0 / float2(160.0, 560.0)) +#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) +#define SMAA_SEARCHTEX_SIZE float2(66.0, 33.0) +#define SMAA_SEARCHTEX_PACKED_SIZE float2(64.0, 16.0) +#define SMAA_CORNER_ROUNDING_NORM (float(SMAA_CORNER_ROUNDING) / 100.0) + +//----------------------------------------------------------------------------- +// Porting Functions + +#if defined(SMAA_HLSL_3) +#define SMAATexture2D(tex) sampler2D tex +#define SMAATexturePass2D(tex) tex +#define SMAASampleLevelZero(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) +#define SMAASampleLevelZeroPoint(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) +#define SMAASampleLevelZeroOffset(tex, coord, offset) tex2Dlod(tex, float4(coord + offset * SMAA_RT_METRICS.xy, 0.0, 0.0)) +#define SMAASample(tex, coord) tex2D(tex, coord) +#define SMAASamplePoint(tex, coord) tex2D(tex, coord) +#define SMAASampleOffset(tex, coord, offset) tex2D(tex, coord + offset * SMAA_RT_METRICS.xy) +#define SMAA_FLATTEN [flatten] +#define SMAA_BRANCH [branch] +#endif +#if defined(SMAA_HLSL_4) || defined(SMAA_HLSL_4_1) +SamplerState LinearSampler { Filter = MIN_MAG_LINEAR_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; +SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; +#define SMAATexture2D(tex) Texture2D tex +#define SMAATexturePass2D(tex) tex +#define SMAASampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0) +#define SMAASampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0) +#define SMAASampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset) +#define SMAASample(tex, coord) tex.Sample(LinearSampler, coord) +#define SMAASamplePoint(tex, coord) tex.Sample(PointSampler, coord) +#define SMAASampleOffset(tex, coord, offset) tex.Sample(LinearSampler, coord, offset) +#define SMAA_FLATTEN [flatten] +#define SMAA_BRANCH [branch] +#define SMAATexture2DMS2(tex) Texture2DMS tex +#define SMAALoad(tex, pos, sample) tex.Load(pos, sample) +#if defined(SMAA_HLSL_4_1) +#define SMAAGather(tex, coord) tex.Gather(LinearSampler, coord, 0) +#endif +#endif +#if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4) +#define SMAATexture2D(tex) sampler2D tex +#define SMAATexturePass2D(tex) tex +#define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0) +#define SMAASampleLevelZeroPoint(tex, coord) textureLod(tex, coord, 0.0) +#define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset) +#define SMAASample(tex, coord) texture(tex, coord) +#define SMAASamplePoint(tex, coord) texture(tex, coord) +#define SMAASampleOffset(tex, coord, offset) texture(tex, coord, offset) +#define SMAA_FLATTEN +#define SMAA_BRANCH +#define lerp(a, b, t) mix(a, b, t) +#define saturate(a) clamp(a, 0.0, 1.0) +#if defined(SMAA_GLSL_4) +#define mad(a, b, c) fma(a, b, c) +#define SMAAGather(tex, coord) textureGather(tex, coord) +#else +#define mad(a, b, c) (a * b + c) +#endif +#define float2 vec2 +#define float3 vec3 +#define float4 vec4 +#define int2 ivec2 +#define int3 ivec3 +#define int4 ivec4 +#define bool2 bvec2 +#define bool3 bvec3 +#define bool4 bvec4 +#endif + +#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL) +#error you must define the shading language: SMAA_HLSL_*, SMAA_GLSL_* or SMAA_CUSTOM_SL +#endif + +//----------------------------------------------------------------------------- +// Misc functions + +/** + * Gathers current pixel, and the top-left neighbors. + */ +float3 SMAAGatherNeighbours(float2 texcoord, + float4 offset[3], + SMAATexture2D(tex)) { + #ifdef SMAAGather + return SMAAGather(tex, texcoord + SMAA_RT_METRICS.xy * float2(-0.5, -0.5)).grb; + #else + float P = SMAASamplePoint(tex, texcoord).r; + float Pleft = SMAASamplePoint(tex, offset[0].xy).r; + float Ptop = SMAASamplePoint(tex, offset[0].zw).r; + return float3(P, Pleft, Ptop); + #endif +} + +/** + * Adjusts the threshold by means of predication. + */ +float2 SMAACalculatePredicatedThreshold(float2 texcoord, + float4 offset[3], + SMAATexture2D(predicationTex)) { + float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(predicationTex)); + float2 delta = abs(neighbours.xx - neighbours.yz); + float2 edges = step(SMAA_PREDICATION_THRESHOLD, delta); + return SMAA_PREDICATION_SCALE * SMAA_THRESHOLD * (1.0 - SMAA_PREDICATION_STRENGTH * edges); +} + +/** + * Conditional move: + */ +void SMAAMovc(bool2 cond, inout float2 variable, float2 value) { + SMAA_FLATTEN if (cond.x) variable.x = value.x; + SMAA_FLATTEN if (cond.y) variable.y = value.y; +} + +void SMAAMovc(bool4 cond, inout float4 variable, float4 value) { + SMAAMovc(cond.xy, variable.xy, value.xy); + SMAAMovc(cond.zw, variable.zw, value.zw); +} + + +#if SMAA_INCLUDE_VS +//----------------------------------------------------------------------------- +// Vertex Shaders + +/** + * Edge Detection Vertex Shader + */ +void SMAAEdgeDetectionVS(float2 texcoord, + out float4 offset[3]) { + offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-1.0, 0.0, 0.0, -1.0), texcoord.xyxy); + offset[1] = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy); + offset[2] = mad(SMAA_RT_METRICS.xyxy, float4(-2.0, 0.0, 0.0, -2.0), texcoord.xyxy); +} + +/** + * Blend Weight Calculation Vertex Shader + */ +void SMAABlendingWeightCalculationVS(float2 texcoord, + out float2 pixcoord, + out float4 offset[3]) { + pixcoord = texcoord * SMAA_RT_METRICS.zw; + + // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): + offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-0.25, -0.125, 1.25, -0.125), texcoord.xyxy); + offset[1] = mad(SMAA_RT_METRICS.xyxy, float4(-0.125, -0.25, -0.125, 1.25), texcoord.xyxy); + + // And these for the searches, they indicate the ends of the loops: + offset[2] = mad(SMAA_RT_METRICS.xxyy, + float4(-2.0, 2.0, -2.0, 2.0) * float(SMAA_MAX_SEARCH_STEPS), + float4(offset[0].xz, offset[1].yw)); +} + +/** + * Neighborhood Blending Vertex Shader + */ +void SMAANeighborhoodBlendingVS(float2 texcoord, + out float4 offset) { + offset = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy); +} +#endif // SMAA_INCLUDE_VS + +#if SMAA_INCLUDE_PS +//----------------------------------------------------------------------------- +// Edge Detection Pixel Shaders (First Pass) + +/** + * Luma Edge Detection + * + * IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and + * thus 'colorTex' should be a non-sRGB texture. + */ +float2 SMAALumaEdgeDetectionPS(float2 texcoord, + float4 offset[3], + SMAATexture2D(colorTex) + ) { + // Calculate the threshold: + float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD); + + // Calculate lumas: + float3 weights = float3(0.2126, 0.7152, 0.0722); + float L = dot(SMAASamplePoint(colorTex, texcoord).rgb, weights); + + float Lleft = dot(SMAASamplePoint(colorTex, offset[0].xy).rgb, weights); + float Ltop = dot(SMAASamplePoint(colorTex, offset[0].zw).rgb, weights); + + // We do the usual threshold: + float4 delta; + delta.xy = abs(L - float2(Lleft, Ltop)); + float2 edges = step(threshold, delta.xy); + + // Then discard if there is no edge: + if (dot(edges, float2(1.0, 1.0)) == 0.0) + discard; + + // Calculate right and bottom deltas: + float Lright = dot(SMAASamplePoint(colorTex, offset[1].xy).rgb, weights); + float Lbottom = dot(SMAASamplePoint(colorTex, offset[1].zw).rgb, weights); + delta.zw = abs(L - float2(Lright, Lbottom)); + + // Calculate the maximum delta in the direct neighborhood: + float2 maxDelta = max(delta.xy, delta.zw); + + // Calculate left-left and top-top deltas: + float Lleftleft = dot(SMAASamplePoint(colorTex, offset[2].xy).rgb, weights); + float Ltoptop = dot(SMAASamplePoint(colorTex, offset[2].zw).rgb, weights); + delta.zw = abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop)); + + // Calculate the final maximum delta: + maxDelta = max(maxDelta.xy, delta.zw); + float finalDelta = max(maxDelta.x, maxDelta.y); + + // Local contrast adaptation: + edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); + + return edges; +} + +float2 SMAALumaEdgePredicationDetectionPS(float2 texcoord, + float4 offset[3], + SMAATexture2D(colorTex) + , SMAATexture2D(predicationTex) + ) { + // Calculate the threshold: + float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex)); + + // Calculate lumas: + float3 weights = float3(0.2126, 0.7152, 0.0722); + float L = dot(SMAASamplePoint(colorTex, texcoord).rgb, weights); + + float Lleft = dot(SMAASamplePoint(colorTex, offset[0].xy).rgb, weights); + float Ltop = dot(SMAASamplePoint(colorTex, offset[0].zw).rgb, weights); + + // We do the usual threshold: + float4 delta; + delta.xy = abs(L - float2(Lleft, Ltop)); + float2 edges = step(threshold, delta.xy); + + // Then discard if there is no edge: + if (dot(edges, float2(1.0, 1.0)) == 0.0) + discard; + + // Calculate right and bottom deltas: + float Lright = dot(SMAASamplePoint(colorTex, offset[1].xy).rgb, weights); + float Lbottom = dot(SMAASamplePoint(colorTex, offset[1].zw).rgb, weights); + delta.zw = abs(L - float2(Lright, Lbottom)); + + // Calculate the maximum delta in the direct neighborhood: + float2 maxDelta = max(delta.xy, delta.zw); + + // Calculate left-left and top-top deltas: + float Lleftleft = dot(SMAASamplePoint(colorTex, offset[2].xy).rgb, weights); + float Ltoptop = dot(SMAASamplePoint(colorTex, offset[2].zw).rgb, weights); + delta.zw = abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop)); + + // Calculate the final maximum delta: + maxDelta = max(maxDelta.xy, delta.zw); + float finalDelta = max(maxDelta.x, maxDelta.y); + + // Local contrast adaptation: + edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); + + return edges; +} + +/** + * Color Edge Detection + * + * IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and + * thus 'colorTex' should be a non-sRGB texture. + */ +float2 SMAAColorEdgeDetectionPS(float2 texcoord, + float4 offset[3], + SMAATexture2D(colorTex) + ) { + // Calculate the threshold: + float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD); + + // Calculate color deltas: + float4 delta; + float3 C = SMAASamplePoint(colorTex, texcoord).rgb; + + float3 Cleft = SMAASamplePoint(colorTex, offset[0].xy).rgb; + float3 t = abs(C - Cleft); + delta.x = max(max(t.r, t.g), t.b); + + float3 Ctop = SMAASamplePoint(colorTex, offset[0].zw).rgb; + t = abs(C - Ctop); + delta.y = max(max(t.r, t.g), t.b); + + // We do the usual threshold: + float2 edges = step(threshold, delta.xy); + + // Then discard if there is no edge: + if (dot(edges, float2(1.0, 1.0)) == 0.0) + discard; + + // Calculate right and bottom deltas: + float3 Cright = SMAASamplePoint(colorTex, offset[1].xy).rgb; + t = abs(C - Cright); + delta.z = max(max(t.r, t.g), t.b); + + float3 Cbottom = SMAASamplePoint(colorTex, offset[1].zw).rgb; + t = abs(C - Cbottom); + delta.w = max(max(t.r, t.g), t.b); + + // Calculate the maximum delta in the direct neighborhood: + float2 maxDelta = max(delta.xy, delta.zw); + + // Calculate left-left and top-top deltas: + float3 Cleftleft = SMAASamplePoint(colorTex, offset[2].xy).rgb; + t = abs(Cleft - Cleftleft); + delta.z = max(max(t.r, t.g), t.b); + + float3 Ctoptop = SMAASamplePoint(colorTex, offset[2].zw).rgb; + t = abs(Ctop - Ctoptop); + delta.w = max(max(t.r, t.g), t.b); + + // Calculate the final maximum delta: + maxDelta = max(maxDelta.xy, delta.zw); + float finalDelta = max(maxDelta.x, maxDelta.y); + + // Local contrast adaptation: + edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); + + return edges; +} + +float2 SMAAColorEdgePredicationDetectionPS(float2 texcoord, + float4 offset[3], + SMAATexture2D(colorTex) + , SMAATexture2D(predicationTex) + ) { + // Calculate the threshold: + float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex); + + // Calculate color deltas: + float4 delta; + float3 C = SMAASamplePoint(colorTex, texcoord).rgb; + + float3 Cleft = SMAASamplePoint(colorTex, offset[0].xy).rgb; + float3 t = abs(C - Cleft); + delta.x = max(max(t.r, t.g), t.b); + + float3 Ctop = SMAASamplePoint(colorTex, offset[0].zw).rgb; + t = abs(C - Ctop); + delta.y = max(max(t.r, t.g), t.b); + + // We do the usual threshold: + float2 edges = step(threshold, delta.xy); + + // Then discard if there is no edge: + if (dot(edges, float2(1.0, 1.0)) == 0.0) + discard; + + // Calculate right and bottom deltas: + float3 Cright = SMAASamplePoint(colorTex, offset[1].xy).rgb; + t = abs(C - Cright); + delta.z = max(max(t.r, t.g), t.b); + + float3 Cbottom = SMAASamplePoint(colorTex, offset[1].zw).rgb; + t = abs(C - Cbottom); + delta.w = max(max(t.r, t.g), t.b); + + // Calculate the maximum delta in the direct neighborhood: + float2 maxDelta = max(delta.xy, delta.zw); + + // Calculate left-left and top-top deltas: + float3 Cleftleft = SMAASamplePoint(colorTex, offset[2].xy).rgb; + t = abs(Cleft - Cleftleft); + delta.z = max(max(t.r, t.g), t.b); + + float3 Ctoptop = SMAASamplePoint(colorTex, offset[2].zw).rgb; + t = abs(Ctop - Ctoptop); + delta.w = max(max(t.r, t.g), t.b); + + // Calculate the final maximum delta: + maxDelta = max(maxDelta.xy, delta.zw); + float finalDelta = max(maxDelta.x, maxDelta.y); + + // Local contrast adaptation: + edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); + + return edges; +} + +/** + * Depth Edge Detection + */ +float2 SMAADepthEdgeDetectionPS(float2 texcoord, + float4 offset[3], + SMAATexture2D(depthTex)) { + float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(depthTex)); + float2 delta = abs(neighbours.xx - float2(neighbours.y, neighbours.z)); + float2 edges = step(SMAA_DEPTH_THRESHOLD, delta); + + if (dot(edges, float2(1.0, 1.0)) == 0.0) + discard; + + return edges; +} + +//----------------------------------------------------------------------------- +// Diagonal Search Functions + +#if !defined(SMAA_DISABLE_DIAG_DETECTION) + +/** + * Allows to decode two binary values from a bilinear-filtered access. + */ +float2 SMAADecodeDiagBilinearAccess(float2 e) { + // Bilinear access for fetching 'e' have a 0.25 offset, and we are + // interested in the R and G edges: + // + // +---G---+-------+ + // | x o R x | + // +-------+-------+ + // + // Then, if one of these edge is enabled: + // Red: (0.75 * X + 0.25 * 1) => 0.25 or 1.0 + // Green: (0.75 * 1 + 0.25 * X) => 0.75 or 1.0 + // + // This function will unpack the values (mad + mul + round): + // wolframalpha.com: round(x * abs(5 * x - 5 * 0.75)) plot 0 to 1 + e.r = e.r * abs(5.0 * e.r - 5.0 * 0.75); + return round(e); +} + +float4 SMAADecodeDiagBilinearAccess(float4 e) { + e.rb = e.rb * abs(5.0 * e.rb - 5.0 * 0.75); + return round(e); +} + +/** + * These functions allows to perform diagonal pattern searches. + */ +float2 SMAASearchDiag1(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) { + float4 coord = float4(texcoord, -1.0, 1.0); + float3 t = float3(SMAA_RT_METRICS.xy, 1.0); + while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && + coord.w > 0.9) { + coord.xyz = mad(t, float3(dir, 1.0), coord.xyz); + e = SMAASampleLevelZero(edgesTex, coord.xy).rg; + coord.w = dot(e, float2(0.5, 0.5)); + } + return coord.zw; +} + +float2 SMAASearchDiag2(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) { + float4 coord = float4(texcoord, -1.0, 1.0); + coord.x += 0.25 * SMAA_RT_METRICS.x; // See @SearchDiag2Optimization + float3 t = float3(SMAA_RT_METRICS.xy, 1.0); + while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && + coord.w > 0.9) { + coord.xyz = mad(t, float3(dir, 1.0), coord.xyz); + + // @SearchDiag2Optimization + // Fetch both edges at once using bilinear filtering: + e = SMAASampleLevelZero(edgesTex, coord.xy).rg; + e = SMAADecodeDiagBilinearAccess(e); + + // Non-optimized version: + // e.g = SMAASampleLevelZero(edgesTex, coord.xy).g; + // e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, int2(1, 0)).r; + + coord.w = dot(e, float2(0.5, 0.5)); + } + return coord.zw; +} + +/** + * Similar to SMAAArea, this calculates the area corresponding to a certain + * diagonal distance and crossing edges 'e'. + */ +float2 SMAAAreaDiag(SMAATexture2D(areaTex), float2 dist, float2 e, float offset) { + float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, dist); + + // We do a scale and bias for mapping to texel space: + texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); + + // Diagonal areas are on the second half of the texture: + texcoord.x += 0.5; + + // Move to proper place, according to the subpixel offset: + texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; + + // Do it! + return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); +} + +/** + * This searches for diagonal patterns and returns the corresponding weights. + */ +float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), SMAATexture2D(areaTex), float2 texcoord, float2 e, float4 subsampleIndices) { + float2 weights = float2(0.0, 0.0); + + // Search for the line ends: + float4 d; + float2 end; + if (e.r > 0.0) { + d.xz = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, 1.0), end); + d.x += float(end.y > 0.9); + } else + d.xz = float2(0.0, 0.0); + d.yw = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, -1.0), end); + + SMAA_BRANCH + if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 + // Fetch the crossing edges: + float4 coords = mad(float4(-d.x + 0.25, d.x, d.y, -d.y - 0.25), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + float4 c; + c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).rg; + c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).rg; + c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw); + + // Non-optimized version: + // float4 coords = mad(float4(-d.x, d.x, d.y, -d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + // float4 c; + // c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g; + // c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, 0)).r; + // c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).g; + // c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, -1)).r; + + // Merge crossing edges at each side into a single value: + float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw); + + // Remove the crossing edge if we didn't found the end of the line: + SMAAMovc(bool2(step(0.9, d.zw)), cc, float2(0.0, 0.0)); + + // Fetch the areas for this line: + weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.z); + } + + // Search for the line ends: + d.xz = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, -1.0), end); + if (SMAASampleLevelZeroOffset(edgesTex, texcoord, int2(1, 0)).r > 0.0) { + d.yw = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, 1.0), end); + d.y += float(end.y > 0.9); + } else + d.yw = float2(0.0, 0.0); + + SMAA_BRANCH + if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 + // Fetch the crossing edges: + float4 coords = mad(float4(-d.x, -d.x, d.y, d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); + float4 c; + c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g; + c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, -1)).r; + c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).gr; + float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw); + + // Remove the crossing edge if we didn't found the end of the line: + SMAAMovc(bool2(step(0.9, d.zw)), cc, float2(0.0, 0.0)); + + // Fetch the areas for this line: + weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.w).gr; + } + + return weights; +} +#endif + +//----------------------------------------------------------------------------- +// Horizontal/Vertical Search Functions + +/** + * This allows to determine how much length should we add in the last step + * of the searches. It takes the bilinearly interpolated edge (see + * @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and + * crossing edges are active. + */ +float SMAASearchLength(SMAATexture2D(searchTex), float2 e, float offset) { + // The texture is flipped vertically, with left and right cases taking half + // of the space horizontally: + float2 scale = SMAA_SEARCHTEX_SIZE * float2(0.5, -1.0); + float2 bias = SMAA_SEARCHTEX_SIZE * float2(offset, 1.0); + + // Scale and bias to access texel centers: + scale += float2(-1.0, 1.0); + bias += float2( 0.5, -0.5); + + // Convert from pixel coordinates to texcoords: + // (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped) + scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; + bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; + + // Lookup the search texture: + return SMAA_SEARCHTEX_SELECT(SMAASampleLevelZero(searchTex, mad(scale, e, bias))); +} + +/** + * Horizontal/vertical search functions for the 2nd pass. + */ +float SMAASearchXLeft(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { + /** + * @PSEUDO_GATHER4 + * This texcoord has been offset by (-0.25, -0.125) in the vertex shader to + * sample between edge, thus fetching four edges in a row. + * Sampling with different offsets in each direction allows to disambiguate + * which edges are active from the four fetched ones. + */ + float2 e = float2(0.0, 1.0); + while (texcoord.x > end && + e.g > 0.8281 && // Is there some edge not activated? + e.r == 0.0) { // Or is there a crossing edge that breaks the line? + e = SMAASampleLevelZero(edgesTex, texcoord).rg; + texcoord = mad(-float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); + } + + float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0), 3.25); + return mad(SMAA_RT_METRICS.x, offset, texcoord.x); + + // Non-optimized version: + // We correct the previous (-0.25, -0.125) offset we applied: + // texcoord.x += 0.25 * SMAA_RT_METRICS.x; + + // The searches are bias by 1, so adjust the coords accordingly: + // texcoord.x += SMAA_RT_METRICS.x; + + // Disambiguate the length added by the last step: + // texcoord.x += 2.0 * SMAA_RT_METRICS.x; // Undo last step + // texcoord.x -= SMAA_RT_METRICS.x * (255.0 / 127.0) * SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0); + // return mad(SMAA_RT_METRICS.x, offset, texcoord.x); +} + +float SMAASearchXRight(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { + float2 e = float2(0.0, 1.0); + while (texcoord.x < end && + e.g > 0.8281 && // Is there some edge not activated? + e.r == 0.0) { // Or is there a crossing edge that breaks the line? + e = SMAASampleLevelZero(edgesTex, texcoord).rg; + texcoord = mad(float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.5), 3.25); + return mad(-SMAA_RT_METRICS.x, offset, texcoord.x); +} + +float SMAASearchYUp(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { + float2 e = float2(1.0, 0.0); + while (texcoord.y > end && + e.r > 0.8281 && // Is there some edge not activated? + e.g == 0.0) { // Or is there a crossing edge that breaks the line? + e = SMAASampleLevelZero(edgesTex, texcoord).rg; + texcoord = mad(-float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.0), 3.25); + return mad(SMAA_RT_METRICS.y, offset, texcoord.y); +} + +float SMAASearchYDown(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { + float2 e = float2(1.0, 0.0); + while (texcoord.y < end && + e.r > 0.8281 && // Is there some edge not activated? + e.g == 0.0) { // Or is there a crossing edge that breaks the line? + e = SMAASampleLevelZero(edgesTex, texcoord).rg; + texcoord = mad(float2(0.0, 2.0), SMAA_RT_METRICS.xy, texcoord); + } + float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.5), 3.25); + return mad(-SMAA_RT_METRICS.y, offset, texcoord.y); +} + +/** + * Ok, we have the distance and both crossing edges. So, what are the areas + * at each side of current edge? + */ +float2 SMAAArea(SMAATexture2D(areaTex), float2 dist, float e1, float e2, float offset) { + // Rounding prevents precision errors of bilinear filtering: + float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * float2(e1, e2)), dist); + + // We do a scale and bias for mapping to texel space: + texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); + + // Move to proper place, according to the subpixel offset: + texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y); + + // Do it! + return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); +} + +//----------------------------------------------------------------------------- +// Corner Detection Functions + +void SMAADetectHorizontalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) { + #if !defined(SMAA_DISABLE_CORNER_DETECTION) + float2 leftRight = step(d.xy, d.yx); + float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; + + rounding /= leftRight.x + leftRight.y; // Reduce blending for pixels in the center of a line. + + float2 factor = float2(1.0, 1.0); + factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, 1)).r; + factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, 1)).r; + factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, -2)).r; + factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, -2)).r; + + weights *= saturate(factor); + #endif +} + +void SMAADetectVerticalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) { + #if !defined(SMAA_DISABLE_CORNER_DETECTION) + float2 leftRight = step(d.xy, d.yx); + float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; + + rounding /= leftRight.x + leftRight.y; + + float2 factor = float2(1.0, 1.0); + factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2( 1, 0)).g; + factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2( 1, 1)).g; + factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(-2, 0)).g; + factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(-2, 1)).g; + + weights *= saturate(factor); + #endif +} + +//----------------------------------------------------------------------------- +// Blending Weight Calculation Pixel Shader (Second Pass) + +float4 SMAABlendingWeightCalculationPS(float2 texcoord, + float2 pixcoord, + float4 offset[3], + SMAATexture2D(edgesTex), + SMAATexture2D(areaTex), + SMAATexture2D(searchTex), + float4 subsampleIndices) { // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES. + float4 weights = float4(0.0, 0.0, 0.0, 0.0); + + float2 e = SMAASample(edgesTex, texcoord).rg; + + SMAA_BRANCH + if (e.g > 0.0) { // Edge at north + #if !defined(SMAA_DISABLE_DIAG_DETECTION) + // Diagonals have both north and west edges, so searching for them in + // one of the boundaries is enough. + weights.rg = SMAACalculateDiagWeights(SMAATexturePass2D(edgesTex), SMAATexturePass2D(areaTex), texcoord, e, subsampleIndices); + + // We give priority to diagonals, so if we find a diagonal we skip + // horizontal/vertical processing. + SMAA_BRANCH + if (weights.r == -weights.g) { // weights.r + weights.g == 0.0 + #endif + + float2 d; + + // Find the distance to the left: + float3 coords; + coords.x = SMAASearchXLeft(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].xy, offset[2].x); + coords.y = offset[1].y; // offset[1].y = texcoord.y - 0.25 * SMAA_RT_METRICS.y (@CROSSING_OFFSET) + d.x = coords.x; + + // Now fetch the left crossing edges, two at a time using bilinear + // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to + // discern what value each edge has: + float e1 = SMAASampleLevelZero(edgesTex, coords.xy).r; + + // Find the distance to the right: + coords.z = SMAASearchXRight(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].zw, offset[2].y); + d.y = coords.z; + + // We want the distances to be in pixel units (doing this here allow to + // better interleave arithmetic and memory accesses): + d = abs(round(mad(SMAA_RT_METRICS.zz, d, -pixcoord.xx))); + + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + float2 sqrt_d = sqrt(d); + + // Fetch the right crossing edges: + float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.zy, int2(1, 0)).r; + + // Ok, we know how this pattern looks like, now it is time for getting + // the actual area: + weights.rg = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.y); + + // Fix corners: + coords.y = texcoord.y; + SMAADetectHorizontalCornerPattern(SMAATexturePass2D(edgesTex), weights.rg, coords.xyzy, d); + + #if !defined(SMAA_DISABLE_DIAG_DETECTION) + } else + e.r = 0.0; // Skip vertical processing. + #endif + } + + SMAA_BRANCH + if (e.r > 0.0) { // Edge at west + float2 d; + + // Find the distance to the top: + float3 coords; + coords.y = SMAASearchYUp(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].xy, offset[2].z); + coords.x = offset[0].x; // offset[1].x = texcoord.x - 0.25 * SMAA_RT_METRICS.x; + d.x = coords.y; + + // Fetch the top crossing edges: + float e1 = SMAASampleLevelZero(edgesTex, coords.xy).g; + + // Find the distance to the bottom: + coords.z = SMAASearchYDown(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].zw, offset[2].w); + d.y = coords.z; + + // We want the distances to be in pixel units: + d = abs(round(mad(SMAA_RT_METRICS.ww, d, -pixcoord.yy))); + + // SMAAArea below needs a sqrt, as the areas texture is compressed + // quadratically: + float2 sqrt_d = sqrt(d); + + // Fetch the bottom crossing edges: + float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.xz, int2(0, 1)).g; + + // Get the area for this direction: + weights.ba = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.x); + + // Fix corners: + coords.x = texcoord.x; + SMAADetectVerticalCornerPattern(SMAATexturePass2D(edgesTex), weights.ba, coords.xyxz, d); + } + + return weights; +} + +//----------------------------------------------------------------------------- +// Neighborhood Blending Pixel Shader (Third Pass) + +float4 SMAANeighborhoodBlendingPS(float2 texcoord, + float4 offset, + SMAATexture2D(colorTex), + SMAATexture2D(blendTex) + #if SMAA_REPROJECTION + , SMAATexture2D(velocityTex) + #endif + ) { + // Fetch the blending weights for current pixel: + float4 a; + a.x = SMAASample(blendTex, offset.xy).a; // Right + a.y = SMAASample(blendTex, offset.zw).g; // Top + a.wz = SMAASample(blendTex, texcoord).xz; // Bottom / Left + + // Is there any blending weight with a value greater than 0.0? + SMAA_BRANCH + if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5) { + float4 color = SMAASampleLevelZero(colorTex, texcoord); + + #if SMAA_REPROJECTION + float2 velocity = SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, texcoord)); + + // Pack velocity into the alpha channel: + color.a = sqrt(5.0 * length(velocity)); + #endif + + return color; + } else { + bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical) + + // Calculate the blending offsets: + float4 blendingOffset = float4(0.0, a.y, 0.0, a.w); + float2 blendingWeight = a.yw; + SMAAMovc(bool4(h, h, h, h), blendingOffset, float4(a.x, 0.0, a.z, 0.0)); + SMAAMovc(bool2(h, h), blendingWeight, a.xz); + blendingWeight /= dot(blendingWeight, float2(1.0, 1.0)); + + // Calculate the texture coordinates: + float4 blendingCoord = mad(blendingOffset, float4(SMAA_RT_METRICS.xy, -SMAA_RT_METRICS.xy), texcoord.xyxy); + + // We exploit bilinear filtering to mix current pixel with the chosen + // neighbor: + float4 color = blendingWeight.x * SMAASampleLevelZero(colorTex, blendingCoord.xy); + color += blendingWeight.y * SMAASampleLevelZero(colorTex, blendingCoord.zw); + + #if SMAA_REPROJECTION + // Antialias velocity for proper reprojection in a later stage: + float2 velocity = blendingWeight.x * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.xy)); + velocity += blendingWeight.y * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.zw)); + + // Pack velocity into the alpha channel: + color.a = sqrt(5.0 * length(velocity)); + #endif + + return color; + } +} + +//----------------------------------------------------------------------------- +// Temporal Resolve Pixel Shader (Optional Pass) + +float4 SMAAResolvePS(float2 texcoord, + SMAATexture2D(currentColorTex), + SMAATexture2D(previousColorTex) + #if SMAA_REPROJECTION + , SMAATexture2D(velocityTex) + #endif + ) { + #if SMAA_REPROJECTION + // Velocity is assumed to be calculated for motion blur, so we need to + // inverse it for reprojection: + float2 velocity = -SMAA_DECODE_VELOCITY(SMAASamplePoint(velocityTex, texcoord).rg); + + // Fetch current pixel: + float4 current = SMAASamplePoint(currentColorTex, texcoord); + + // Reproject current coordinates and fetch previous pixel: + float4 previous = SMAASamplePoint(previousColorTex, texcoord + velocity); + + // Attenuate the previous pixel if the velocity is different: + float delta = abs(current.a * current.a - previous.a * previous.a) / 5.0; + float weight = 0.5 * saturate(1.0 - sqrt(delta) * SMAA_REPROJECTION_WEIGHT_SCALE); + + // Blend the pixels according to the calculated weight: + return lerp(current, previous, weight); + #else + // Just blend the pixels: + float4 current = SMAASamplePoint(currentColorTex, texcoord); + float4 previous = SMAASamplePoint(previousColorTex, texcoord); + return lerp(current, previous, 0.5); + #endif +} + +//----------------------------------------------------------------------------- +// Separate Multisamples Pixel Shader (Optional Pass) + +#ifdef SMAALoad +void SMAASeparatePS(float4 position, + float2 texcoord, + out float4 target0, + out float4 target1, + SMAATexture2DMS2(colorTexMS)) { + int2 pos = int2(position.xy); + target0 = SMAALoad(colorTexMS, pos, 0); + target1 = SMAALoad(colorTexMS, pos, 1); +} +#endif + +//----------------------------------------------------------------------------- +#endif // SMAA_INCLUDE_PS diff --git a/data_from_portwine/Reshade/Shaders/Sepia.fx b/data_from_portwine/Reshade/Shaders/Sepia.fx new file mode 100644 index 00000000..0e266555 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Sepia.fx @@ -0,0 +1,27 @@ +#include "ReShadeUI.fxh" + +uniform float3 Tint < __UNIFORM_COLOR_FLOAT3 +> = float3(0.55, 0.43, 0.42); + +uniform float Strength < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Adjust the strength of the effect."; +> = 0.58; + +#include "ReShade.fxh" + +float3 TintPass(float4 vois : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 col = tex2D(ReShade::BackBuffer, texcoord).rgb; + + return lerp(col, col * Tint * 2.55, Strength); +} + +technique Tint +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = TintPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Smart_Sharp.fx b/data_from_portwine/Reshade/Shaders/Smart_Sharp.fx new file mode 100644 index 00000000..e9a3bf56 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Smart_Sharp.fx @@ -0,0 +1,768 @@ + ////---------------// + ///**Smart Sharp**/// + //---------------//// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Depth Based Unsharp Mask Bilateral Contrast Adaptive Sharpening v2.4 +// For Reshade 3.0+ +// --------------------------------- +// https://web.stanford.edu/class/cs448f/lectures/2.1/Sharpening.pdf +// +// Bilateral Filter Made by mrharicot ported over to Reshade by BSD +// GitHub Link for sorce info github.com/SableRaf/Filters4Processin +// Shadertoy Link https://www.shadertoy.com/view/4dfGDH Thank You. +// +// Everyone wants to best the bilateral filter..... +// +// +// LICENSE +// ============ +// Overwatch & Code out side the work of people mention above is licenses under: Attribution-NoDerivatives 4.0 International +// +// 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. +// +// NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. +// +// 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-nd/4.0/ +// +// Have fun, +// Jose Negrete AKA BlueSkyDefender +// +// https://github.com/BlueSkyDefender/Depth3D +// http://reshade.me/forum/shader-presentation/2128-sidebyside-3d-depth-map-based-stereoscopic-shader +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if exists "Overwatch.fxh" //Overwatch Intercepter// + #include "Overwatch.fxh" +#else //DA_W Depth_Linearization | DB_X Depth_Flip + static const float DA_W = 0.0, DB_X = 0; + #define NC 0 + #define NP 0 +#endif + +// This is the practical limit for the algorithm's scaling ability. Example resolutions; +// 1280x720 -> 1080p = 2.25x area +// 1536x864 -> 1080p = 1.56x area +// 1792x1008 -> 1440p = 2.04x area +// 1920x1080 -> 1440p = 1.78x area +// 1920x1080 -> 4K = 4.0x area +// 2048x1152 -> 1440p = 1.56x area +// 2560x1440 -> 4K = 2.25x area +// 3072x1728 -> 4K = 1.56x area + +// Determines the power of the Bilateral Filter and sharpening quality. Lower the setting the more performance you would get along with lower quality. +// 0 = Off +// 1 = Low +// 2 = Default +// 3 = Medium +// 4 = High +// Default is off. +#define M_Quality 0 //Manualy set shader Quality. Defaults to 2 when set to off. + +//Zero is Fast, a ''Optimized'' Bilateral Filtering approach wink wink and One is a Acuurate. Acuurate is the correct way of doing Bilateral filtering. +#define B_Accuracy 0 //Bilateral Accuracy + +//Use this to enable motion Sharpen option also reduces perf a bit more +#define Motion_Sharpen 0 + +#define SRGB 0 + +// It is best to run Smart Sharp after tonemapping. +#if !defined(__RESHADE__) || __RESHADE__ < 40000 + #define Compatibility 1 +#else + #define Compatibility 0 +#endif +/* +uniform float TEST < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; +> = 0.0; +*/ + +uniform int Depth_Map < + ui_type = "combo"; + ui_items = "Normal\0Reverse\0"; + ui_label = "Custom Depth Map"; + ui_tooltip = "Pick your Depth Map."; + ui_category = "Depth Buffer"; +> = DA_W; + +uniform float Depth_Map_Adjust < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 1.0; ui_max = 1000.0; ui_step = 0.125; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "Adjust the depth map and sharpness distance."; + ui_category = "Depth Buffer"; +> = 250.0; + +uniform bool Depth_Map_Flip < + ui_label = "Depth Map Flip"; + ui_tooltip = "Flip the depth map if it is upside down."; + ui_category = "Depth Buffer"; +> = DB_X; + +uniform bool No_Depth_Map < + ui_label = "No Depth Map"; + ui_tooltip = "If you have No Depth Buffer turn this On."; + ui_category = "Depth Buffer"; +> = false; + +uniform float Sharpness < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_label = "Sharpening Strength"; + ui_min = 0.0; ui_max = 2.0; + ui_tooltip = "Scaled by adjusting this slider from Zero to One to increase sharpness of the image.\n" + "Zero = No Sharpening, to One = Full Sharpening, and Past One = Extra Crispy.\n" + "Number 0.625 is Equal to AMD FidelityFX Contrast Adaptive Sharpening at max settings.\n" + "Number 0.625 is default."; + ui_category = "Bilateral CAS"; +> = 0.625; + +uniform float B_Grounding < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_label = "Coarseness"; + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Like Coffee pick how rough do you want this shader to be, really just adjusts the radius of the filter.\n" + "Fine -> Medium -> Coarse too what ever you think looks good.\n" + "Let me have fun with names and tooltips........\n" + "Number 0.0 is default."; + ui_category = "Bilateral CAS"; +> = 0.0; + +uniform bool CAM_IOB < + ui_label = "CAM Ignore Overbright"; + ui_tooltip = "Instead of of allowing Overbright in the mask this allows sharpening of this area.\n" + "I think it's more accurate to leave this on."; + ui_category = "Bilateral CAS"; +> = false; + +uniform bool CA_Mask_Boost < + ui_label = "CAM Boost"; + ui_tooltip = "This boosts the power of Contrast Adaptive Masking part of the shader."; + ui_category = "Bilateral CAS"; +> = false; + +uniform bool CA_Removal < + ui_label = "CAM Removal"; + ui_tooltip = "This removes the extra Contrast Adaptive Masking part of the shader.\n" + "Keep in mind This filter already has a level of Contrast Masking.\n" + "This is for people who like the Raw look of Bilateral Sharpen.\n" + "Noise reduction from the Bilateral Filter applies automatically."; + ui_category = "Bilateral CAS"; +> = false; + +#if Motion_Sharpen +uniform int Local_Motion < + ui_type = "combo"; + ui_items = "General Motion\0Local Motion\0"; + ui_label = "View Mode"; + ui_tooltip = "This is used to select between General Motion & Local Motion.\n" + "Default is General Motion."; + ui_category = "Motion Bilateral CAS"; +> = 0; + +uniform float GMD < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_label = "General Motion Detection"; + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Increase the General Motion Detection power.\n" + "This is used to boost Sharpening strength by the user selected ammount.\n" + "Number Zero is default, Off."; + ui_category = "Motion Bilateral CAS"; +> = 0.0; + +uniform float MDSM < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_label = "Sharpen Multiplier"; + ui_min = 1.0; ui_max = 10.0; + ui_tooltip = "Motion Detection Sharpen Multiplier.\n" + "This is the user set mutliplyer for how much you want to increase the base sharpen.\n" + "A Multiplier of 5 should be fine at base sharpness, Try messing around with this.\n" + "A Sharpen Multiplier of 2 is two times the user set Sharpening Strength.\n" + "Number 1 is default."; + ui_category = "Motion Bilateral CAS"; +> = 1.0; +#else +static const int Local_Motion = 0; +static const float GMD = 0.0; +static const float MDSM = 0.0; +#endif +uniform int Debug_View < + ui_type = "combo"; + ui_items = "Normal\0Sharpen View\0Depth Masking\0CAS Mask\0Noise Mask\0"; + ui_label = "Debug View"; + ui_tooltip = "This is to DeBug Smart Sharp and lets you fine tune the shader.\n" + "Let me have fun with names and tooltips......."; + ui_category = "Debug"; +> = 0; + +uniform int F_DeNoise < + ui_type = "combo"; + ui_items = "Off\0Level One DeNoiser\0Level Two DeNoiser\0"; + ui_label = "Smart Denoiser Options"; + ui_tooltip = "This Denoiser can help with Noise in the image.\n" + "LvL One DeNoiser Works with Smart Sharp Only.\n" + "LvL Two DeNoiser Works with other shaders. But, it's a little stronger.\n" + "LvL Three DeNoiser N/A Future add on."; + ui_category = "Extra Menu"; +> = false; + +uniform float Denoise_Power < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_label = "Denoise Power"; + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Increase the Sharpening strength of the DeNoiser.\n" + "Number Zero is default, Off."; + ui_category = "Extra Menu"; +> = 0.5; + +uniform bool ClampSharp < + ui_label = "Clamp Sharpen"; + ui_tooltip = "This Clamps the output of the Sharpen Shader."; + ui_category = "Extra Menu"; +> = true; + +#define Quality 2 + +#if M_Quality > 0 + #undef Quality + #define Quality M_Quality +#endif +/////////////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +#define TexSize float2(BUFFER_WIDTH, BUFFER_HEIGHT) +uniform float timer < source = "timer"; >; +//Since I don't use this for the incorrect Blur I keep it here for the correct one. +#define SIGMA 15 +#define BSIGMA 0.25 //Now I need to keep this one below 0.25 or Halo will happen MC and everything. + +#if Quality == 1 + #define MSIZE 3 +#endif +#if Quality == 2 + #define MSIZE 5 +#endif +#if Quality == 3 + #define MSIZE 7 +#endif +#if Quality == 4 + #define MSIZE 9 +#endif + +texture DepthBufferTex : DEPTH; + +sampler DepthBuffer + { + Texture = DepthBufferTex; + }; + +texture BackBufferTex : COLOR; + +sampler BackBuffer + { + Texture = BackBufferTex; + #if SRGB + SRGBTexture = true; + #endif + }; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if Motion_Sharpen +texture CurrentBBSSTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;}; + +sampler CBBSS + { + Texture = CurrentBBSSTex; + }; + +texture PastBBSSTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;}; + +sampler PBBSS + { + Texture = PastBBSSTex; + }; + +texture DownSTex {Width = 256; Height = 256; Format = R8; MipLevels = 9;}; + +sampler DSM + { + Texture = DownSTex; + }; +#endif +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Depth(in float2 texcoord : TEXCOORD0) +{ + if (Depth_Map_Flip) + texcoord.y = 1 - texcoord.y; + + float zBuffer = tex2Dlod(DepthBuffer, float4(texcoord,0,0)).x; //Depth Buffer + + //Conversions to linear space..... + //Near & Far Adjustment + float Far = 1.0, Near = 0.125/Depth_Map_Adjust; //Division Depth Map Adjust - Near + + float2 Z = float2( zBuffer, 1-zBuffer ); + + if (Depth_Map == 0)//DM0. Normal + zBuffer = Far * Near / (Far + Z.x * (Near - Far)); + else if (Depth_Map == 1)//DM1. Reverse + zBuffer = Far * Near / (Far + Z.y * (Near - Far)); + + return saturate(zBuffer); +} + +float3 RGBtoYCbCr(float3 rgb) +{ float C[1];//The Chronicles of Riddick: Assault on Dark Athena FIX I don't know why it works....... + float Y = .299 * rgb.x + .587 * rgb.y + .114 * rgb.z; // Luminance + float Cb = -.169 * rgb.x - .331 * rgb.y + .500 * rgb.z; // Chrominance Blue + float Cr = .500 * rgb.x - .419 * rgb.y - .081 * rgb.z; // Chrominance Red + return float3(Y,Cb + 128./255.,Cr + 128./255.); +} + +float3 YCbCrtoRGB(float3 ycc) +{ + float3 c = ycc - float3(0., 128./255., 128./255.); + + float R = c.x + 1.400 * c.z; + float G = c.x - 0.343 * c.y - 0.711 * c.z; + float B = c.x + 1.765 * c.y; + return float3(R,G,B); +} + +float Min3(float x, float y, float z) +{ + return min(x, min(y, z)); +} + +float Max3(float x, float y, float z) +{ + return max(x, max(y, z)); +} + +float normpdf(in float x, in float sigma) +{ + return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma; +} + +float normpdf3(in float3 v, in float sigma) +{ + return 0.39894*exp(-0.5*dot(v,v)/(sigma*sigma))/sigma; +} + +float3 BB(in float2 texcoord, float2 AD) +{ + return tex2Dlod(BackBuffer, float4(texcoord + AD,0,0)).rgb; +} + +float LI(float3 RGB) +{ + return dot(RGB,float3(0.2126, 0.7152, 0.0722)); +} + +float GT() { return lerp(1.0,0.5,B_Grounding);} + +float MotionSharpen(float2 texcoord) +{ +#if Motion_Sharpen + float2 PS = pix * 5.0; + float BlurMotion = tex2D(DSM,texcoord).x; + if(Local_Motion) + { + BlurMotion += tex2D(DSM,texcoord + float2(0,PS.y)).x; + BlurMotion += tex2D(DSM,texcoord + float2(PS.x,0)).x; + BlurMotion += tex2D(DSM,texcoord + float2(-PS.x,0)).x; + BlurMotion += tex2D(DSM,texcoord + float2(0,-PS.y)).x; + return (BlurMotion * 0.2) * 12.5; + } + else + return tex2Dlod(DSM,float4(texcoord,0,11)).x * lerp(0.0,25.0,GMD); +#else + return 0; +#endif +} + +float4 GetBBfetch(float2 texcoord, int2 Offset ) +{ + return tex2Dfetch(BackBuffer, texcoord * TexSize + Offset ); +} + +void Smart_Sharp( float2 texcoord,inout float Edge, inout float3 LVB, inout float CAM) +{ + //Bilateral Filter// + const int kSize = MSIZE * 0.5; // Default M-size is Quality 2 so [MSIZE 3] [MSIZE 5] [MSIZE 7] [MSIZE 9] / 2. + float mnRGB, mxRGB, t, l, r, s; + + // Find Edges + t = LI(GetBBfetch(texcoord , int2( 0,-2) ).rgb); + s = LI(GetBBfetch(texcoord , int2( 0, 2) ).rgb); + l = LI(GetBBfetch(texcoord , int2(-2, 0) ).rgb); + r = LI(GetBBfetch(texcoord , int2( 2, 0) ).rgb); + float2 n = float2(t - s,-(r - l)); + float nl = length(n); + + //Later I will add a 3x3 Medium Filter for LVL Three WIP + + float3 final_color, c = BB(texcoord.xy,0), cc; + float2 RPC_WS = pix; + float bZ = rcp(normpdf(0.0, BSIGMA)), Z, factor; + #if B_Accuracy + float kernal[MSIZE]; + [unroll] + for (int o = 0; o <= kSize; ++o) + { + kernal[kSize+o] = kernal[kSize-o] = normpdf(o, SIGMA); + } + #endif + [loop] + for (int i=-kSize; i <= kSize; ++i) + { + for (int j=-kSize; j <= kSize; ++j) + { + cc = BB(texcoord.xy, float2(i,j) * RPC_WS * rcp(kSize * GT()) ); + #if B_Accuracy + factor = normpdf3(cc-c, BSIGMA) * bZ * kernal[kSize+j] * kernal[kSize+i]; + #else + factor = normpdf3(cc-c, BSIGMA); + #endif + Z += factor; + final_color += factor * cc; + } + } + + final_color = saturate(final_color/Z); + + mnRGB = min( min( LI(c), LI(final_color)), LI(cc)); + mxRGB = max( max( LI(c), LI(final_color)), LI(cc)); + + // Smooth minimum distance to signal limit divided by smooth max. + float rcpMRGB = rcp(mxRGB), RGB_D = saturate(min(mnRGB, 1.0 - mxRGB) * rcpMRGB); + + if( CAM_IOB ) + RGB_D = saturate(min(mnRGB, 2.0 - mxRGB) * rcpMRGB); + + // Shaping amount of sharpening masked + float CAS_Mask = RGB_D, Sharp = Sharpness, MD = MotionSharpen(texcoord); + + if(GMD > 0 || Local_Motion) + Sharp = Sharpness * lerp( 1,MDSM,saturate(MD)); + + if(CA_Mask_Boost) + CAS_Mask = lerp(CAS_Mask,CAS_Mask * CAS_Mask,saturate(Sharp * 0.5)); + + if(CA_Removal) + CAS_Mask = 1; + + //Edge Detection + Edge = nl; + //Low Variance Blur + LVB = final_color; + //Contrast Adaptive Masking + CAM = CAS_Mask; + +} + + +float4 Sharpen_Out(float2 texcoord) +{ + float Noise, Edge, CAM, Sharpen_Power = Sharpness, MD = MotionSharpen(texcoord); + float3 LVB; + float4 color = tex2D(BackBuffer, texcoord),Done; + + Smart_Sharp( texcoord, Edge, LVB, CAM); + + if(GMD > 0 || Local_Motion) + Sharpen_Power = Sharpness * lerp( 1,MDSM,saturate(MD)); + + if( F_DeNoise ) + { //Noise reduction for pure Bilateral Sharp + Done = color; + Done /= LVB; + Done = min( Min3(Done.r,Done.g,Done.b) ,2-Max3(Done.r,Done.g,Done.b)); + Noise = saturate(length(Done > 0.950f)); + } + + Sharpen_Power *= 3.1; + + float3 Sharpen;// = (tex2D(BackBuffer,texcoord).rgb - LVB) * Sharpen_Power ; + +//RGBtoYCbCr( +//YCbCrtoRGB( +Sharpen = RGBtoYCbCr(tex2D(BackBuffer,texcoord).rgb - LVB); + +Sharpen.x *= Sharpen_Power; + +Sharpen = YCbCrtoRGB(Sharpen); + + if (ClampSharp) + Sharpen = saturate(Sharpen); +/* + float Grayscale_Sharpen = LI(Sharpen); + + if (Output_Selection == 0) + Sharpen = lerp(Grayscale_Sharpen,Sharpen,0.5); + else if (Output_Selection == 1) + Sharpen = Sharpen; + else + Sharpen = Grayscale_Sharpen; +*/ + float SNoise = Noise; + Noise = saturate(lerp( 1, Noise , Denoise_Power)); + Edge = saturate(Edge > 0.125); + + Sharpen = lerp( max(0,lerp( 0 , Sharpen , Noise )) , Sharpen, Edge) ; + + if( Debug_View == 1) + { + Sharpen = Sharpen; + } + else + { + if( F_DeNoise ) + { + float3 B = LVB, C = F_DeNoise == 1 ? color.rgb : B, S = color.rgb + Sharpen; + + C = RGBtoYCbCr(C); S = RGBtoYCbCr(S); B = RGBtoYCbCr(B); + + C.x = lerp( C.x , S.x , Noise ); + C.yz = lerp( Debug_View == 4 ? 1 : B.yz , S.yz , SNoise ); + + Sharpen.rgb = YCbCrtoRGB(lerp( C , S, Edge )) ; + } + else + Sharpen.rgb = color.rgb + Sharpen; + } + + return float4(lerp(Debug_View == 1 ? 0 : color.rgb,Sharpen, CAM * saturate(Sharpen_Power)),CAM); //Sharpen Out +} + + +float3 ShaderOut(float2 texcoord) +{ + float3 Out, Luma, Sharpen = Sharpen_Out(texcoord).rgb,BB = tex2D(BackBuffer,texcoord).rgb; + float DB = Depth(texcoord).r; + + if(No_Depth_Map) + DB = 0.0; + + if (Debug_View == 0) + Out.rgb = lerp(Sharpen, BB, DB); + else if (Debug_View == 1) + Out.rgb = Sharpen_Out(texcoord).rgb; + else if (Debug_View == 2) + Out.rgb = lerp(float3(1., 0., 1.),tex2D(BackBuffer,float2(texcoord.x,texcoord.y)).rgb,DB); + else if (Debug_View == 3) + Out.rgb = lerp(1.0,Sharpen_Out(texcoord).www,1-DB); + else if (Debug_View == 4) + Out.rgb = lerp(Sharpen, BB, DB); + + + #if Motion_Sharpen + if (Debug_View >= 1) + { + if(texcoord.y < 0.666 && texcoord.y > 0.333 && texcoord.x < 0.666 && texcoord.x > 0.333) + Out = lerp( 0,MDSM,MotionSharpen(texcoord * 3 - 1.0)); + } + #endif + + return Out; +} +#if Motion_Sharpen +float CBackBuffer_SS(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + return dot(tex2D(BackBuffer,texcoord),0.333); +} + +float PBackBuffer_SS(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + return tex2D(CBBSS,texcoord).x; +} + +float2 DownSampleMotion(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ float Motion = abs(tex2D(CBBSS,texcoord).x - tex2D(PBBSS,texcoord).x); + return Motion; +} +#endif +////////////////////////////////////////////////////////Logo///////////////////////////////////////////////////////////////////////// +float3 Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ //Overwatch integration + float PosX = 0.9525f*BUFFER_WIDTH*pix.x,PosY = 0.975f*BUFFER_HEIGHT*pix.y, Text_Timer = 12500, BT = smoothstep(0,1,sin(timer*(3.75/1000))); + float D,E,P,T,H,Three,DD,Dot,I,N,F,O,R,EE,A,DDD,HH,EEE,L,PP,NN,PPP,C,Not,No; + float3 Color = ShaderOut(texcoord).rgb; + //Color = tex2Dlod(DSM,float4(texcoord,0,11)).x * lerp(0.0,25.0,GMD); + if(NC || NP) + Text_Timer = 18750; + + [branch] if(timer <= Text_Timer) + { + //DEPTH + //D + float PosXD = -0.035+PosX, offsetD = 0.001; + float OneD = all( abs(float2( texcoord.x -PosXD, texcoord.y-PosY)) < float2(0.0025,0.009)); + float TwoD = all( abs(float2( texcoord.x -PosXD-offsetD, texcoord.y-PosY)) < float2(0.0025,0.007)); + D = OneD-TwoD; + //E + float PosXE = -0.028+PosX, offsetE = 0.0005; + float OneE = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.009)); + float TwoE = all( abs(float2( texcoord.x -PosXE-offsetE, texcoord.y-PosY)) < float2(0.0025,0.007)); + float ThreeE = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.001)); + E = (OneE-TwoE)+ThreeE; + //P + float PosXP = -0.0215+PosX, PosYP = -0.0025+PosY, offsetP = 0.001, offsetP1 = 0.002; + float OneP = all( abs(float2( texcoord.x -PosXP, texcoord.y-PosYP)) < float2(0.0025,0.009*0.775)); + float TwoP = all( abs(float2( texcoord.x -PosXP-offsetP, texcoord.y-PosYP)) < float2(0.0025,0.007*0.680)); + float ThreeP = all( abs(float2( texcoord.x -PosXP+offsetP1, texcoord.y-PosY)) < float2(0.0005,0.009)); + P = (OneP-TwoP) + ThreeP; + //T + float PosXT = -0.014+PosX, PosYT = -0.008+PosY; + float OneT = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosYT)) < float2(0.003,0.001)); + float TwoT = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosY)) < float2(0.000625,0.009)); + T = OneT+TwoT; + //H + float PosXH = -0.0072+PosX; + float OneH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.001)); + float TwoH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.009)); + float ThreeH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.00325,0.009)); + H = (OneH-TwoH)+ThreeH; + //Three + float offsetFive = 0.001, PosX3 = -0.001+PosX; + float OneThree = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.009)); + float TwoThree = all( abs(float2( texcoord.x -PosX3 - offsetFive, texcoord.y-PosY)) < float2(0.003,0.007)); + float ThreeThree = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.001)); + Three = (OneThree-TwoThree)+ThreeThree; + //DD + float PosXDD = 0.006+PosX, offsetDD = 0.001; + float OneDD = all( abs(float2( texcoord.x -PosXDD, texcoord.y-PosY)) < float2(0.0025,0.009)); + float TwoDD = all( abs(float2( texcoord.x -PosXDD-offsetDD, texcoord.y-PosY)) < float2(0.0025,0.007)); + DD = OneDD-TwoDD; + //Dot + float PosXDot = 0.011+PosX, PosYDot = 0.008+PosY; + float OneDot = all( abs(float2( texcoord.x -PosXDot, texcoord.y-PosYDot)) < float2(0.00075,0.0015)); + Dot = OneDot; + //INFO + //I + float PosXI = 0.0155+PosX, PosYI = 0.004+PosY, PosYII = 0.008+PosY; + float OneI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosY)) < float2(0.003,0.001)); + float TwoI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYI)) < float2(0.000625,0.005)); + float ThreeI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYII)) < float2(0.003,0.001)); + I = OneI+TwoI+ThreeI; + //N + float PosXN = 0.0225+PosX, PosYN = 0.005+PosY,offsetN = -0.001; + float OneN = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN)) < float2(0.002,0.004)); + float TwoN = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN - offsetN)) < float2(0.003,0.005)); + N = OneN-TwoN; + //F + float PosXF = 0.029+PosX, PosYF = 0.004+PosY, offsetF = 0.0005, offsetF1 = 0.001; + float OneF = all( abs(float2( texcoord.x -PosXF-offsetF, texcoord.y-PosYF-offsetF1)) < float2(0.002,0.004)); + float TwoF = all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0025,0.005)); + float ThreeF = all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0015,0.00075)); + F = (OneF-TwoF)+ThreeF; + //O + float PosXO = 0.035+PosX, PosYO = 0.004+PosY; + float OneO = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.003,0.005)); + float TwoO = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.002,0.003)); + O = OneO-TwoO; + //Text Warnings: No Profile / Not Compatible + //PosY += 0.953; + PosX -= 0.483; + float PosXNN = -0.458+PosX, offsetNN = 0.0015; + float OneNN = all( abs(float2( texcoord.x -PosXNN, texcoord.y-PosY)) < float2(0.00325,0.009)); + float TwoNN = all( abs(float2( texcoord.x -PosXNN, texcoord.y-PosY-offsetNN)) < float2(0.002,0.008)); + NN = OneNN-TwoNN; + //PPP + float PosXPPP = -0.451+PosX, PosYPPP = -0.0025+PosY, offsetPPP = 0.001, offsetPPP1 = 0.002; + float OnePPP = all( abs(float2( texcoord.x -PosXPPP, texcoord.y-PosYPPP)) < float2(0.0025,0.009*0.775)); + float TwoPPP = all( abs(float2( texcoord.x -PosXPPP-offsetPPP, texcoord.y-PosYPPP)) < float2(0.0025,0.007*0.680)); + float ThreePPP = all( abs(float2( texcoord.x -PosXPPP+offsetPPP1, texcoord.y-PosY)) < float2(0.0005,0.009)); + PPP = (OnePPP-TwoPPP) + ThreePPP; + //C + float PosXC = -0.450+PosX, offsetC = 0.001; + float OneC = all( abs(float2( texcoord.x -PosXC, texcoord.y-PosY)) < float2(0.0035,0.009)); + float TwoC = all( abs(float2( texcoord.x -PosXC-offsetC, texcoord.y-PosY)) < float2(0.0025,0.007)); + C = OneC-TwoC; + if(NP) + No = (NN + PPP) * BT; //Blinking Text + if(NC) + Not = (NN + C) * BT; //Blinking Text + //Website + return D+E+P+T+H+Three+DD+Dot+I+N+F+O+No+Not ? (1-texcoord.y*50.0+48.85)*texcoord.y-0.500: Color; + } + else + return Color; +} + +///////////////////////////////////////////////////////////ReShade.fxh///////////////////////////////////////////////////////////// + +// 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) +{ + 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 Smart_Sharp +< ui_tooltip = "Suggestion : You Can Enable 'Performance Mode Checkbox,' in the lower bottom right of the ReShade's Main UI.\n" + " Do this once you set your Smart Sharp settings of course."; > +{ + #if Motion_Sharpen // Motion Sharpen makes this shader slower. + pass PBB //Done this way to keep Freestyle comp. + { + VertexShader = PostProcessVS; + PixelShader = PBackBuffer_SS; + RenderTarget = PastBBSSTex; + } + pass CBB + { + VertexShader = PostProcessVS; + PixelShader = CBackBuffer_SS; + RenderTarget = CurrentBBSSTex; + } + pass Down_Sample_Motion + { + VertexShader = PostProcessVS; + PixelShader = DownSampleMotion; + RenderTarget = DownSTex; + } + #endif + pass UnsharpMask + { + VertexShader = PostProcessVS; + PixelShader = Out; + #if SRGB + SRGBWriteEnable = true; + #endif + } +} diff --git a/data_from_portwine/Reshade/Shaders/Splitscreen.fx b/data_from_portwine/Reshade/Shaders/Splitscreen.fx new file mode 100644 index 00000000..1056a1a0 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Splitscreen.fx @@ -0,0 +1,176 @@ +/*------------------. +| :: Description :: | +'-------------------/ + + Splitscreen (version 2.0) + + Author: CeeJay.dk + License: MIT + + About: + Displays the image before and after it has been modified by effects using a splitscreen + + + Ideas for future improvement: + * + + History: + (*) Feature (+) Improvement (x) Bugfix (-) Information (!) Compatibility + + Version 1.0 + * Does a splitscreen before/after view + + Version 2.0 + * Ported to Reshade 3.x + * Added UI settings. + * Added Diagonal split mode + - Removed curvy mode. I didn't like how it looked. + - Threatened other modes to behave or they would be next. +*/ + +/*------------------. +| :: UI Settings :: | +'------------------*/ + +#include "ReShadeUI.fxh" + +uniform int splitscreen_mode < + ui_type = "combo"; + ui_label = "Mode"; + ui_tooltip = "Choose a mode"; + //ui_category = ""; + ui_items = + "Vertical 50/50 split\0" + "Vertical 25/50/25 split\0" + "Angled 50/50 split\0" + "Angled 25/50/25 split\0" + "Horizontal 50/50 split\0" + "Horizontal 25/50/25 split\0" + "Diagonal split\0" + ; +> = 0; + +/*---------------. +| :: Includes :: | +'---------------*/ + +#include "ReShade.fxh" + + +/*-------------------------. +| :: Texture and sampler:: | +'-------------------------*/ + +texture Before { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; }; +sampler Before_sampler { Texture = Before; }; + + +/*-------------. +| :: Effect :: | +'-------------*/ + +float4 PS_Before(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + return tex2D(ReShade::BackBuffer, texcoord); +} + +float4 PS_After(float4 pos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float4 color; + + // -- Vertical 50/50 split -- + [branch] if (splitscreen_mode == 0) + color = (texcoord.x < 0.5 ) ? tex2D(Before_sampler, texcoord) : tex2D(ReShade::BackBuffer, texcoord); + + // -- Vertical 25/50/25 split -- + [branch] if (splitscreen_mode == 1) + { + //Calculate the distance from center + float dist = abs(texcoord.x - 0.5); + + //Further than 1/4 away from center? + dist = saturate(dist - 0.25); + + color = dist ? tex2D(Before_sampler, texcoord) : tex2D(ReShade::BackBuffer, texcoord); + } + + // -- Angled 50/50 split -- + [branch] if (splitscreen_mode == 2) + { + //Calculate the distance from center + float dist = ((texcoord.x - 3.0/8.0) + (texcoord.y * 0.25)); + + //Further than 1/4 away from center? + dist = saturate(dist - 0.25); + + color = dist ? tex2D(ReShade::BackBuffer, texcoord) : tex2D(Before_sampler, texcoord); + } + + // -- Angled 25/50/25 split -- + [branch] if (splitscreen_mode == 3) + { + //Calculate the distance from center + float dist = ((texcoord.x - 3.0/8.0) + (texcoord.y * 0.25)); + + dist = abs(dist - 0.25); + + //Further than 1/4 away from center? + dist = saturate(dist - 0.25); + + color = dist ? tex2D(Before_sampler, texcoord) : tex2D(ReShade::BackBuffer, texcoord); + } + + // -- Horizontal 50/50 split -- + [branch] if (splitscreen_mode == 4) + color = (texcoord.y < 0.5) ? tex2D(Before_sampler, texcoord) : tex2D(ReShade::BackBuffer, texcoord); + + // -- Horizontal 25/50/25 split -- + [branch] if (splitscreen_mode == 5) + { + //Calculate the distance from center + float dist = abs(texcoord.y - 0.5); + + //Further than 1/4 away from center? + dist = saturate(dist - 0.25); + + color = dist ? tex2D(Before_sampler, texcoord) : tex2D(ReShade::BackBuffer, texcoord); + } + + // -- Diagonal split -- + [branch] if (splitscreen_mode == 6) + { + //Calculate the distance from center + float dist = (texcoord.x + texcoord.y); + + //Further than 1/2 away from center? + //dist = saturate(dist - 1.0); + + color = (dist < 1.0) ? tex2D(Before_sampler, texcoord) : tex2D(ReShade::BackBuffer, texcoord); + } + + return color; +} + + +/*-----------------. +| :: Techniques :: | +'-----------------*/ + +technique Before +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_Before; + RenderTarget = Before; + } +} + +technique After +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_After; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Technicolor.fx b/data_from_portwine/Reshade/Shaders/Technicolor.fx new file mode 100644 index 00000000..40f3c36f --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Technicolor.fx @@ -0,0 +1,50 @@ +/** + * Technicolor version 1.1 + * Original by DKT70 + * Optimized by CeeJay.dk + */ + +#include "ReShadeUI.fxh" + +uniform float Power < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 8.0; +> = 4.0; +uniform float3 RGBNegativeAmount < __UNIFORM_COLOR_FLOAT3 +> = float3(0.88, 0.88, 0.88); + +uniform float Strength < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Adjust the strength of the effect."; +> = 0.4; + +#include "ReShade.fxh" + +float3 TechnicolorPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + const float3 cyanfilter = float3(0.0, 1.30, 1.0); + const float3 magentafilter = float3(1.0, 0.0, 1.05); + const float3 yellowfilter = float3(1.6, 1.6, 0.05); + const float2 redorangefilter = float2(1.05, 0.620); // RG_ + const float2 greenfilter = float2(0.30, 1.0); // RG_ + const float2 magentafilter2 = magentafilter.rb; // R_B + + float3 tcol = tex2D(ReShade::BackBuffer, texcoord).rgb; + + float2 negative_mul_r = tcol.rg * (1.0 / (RGBNegativeAmount.r * Power)); + float2 negative_mul_g = tcol.rg * (1.0 / (RGBNegativeAmount.g * Power)); + float2 negative_mul_b = tcol.rb * (1.0 / (RGBNegativeAmount.b * Power)); + float3 output_r = dot(redorangefilter, negative_mul_r).xxx + cyanfilter; + float3 output_g = dot(greenfilter, negative_mul_g).xxx + magentafilter; + float3 output_b = dot(magentafilter2, negative_mul_b).xxx + yellowfilter; + + return lerp(tcol, output_r * output_g * output_b, Strength); +} + +technique Technicolor +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = TechnicolorPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Technicolor2.fx b/data_from_portwine/Reshade/Shaders/Technicolor2.fx new file mode 100644 index 00000000..cd0e5af7 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Technicolor2.fx @@ -0,0 +1,62 @@ +/** + * Technicolor2 version 1.0 + * Original by Prod80 + * Optimized by CeeJay.dk + */ + +#include "ReShadeUI.fxh" + +uniform float3 ColorStrength < __UNIFORM_COLOR_FLOAT3 + ui_tooltip = "Higher means darker and more intense colors."; +> = float3(0.2, 0.2, 0.2); + +uniform float Brightness < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.5; ui_max = 1.5; + ui_tooltip = "Higher means brighter image."; +> = 1.0; +uniform float Saturation < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.5; + ui_tooltip = "Additional saturation control since this effect tends to oversaturate the image."; +> = 1.0; + +uniform float Strength < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Adjust the strength of the effect."; +> = 1.0; + +#include "ReShade.fxh" + +float3 TechnicolorPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = saturate(tex2D(ReShade::BackBuffer, texcoord).rgb); + + float3 temp = 1.0 - color; + float3 target = temp.grg; + float3 target2 = temp.bbr; + float3 temp2 = color * target; + temp2 *= target2; + + temp = temp2 * ColorStrength; + temp2 *= Brightness; + + target = temp.grg; + target2 = temp.bbr; + + temp = color - target; + temp += temp2; + temp2 = temp - target2; + + color = lerp(color, temp2, Strength); + color = lerp(dot(color, 0.333), color, Saturation); + + return color; +} + +technique Technicolor2 +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = TechnicolorPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Temporal_AA.fx b/data_from_portwine/Reshade/Shaders/Temporal_AA.fx new file mode 100644 index 00000000..13ab6a2c --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Temporal_AA.fx @@ -0,0 +1,454 @@ + ////-------// + ///**TAA**/// + //-------//// + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //* Temporal AA "Epic Games" implementation + Some Magic: + //* For ReShade 3.0+ v 1.1 + //* --------------------------------- + //* TAA + //* Due Diligence + //* Based on port by yvt + //* https://www.shadertoy.com/view/4tcXD2 + //* https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf + //* If I missed any please tell me. + //* + //* LICENSE + //* ============ + //* Image Contrast Enhancement is licenses under: Attribution-NoDerivatives 4.0 International + //* + //* 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. + //* + //* NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + //* + //* 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-nd/4.0/ + //* + //* Have fun, + //* Jose Negrete AKA BlueSkyDefender + //* + //* https://github.com/BlueSkyDefender/Depth3D + //* + //* Special thank you too "Jak0bW" j4712@web.de For Mouse Compatibility & Guidance. + //* Please feel free to message him for help and information + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if exists "Overwatch.fxh" //Overwatch Intercepter// + #include "Overwatch.fxh" +#else //DA_W Depth_Linearization | DB_X Depth_Flip + static const float DA_W = 0.0, DB_X = 0; + #define NC 0 + #define NP 0 +#endif + +#define App_Sync 0 + +uniform float Clamping_Adjust < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 0; ui_max = 1.0; + ui_label = "Clamping Adjust"; + ui_tooltip = "Adjust Clamping that effects Blur.\n" + "Default is Zero."; + ui_category = "TAA"; +> = 0.0; + +uniform float Persistence < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 0.0; ui_max = 1.00; + ui_label = "User Adjust"; + ui_tooltip = "Increase persistence of the frames this is really the Temporal Part.\n" + "Default is 0.25. But, a value around 0.05 is recommended."; + ui_category = "TAA"; +> = 0.125; + +uniform float Similarity < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = -1.0; ui_max = 1.0; + ui_label = "Depth Similarity"; + ui_tooltip = "Extra Image clamping based on Depth Similarities between Past and Current Depth for DeGhosing TAA.\n" + "Works on Depth & Color Delta is Selected and Depth is working in the game.\n" + "Default is 0.25."; + ui_category = "TAA"; +> = 0.25; + +uniform int Delta < + ui_type = "combo"; + ui_label = "Used Delta Masking"; + ui_items = "Color Delta\0Depth Delta\0"; + ui_label = "TAA"; + ui_category = "TAA"; +> = 0; + +uniform float Delta_Power < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 0.0; ui_max = 1.0; + ui_label = "Color & Depth Delta Power"; + ui_tooltip = "Extra Image clamping based on delta between Past and Current Depth Buffer.\n" + "Only works on Depth Delta is Selected and Depth is working in the game.\n" + "Default is 0.25."; + ui_category = "TAA"; +> = 0.25; + +//Depth Map// +uniform int Debug < + ui_type = "combo"; + ui_items = "TAA\0Delta Clamping\0DeGhosting Mask\0Depth\0"; + ui_label = "Debug View"; +> = 0; + +uniform int Depth_Map < + ui_type = "combo"; + ui_items = "Normal\0Reverse\0"; + ui_label = "Custom Depth Map"; + ui_tooltip = "Pick your Depth Map."; + ui_category = "Depth Buffer"; +> = DA_W; + +uniform float Depth_Map_Adjust < + #if Compatibility + ui_type = "drag"; + #else + ui_type = "slider"; + #endif + ui_min = 1.0; ui_max = 1000.0; ui_step = 0.125; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "Adjust the depth map and sharpness distance."; + ui_category = "Depth Buffer"; +> = 250.0; + +uniform float Depth_CutOff < + ui_type = "drag"; + ui_min = -1.0; ui_max = 1.0; + ui_label = "Depth CutOff point"; + ui_tooltip = "Use this too set a TAA Cutoff point based on depth.\n" + "Default is 0.0."; + ui_category = "Depth Buffer"; +> = 0.0; + +uniform bool Depth_Map_Flip < + ui_label = "Depth Map Flip"; + ui_tooltip = "Flip the depth map if it is upside down."; + ui_category = "Depth Buffer"; +> = DB_X; + +/////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// +texture DepthBufferTex : DEPTH; + +sampler DepthBuffer + { + Texture = DepthBufferTex; + }; + +texture BackBufferTex : COLOR; + +sampler BackBuffer + { + Texture = BackBufferTex; + }; + +texture CurrentBackBufferTAA { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;}; + +sampler CBackBuffer + { + Texture = CurrentBackBufferTAA; + }; + +texture CurrentDepthBufferTAA { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16f;}; + +sampler CDepthBuffer + { + Texture = CurrentDepthBufferTAA; + }; + +texture PastBackBufferTAA { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;}; + +sampler PBackBuffer + { + Texture = PastBackBufferTAA; + }; + +texture PastSingleBackBufferTAA { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;}; + +sampler PSBackBuffer + { + Texture = PastSingleBackBufferTAA; + }; + +texture PastSingleDepthBufferTAA { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16f;}; + +sampler PSDepthBuffer + { + Texture = PastSingleDepthBufferTAA; + }; +//Total amount of frames since the game started. +uniform uint framecount < source = "framecount"; >; +uniform float timer < source = "timer"; >; +///////////////////////////////////////////////////////////TAA///////////////////////////////////////////////////////////////////// +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +#define iResolution float2(BUFFER_WIDTH, BUFFER_HEIGHT) +#define Alternate framecount % 2 == 0 + +float2 DepthM(float2 texcoord) +{ + if (Depth_Map_Flip) + texcoord.y = 1 - texcoord.y; + + float zBuffer = tex2D(DepthBuffer, texcoord).x; //Depth Buffer + //Conversions to linear space..... + //Near & Far Adjustment + float Far = 1.0, Near = 0.125/Depth_Map_Adjust; //Division Depth Map Adjust - Near + + float2 Z = float2( zBuffer, 1-zBuffer ); + + if (Depth_Map == 0)//DM0. Normal + zBuffer = Far * Near / (Far + Z.x * (Near - Far)); + else if (Depth_Map == 1)//DM1. Reverse + zBuffer = Far * Near / (Far + Z.y * (Near - Far)); + + return float2(step(smoothstep(0,1,zBuffer),abs(Depth_CutOff)),zBuffer); +} + +float4 BB_H(float2 TC) +{ + return tex2D(BackBuffer, TC ); +} + +// YUV-RGB conversion routine from Hyper3D +float3 encodePalYuv(float3 rgb) +{ + float3 RGB2Y = float3( 0.299, 0.587, 0.114); + float3 RGB2Cb = float3(-0.169,-0.331, 0.500); + float3 RGB2Cr = float3( 0.500,-0.419,-0.081); + + return float3(dot(rgb, RGB2Y), dot(rgb, RGB2Cb), dot(rgb, RGB2Cr)); +} + +float3 decodePalYuv(float3 ycc) +{ + float3 YCbCr2R = float3( 1.000, 0.000, 1.400); + float3 YCbCr2G = float3( 1.000,-0.343,-0.711); + float3 YCbCr2B = float3( 1.000, 1.765, 0.000); + + return float3(dot(ycc, YCbCr2R), dot(ycc, YCbCr2G), dot(ycc, YCbCr2B)); +} + +float4 TAA(float2 texcoord) +{ //Depth Similarity + float M_Similarity = 1-abs(Similarity), D_Similarity = saturate(pow(abs(DepthM(texcoord).y/tex2D(PSDepthBuffer,texcoord).x), 100) + M_Similarity); + //Velocity Scaler + float S_Velocity = 12.5 * lerp( 1, 80,Delta_Power), V_Buffer = saturate(distance(DepthM(texcoord).y,tex2D(PSDepthBuffer,texcoord).x) * S_Velocity); + + float Per = 1-Persistence; + float4 PastColor = tex2Dlod(PBackBuffer,float4(texcoord,0,0) );//Past Back Buffer + PastColor = (1-Per) * tex2D(BackBuffer, texcoord) + Per * PastColor; + + float3 antialiased = PastColor.xyz; + float mixRate = min(PastColor.w, 0.5), MB = Clamping_Adjust;//WIP + + float3 BB = tex2D(BackBuffer, texcoord).xyz; + + antialiased = lerp(antialiased * antialiased, BB * BB, mixRate); + antialiased = sqrt(antialiased); + + const float2 XYoffset[8] = { float2( 0,+pix.y ), float2( 0,-pix.y), float2(+pix.x, 0), float2(-pix.x, 0), float2(-pix.x,-pix.y), float2(+pix.x,-pix.y), float2(-pix.x,+pix.y), float2(+pix.x,+pix.y) }; + + float3 minColor = encodePalYuv(tex2D(BackBuffer, texcoord ).rgb) - MB; + float3 maxColor = encodePalYuv(tex2D(BackBuffer, texcoord ).rgb) + MB; + for(int i = 1; i < 8; ++i) + { //DX9 work around. + minColor = min(minColor,encodePalYuv(tex2Dlod(BackBuffer, float4(texcoord + XYoffset[i],0,0)).rgb)) - MB; + maxColor = max(maxColor,encodePalYuv(tex2Dlod(BackBuffer, float4(texcoord + XYoffset[i],0,0)).rgb)) + MB; + } + antialiased = clamp(encodePalYuv(antialiased), minColor, maxColor); + + mixRate = rcp(1.0 / mixRate + 1.0); + + float diff = length(BB - tex2D(PSBackBuffer, texcoord).xyz) * lerp(1.0,8.0,Delta_Power); + + if(Delta == 1) + diff = V_Buffer; + + float clampAmount = diff; + + mixRate += clampAmount; + mixRate = clamp(mixRate, 0.05, 0.5); + + antialiased = decodePalYuv(antialiased); + //Need to check for DX9 + float4 Output = Similarity > 0 ? lerp(float4(BB,1), float4(antialiased,mixRate), D_Similarity) : float4(lerp(BB,antialiased, D_Similarity),mixRate); + + if (Debug == 1) + Output = diff; + else if (Debug == 2) + Output = lerp(float3(1,0,0),Output.rgb, D_Similarity); + else if (Debug == 3) + Output = DepthM(texcoord).y; + + return Output; +} + +void Out(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 color : SV_Target) +{ + float PosX = 0.9525f*BUFFER_WIDTH*pix.x,PosY = 0.975f*BUFFER_HEIGHT*pix.y, Scale = 2; + float3 D,E,P,T,H,Three,DD,Dot,I,N,F,O; + + float4 T_A_A = TAA(texcoord); + + #if App_Sync + if(texcoord.x < pix.x * Scale && 1-texcoord.y < pix.y * Scale) + T_A_A = Alternate ? 0 : 1; //Jak0bW Suggestion for Mouse Jiggle Wiggle + #endif + + [branch] if(timer <= 12500) + { + //DEPTH + //D + float PosXD = -0.035+PosX, offsetD = 0.001; + float3 OneD = all( abs(float2( texcoord.x -PosXD, texcoord.y-PosY)) < float2(0.0025,0.009)); + float3 TwoD = all( abs(float2( texcoord.x -PosXD-offsetD, texcoord.y-PosY)) < float2(0.0025,0.007)); + D = OneD-TwoD; + + //E + float PosXE = -0.028+PosX, offsetE = 0.0005; + float3 OneE = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.009)); + float3 TwoE = all( abs(float2( texcoord.x -PosXE-offsetE, texcoord.y-PosY)) < float2(0.0025,0.007)); + float3 ThreeE = all( abs(float2( texcoord.x -PosXE, texcoord.y-PosY)) < float2(0.003,0.001)); + E = (OneE-TwoE)+ThreeE; + + //P + float PosXP = -0.0215+PosX, PosYP = -0.0025+PosY, offsetP = 0.001, offsetP1 = 0.002; + float3 OneP = all( abs(float2( texcoord.x -PosXP, texcoord.y-PosYP)) < float2(0.0025,0.009*0.775)); + float3 TwoP = all( abs(float2( texcoord.x -PosXP-offsetP, texcoord.y-PosYP)) < float2(0.0025,0.007*0.680)); + float3 ThreeP = all( abs(float2( texcoord.x -PosXP+offsetP1, texcoord.y-PosY)) < float2(0.0005,0.009)); + P = (OneP-TwoP) + ThreeP; + + //T + float PosXT = -0.014+PosX, PosYT = -0.008+PosY; + float3 OneT = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosYT)) < float2(0.003,0.001)); + float3 TwoT = all( abs(float2( texcoord.x -PosXT, texcoord.y-PosY)) < float2(0.000625,0.009)); + T = OneT+TwoT; + + //H + float PosXH = -0.0072+PosX; + float3 OneH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.001)); + float3 TwoH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.002,0.009)); + float3 ThreeH = all( abs(float2( texcoord.x -PosXH, texcoord.y-PosY)) < float2(0.00325,0.009)); + H = (OneH-TwoH)+ThreeH; + + //Three + float offsetFive = 0.001, PosX3 = -0.001+PosX; + float3 OneThree = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.009)); + float3 TwoThree = all( abs(float2( texcoord.x -PosX3 - offsetFive, texcoord.y-PosY)) < float2(0.003,0.007)); + float3 ThreeThree = all( abs(float2( texcoord.x -PosX3, texcoord.y-PosY)) < float2(0.002,0.001)); + Three = (OneThree-TwoThree)+ThreeThree; + + //DD + float PosXDD = 0.006+PosX, offsetDD = 0.001; + float3 OneDD = all( abs(float2( texcoord.x -PosXDD, texcoord.y-PosY)) < float2(0.0025,0.009)); + float3 TwoDD = all( abs(float2( texcoord.x -PosXDD-offsetDD, texcoord.y-PosY)) < float2(0.0025,0.007)); + DD = OneDD-TwoDD; + + //Dot + float PosXDot = 0.011+PosX, PosYDot = 0.008+PosY; + float3 OneDot = all( abs(float2( texcoord.x -PosXDot, texcoord.y-PosYDot)) < float2(0.00075,0.0015)); + Dot = OneDot; + + //INFO + //I + float PosXI = 0.0155+PosX, PosYI = 0.004+PosY, PosYII = 0.008+PosY; + float3 OneI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosY)) < float2(0.003,0.001)); + float3 TwoI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYI)) < float2(0.000625,0.005)); + float3 ThreeI = all( abs(float2( texcoord.x - PosXI, texcoord.y - PosYII)) < float2(0.003,0.001)); + I = OneI+TwoI+ThreeI; + + //N + float PosXN = 0.0225+PosX, PosYN = 0.005+PosY,offsetN = -0.001; + float3 OneN = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN)) < float2(0.002,0.004)); + float3 TwoN = all( abs(float2( texcoord.x - PosXN, texcoord.y - PosYN - offsetN)) < float2(0.003,0.005)); + N = OneN-TwoN; + + //F + float PosXF = 0.029+PosX, PosYF = 0.004+PosY, offsetF = 0.0005, offsetF1 = 0.001; + float3 OneF = all( abs(float2( texcoord.x -PosXF-offsetF, texcoord.y-PosYF-offsetF1)) < float2(0.002,0.004)); + float3 TwoF = all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0025,0.005)); + float3 ThreeF = all( abs(float2( texcoord.x -PosXF, texcoord.y-PosYF)) < float2(0.0015,0.00075)); + F = (OneF-TwoF)+ThreeF; + + //O + float PosXO = 0.035+PosX, PosYO = 0.004+PosY; + float3 OneO = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.003,0.005)); + float3 TwoO = all( abs(float2( texcoord.x -PosXO, texcoord.y-PosYO)) < float2(0.002,0.003)); + O = OneO-TwoO; + //Website + color = float4(D+E+P+T+H+Three+DD+Dot+I+N+F+O,1.) ? 1-texcoord.y*50.0+48.35f : T_A_A; + } + else + color = T_A_A; +} + +void Current_BackBuffer(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 Color : SV_Target0, out float Depth : SV_Target1) +{ + Color = BB_H(texcoord); + Depth = DepthM(texcoord).y; +} + +void Past_BackBuffer(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 PastSingleC : SV_Target0, out float PastSingleD : SV_Target1, out float4 Past : SV_Target2) +{ + PastSingleC = tex2D(CBackBuffer,texcoord).rgba; + PastSingleD = tex2D(CDepthBuffer,texcoord).x; + Past = BB_H(texcoord); +} +///////////////////////////////////////////////////////////ReShade.fxh///////////////////////////////////////////////////////////// +// 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) +{ + 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); +} + +technique TAA + { + pass CBB + { + VertexShader = PostProcessVS; + PixelShader = Current_BackBuffer; + RenderTarget0 = CurrentBackBufferTAA; + RenderTarget1 = CurrentDepthBufferTAA; + } + pass Out + { + VertexShader = PostProcessVS; + PixelShader = Out; + } + pass PBB + { + VertexShader = PostProcessVS; + PixelShader = Past_BackBuffer; + RenderTarget0 = PastSingleBackBufferTAA; + RenderTarget1 = PastSingleDepthBufferTAA; + RenderTarget2 = PastBackBufferTAA; + } + } diff --git a/data_from_portwine/Reshade/Shaders/TobiiEye_FreePie_AstrayFX.py b/data_from_portwine/Reshade/Shaders/TobiiEye_FreePie_AstrayFX.py new file mode 100644 index 00000000..cecb67ce --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/TobiiEye_FreePie_AstrayFX.py @@ -0,0 +1,68 @@ +#To use this script load it up in FreePie and make sure you have Tobii Eye Tracker fully installed and Enabled. + +#Then make sure to start FreePie in Admin mode then run this script. Once that is done Move your head the full +#length of your monitor so that it calibrates it's center. Then start your game with reshade and start my Shader. +#Once in game and in SuperDepth3D's Menu use the Calibrate slider to reduce the ghosting in game to a tolerable +#level. There should be a veary slight delay in tracking this is ok for now maybe it can be improved later. + +#Thank you and as always for more information head over to http://www.Depth3D.com +#If you like to dontate please do at. https://www.buymeacoffee.com/BlueSkyDefender + +#Downloads Needed +#https://andersmalmgren.github.io/FreePIE/ +#https://gaming.tobii.com/getstarted/ + +#If you don't know what your doing don't adjust the script below this line. +def map_tobii(n): + IsLooking = tobiiEyeX.userPresence == "Present" + Center = 4 + MC = Center * 2 + + if (IsLooking): #and enabled): + #yaw = rotobiiEyeX.yaw + #roll = tobiiEyeX.roll + #x = tobiiEyeX.averageEyePositionInMmX + #y = tobiiEyeX.averageEyePositionInMmY + #z = tobiiEyeX.averageEyePositionInMmZ + x = tobiiEyeX.averageEyePositionNormalizedX * MC - Center + y = tobiiEyeX.averageEyePositionNormalizedY * MC - Center + z = round(tobiiEyeX.averageEyePositionNormalizedZ * MC) + #x = tobiiEyeX.normalizedCenterDeltaX + #y = tobiiEyeX.normalizedCenterDeltaY + #x = tobiiEyeX.gazePointInPixelsX + #y = tobiiEyeX.gazePointInPixelsY + else : + #yaw = 0 + #roll = 0 + x = 0 + y = 0 + z = 0 + + #freePieIO[0].yaw = 0 + #freePieIO[0].pitch = 0 + #freePieIO[0].roll = 0 + freePieIO[0].x = x + freePieIO[0].y = y + freePieIO[0].z = z + + #diagnostics.watch(enabled) + #diagnostics.watch(yaw) + #diagnostics.watch(roll) + diagnostics.watch(x) + diagnostics.watch(y) + diagnostics.watch(z) + +#Tobii update function +def update(): + map_tobii(0) + +if starting: + #enabled = True + system.setThreadTiming(TimingTypes.HighresSystemTimer) + system.threadExecutionInterval = 0 + tobiiEyeX.update += update + +#toggleA = keyboard.getPressed(Key.X) + +#if toggleA: + #enabled = not enabled diff --git a/data_from_portwine/Reshade/Shaders/Tonemap.fx b/data_from_portwine/Reshade/Shaders/Tonemap.fx new file mode 100644 index 00000000..2b54b386 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Tonemap.fx @@ -0,0 +1,72 @@ +/** + * Tonemap version 1.1 + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + */ + +#include "ReShadeUI.fxh" + +uniform float Gamma < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 2.0; + ui_tooltip = "Adjust midtones. 1.0 is neutral. This setting does exactly the same as the one in Lift Gamma Gain, only with less control."; +> = 1.0; +uniform float Exposure < __UNIFORM_SLIDER_FLOAT1 + ui_min = -1.0; ui_max = 1.0; + ui_tooltip = "Adjust exposure"; +> = 0.0; +uniform float Saturation < __UNIFORM_SLIDER_FLOAT1 + ui_min = -1.0; ui_max = 1.0; + ui_tooltip = "Adjust saturation"; +> = 0.0; + +uniform float Bleach < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Brightens the shadows and fades the colors"; +> = 0.0; + +uniform float Defog < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "How much of the color tint to remove"; +> = 0.0; +uniform float3 FogColor < __UNIFORM_COLOR_FLOAT3 + ui_label = "Defog Color"; + ui_tooltip = "Which color tint to remove"; +> = float3(0.0, 0.0, 1.0); + + +#include "ReShade.fxh" + +float3 TonemapPass(float4 position : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + color = saturate(color - Defog * FogColor * 2.55); // Defog + color *= pow(2.0f, Exposure); // Exposure + color = pow(color, Gamma); // Gamma + + const float3 coefLuma = float3(0.2126, 0.7152, 0.0722); + float lum = dot(coefLuma, color); + + float L = saturate(10.0 * (lum - 0.45)); + float3 A2 = Bleach * color; + + float3 result1 = 2.0f * color * lum; + float3 result2 = 1.0f - 2.0f * (1.0f - lum) * (1.0f - color); + + float3 newColor = lerp(result1, result2, L); + float3 mixRGB = A2 * newColor; + color += ((1.0f - A2) * mixRGB); + + float3 middlegray = dot(color, (1.0 / 3.0)); + float3 diffcolor = color - middlegray; + color = (color + diffcolor * Saturation) / (1 + (diffcolor * Saturation)); // Saturation + + return color; +} + +technique Tonemap +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = TonemapPass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Trails.fx b/data_from_portwine/Reshade/Shaders/Trails.fx new file mode 100644 index 00000000..a68e7dfb --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Trails.fx @@ -0,0 +1,306 @@ +////----------// +///**Trails**/// +//----------//// + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//* Trails +//* 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 +//* +//* https://github.com/BlueSkyDefender/Depth3D +//* --------------------------------- +//* +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define Per_Color_Channel 0 // Lets you adjust per Color Channel.Default 0 off +#define Add_Depth_Effects 0 // Lets this effect be affected by Depth..Default 0 off + +#if !Per_Color_Channel +uniform float Persistence < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "Persistence"; + ui_tooltip = "Increase persistence longer the trail or afterimage.\n" + "If pushed out the effect is alot like long exposure.\n" + "This can be used for light painting in games.\n" + "1000/1 is 1.0, so 1/2 is 0.5 and so forth.\n" + "Default is 0.25, 0 is infinity."; +> = 0.25; +#else +uniform float3 Persistence < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "Persistence"; + ui_tooltip = "Increase persistence longer the trail or afterimage RGB.\n" + "If pushed out the effect is alot like long exposure.\n" + "This can be used for light painting in games.\n" + "1000/1 is 1.0, so 1/2 is 0.5 and so forth.\n" + "Default is 0.25, 0 is infinity."; +> = float3(0.25,0.25,0.25); +#endif + +uniform float TQ < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Trail Blur Quality"; + ui_tooltip = "Adjust Trail Blur Quality.\n" + "Default is Zero."; +> = 0.0; + +//uniform bool TrailsX2 < +// ui_label = "Trails X2"; +// ui_tooltip = "Two times the samples.\n" +// "This disables Trail Quality."; +//> = false; + +uniform bool PS2 < + ui_label = "PS2 Style Echo"; + ui_tooltip = "This enables PS2 Style Echo in your game.\n" + "This disables Trail Quality."; +> = false; +#if Add_Depth_Effects +uniform bool Allow_Depth < + ui_label = "Depth Map Toggle"; + ui_tooltip = "This Alows Depth to be used in Trails."; + ui_category = "Depth Buffer"; +> = 0; + +uniform int Depth_Map < + ui_type = "combo"; + ui_items = "Normal\0Reverse\0"; + ui_label = "Custom Depth Map"; + ui_tooltip = "Pick your Depth Map."; + ui_category = "Depth Buffer"; +> = 0; + +uniform float Depth_Map_Adjust < + ui_type = "slider"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Depth Map Adjustment"; + ui_tooltip = "Adjust the depth map and sharpness distance."; + ui_category = "Depth Buffer"; +> = 0.0; + +uniform bool Hard_CutOff < + ui_label = "Hard CutOff"; + ui_tooltip = "Depth Cutoff toggle this give a hard cutoff for depth isolation."; + ui_category = "Depth Buffer"; +> = 0; + +uniform bool Depth_Map_Flip < + ui_label = "Depth Map Flip"; + ui_tooltip = "Flip the depth map if it is upside down."; + ui_category = "Depth Buffer"; +> = 0; + +uniform bool Invert_Depth < + ui_label = "Depth Map Inverte"; + ui_tooltip = "Inverts Depth so you can target only your weapon or what's near you."; + ui_category = "Depth Buffer"; +> = 0; + +uniform bool Depth_View < + ui_label = "Depth Map View"; + ui_tooltip = "Lets you see Depth so you can Debug."; + ui_category = "Depth Buffer"; +> = 0; +#else +static const int Allow_Depth = 0; +static const int Depth_Map = 0; +static const float Depth_Map_Adjust = 250.0; +static const int Depth_Map_Flip = 0; +static const int Invert_Depth = 0; +static const int Depth_View = 0; +static const int Hard_CutOff = 0; +#endif +/////////////////////////////////////////////D3D Starts Here///////////////////////////////////////////////////////////////// +texture DepthBufferTex : DEPTH; + +sampler DepthBuffer + { + Texture = DepthBufferTex; + }; + +texture BackBufferTex : COLOR; + +sampler BackBuffer + { + Texture = BackBufferTex; + }; + +texture CurrentBackBufferT { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;}; + +sampler CBackBuffer + { + Texture = CurrentBackBufferT; + }; + + +texture PBB { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 2;}; + +sampler PBackBuffer + { + Texture = PBB; + }; + +texture PSBB { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8;}; + +sampler PSBackBuffer + { + Texture = PSBB; + }; + +///////////////////////////////////////////////////////////TAA///////////////////////////////////////////////////////////////////// +#define pix float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Depth(in float2 texcoord : TEXCOORD0) +{ + if (Depth_Map_Flip) + texcoord.y = 1 - texcoord.y; + + float zBuffer = tex2D(DepthBuffer, texcoord).x; //Depth Buffer + + //Conversions to linear space..... + //Near & Far Adjustment + float Far = 1.0, Near = 0.125/250.0; //Division Depth Map Adjust - Near + + float2 Z = float2( zBuffer, 1-zBuffer ); + + if (Depth_Map == 0)//DM0. Normal + zBuffer = Far * Near / (Far + Z.x * (Near - Far)); + else if (Depth_Map == 1)//DM1. Reverse + zBuffer = Far * Near / (Far + Z.y * (Near - Far)); + + return saturate(zBuffer); +} + +float3 T_Out(float4 position : SV_Position, float2 texcoord : TEXCOORD) : SV_Target +{ + float TQA = TQ, D = Depth(texcoord); + if(PS2) + TQA = 0; + + float3 C = tex2D(BackBuffer, texcoord).rgb; + //float3 PS = tex2D(PSBackBuffer, texcoord).rgb; + + float3 P = tex2Dlod(PBackBuffer, float4(texcoord,0,TQA)).rgb; + + #if !PerColor + float Per = 1-Persistence; + #else + float3 Per = 1-Persistence; + #endif + + D = smoothstep(0,Depth_Map_Adjust,D); + + if(Hard_CutOff) + D = step(0.5,D); + + if(Invert_Depth) + D = 1-D; + + if(!PS2) + { + P *= Per; + C = max( tex2D(BackBuffer, texcoord).rgb, P); + //PS = max( tex2D(BackBuffer, texcoord).rgb, P); + } + else + { + C = (1-Per) * C + Per * P; + //PS = (1-Per) * PS + Per * P; + } + + //if(TrailsX2) + //{ + // C = lerp(PS,C,0.5); + //} + + if(Allow_Depth) + C = lerp(C,tex2D(BackBuffer, texcoord).rgb,saturate(D)); + + if(Depth_View) + C = D; + + return C; +} + +void Current_BackBuffer_T(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 color : SV_Target0) +{ + color = tex2D(BackBuffer,texcoord); +} + +void Past_BB(float4 position : SV_Position, float2 texcoord : TEXCOORD, out float4 Past : SV_Target0, out float4 PastSingle : SV_Target1) +{ float2 samples[12] = { + float2(-0.326212, -0.405805), + float2(-0.840144, -0.073580), + float2(-0.695914, 0.457137), + float2(-0.203345, 0.620716), + float2(0.962340, -0.194983), + float2(0.473434, -0.480026), + float2(0.519456, 0.767022), + float2(0.185461, -0.893124), + float2(0.507431, 0.064425), + float2(0.896420, 0.412458), + float2(-0.321940, -0.932615), + float2(-0.791559, -0.597705) + }; + + float4 sum_A = tex2D(BackBuffer,texcoord), sum_B = 0;//tex2D(CBackBuffer,texcoord); + + if(!PS2) + { + float Adjust = TQ*pix.x; + [loop] + for (int i = 0; i < 12; i++) + { + sum_A += tex2Dlod(BackBuffer, float4(texcoord + Adjust * samples[i],0,0)); + //sum_B += tex2Dlod(CBackBuffer, float4(texcoord + Adjust * samples[i],0,0)); + } + Past = sum_A * 0.07692307; + PastSingle = 0;//sum_B * 0.07692307; + } + else + { + Past = sum_A; + PastSingle = 0;//sum_B * 0.07692307; + } +} + +///////////////////////////////////////////////////////////ReShade.fxh///////////////////////////////////////////////////////////// +// 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) +{ + 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); +} +technique Trails + { + pass CBB + { + VertexShader = PostProcessVS; + PixelShader = Current_BackBuffer_T; + RenderTarget = CurrentBackBufferT; + } + pass Trails + { + VertexShader = PostProcessVS; + PixelShader = T_Out; + } + pass PBB + { + VertexShader = PostProcessVS; + PixelShader = Past_BB; + RenderTarget0 = PBB; + RenderTarget1 = PSBB; + + } + } diff --git a/data_from_portwine/Reshade/Shaders/TriDither.fxh b/data_from_portwine/Reshade/Shaders/TriDither.fxh new file mode 100644 index 00000000..922e325a --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/TriDither.fxh @@ -0,0 +1,73 @@ +//////////////////////////////////////////////////////////////////////////////// +// Triangular Dither // +// By The Sandvich Maker // +// Ported to ReShade by TreyM // +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// // +// Usage: // +// Include this file in your shader like so: #include "TriDither.fx" // +// // +// For shader developers, use this syntax to do a function call in your // +// code as the last thing before exiting a given shader. You should dither // +// anytime data is going to be truncated to a lower bitdepth. Color input // +// must be a float3 value. // +// // +// input.rgb += TriDither(input.rgb, uv, bits); // +// // +// "bits" is an integer number that determines the bit depth // +// being dithered to. Usually 8, sometimes 10 // +// You can automate this by letting Reshade decide like so: // +// // +// input += TriDither(input, uv, BUFFER_COLOR_BIT_DEPTH); // +// // +// Manual setup looks something like this for an 8-bit backbuffer: // +// // +// input.rgb += TriDither(input.rgb, uv, 8); // +// // +//////////////////////////////////////////////////////////////////////////////// + +uniform float DitherTimer < source = "timer"; >; +#define remap(v, a, b) (((v) - (a)) / ((b) - (a))) + +float rand21(float2 uv) +{ + float2 noise = frac(sin(dot(uv, float2(12.9898, 78.233) * 2.0)) * 43758.5453); + return (noise.x + noise.y) * 0.5; +} + +float rand11(float x) +{ + return frac(x * 0.024390243); +} + +float permute(float x) +{ + return ((34.0 * x + 1.0) * x) % 289.0; +} + +float3 TriDither(float3 color, float2 uv, int bits) +{ + float bitstep = exp2(bits) - 1.0; + float lsb = 1.0 / bitstep; + float lobit = 0.5 / bitstep; + float hibit = (bitstep - 0.5) / bitstep; + + float3 m = float3(uv, rand21(uv + (DitherTimer * 0.001))) + 1.0; + float h = permute(permute(permute(m.x) + m.y) + m.z); + + float3 noise1, noise2; + noise1.x = rand11(h); h = permute(h); + noise2.x = rand11(h); h = permute(h); + noise1.y = rand11(h); h = permute(h); + noise2.y = rand11(h); h = permute(h); + noise1.z = rand11(h); h = permute(h); + noise2.z = rand11(h); + + float3 lo = saturate(remap(color.xyz, 0.0, lobit)); + float3 hi = saturate(remap(color.xyz, 1.0, hibit)); + float3 uni = noise1 - 0.5; + float3 tri = noise1 - noise2; + return lerp(uni, tri, min(lo, hi)) * lsb; +} diff --git a/data_from_portwine/Reshade/Shaders/UIMask.fx b/data_from_portwine/Reshade/Shaders/UIMask.fx new file mode 100644 index 00000000..147690c6 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/UIMask.fx @@ -0,0 +1,310 @@ +/* + Simple UIMask shader by luluco250 + + I have no idea why this was never ported back to ReShade 3.0 from 2.0, + but if you missed it, here it is. + + It doesn't feature the auto mask from the original shader. + + It does feature a new multi-channnel masking feature. UI masks can now contain + separate 'modes' within each of the three color channels. + + For example, you can have the regular hud on the red channel (the default one), + a mask for an inventory screen on the green channel and a mask for a quest menu + on the blue channel. You can then use keyboard keys to toggle each channel on or off. + + Multiple channels can be active at once, they'll just add up to mask the image. + + Simple/legacy masks are not affected by this, they'll work just as you'd expect, + so you can still make simple black and white masks that use all color channels, it'll + be no different than just having it on a single channel. + + Tips: + + --You can adjust how much it will affect your HUD by changing "Mask Intensity". + + --You don't actually need to place the UIMask_Bottom technique at the bottom of + your shader pipeline, if you have any effects that don't necessarily affect + the visibility of the HUD you can place it before that. + For instance, if you use color correction shaders like LUT, you might want + to place UIMask_Bottom just before that. + + --Preprocessor flags: + --UIMASK_MULTICHANNEL: + Enables having up to three different masks on each color channel. + --UIMASK_TOGGLEKEY_RED: + Keycode that toggles the red channel of the mask. + --UIMASK_TOGGLEKEY_BLUE: + Keycode that toggles the blue channel of the mask. + --UIMASK_TOGGLEKEY_GREEN: + Keycode that toggles the green channel of the mask. + + --Refer to this page for keycodes: + https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx + + --To make a custom mask: + + 1-Take a screenshot of your game with the HUD enabled, + preferrably with any effects disabled for maximum visibility. + + 2-Open the screenshot with your preferred image editor program, I use GIMP. + + 3-Make a background white layer if there isn't one already. + Be sure to leave it behind your actual screenshot for the while. + + 4-Make an empty layer for the mask itself, you can call it "mask". + + 5-Having selected the mask layer, paint the places where HUD constantly is, + such as health bars, important messages, minimaps etc. + + 6-Delete or make your screenshot layer invisible. + + 7-Before saving your mask, let's do some gaussian blurring to improve it's look and feel: + For every step of blurring you want to do, make a new layer, such as: + Mask - Blur16x16 + Mask - Blur8x8 + Mask - Blur4x4 + Mask - Blur2x2 + Mask - NoBlur + You should use your image editor's default gaussian blurring filter, if there is one. + This avoids possible artifacts and makes the mask blend more easily on the eyes. + You may not need this if your mask is accurate enough and/or the HUD is simple enough. + + 8-Now save the final image as "UIMask.png" in your textures folder and you're done! + + + MIT Licensed: + + Copyright (c) 2017 Lucas Melo + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +//#region Preprocessor + +#include "ReShade.fxh" +#include "ReShadeUI.fxh" + +#ifndef UIMASK_MULTICHANNEL + #define UIMASK_MULTICHANNEL 0 +#endif + +#ifndef UIMASK_TOGGLEKEY_RED + #define UIMASK_TOGGLEKEY_RED 0x67 //Numpad 7 +#endif + +#ifndef UIMASK_TOGGLEKEY_GREEN + #define UIMASK_TOGGLEKEY_GREEN 0x68 //Numpad 8 +#endif + +#ifndef UIMASK_TOGGLEKEY_BLUE + #define UIMASK_TOGGLEKEY_BLUE 0x69 //Numpad 9 +#endif + +#if !UIMASK_MULTICHANNEL + #define TEXFORMAT R8 +#else + #define TEXFORMAT RGBA8 +#endif + +//#endregion + +namespace UIMask +{ + +//#region Uniforms + +uniform int _Help +< + ui_label = " "; + ui_text = + "For more detailed instructions, see the text at the top of this " + "effect's shader file (UIMask.fx).\n" + "\n" + "Available preprocessor definitions:\n" + " UIMASK_MULTICHANNEL:\n" + " If set to 1, each of the RGB color channels in the texture is " + "treated as a separate mask.\n" + " UIMASK_TOGGLEKEY_RED:\n" + " Defines the key for using the mask in the red channel, the " + "default is Numpad 7.\n" + " UIMASK_TOGGLEKEY_GREEN:\n" + " Defines the key for using the mask in the green channel, the " + "default is Numpad 8.\n" + " UIMASK_TOGGLEKEY_BLUE:\n" + " Defines the key for using the mask in the blue channel, the " + "default is Numpad 9.\n" + "\n" + "Google \"virtual key codes\" for the values of each keyboard key.\n" + "\n" + "How to create a mask:\n" + "\n" + "1. Take a screenshot with the game's UI appearing.\n" + "2. Open the screenshot in an image editor, GIMP or Photoshop are " + "recommended.\n" + "3. Create a new layer over the screenshot layer, fill it with black.\n" + "4. Reduce the layer opacity so you can see the screenshot layer " + "below.\n" + "5. Cover the UI with white to mask it from effects. The stronger the " + "mask white color, the more opaque the mask will be.\n" + "6. Set the mask layer opacity back to 100%.\n" + "7. Save the image in one of your texture folders, named " + "\"UIMask.png\".\n" + ; + ui_category = "Help"; + ui_category_closed = true; + ui_type = "radio"; +>; + +uniform float fMask_Intensity +< + __UNIFORM_SLIDER_FLOAT1 + + ui_label = "Mask Intensity"; + ui_tooltip = + "How much to mask effects from affecting the original image.\n" + "\nDefault: 1.0"; + ui_min = 0.0; + ui_max = 1.0; + ui_step = 0.001; +> = 1.0; + +uniform bool bDisplayMask < + ui_label = "Display Mask"; + ui_tooltip = + "Display the mask texture.\n" + "Useful for testing multiple channels or simply the mask itself.\n" + "\nDefault: Off"; +> = false; + +#if UIMASK_MULTICHANNEL + +uniform bool ToggleRed +< + source = "key"; + keycode = UIMASK_TOGGLEKEY_RED; + toggle = true; +>; + +uniform bool ToggleGreen +< + source = "key"; + keycode = UIMASK_TOGGLEKEY_GREEN; + toggle = true; +>; + +uniform bool ToggleBlue +< + source = "key"; + keycode = UIMASK_TOGGLEKEY_BLUE; + toggle = true; +>; + +#endif + +//#endregion + +//#region Textures + +texture BackupTex +{ + Width = BUFFER_WIDTH; + Height = BUFFER_HEIGHT; +}; +sampler Backup +{ + Texture = BackupTex; +}; + +texture MaskTex +{ + Width = BUFFER_WIDTH; + Height = BUFFER_HEIGHT; + Format = TEXFORMAT; +}; +sampler Mask +{ + Texture = MaskTex; +}; + +//#endregion + +//#region Shaders + +float4 BackupPS(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target { + return tex2D(ReShade::BackBuffer, uv); +} + +float4 MainPS(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target { + float4 color = tex2D(ReShade::BackBuffer, uv); + float4 backup = tex2D(Backup, uv); + + #if !UIMASK_MULTICHANNEL + float mask = tex2D(Mask, uv).r; + #else + float3 mask_rgb = tex2D(Mask, uv).rgb; + + // This just works, it basically adds masking with each channel that has + // been toggled. 'ToggleRed' is inverted so it defaults to 'true' upon + // start. + float mask = saturate( + 1.0 - dot(1.0 - mask_rgb, + float3(!ToggleRed, ToggleGreen, ToggleBlue))); + #endif + + color = lerp(color, backup, mask * fMask_Intensity); + color = bDisplayMask ? mask : color; + + return color; +} + +//#endregion + +//#region Techniques + +technique UIMask_Top +< + ui_tooltip = "Place this *above* the effects to be masked."; +> +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = BackupPS; + RenderTarget = BackupTex; + } +} + +technique UIMask_Bottom +< + ui_tooltip = + "Place this *below* the effects to be masked.\n" + "If you want to add a toggle key for the effect, set it to this one."; +> +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = MainPS; + } +} + +//#endregion + +} // Namespace. diff --git a/data_from_portwine/Reshade/Shaders/Vibrance.fx b/data_from_portwine/Reshade/Shaders/Vibrance.fx new file mode 100644 index 00000000..78154bfe --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Vibrance.fx @@ -0,0 +1,75 @@ +/** + Vibrance + by Christian Cann Schuldt Jensen ~ CeeJay.dk + + Vibrance intelligently boosts the saturation of pixels so pixels that had little color get a larger boost than pixels that had a lot. + This avoids oversaturation of pixels that were already very saturated. + + History: + + Version 1.0 by Ceejay.dk + - Original + Version 1.1 by CeeJay.dk + - Introduced RBG balance to help colorblind users + Version 1.1.1 + - Minor UI improvements for Reshade 3.x + */ + +#include "ReShadeUI.fxh" + +uniform float Vibrance < __UNIFORM_SLIDER_FLOAT1 + ui_min = -1.0; ui_max = 1.0; + ui_tooltip = "Intelligently saturates (or desaturates if you use negative values) the pixels depending on their original saturation."; +> = 0.15; + +uniform float3 VibranceRGBBalance < + ui_type = "drag"; + ui_min = 0.0; ui_max = 10.0; + ui_label = "RGB Balance"; + ui_tooltip = "A per channel multiplier to the Vibrance strength so you can give more boost to certain colors over others.\nThis is handy if you are colorblind and less sensitive to a specific color.\nYou can then boost that color more than the others."; +> = float3(1.0, 1.0, 1.0); + +/* +uniform int Vibrance_Luma < + ui_type = "combo"; + ui_label = "Luma type"; + ui_items = "Perceptual\0Even\0"; +> = 0; +*/ + +#include "ReShade.fxh" + +float3 VibrancePass(float4 position : SV_Position, float2 texcoord : TexCoord) : SV_Target +{ + float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb; + + float3 coefLuma = float3(0.212656, 0.715158, 0.072186); + + /* + if (Vibrance_Luma) + coefLuma = float3(0.333333, 0.333334, 0.333333); + */ + + float luma = dot(coefLuma, color); + + + float max_color = max(color.r, max(color.g, color.b)); // Find the strongest color + float min_color = min(color.r, min(color.g, color.b)); // Find the weakest color + + float color_saturation = max_color - min_color; // The difference between the two is the saturation + + // Extrapolate between luma and original by 1 + (1-saturation) - current + float3 coeffVibrance = float3(VibranceRGBBalance * Vibrance); + color = lerp(luma, color, 1.0 + (coeffVibrance * (1.0 - (sign(coeffVibrance) * color_saturation)))); + + return color; +} + +technique Vibrance +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = VibrancePass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/Vignette.fx b/data_from_portwine/Reshade/Shaders/Vignette.fx new file mode 100644 index 00000000..98cf4d1a --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/Vignette.fx @@ -0,0 +1,115 @@ +/** + * Vignette version 1.3 + * by Christian Cann Schuldt Jensen ~ CeeJay.dk + * + * Darkens the edges of the image to make it look more like it was shot with a camera lens. + * May cause banding artifacts. + */ + +#include "ReShadeUI.fxh" + +uniform int Type < + ui_type = "combo"; + ui_items = "Original\0New\0TV style\0Untitled 1\0Untitled 2\0Untitled 3\0Untitled 4\0"; +> = 0; +uniform float Ratio < __UNIFORM_SLIDER_FLOAT1 + ui_min = 0.15; ui_max = 6.0; + ui_tooltip = "Sets a width to height ratio. 1.00 (1/1) is perfectly round, while 1.60 (16/10) is 60 % wider than it's high."; +> = 1.0; +uniform float Radius < __UNIFORM_SLIDER_FLOAT1 + ui_min = -1.0; ui_max = 3.0; + ui_tooltip = "lower values = stronger radial effect from center"; +> = 2.0; +uniform float Amount < __UNIFORM_SLIDER_FLOAT1 + ui_min = -2.0; ui_max = 1.0; + ui_tooltip = "Strength of black. -2.00 = Max Black, 1.00 = Max White."; +> = -1.0; +uniform int Slope < __UNIFORM_SLIDER_INT1 + ui_min = 2; ui_max = 16; + ui_tooltip = "How far away from the center the change should start to really grow strong (odd numbers cause a larger fps drop than even numbers)."; +> = 2; +uniform float2 Center < __UNIFORM_SLIDER_FLOAT2 + ui_min = 0.0; ui_max = 1.0; + ui_tooltip = "Center of effect for 'Original' vignette type. 'New' and 'TV style' do not obey this setting."; +> = float2(0.5, 0.5); + +#include "ReShade.fxh" + +float4 VignettePass(float4 vpos : SV_Position, float2 tex : TexCoord) : SV_Target +{ + float4 color = tex2D(ReShade::BackBuffer, tex); + + if (Type == 0) + { + // Set the center + float2 distance_xy = tex - Center; + + // Adjust the ratio + distance_xy *= float2((BUFFER_RCP_HEIGHT / BUFFER_RCP_WIDTH), Ratio); + + // Calculate the distance + distance_xy /= Radius; + float distance = dot(distance_xy, distance_xy); + + // Apply the vignette + color.rgb *= (1.0 + pow(distance, Slope * 0.5) * Amount); //pow - multiply + } + + if (Type == 1) // New round (-x*x+x) + (-y*y+y) method. + { + tex = -tex * tex + tex; + color.rgb = saturate(((BUFFER_RCP_HEIGHT / BUFFER_RCP_WIDTH)*(BUFFER_RCP_HEIGHT / BUFFER_RCP_WIDTH) * Ratio * tex.x + tex.y) * 4.0) * color.rgb; + } + + if (Type == 2) // New (-x*x+x) * (-y*y+y) TV style method. + { + tex = -tex * tex + tex; + color.rgb = saturate(tex.x * tex.y * 100.0) * color.rgb; + } + + if (Type == 3) + { + tex = abs(tex - 0.5); + float tc = dot(float4(-tex.x, -tex.x, tex.x, tex.y), float4(tex.y, tex.y, 1.0, 1.0)); //XOR + + tc = saturate(tc - 0.495); + color.rgb *= (pow((1.0 - tc * 200), 4) + 0.25); //or maybe abs(tc*100-1) (-(tc*100)-1) + } + + if (Type == 4) + { + tex = abs(tex - 0.5); + float tc = dot(float4(-tex.x, -tex.x, tex.x, tex.y), float4(tex.y, tex.y, 1.0, 1.0)); //XOR + + tc = saturate(tc - 0.495) - 0.0002; + color.rgb *= (pow((1.0 - tc * 200), 4) + 0.0); //or maybe abs(tc*100-1) (-(tc*100)-1) + } + + if (Type == 5) // MAD version of 2 + { + tex = abs(tex - 0.5); + float tc = tex.x * (-2.0 * tex.y + 1.0) + tex.y; //XOR + + tc = saturate(tc - 0.495); + color.rgb *= (pow((-tc * 200 + 1.0), 4) + 0.25); //or maybe abs(tc*100-1) (-(tc*100)-1) + //color.rgb *= (pow(((tc*200.0)-1.0),4)); //or maybe abs(tc*100-1) (-(tc*100)-1) + } + + if (Type == 6) // New round (-x*x+x) * (-y*y+y) method. + { + //tex.y /= float2((BUFFER_RCP_HEIGHT / BUFFER_RCP_WIDTH), Ratio); + float tex_xy = dot(float4(tex, tex), float4(-tex, 1.0, 1.0)); //dot is actually slower + color.rgb = saturate(tex_xy * 4.0) * color.rgb; + } + + return color; +} + +technique Vignette +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = VignettePass; + } +} diff --git a/data_from_portwine/Reshade/Shaders/qUINT_bloom.fx b/data_from_portwine/Reshade/Shaders/qUINT_bloom.fx new file mode 100644 index 00000000..12811134 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/qUINT_bloom.fx @@ -0,0 +1,409 @@ +/*============================================================================= + + ReShade 4 effect file + github.com/martymcmodding + + Support me: + paypal.me/mcflypg + patreon.com/mcflypg + + Simple Bloom + by Marty McFly / P.Gilcher + part of qUINT shader library for ReShade 4 + + Copyright (c) Pascal Gilcher / Marty McFly. All rights reserved. + +=============================================================================*/ + +/*============================================================================= + Preprocessor settings +=============================================================================*/ + +#ifndef SAMPLE_HIGH_QUALITY + #define SAMPLE_HIGH_QUALITY 0 +#endif + +/*============================================================================= + UI Uniforms +=============================================================================*/ + +uniform float BLOOM_INTENSITY < + ui_type = "drag"; + ui_min = 0.00; ui_max = 10.00; + ui_label = "Bloom Intensity"; + ui_tooltip = "Scales bloom brightness."; +> = 1.2; + +uniform float BLOOM_CURVE < + ui_type = "drag"; + ui_min = 0.00; ui_max = 10.00; + ui_label = "Bloom Curve"; + ui_tooltip = "Higher values limit bloom to bright light sources only."; +> = 1.5; + +uniform float BLOOM_SAT < + ui_type = "drag"; + ui_min = 0.00; ui_max = 5.00; + ui_label = "Bloom Saturation"; + ui_tooltip = "Adjusts the color strength of the bloom effect"; +> = 2.0; +/* +uniform float BLOOM_DIRT < + ui_type = "drag"; + ui_min = 0.00; ui_max = 2.00; + ui_label = "Lens Dirt Amount"; + ui_tooltip = "Applies a dirt mask on top of the original bloom."; +> = 0.0; +*/ +uniform float BLOOM_LAYER_MULT_1 < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Bloom Layer 1 Intensity"; + ui_tooltip = "Intensity of this bloom layer. 1 is sharpest layer, 7 the most blurry."; +> = 0.05; +uniform float BLOOM_LAYER_MULT_2 < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Bloom Layer 2 Intensity"; + ui_tooltip = "Intensity of this bloom layer. 1 is sharpest layer, 7 the most blurry."; +> = 0.05; +uniform float BLOOM_LAYER_MULT_3 < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Bloom Layer 3 Intensity"; + ui_tooltip = "Intensity of this bloom layer. 1 is sharpest layer, 7 the most blurry."; +> = 0.05; +uniform float BLOOM_LAYER_MULT_4 < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Bloom Layer 4 Intensity"; + ui_tooltip = "Intensity of this bloom layer. 1 is sharpest layer, 7 the most blurry."; +> = 0.1; +uniform float BLOOM_LAYER_MULT_5 < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Bloom Layer 5 Intensity"; + ui_tooltip = "Intensity of this bloom layer. 1 is sharpest layer, 7 the most blurry."; +> = 0.5; +uniform float BLOOM_LAYER_MULT_6 < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Bloom Layer 6 Intensity"; + ui_tooltip = "Intensity of this bloom layer. 1 is sharpest layer, 7 the most blurry."; +> = 0.01; +uniform float BLOOM_LAYER_MULT_7 < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Bloom Layer 7 Intensity"; + ui_tooltip = "Intensity of this bloom layer. 1 is sharpest layer, 7 the most blurry."; +> = 0.01; +uniform float BLOOM_ADAPT_STRENGTH < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Bloom Scene Adaptation Sensitivity"; + ui_tooltip = "Amount of adaptation applied, 0 means same exposure for all scenes, 1 means complete autoexposure."; +> = 0.5; +uniform float BLOOM_ADAPT_EXPOSURE < + ui_type = "drag"; + ui_min = -5.00; ui_max = 5.00; + ui_label = "Bloom Scene Exposure Bias"; + ui_tooltip = "qUINT bloom employs eye adaptation to tune bloom intensity for scene differences.\nThis parameter adjusts the final scene exposure."; +> = 0.0; +uniform float BLOOM_ADAPT_SPEED < + ui_type = "drag"; + ui_min = 0.50; ui_max = 10.00; + ui_label = "Bloom Scene Adaptation Speed"; + ui_tooltip = "Eye adaptation data is created by exponential moving average with last frame data.\nThis parameter controls the adjustment speed.\nHigher parameters let the image adjust more quickly."; +> = 2.0; +uniform bool BLOOM_ADAPT_MODE < + ui_label = "Adapt bloom only"; +> = false; +uniform float BLOOM_TONEMAP_COMPRESSION < + ui_type = "drag"; + ui_min = 0.00; ui_max = 10.00; + ui_label = "Bloom Tonemap Compression"; + ui_tooltip = "Lower values compress a larger color range."; +> = 4.0; + +/*============================================================================= + Textures, Samplers, Globals +=============================================================================*/ + +#define RESHADE_QUINT_COMMON_VERSION_REQUIRE 200 +#include "qUINT_common.fxh" + +#define INT_LOG2(v) (((v >> 1) != 0) + ((v >> 2) != 0) + ((v >> 3) != 0) + ((v >> 4) != 0) + ((v >> 5) != 0) + ((v >> 6) != 0) + ((v >> 7) != 0) + ((v >> 8) != 0) + ((v >> 9) != 0) + ((v >> 10) != 0) + ((v >> 11) != 0) + ((v >> 12) != 0) + ((v >> 13) != 0) + ((v >> 14) != 0) + ((v >> 15) != 0) + ((v >> 16) != 0)) + +//static const int BloomTex7_LowestMip = int(log(BUFFER_HEIGHT/128) / log(2)) + 1; +static const int BloomTex7_LowestMip = INT_LOG2(BUFFER_HEIGHT/128); + +texture2D MXBLOOM_BloomTexSource { Width = BUFFER_WIDTH/2; Height = BUFFER_HEIGHT/2; Format = RGBA16F;}; +texture2D MXBLOOM_BloomTex1 { Width = BUFFER_WIDTH/2; Height = BUFFER_HEIGHT/2; Format = RGBA16F;}; +texture2D MXBLOOM_BloomTex2 { Width = BUFFER_WIDTH/4; Height = BUFFER_HEIGHT/4; Format = RGBA16F;}; +texture2D MXBLOOM_BloomTex3 { Width = BUFFER_WIDTH/8; Height = BUFFER_HEIGHT/8; Format = RGBA16F;}; +texture2D MXBLOOM_BloomTex4 { Width = BUFFER_WIDTH/16; Height = BUFFER_HEIGHT/16; Format = RGBA16F;}; +texture2D MXBLOOM_BloomTex5 { Width = BUFFER_WIDTH/32; Height = BUFFER_HEIGHT/32; Format = RGBA16F;}; +texture2D MXBLOOM_BloomTex6 { Width = BUFFER_WIDTH/64; Height = BUFFER_HEIGHT/64; Format = RGBA16F;}; +texture2D MXBLOOM_BloomTex7 { Width = BUFFER_WIDTH/128; Height = BUFFER_HEIGHT/128; Format = RGBA16F; MipLevels = BloomTex7_LowestMip;}; +texture2D MXBLOOM_BloomTexAdapt { Format = R16F; }; + +sampler2D sMXBLOOM_BloomTexSource { Texture = MXBLOOM_BloomTexSource; }; +sampler2D sMXBLOOM_BloomTex1 { Texture = MXBLOOM_BloomTex1; }; +sampler2D sMXBLOOM_BloomTex2 { Texture = MXBLOOM_BloomTex2; }; +sampler2D sMXBLOOM_BloomTex3 { Texture = MXBLOOM_BloomTex3; }; +sampler2D sMXBLOOM_BloomTex4 { Texture = MXBLOOM_BloomTex4; }; +sampler2D sMXBLOOM_BloomTex5 { Texture = MXBLOOM_BloomTex5; }; +sampler2D sMXBLOOM_BloomTex6 { Texture = MXBLOOM_BloomTex6; }; +sampler2D sMXBLOOM_BloomTex7 { Texture = MXBLOOM_BloomTex7; }; +sampler2D sMXBLOOM_BloomTexAdapt { Texture = MXBLOOM_BloomTexAdapt; }; + +/*============================================================================= + Functions +=============================================================================*/ + +float4 downsample(sampler2D tex, float2 tex_size, float2 uv) +{ + float4 offset_uv = 0; + + float2 kernel_small_offsets = float2(2.0,2.0) / tex_size; + float2 kernel_large_offsets = float2(4.0,4.0) / tex_size; + + float4 kernel_center = tex2D(tex, uv); + + float4 kernel_small = 0; + + offset_uv.xy = uv + kernel_small_offsets; + kernel_small += tex2Dlod(tex, offset_uv); //++ + offset_uv.x = uv.x - kernel_small_offsets.x; + kernel_small += tex2Dlod(tex, offset_uv); //-+ + offset_uv.y = uv.y - kernel_small_offsets.y; + kernel_small += tex2Dlod(tex, offset_uv); //-- + offset_uv.x = uv.x + kernel_small_offsets.x; + kernel_small += tex2Dlod(tex, offset_uv); //+- + +#if SAMPLE_HIGH_QUALITY == 0 + return kernel_center / 5.0 + + kernel_small / 5.0; +#else + float4 kernel_large_1 = 0; + + offset_uv.xy = uv + kernel_large_offsets; + kernel_large_1 += tex2Dlod(tex, offset_uv); //++ + offset_uv.x = uv.x - kernel_large_offsets.x; + kernel_large_1 += tex2Dlod(tex, offset_uv); //-+ + offset_uv.y = uv.y - kernel_large_offsets.y; + kernel_large_1 += tex2Dlod(tex, offset_uv); //-- + offset_uv.x = uv.x + kernel_large_offsets.x; + kernel_large_1 += tex2Dlod(tex, offset_uv); //+- + + float4 kernel_large_2 = 0; + + offset_uv.xy = uv; + offset_uv.x += kernel_large_offsets.x; + kernel_large_2 += tex2Dlod(tex, offset_uv); //+0 + offset_uv.x -= kernel_large_offsets.x * 2.0; + kernel_large_2 += tex2Dlod(tex, offset_uv); //-0 + offset_uv.x = uv.x; + offset_uv.y += kernel_large_offsets.y; + kernel_large_2 += tex2Dlod(tex, offset_uv); //0+ + offset_uv.y -= kernel_large_offsets.y * 2.0; + kernel_large_2 += tex2Dlod(tex, offset_uv); //0- + + return kernel_center * 0.5 / 4.0 + + kernel_small * 0.5 / 4.0 + + kernel_large_1 * 0.125 / 4.0 + + kernel_large_2 * 0.25 / 4.0; +#endif +} + +float3 Upsample(sampler2D tex, float2 texel_size, float2 uv) +{ + float4 offset_uv = 0; + + float4 kernel_small_offsets; + kernel_small_offsets.xy = 1.5 * texel_size; + kernel_small_offsets.zw = kernel_small_offsets.xy * 2; + + float3 kernel_center = tex2D(tex, uv).rgb; + + float3 kernel_small_1 = 0; + + offset_uv.xy = uv.xy - kernel_small_offsets.xy; + kernel_small_1 += tex2Dlod(tex, offset_uv).rgb; //-- + offset_uv.x += kernel_small_offsets.z; + kernel_small_1 += tex2Dlod(tex, offset_uv).rgb; //+- + offset_uv.y += kernel_small_offsets.w; + kernel_small_1 += tex2Dlod(tex, offset_uv).rgb; //++ + offset_uv.x -= kernel_small_offsets.z; + kernel_small_1 += tex2Dlod(tex, offset_uv).rgb; //-+ + +#if SAMPLE_HIGH_QUALITY == 0 + return kernel_center / 5.0 + + kernel_small_1 / 5.0; +#else + float3 kernel_small_2 = 0; + + offset_uv.xy = uv.xy + float2(kernel_small_offsets.x, 0); + kernel_small_2 += tex2Dlod(tex, offset_uv).rgb; //+0 + offset_uv.x -= kernel_small_offsets.z; + kernel_small_2 += tex2Dlod(tex, offset_uv).rgb; //-0 + offset_uv.xy = uv.xy + float2(0, kernel_small_offsets.y); + kernel_small_2 += tex2Dlod(tex, offset_uv).rgb; //0+ + offset_uv.y -= kernel_small_offsets.w; + kernel_small_2 += tex2Dlod(tex, offset_uv).rgb; //0- + + return kernel_center * 4.0 / 16.0 + + kernel_small_1 * 1.0 / 16.0 + + kernel_small_2 * 2.0 / 16.0; +#endif +} + +/*============================================================================= + Pixel Shaders +=============================================================================*/ + +void PS_BloomPrepass(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 color : SV_Target0) +{ + color = downsample(qUINT::sBackBufferTex, qUINT::SCREEN_SIZE, uv); + color.w = saturate(dot(color.rgb, 0.333)); + + color.rgb = lerp(color.w, color.rgb, BLOOM_SAT); + color.rgb *= (pow(color.w, BLOOM_CURVE) * BLOOM_INTENSITY * BLOOM_INTENSITY * BLOOM_INTENSITY) / (color.w + 1e-3); +} + +void PS_Downsample1(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = downsample(sMXBLOOM_BloomTexSource, ldexp(qUINT::SCREEN_SIZE, -1.0), uv); +} +void PS_Downsample2(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = downsample(sMXBLOOM_BloomTex1, ldexp(qUINT::SCREEN_SIZE, -2.0), uv); +} +void PS_Downsample3(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = downsample(sMXBLOOM_BloomTex2, ldexp(qUINT::SCREEN_SIZE, -3.0), uv); +} +void PS_Downsample4(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = downsample(sMXBLOOM_BloomTex3, ldexp(qUINT::SCREEN_SIZE, -4.0), uv); +} +void PS_Downsample5(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = downsample(sMXBLOOM_BloomTex4, ldexp(qUINT::SCREEN_SIZE, -5.0), uv); +} +void PS_Downsample6(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = downsample(sMXBLOOM_BloomTex5, ldexp(qUINT::SCREEN_SIZE, -6.0), uv); +} +void PS_Downsample7(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = downsample(sMXBLOOM_BloomTex6, ldexp(qUINT::SCREEN_SIZE, -7.0), uv); + bloom.w = lerp(tex2D(sMXBLOOM_BloomTexAdapt, 0).x /*last*/, + bloom.w /*current*/, + saturate(qUINT::FRAME_TIME * 1e-3 * BLOOM_ADAPT_SPEED)); +} + +void PS_AdaptStoreLast(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float adapt : SV_Target0) +{ adapt = tex2Dlod(sMXBLOOM_BloomTex7, float4(uv.xy,0,BloomTex7_LowestMip)).w;} + +void PS_Upsample1(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = float4(Upsample(sMXBLOOM_BloomTex7, ldexp(qUINT::PIXEL_SIZE, 7.0), uv) * BLOOM_LAYER_MULT_7, BLOOM_LAYER_MULT_6);} +void PS_Upsample2(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = float4(Upsample(sMXBLOOM_BloomTex6, ldexp(qUINT::PIXEL_SIZE, 6.0), uv), BLOOM_LAYER_MULT_5); +} +void PS_Upsample3(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = float4(Upsample(sMXBLOOM_BloomTex5, ldexp(qUINT::PIXEL_SIZE, 5.0), uv), BLOOM_LAYER_MULT_4); +} +void PS_Upsample4(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = float4(Upsample(sMXBLOOM_BloomTex4, ldexp(qUINT::PIXEL_SIZE, 4.0), uv), BLOOM_LAYER_MULT_3); +} +void PS_Upsample5(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = float4(Upsample(sMXBLOOM_BloomTex3, ldexp(qUINT::PIXEL_SIZE, 3.0), uv), BLOOM_LAYER_MULT_2); +} +void PS_Upsample6(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 bloom : SV_Target0) +{ + bloom = float4(Upsample(sMXBLOOM_BloomTex2, ldexp(qUINT::PIXEL_SIZE, 2.0), uv), BLOOM_LAYER_MULT_1); +} + +void PS_Combine(in float4 pos : SV_Position, in float2 uv : TEXCOORD, out float4 color : SV_Target0) +{ + float3 bloom = Upsample(sMXBLOOM_BloomTex1, ldexp(qUINT::PIXEL_SIZE, 1.0), uv); + bloom /= dot(float4(BLOOM_LAYER_MULT_1, BLOOM_LAYER_MULT_2, BLOOM_LAYER_MULT_3, BLOOM_LAYER_MULT_4), 1) + dot(float3(BLOOM_LAYER_MULT_5, BLOOM_LAYER_MULT_6, BLOOM_LAYER_MULT_7), 1); + color = tex2D(qUINT::sBackBufferTex, uv); + + float adapt = tex2D(sMXBLOOM_BloomTexAdapt, 0).x + 1e-3; // we lerped to 0.5 earlier. + adapt *= 8; + + //based on suggestion by https://github.com/KarlRamstedt + if(BLOOM_ADAPT_MODE) + { + bloom *= lerp(1, rcp(adapt), BLOOM_ADAPT_STRENGTH); + bloom *= exp2(BLOOM_ADAPT_EXPOSURE); + color.rgb += bloom; + } + else + { + color.rgb += bloom; + color.rgb *= lerp(1, rcp(adapt), BLOOM_ADAPT_STRENGTH); + color.rgb *= exp2(BLOOM_ADAPT_EXPOSURE); + } + + color.rgb = pow(max(0,color.rgb), BLOOM_TONEMAP_COMPRESSION); + color.rgb = color.rgb / (1.0 + color.rgb); + color.rgb = pow(color.rgb, 1.0 / BLOOM_TONEMAP_COMPRESSION); +} + +/*============================================================================= + Techniques +=============================================================================*/ + +technique Bloom +< ui_tooltip = " >> qUINT::Bloom <<\n\n" + "Bloom is a shader that produces a glow around bright\n" + "light sources and other emitters on screen.\n" + "\nBloom is written by Marty McFly / Pascal Gilcher"; > +{ + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_BloomPrepass; + RenderTarget0 = MXBLOOM_BloomTexSource; + } + + #define PASS_DOWNSAMPLE(i) pass { VertexShader = PostProcessVS; PixelShader = PS_Downsample##i; RenderTarget0 = MXBLOOM_BloomTex##i; } + + PASS_DOWNSAMPLE(1) + PASS_DOWNSAMPLE(2) + PASS_DOWNSAMPLE(3) + PASS_DOWNSAMPLE(4) + PASS_DOWNSAMPLE(5) + PASS_DOWNSAMPLE(6) + PASS_DOWNSAMPLE(7) + + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_AdaptStoreLast; + RenderTarget0 = MXBLOOM_BloomTexAdapt; + } + + #define PASS_UPSAMPLE(i,j) pass {VertexShader = PostProcessVS;PixelShader = PS_Upsample##i;RenderTarget0 = MXBLOOM_BloomTex##j;ClearRenderTargets = false;BlendEnable = true;BlendOp = ADD;SrcBlend = ONE;DestBlend = SRCALPHA;} + + PASS_UPSAMPLE(1,6) + PASS_UPSAMPLE(2,5) + PASS_UPSAMPLE(3,4) + PASS_UPSAMPLE(4,3) + PASS_UPSAMPLE(5,2) + PASS_UPSAMPLE(6,1) + + pass + { + VertexShader = PostProcessVS; + PixelShader = PS_Combine; + } +} diff --git a/data_from_portwine/Reshade/Shaders/qUINT_common.fxh b/data_from_portwine/Reshade/Shaders/qUINT_common.fxh new file mode 100644 index 00000000..547e355f --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/qUINT_common.fxh @@ -0,0 +1,199 @@ + +/* + changelog: + + 2.0.0: added frame count parameter + added versioning system + removed common textures - should only be declared if needed + flipped reversed depth buffer switch by default as most games use this format + 2.0.1: added more depth scaling parameters to match ReShade.fxh + 2.0.2: added UI for depth linearization when loaded by NVIDIA FreeStyle/Ansel + with cue given by effect if depth is required + 2.0.3: fixed scaling ( "-define" resulted in "--define" if define was negative) + split depth buffer retrieval into 2 functions, so that nonlinearized + depth can also be taken and a given depth be linearized manually + 2.0.4: splitted get_depth function into submodules that correct UV scaling and alignment + and a function that samples depth using this corrected UV + 2.0.5: renamed linear_depth(depth) to linearize_depth(depth). Polymorphism is cool, but unintuitive. + Perfect time to do this change now as no filter uses that function in this way yet. + 2.0.6: added new pixel offsets to depth buffer and reorganized the existing defines +*/ + +/*============================================================================= + Version checks +=============================================================================*/ + +#ifndef RESHADE_QUINT_COMMON_VERSION + #define RESHADE_QUINT_COMMON_VERSION 206 +#endif + +#if RESHADE_QUINT_COMMON_VERSION_REQUIRE > RESHADE_QUINT_COMMON_VERSION + #error "qUINT_common.fxh outdated." + #error "Please download update from github.com/martymcmodding/qUINT" +#endif + +#if !defined(RESHADE_QUINT_COMMON_VERSION_REQUIRE) + #error "Incompatible qUINT_common.fxh and shaders." + #error "Do not mix different file versions." +#endif + +#if !defined(__RESHADE__) || __RESHADE__ < 40000 + #error "ReShade 4.4+ is required to use this header file" +#endif + +/*============================================================================= + Define defaults +=============================================================================*/ + +//depth buffer +#ifndef RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN + #define RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 0 +#endif +#ifndef RESHADE_DEPTH_INPUT_IS_REVERSED + #define RESHADE_DEPTH_INPUT_IS_REVERSED 1 +#endif +#ifndef RESHADE_DEPTH_INPUT_IS_LOGARITHMIC + #define RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 0 +#endif +#ifndef RESHADE_DEPTH_LINEARIZATION_FAR_PLANE + #define RESHADE_DEPTH_LINEARIZATION_FAR_PLANE 1000.0 +#endif + +//new compatibility flags +#ifndef RESHADE_DEPTH_MULTIPLIER + #define RESHADE_DEPTH_MULTIPLIER 1 //mcfly: probably not a good idea, many shaders depend on having depth range 0-1 +#endif +#ifndef RESHADE_DEPTH_INPUT_X_SCALE + #define RESHADE_DEPTH_INPUT_X_SCALE 1 +#endif +#ifndef RESHADE_DEPTH_INPUT_Y_SCALE + #define RESHADE_DEPTH_INPUT_Y_SCALE 1 +#endif +// An offset to add to the X coordinate, (+) = move right, (-) = move left +#ifndef RESHADE_DEPTH_INPUT_X_OFFSET + #define RESHADE_DEPTH_INPUT_X_OFFSET 0 +#endif +// An offset to add to the Y coordinate, (+) = move up, (-) = move down +#ifndef RESHADE_DEPTH_INPUT_Y_OFFSET + #define RESHADE_DEPTH_INPUT_Y_OFFSET 0 +#endif +// An offset to add to the X coordinate, (+) = move right, (-) = move left +#ifndef RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET + #define RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET 0 +#endif +// An offset to add to the Y coordinate, (+) = move up, (-) = move down +#ifndef RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET + #define RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET 0 +#endif + +/*============================================================================= + Depth UI +=============================================================================*/ + +#if defined(__RESHADE_FXC__) +//if using FreeStyle or Ansel and effect requires depth, make UI toggle +//available. If not, replace with dummy which is unused anyways. +#if defined(RESHADE_QUINT_EFFECT_DEPTH_REQUIRE) + uniform bool UI_RESHADE_DEPTH_INPUT_IS_REVERSED < + ui_type = "bool"; + ui_label = "Depth input is reversed"; + > = RESHADE_DEPTH_INPUT_IS_REVERSED; //use default preprocessor setting +#else + #define UI_RESHADE_DEPTH_INPUT_IS_REVERSED RESHADE_DEPTH_INPUT_IS_REVERSED +#endif + +#endif + +/*============================================================================= + Uniforms +=============================================================================*/ + +namespace qUINT +{ + uniform float FRAME_TIME < source = "frametime"; >; + uniform int FRAME_COUNT < source = "framecount"; >; + +#if defined(__RESHADE_FXC__) + float2 get_aspect_ratio() { return float2(1.0, BUFFER_WIDTH * BUFFER_RCP_HEIGHT); } + float2 get_pixel_size() { return float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); } + float2 get_screen_size() { return float2(BUFFER_WIDTH, BUFFER_HEIGHT); } + #define ASPECT_RATIO get_aspect_ratio() + #define PIXEL_SIZE get_pixel_size() + #define SCREEN_SIZE get_screen_size() +#else + static const float2 ASPECT_RATIO = float2(1.0, BUFFER_WIDTH * BUFFER_RCP_HEIGHT); + static const float2 PIXEL_SIZE = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); + static const float2 SCREEN_SIZE = float2(BUFFER_WIDTH, BUFFER_HEIGHT); +#endif + + // Global textures and samplers + texture BackBufferTex : COLOR; + texture DepthBufferTex : DEPTH; + + sampler sBackBufferTex { Texture = BackBufferTex; }; + sampler sDepthBufferTex { Texture = DepthBufferTex; }; + + float2 depthtex_uv(float2 uv) + { +#if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN + uv.y = 1.0 - uv.y; +#endif + uv.x /= RESHADE_DEPTH_INPUT_X_SCALE; + uv.y /= RESHADE_DEPTH_INPUT_Y_SCALE; +#if RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET + uv.x -= RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET * BUFFER_RCP_WIDTH; +#else // Do not check RESHADE_DEPTH_INPUT_X_OFFSET, since it may be a decimal number, which the preprocessor cannot handle + uv.x -= RESHADE_DEPTH_INPUT_X_OFFSET / 2.000000001; +#endif +#if RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET + uv.y += RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET * BUFFER_RCP_HEIGHT; +#else + uv.y += RESHADE_DEPTH_INPUT_Y_OFFSET / 2.000000001; +#endif + return uv; + } + + float get_depth(float2 uv) + { + float depth = tex2Dlod(sDepthBufferTex, float4(depthtex_uv(uv), 0, 0)).x; + return depth; + } + + float linearize_depth(float depth) + { + depth *= RESHADE_DEPTH_MULTIPLIER; +#if RESHADE_DEPTH_INPUT_IS_LOGARITHMIC + const float C = 0.01; + depth = (exp(depth * log(C + 1.0)) - 1.0) / C; +#endif +#if defined(__RESHADE_FXC__) + depth = UI_RESHADE_DEPTH_INPUT_IS_REVERSED ? 1.0 - depth : depth; +#else +#if RESHADE_DEPTH_INPUT_IS_REVERSED + depth = 1.0 - depth; +#endif +#endif + const float N = 1.0; + depth /= RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - depth * (RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - N); + + return saturate(depth); + } + + //standard linear depth fetch + float linear_depth(float2 uv) + { + float depth = get_depth(uv); + depth = linearize_depth(depth); + return depth; + } +} + +// Vertex shader generating a triangle covering the entire screen +void PostProcessVS(in uint id : SV_VertexID, out float4 vpos : SV_Position, out float2 uv : TEXCOORD) +{ + uv.x = (id == 2) ? 2.0 : 0.0; + uv.y = (id == 1) ? 2.0 : 0.0; + vpos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); +} + + diff --git a/data_from_portwine/Reshade/Shaders/qUINT_deband.fx b/data_from_portwine/Reshade/Shaders/qUINT_deband.fx new file mode 100644 index 00000000..b8323bf3 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/qUINT_deband.fx @@ -0,0 +1,134 @@ +/*============================================================================= + + ReShade 4 effect file + github.com/martymcmodding + + Support me: + paypal.me/mcflypg + patreon.com/mcflypg + + Dither / Deband filter + + * Unauthorized copying of this file, via any medium is strictly prohibited + * Proprietary and confidential + +=============================================================================*/ + +/*============================================================================= + Preprocessor settings +=============================================================================*/ + +/*============================================================================= + UI Uniforms +=============================================================================*/ + +uniform float SEARCH_RADIUS < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 1.0; + ui_label = "Debanding Search Radius"; +> = 0.5; + +uniform int BIT_DEPTH < + ui_type = "slider"; + ui_min = 4; ui_max = 10; + ui_label = "Bit depth of data to be debanded"; +> = 8; + +uniform bool AUTOMATE_BIT_DEPTH < + ui_label = "Automatic bit depth detection"; +> = true; + +uniform int DEBAND_MODE < + ui_type = "radio"; + ui_label = "Dither mode"; + ui_items = "None\0Dither\0Deband\0"; +> = 2; + +uniform bool SKY_ONLY < + ui_label = "Apply to sky only"; +> = false; + +/*============================================================================= + Textures, Samplers, Globals +=============================================================================*/ + +#define RESHADE_QUINT_COMMON_VERSION_REQUIRE 202 +#include "qUINT_common.fxh" + +/*============================================================================= + Vertex Shader +=============================================================================*/ + +struct VSOUT +{ + float4 vpos : SV_Position; + float2 uv : TEXCOORD0; +}; + +VSOUT VSMain(in uint id : SV_VertexID) +{ + VSOUT o; + PostProcessVS(id, o.vpos, o.uv); //use original fullscreen triangle VS + return o; +} + +/*============================================================================= + Functions +=============================================================================*/ + +/*============================================================================= + Pixel Shaders +=============================================================================*/ + +void PSMain(in VSOUT i, out float3 o : SV_Target0) +{ + o = tex2D(qUINT::sBackBufferTex, i.uv).rgb; + + const float2 magicdot = float2(0.75487766624669276, 0.569840290998); + const float3 magicadd = float3(0, 0.025, 0.0125) * dot(magicdot, 1); + float3 dither = frac(dot(i.vpos.xy, magicdot) + magicadd); + + if(SKY_ONLY) + { + if(qUINT::linear_depth(i.uv) < 0.98) return; + } + + float bit_depth = AUTOMATE_BIT_DEPTH ? BUFFER_COLOR_BIT_DEPTH : BIT_DEPTH; + float lsb = rcp(exp2(bit_depth) - 1.0); + + if(DEBAND_MODE == 2) + { + float2 shift; + sincos(6.283 * 30.694 * dither.x, shift.x, shift.y); + shift = shift * sqrt(dither.y); + + float3 scatter = tex2Dlod(qUINT::sBackBufferTex, float4(i.uv + shift * 0.025 * SEARCH_RADIUS, 0, 0)).rgb; + float4 diff; + diff.rgb = abs(o.rgb - scatter); + diff.w = max(max(diff.x, diff.y), diff.z); + + o = lerp(o, scatter, diff.w <= lsb); + } + else if(DEBAND_MODE == 1) + { + o += (dither - 0.5) * lsb; + } +} + +/*============================================================================= + Techniques +=============================================================================*/ + +technique Debanding +< ui_tooltip = " >> qUINT::Debanding <<\n\n" + "This is a simple debanding filter, which aims to hide color\n" + "quantization artifacts in games. \n" + "\nqUINT Debanding is written by Marty McFly / Pascal Gilcher"; > +{ + pass + { + VertexShader = VSMain; + PixelShader = PSMain; + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/qUINT_dof.fx b/data_from_portwine/Reshade/Shaders/qUINT_dof.fx new file mode 100644 index 00000000..4a38824a --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/qUINT_dof.fx @@ -0,0 +1,772 @@ +/*============================================================================= + + ReShade 4 effect file + github.com/martymcmodding + + Support me: + paypal.me/mcflypg + patreon.com/mcflypg + + Advanced Depth of Field "ADoF" + by Marty McFly / P.Gilcher + part of qUINT shader library for ReShade 4 + + Copyright (c) Pascal Gilcher / Marty McFly. All rights reserved. + +=============================================================================*/ + +/* +TODO: extend tiles to contain min abs depth for better high precision sampling +*/ + +/*============================================================================= + Preprocessor settings +=============================================================================*/ + +//------------------------------------------------------------------ +//Enables partial occlusion of bokeh disc at screen corners +#ifndef ADOF_OPTICAL_VIGNETTE_ENABLE + #define ADOF_OPTICAL_VIGNETTE_ENABLE 0 //[0 or 1] +#endif +//------------------------------------------------------------------ +//Enables chromatic aberration at bokeh shape borders. +#ifndef ADOF_CHROMATIC_ABERRATION_ENABLE + #define ADOF_CHROMATIC_ABERRATION_ENABLE 1 //[0 or 1] +#endif + +/*============================================================================= + UI Uniforms +=============================================================================*/ + +uniform bool bADOF_AutofocusEnable < + ui_type = "bool"; + ui_label = "Enable Autofocus"; + ui_tooltip = "Enables automated focus calculation."; + ui_category = "Focusing"; +> = true; + +uniform float2 fADOF_AutofocusCenter < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.0; + ui_label = "Autofocus Center"; + ui_tooltip = "X and Y coordinates of autofocus center. Axes start from upper left screen corner."; + ui_category = "Focusing"; +> = float2(0.5, 0.5); + +uniform float fADOF_AutofocusRadius < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 1.0; + ui_label = "Autofocus sample radius"; + ui_tooltip = "Radius of area contributing to focus calculation."; + ui_category = "Focusing"; +> = 0.6; + +uniform float fADOF_AutofocusSpeed < + ui_type = "drag"; + ui_min = 0.05; + ui_max = 1.0; + ui_label = "Autofocus Adjustment Speed"; + ui_tooltip = "Adjustment speed of autofocus on focus change"; + ui_category = "Focusing"; +> = 0.1; + +uniform float fADOF_ManualfocusDepth < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 1.0; + ui_label = "Manual focus depth"; + ui_tooltip = "Manually adjusted static focus depth, disable autofocus to use it."; + ui_category = "Focusing"; +> = 0.001; + +uniform float fADOF_NearBlurCurve < + ui_type = "drag"; + ui_min = 0.5; + ui_max = 6.0; + ui_label = "Near blur curve"; + ui_category = "Focusing"; +> = 6.0; + +uniform float fADOF_FarBlurCurve < + ui_type = "drag"; + ui_min = 0.5; + ui_max = 6.0; + ui_label = "Far blur curve"; + ui_category = "Focusing"; +> = 1.5; + +uniform float fADOF_HyperFocus < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 1.0; + ui_label = "Hyperfocal depth distance"; + ui_category = "Focusing"; +> = 0.10; + +uniform float fADOF_RenderResolutionMult < + ui_type = "drag"; + ui_min = 0.5; + ui_max = 1.0; + ui_label = "Size Scale"; + ui_tooltip = "Resolution Scale of bokeh blur. 0.5 means 1/2 screen width and height."; + ui_category = "Blur & Quality"; +> = 0.5; + +uniform float fADOF_ShapeRadius < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 100.0; + ui_label = "Bokeh Maximal Blur Size"; + ui_tooltip = "Blur size of areas entirely out of focus."; + ui_category = "Blur & Quality"; +> = 20.5; + +uniform float fADOF_SmootheningAmount < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 20.0; + ui_label = "Gaussian blur width"; + ui_tooltip = "Width of gaussian blur after bokeh filter."; + ui_category = "Blur & Quality"; +> = 4.0; + +uniform float fADOF_BokehIntensity < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 1.0; + ui_label = "Bokeh Intensity"; + ui_tooltip = "Intensity of bokeh discs."; + ui_category = "Bokeh"; +> = 0.3; + +uniform int iADOF_BokehMode < + ui_type = "slider"; + ui_min = 0; + ui_max = 3; + ui_label = "Bokeh highlight type"; + ui_tooltip = "Different methods to emphasize bokeh sprites"; + ui_category = "Bokeh"; +> = 2; + +uniform int iADOF_ShapeVertices < + ui_type = "drag"; + ui_min = 3; + ui_max = 9; + ui_label = "Bokeh shape vertices"; + ui_tooltip = "Vertices of bokeh kernel. 5 = pentagon, 6 = hexagon etc."; + ui_category = "Bokeh"; +> = 6; + +uniform int iADOF_ShapeQuality < + ui_type = "drag"; + ui_min = 2; + ui_max = 25; + ui_label = "Bokeh shape quality"; + ui_category = "Bokeh"; +> = 5; + +uniform float fADOF_ShapeCurvatureAmount < + ui_type = "drag"; + ui_min = -1.0; + ui_max = 1.0; + ui_label = "Bokeh shape roundness"; + ui_tooltip = "Roundness of bokeh kernel. 1.0 = circle, 0.0 = polygon."; + ui_category = "Bokeh"; +> = 1.0; + +uniform float fADOF_ShapeRotation < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 360.0; + ui_label = "Bokeh shape rotation"; + ui_category = "Bokeh"; +> = 0.0; + +uniform float fADOF_ShapeAnamorphRatio < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 1.0; + ui_label = "Bokeh shape aspect ratio"; + ui_category = "Bokeh"; +> = 1.0; + +#if(ADOF_OPTICAL_VIGNETTE_ENABLE != 0) + uniform float fADOF_ShapeVignetteCurve < + ui_type = "drag"; + ui_min = 0.5; + ui_max = 2.5; + ui_label = "Bokeh shape vignette curve"; + ui_category = "Bokeh"; + > = 0.75; + + uniform float fADOF_ShapeVignetteAmount < + ui_type = "drag"; + ui_min = 0.0; + ui_max = 2.0; + ui_label = "Bokeh shape vignette amount"; + ui_category = "Bokeh"; + > = 1.0; +#endif + +#if(ADOF_CHROMATIC_ABERRATION_ENABLE != 0) + uniform float fADOF_ShapeChromaAmount < + ui_type = "drag"; + ui_min = -1.0; + ui_max = 1.0; + ui_label = "Shape chromatic aberration amount"; + ui_category = "Chromatic Aberration"; + > = -0.1; + + uniform int iADOF_ShapeChromaMode < + ui_type = "drag"; + ui_min = 0; + ui_max = 2; + ui_label = "Shape chromatic aberration type"; + ui_category = "Chromatic Aberration"; + > = 2; +#endif + +/*============================================================================= + Textures, Samplers, Globals +=============================================================================*/ + +#define RESHADE_QUINT_COMMON_VERSION_REQUIRE 202 +#define RESHADE_QUINT_EFFECT_DEPTH_REQUIRE //effect requires depth access +#include "qUINT_common.fxh" + +#define DISCRADIUS_RESOLUTION_BOUNDARY_LOWER 0.25//1.0 //used for blending blurred scene. +#define DISCRADIUS_RESOLUTION_BOUNDARY_UPPER 2.0//6.0 //used for blending blurred scene. +#define DISCRADIUS_RESOLUTION_BOUNDARY_CURVE 0.5 //used for blending blurred scene. +#define FPS_HAND_BLUR_CUTOFF_DIST 0.3353 //fps hand depth (x10.000), change if you perceive blurred fps weapons. +#define FPS_HAND_BLUR_CUTOFF_CHECK 0 //blur = max if depth > hand depth, else 0, useful for tweaking above param +#define GAUSSIAN_BUILDUP_MULT 4.0 //value of x -> gaussian reaches max radius at |CoC| == 1/x + +texture2D ADOF_FocusTex { Format = R16F; }; +texture2D ADOF_FocusTexPrev { Format = R16F; }; + +sampler2D sADOF_FocusTex { Texture = ADOF_FocusTex; }; +sampler2D sADOF_FocusTexPrev { Texture = ADOF_FocusTexPrev; }; + +texture2D CommonTex0 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; +sampler2D sCommonTex0 { Texture = CommonTex0; }; + +texture2D CommonTex1 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; +sampler2D sCommonTex1 { Texture = CommonTex1; }; + +/*============================================================================= + Vertex Shader +=============================================================================*/ + +struct ADOF_VSOUT +{ + float4 vpos : SV_Position; + float4 txcoord : TEXCOORD0; + float4 offset0 : TEXCOORD1; + float2x2 offsmat : TEXCOORD2; + +}; + +ADOF_VSOUT VS_ADOF(in uint id : SV_VertexID) +{ + ADOF_VSOUT OUT; + + OUT.txcoord.x = (id == 2) ? 2.0 : 0.0; + OUT.txcoord.y = (id == 1) ? 2.0 : 0.0; + OUT.txcoord.zw = OUT.txcoord.xy / fADOF_RenderResolutionMult; + OUT.vpos = float4(OUT.txcoord.xy * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); + + //can't precompute vertices directly, not enough registers in sm3 + sincos(6.2831853 / iADOF_ShapeVertices, OUT.offsmat._21, OUT.offsmat._22); + OUT.offsmat._11 = OUT.offsmat._22; + OUT.offsmat._12 = -OUT.offsmat._21; + + sincos(radians(fADOF_ShapeRotation), OUT.offset0.x, OUT.offset0.y); + OUT.offset0.zw = mul(OUT.offset0.xy, OUT.offsmat); + + return OUT; +} + +/*============================================================================= + Functions +=============================================================================*/ + +float GetLinearDepth(float2 coords) +{ + return qUINT::linear_depth(coords); +} + +float CircleOfConfusion(float2 texcoord, bool aggressiveLeakReduction) +{ + float2 depthdata; //x - linear scene depth, y - linear scene focus + float scenecoc; //blur value, signed by position relative to focus plane + + depthdata.x = GetLinearDepth(texcoord.xy); + + [branch] + if(aggressiveLeakReduction) + { + float3 neighbourOffsets = float3(qUINT::PIXEL_SIZE.xy, 0); + //sadly, flipped depth buffers etc don't allow for gather or linearizing in batch + float4 neighbourDepths = float4(GetLinearDepth(texcoord.xy - neighbourOffsets.xz), //left + GetLinearDepth(texcoord.xy + neighbourOffsets.xz), //right + GetLinearDepth(texcoord.xy - neighbourOffsets.zy), //top + GetLinearDepth(texcoord.xy + neighbourOffsets.zy));//bottom + + float neighbourMin = min(min(neighbourDepths.x,neighbourDepths.y),min(neighbourDepths.z,neighbourDepths.w)); + depthdata.x = lerp(min(neighbourMin, depthdata.x), depthdata.x, 0.001); + } + + depthdata.y = tex2D(sADOF_FocusTex, texcoord.xy).x; + float handdepth = depthdata.x; + + depthdata.xy = saturate(depthdata.xy / fADOF_HyperFocus); + + [branch] + if(depthdata.x < depthdata.y) + { + scenecoc = depthdata.x / depthdata.y - 1.0; + scenecoc *= exp2(-0.5*fADOF_NearBlurCurve*fADOF_NearBlurCurve); + } + else + { + scenecoc = (depthdata.x - depthdata.y)/((depthdata.y * exp2(fADOF_FarBlurCurve*fADOF_FarBlurCurve)) - depthdata.y); + scenecoc = saturate(scenecoc); + } + +#if(FPS_HAND_BLUR_CUTOFF_CHECK != 0) + scenecoc = (handdepth < FPS_HAND_BLUR_CUTOFF_DIST * 1e-4) ? 0.0 : 1.0; +#else //FPS_HAND_BLUR_CUTOFF_CHECK + scenecoc = (handdepth < FPS_HAND_BLUR_CUTOFF_DIST * 1e-4) ? 0.0 : scenecoc; +#endif //FPS_HAND_BLUR_CUTOFF_CHECK + + return scenecoc; +} + +void ShapeRoundness(inout float2 sampleOffset, in float roundness) +{ + sampleOffset *= (1.0-roundness) + rsqrt(dot(sampleOffset,sampleOffset))*roundness; +} + +void OpticalVignette(in float2 sampleOffset, in float2 centerVec, inout float sampleWeight) +{ + sampleOffset -= centerVec; //scaled by vignette intensity + sampleWeight *= saturate(3.333 - dot(sampleOffset,sampleOffset) * 1.666); //notsosmoothstep to avoid aliasing +} + +float2 CoC2BlurRadius(float CoC) +{ + return float2(fADOF_ShapeAnamorphRatio, qUINT::ASPECT_RATIO.y) * CoC * fADOF_ShapeRadius * 6e-4; +} + +/*============================================================================= + Pixel Shaders +=============================================================================*/ + +void PS_CopyBackBuffer(in ADOF_VSOUT IN, out float4 color : SV_Target0) +{ + color = tex2D(qUINT::sBackBufferTex, IN.txcoord.xy); +} + +void PS_ReadFocus(in ADOF_VSOUT IN, out float focus : SV_Target0) +{ + float scenefocus = 0.0; + + [branch] + if(bADOF_AutofocusEnable == true) + { + float samples = 10.0; + float weightsum = 1e-6; + + for(float xcoord = 0.0; xcoord < samples; xcoord++) + for(float ycoord = 0.0; ycoord < samples; ycoord++) + { + float2 sampleOffset = (float2(xcoord,ycoord) + 0.5) / samples; + sampleOffset = sampleOffset * 2.0 - 1.0; + sampleOffset *= fADOF_AutofocusRadius; + sampleOffset += (fADOF_AutofocusCenter - 0.5); + + float sampleWeight = saturate(1.2 * exp2(-dot(sampleOffset,sampleOffset)*4.0)); + + float tempfocus = GetLinearDepth(sampleOffset * 0.5 + 0.5); + sampleWeight *= rcp(tempfocus + 0.001); + + sampleWeight *= saturate(tempfocus > FPS_HAND_BLUR_CUTOFF_DIST * 1e-4); //remove fps hands from focus calculations + + scenefocus += tempfocus * sampleWeight; + weightsum += sampleWeight; + } + scenefocus /= weightsum; + } + else + { + scenefocus = fADOF_ManualfocusDepth * fADOF_ManualfocusDepth; + } + + float prevscenefocus = tex2D(sADOF_FocusTexPrev, 0.5).x; + float adjustmentspeed = fADOF_AutofocusSpeed * fADOF_AutofocusSpeed; + adjustmentspeed *= prevscenefocus > scenefocus ? 2.0 : 1.0; + + focus = lerp(prevscenefocus, scenefocus, saturate(adjustmentspeed)); +} + +void PS_CopyFocus(in ADOF_VSOUT IN, out float focus : SV_Target0) +{ + focus = tex2D(sADOF_FocusTex, IN.txcoord.xy).x; +} + +void PS_CoC(in ADOF_VSOUT IN, out float4 color : SV_Target0) +{ + color = tex2D(qUINT::sBackBufferTex, IN.txcoord.xy); + + static const float2 sampleOffsets[4] = { float2( 1.5, 0.5) * qUINT::PIXEL_SIZE.xy, + float2( 0.5,-1.5) * qUINT::PIXEL_SIZE.xy, + float2(-1.5,-0.5) * qUINT::PIXEL_SIZE.xy, + float2(-0.5, 1.5) * qUINT::PIXEL_SIZE.xy}; + + float centerDepth = GetLinearDepth(IN.txcoord.xy); + float4 sampleCoord = 0.0; + float3 neighbourOffsets = float3(qUINT::PIXEL_SIZE.xy, 0); + float4 coccolor = 0.0; + + [loop] + for(int i=0; i<4; i++) + { + sampleCoord.xy = IN.txcoord.xy + sampleOffsets[i]; + + float3 sampleColor = tex2Dlod(qUINT::sBackBufferTex, sampleCoord).rgb; + + float4 sampleDepths = float4(GetLinearDepth(sampleCoord.xy + neighbourOffsets.xz), //right + GetLinearDepth(sampleCoord.xy - neighbourOffsets.xz), //left + GetLinearDepth(sampleCoord.xy + neighbourOffsets.zy), //bottom + GetLinearDepth(sampleCoord.xy - neighbourOffsets.zy)); //top + + float sampleDepthMin = min(min(sampleDepths.x,sampleDepths.y),min(sampleDepths.z,sampleDepths.w)); + + sampleColor /= 1.0 + max(max(sampleColor.r, sampleColor.g), sampleColor.b); + + float sampleWeight = saturate(sampleDepthMin * rcp(centerDepth) + 1e-3); + coccolor += float4(sampleColor.rgb * sampleWeight, sampleWeight); + } + + coccolor.rgb /= coccolor.a; + coccolor.rgb /= 1.0 - max(coccolor.r, max(coccolor.g, coccolor.b)); + + color.rgb = lerp(color.rgb, coccolor.rgb, saturate(coccolor.w * 8.0)); + color.w = CircleOfConfusion(IN.txcoord.xy, 1); + color.w = saturate(color.w * 0.5 + 0.5); +} + +void unpack_hdr(inout float3 color) +{ + color = color * rcp(1.2 - saturate(color)); +} + +void pack_hdr(inout float3 color) +{ + color = 1.2 * color * rcp(color + 1.0); +} + +float4 PS_DoF_Main(in ADOF_VSOUT IN) : SV_Target0 +{ + if(max(IN.txcoord.z,IN.txcoord.w) > 1.01) discard; + + float4 BokehSum, BokehMax; + BokehMax = tex2D(sCommonTex0, IN.txcoord.zw); + BokehSum = BokehMax; + float weightSum = 1.0; + float CoC = abs(BokehSum.w * 2.0 - 1.0); + float2 bokehRadiusScaled = CoC2BlurRadius(CoC); + float nRings = lerp(1.0,iADOF_ShapeQuality,saturate(CoC)) + (dot(IN.vpos.xy,1) % 2) * 0.5; + + if(bokehRadiusScaled.x < DISCRADIUS_RESOLUTION_BOUNDARY_LOWER * qUINT::PIXEL_SIZE.x) return BokehSum; + + bokehRadiusScaled /= nRings; + CoC /= nRings; + +#if (ADOF_OPTICAL_VIGNETTE_ENABLE != 0) + float2 centerVec = IN.txcoord.zw - 0.5; + float centerDist = sqrt(dot(centerVec,centerVec)); + float vignette = pow(centerDist, fADOF_ShapeVignetteCurve) * fADOF_ShapeVignetteAmount; + centerVec = centerVec / centerDist * vignette; + weightSum *= saturate(3.33 - vignette * 2.0); + BokehSum *= weightSum; + BokehMax *= weightSum; +#endif + + int densityScale = max(1, 6 - iADOF_ShapeVertices); + + [loop] + for (int iVertices = 0; iVertices < iADOF_ShapeVertices && iVertices < 10; iVertices++) + { + [loop] + for(float iRings = 1; iRings <= nRings && iRings < 26; iRings++) + { + [loop] + for(float iSamplesPerRing = 0; iSamplesPerRing < iRings * densityScale && iSamplesPerRing < 26*2; iSamplesPerRing++) + { + float x = iSamplesPerRing/(iRings * densityScale); + float a = x * x * (3.0 - 2.0 * x); + float l = 2.55 * rcp(iADOF_ShapeVertices * iADOF_ShapeVertices * 0.4 - 1.0); + x = lerp(x, (1.0 + l) * x - a * l, fADOF_ShapeCurvatureAmount); + + float2 sampleOffset = lerp(IN.offset0.xy,IN.offset0.zw, x); + + ShapeRoundness(sampleOffset,fADOF_ShapeCurvatureAmount); + + float4 sampleBokeh = tex2Dlod(sCommonTex0, float4(IN.txcoord.zw + sampleOffset.xy * (bokehRadiusScaled * iRings),0,0)); + float sampleWeight = saturate(1e6 * (abs(sampleBokeh.a * 2.0 - 1.0) - CoC * (float)iRings) + 1.0); + +#if (ADOF_OPTICAL_VIGNETTE_ENABLE != 0) + OpticalVignette(sampleOffset.xy * iRings/nRings, centerVec, sampleWeight); +#endif + sampleBokeh.rgb *= sampleWeight; + weightSum += sampleWeight; + BokehSum += sampleBokeh; + BokehMax = max(BokehMax,sampleBokeh); + } + } + + IN.offset0.xy = IN.offset0.zw; + IN.offset0.zw = mul(IN.offset0.zw, IN.offsmat); + } + + // return lerp(BokehSum / weightSum, BokehMax, fADOF_BokehIntensity * saturate(CoC*nRings*2.0)); + + float4 ret = 0; + + BokehSum /= weightSum; + + unpack_hdr(BokehSum.rgb); + unpack_hdr(BokehMax.rgb); + + if(iADOF_BokehMode == 0) + { + ret = lerp(BokehSum, BokehMax, fADOF_BokehIntensity * saturate(CoC * nRings * 2.0)); + } + else if(iADOF_BokehMode == 1) + { + + float maxlum = dot(float3(0.3, 0.59, 0.11), BokehMax.rgb); + float avglum = dot(float3(0.3, 0.59, 0.11), BokehSum.rgb); + + ret = BokehSum * lerp(avglum, maxlum, fADOF_BokehIntensity * saturate(CoC * nRings * 2.0)) / avglum; + } + else if(iADOF_BokehMode == 2) + { + float maxlum = dot(float3(0.3, 0.59, 0.11), BokehMax.rgb); + float avglum = dot(float3(0.3, 0.59, 0.11), BokehSum.rgb); + + float bokehweight = max(0, maxlum - avglum); + bokehweight = bokehweight * fADOF_BokehIntensity * 2.0; + bokehweight *= bokehweight; + + ret = BokehSum + BokehMax * saturate(bokehweight * CoC * nRings); + } + else if(iADOF_BokehMode == 3) + { + float maxlum = dot(float3(0.3, 0.59, 0.11), BokehMax.rgb); + float avglum = dot(float3(0.3, 0.59, 0.11), BokehSum.rgb); + + float bokehweight = maxlum - avglum; + ret = lerp(BokehSum, BokehMax, saturate(bokehweight * CoC * nRings * fADOF_BokehIntensity)); + } + + pack_hdr(ret.rgb); + + return ret; +} + +void PS_DoF_Combine(in ADOF_VSOUT IN, out float4 color : SV_Target0) +{ + float4 blurredColor = tex2D(sCommonTex1, IN.txcoord.xy * fADOF_RenderResolutionMult); + float4 originalColor = tex2D(qUINT::sBackBufferTex, IN.txcoord.xy); + + float CoC = abs(CircleOfConfusion(IN.txcoord.xy, 0)); + float bokehRadiusPixels = CoC2BlurRadius(CoC).x * BUFFER_WIDTH; + + #define linearstep(a,b,x) saturate((x-a)/(b-a)) + float blendWeight = linearstep(DISCRADIUS_RESOLUTION_BOUNDARY_LOWER, DISCRADIUS_RESOLUTION_BOUNDARY_UPPER, bokehRadiusPixels); + blendWeight = pow(blendWeight,DISCRADIUS_RESOLUTION_BOUNDARY_CURVE); + + color.rgb = lerp(originalColor.rgb, blurredColor.rgb, blendWeight); + color.a = saturate(CoC * GAUSSIAN_BUILDUP_MULT) * 0.5 + 0.5; +} + +void PS_DoF_Gauss1(in ADOF_VSOUT IN, out float4 color : SV_Target0) +{ + float4 centerTap = tex2D(sCommonTex0, IN.txcoord.xy); + float CoC = abs(centerTap.a * 2.0 - 1.0); + + float nSteps = floor(CoC * (fADOF_SmootheningAmount + 0.0)); + float expCoeff = -2.0 * rcp(nSteps * nSteps + 1e-3); //sigma adjusted for blur width + float2 blurAxisScaled = float2(1,0) * qUINT::PIXEL_SIZE.xy; + + float4 gaussianSum = 0.0; + float gaussianSumWeight = 1e-3; + + for(float iStep = -nSteps; iStep <= nSteps; iStep++) + { + float currentWeight = exp(iStep * iStep * expCoeff); + float currentOffset = 2.0 * iStep - 0.5; //Sample between texels to double blur width at no cost + + float4 currentTap = tex2Dlod(sCommonTex0, float4(IN.txcoord.xy + blurAxisScaled.xy * currentOffset, 0, 0)); + currentWeight *= saturate(abs(currentTap.a * 2.0 - 1.0) - CoC * 0.25); //bleed fix + + gaussianSum += currentTap * currentWeight; + gaussianSumWeight += currentWeight; + } + + gaussianSum /= gaussianSumWeight; + + color.rgb = lerp(centerTap.rgb, gaussianSum.rgb, saturate(gaussianSumWeight)); + color.a = centerTap.a; +} + +void PS_DoF_Gauss2(in ADOF_VSOUT IN, out float4 color : SV_Target0) +{ + float4 centerTap = tex2D(sCommonTex1, IN.txcoord.xy); + float CoC = abs(centerTap.a * 2.0 - 1.0); + + float nSteps = min(50,floor(CoC * (fADOF_SmootheningAmount + 0.0))); + float expCoeff = -2.0 * rcp(nSteps * nSteps + 1e-3); //sigma adjusted for blur width + float2 blurAxisScaled = float2(0,1) * qUINT::PIXEL_SIZE.xy; + + float4 gaussianSum = 0.0; + float gaussianSumWeight = 1e-3; + + for(float iStep = -nSteps; iStep <= nSteps; iStep++) + { + float currentWeight = exp(iStep * iStep * expCoeff); + float currentOffset = 2.0 * iStep - 0.5; //Sample between texels to double blur width at no cost + + float4 currentTap = tex2Dlod(sCommonTex1, float4(IN.txcoord.xy + blurAxisScaled.xy * currentOffset, 0, 0)); + currentWeight *= saturate(abs(currentTap.a * 2.0 - 1.0) - CoC * 0.25); //bleed fix + + gaussianSum += currentTap * currentWeight; + gaussianSumWeight += currentWeight; + } + + gaussianSum /= gaussianSumWeight; + + color.rgb = lerp(centerTap.rgb, gaussianSum.rgb, saturate(gaussianSumWeight)); + color.a = centerTap.a; +} + +#if (ADOF_CHROMATIC_ABERRATION_ENABLE != 0) +void PS_DoF_ChromaticAberration(in ADOF_VSOUT IN, out float4 color : SV_Target0) +{ + float4 colorVals[5]; + float3 neighbourOffsets = float3(qUINT::PIXEL_SIZE.xy, 0); + + colorVals[0] = tex2D(sCommonTex0, IN.txcoord.xy); //C + colorVals[1] = tex2D(sCommonTex0, IN.txcoord.xy - neighbourOffsets.xz); //L + colorVals[2] = tex2D(sCommonTex0, IN.txcoord.xy - neighbourOffsets.zy); //T + colorVals[3] = tex2D(sCommonTex0, IN.txcoord.xy + neighbourOffsets.xz); //R + colorVals[4] = tex2D(sCommonTex0, IN.txcoord.xy + neighbourOffsets.zy); //B + + float CoC = abs(colorVals[0].a * 2.0 - 1.0); + float2 bokehRadiusScaled = CoC2BlurRadius(CoC); + + float4 vGradTwosided = float4(dot(colorVals[0].rgb - colorVals[1].rgb, 1), //C - L + dot(colorVals[0].rgb - colorVals[2].rgb, 1), //C - T + dot(colorVals[3].rgb - colorVals[0].rgb, 1), //R - C + dot(colorVals[4].rgb - colorVals[0].rgb, 1)); //B - C + + float2 vGrad = min(vGradTwosided.xy, vGradTwosided.zw); + + float vGradLen = sqrt(dot(vGrad,vGrad)) + 1e-6; + vGrad = vGrad / vGradLen * saturate(vGradLen * 32.0) * bokehRadiusScaled * 0.125 * fADOF_ShapeChromaAmount; + + float4 chromaVals[3]; + + chromaVals[0] = colorVals[0]; + chromaVals[1] = tex2D(sCommonTex0, IN.txcoord.xy + vGrad); + chromaVals[2] = tex2D(sCommonTex0, IN.txcoord.xy - vGrad); + + chromaVals[1].rgb = lerp(chromaVals[0].rgb, chromaVals[1].rgb, saturate(4.0 * abs(chromaVals[1].w))); + chromaVals[2].rgb = lerp(chromaVals[0].rgb, chromaVals[2].rgb, saturate(4.0 * abs(chromaVals[2].w))); + + uint3 chromaMode = (uint3(0,1,2) + iADOF_ShapeChromaMode.xxx) % 3; + + color.rgb = float3(chromaVals[chromaMode.x].r, + chromaVals[chromaMode.y].g, + chromaVals[chromaMode.z].b); + color.a = 1.0; +} +#endif + +/*============================================================================= + Techniques +=============================================================================*/ + +technique ADOF +< ui_tooltip = " >> qUINT::ADOF <<\n\n" + "ADOF is a bokeh depth of field shader.\n" + "It blurs the scene in front of and behind the focus plane\n" + "to simulate the behaviour of real lenses. A multitude of features\n" + "allows to simulate various types of bokeh blur that cameras produce.\n" + "\nADOF is written by Marty McFly / Pascal Gilcher"; > +{ + /* pass + { + VertexShader = VS_ADOF; + PixelShader = PS_CopyBackBuffer; + RenderTarget = texOriginal; + }*/ + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_ReadFocus; + RenderTarget = ADOF_FocusTex; + } + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_CopyFocus; + RenderTarget = ADOF_FocusTexPrev; + } + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_CoC; + RenderTarget = CommonTex0; + } + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_DoF_Main; + RenderTarget = CommonTex1; + } + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_DoF_Combine; + RenderTarget = CommonTex0; + } + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_DoF_Gauss1; + RenderTarget = CommonTex1; + } +#if(ADOF_CHROMATIC_ABERRATION_ENABLE != 0) + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_DoF_Gauss2; + RenderTarget = CommonTex0; + } + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_DoF_ChromaticAberration; + } +#else + pass + { + VertexShader = VS_ADOF; + PixelShader = PS_DoF_Gauss2; + } +#endif +} diff --git a/data_from_portwine/Reshade/Shaders/qUINT_lightroom.fx b/data_from_portwine/Reshade/Shaders/qUINT_lightroom.fx new file mode 100644 index 00000000..2252a610 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/qUINT_lightroom.fx @@ -0,0 +1,910 @@ +/*============================================================================= + + ReShade 4 effect file + github.com/martymcmodding + + Support me: + paypal.me/mcflypg + patreon.com/mcflypg + + Lightroom + by Marty McFly / P.Gilcher + part of qUINT shader library for ReShade 4 + + Copyright (c) Pascal Gilcher / Marty McFly. All rights reserved. + +=============================================================================*/ + +/*============================================================================= + Preprocessor settings +=============================================================================*/ + +#ifndef ENABLE_HISTOGRAM + #define ENABLE_HISTOGRAM 0 +#endif + +#ifndef HISTOGRAM_BINS_NUM + #define HISTOGRAM_BINS_NUM 128 +#endif + +/*============================================================================= + UI Uniforms +=============================================================================*/ + +uniform bool LIGHTROOM_ENABLE_LUT < + ui_label = "Enable LUT Overlay"; + ui_tooltip = "This displays a neutral LUT onscreen, all color adjustments of this shader and consecutive ones are applied to it.\nTaking a screenshot and using the cropped LUT with the TuningPalette will reproduce all changes of this shader.\nTo make sure that all color changes of your current preset are saved, put Lightroom as early in the\ntechnique chain as possible. Putting grain, sharpening, bloom etc after Lightroom.fx will break the LUT."; + ui_category = "LUT"; +> = false; + +uniform int LIGHTROOM_LUT_TILE_SIZE < + ui_type = "drag"; + ui_min = 8; ui_max = 64; + ui_label = "LUT tile size"; + ui_tooltip = "This controls the XY size of tiles of the LUT (which is accuracy in red/green channel)."; + ui_category = "LUT"; +> = 16; + +uniform int LIGHTROOM_LUT_TILE_COUNT < + ui_type = "drag"; + ui_min = 8; ui_max = 64; + ui_label = "LUT tile count"; + ui_tooltip = "This controls the amount of tiles of the LUT (which is accuracy in blue channel).\nBe aware that Tile Size XY * Tile Amount is the width of the LUT and if this value\nis larger than your resolution width, the LUT won't fit on your screen."; + ui_category = "LUT"; +> = 16; + +uniform int LIGHTROOM_LUT_SCROLL < + ui_type = "drag"; + ui_min = 0; ui_max = 5; + ui_label = "LUT scroll"; + ui_tooltip = "If your LUT size exceeds your screen width, set this to 0, take screenshot, set it to 1, take screenshot\netc until you reach the end of your LUT and assemble the screenshots like a panorama.\nIf your LUT fits the screen size however, leave it at 0."; + ui_category = "LUT"; +> = 0; + +uniform bool LIGHTROOM_ENABLE_CURVE_DISPLAY < + ui_label = "Enable Luma Curve Display"; + ui_tooltip = "This enables a small overlay with a luma curve\nso you can monitor changes made by exposure, levels etc."; + ui_category = "Debug"; +> = false; + +uniform bool LIGHTROOM_ENABLE_CLIPPING_DISPLAY < + ui_label = "Enable Black/White Clipping Mask"; + ui_tooltip = "This shows where colors reach #000000 black or #ffffff white, helpful for adjusting levels properly.\nNOTE: Any shader that operates after Lightroom in ReShade technique list can change final color levels afterwards\nso either put Lightroom last in line or take this with a grain of salt."; + ui_category = "Debug"; +> = false; + +#if(ENABLE_HISTOGRAM == 1) + + uniform bool LIGHTROOM_ENABLE_HISTOGRAM < + ui_label = "Enable Histogram"; + ui_tooltip = "This enables a small overlay with a histogram for monitoring purposes.\nFor higher performance, open shader and set HISTOGRAM_BINS_NUM to a lower value."; + ui_category = "Histogram"; + > = false; + + uniform int LIGHTROOM_HISTOGRAM_SAMPLES < + ui_type = "drag"; + ui_min = 32; ui_max = 96; + ui_label = "Histogram Samples"; + ui_tooltip = "The amount of samples, 20 means 20x20 samples distributed on the screen.\nHigher means a more accurate histogram depicition and less temporal noise."; + ui_category = "Histogram"; + > = 20; + + uniform float LIGHTROOM_HISTOGRAM_HEIGHT < + ui_type = "drag"; + ui_step = 1; + ui_min = 5.0; ui_max = 50.0; + ui_label = "Histogram Curve Height"; + ui_tooltip = "Raises the Histogram curve if the values are highly distributed and not visible very well."; + ui_category = "Histogram"; + > = 15; + + uniform float LIGHTROOM_HISTOGRAM_SMOOTHNESS < + ui_type = "drag"; + ui_min = 1.0; ui_max = 10.00; + ui_label = "Histogram Curve Smoothness"; + ui_tooltip = "Smoothens the Histogram curve for a more temporally coherent result.\nNote that raising this falsifies the Histogram data."; + ui_category = "Histogram"; + > = 5.00; + +#endif + +//============================================================================= + +uniform float LIGHTROOM_RED_HUESHIFT < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Red Hue Control"; + ui_tooltip = "Magenta <= ... Red ... => Orange"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_ORANGE_HUESHIFT < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Orange Hue Control"; + ui_tooltip = "Red <= ... Orange ... => Yellow"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_YELLOW_HUESHIFT < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Yellow Hue Control"; + ui_tooltip = "Orange <= ... Yellow ... => Green"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_GREEN_HUESHIFT < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Green Hue Control"; + ui_tooltip = "Yellow <= ... Green ... => Aqua"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_AQUA_HUESHIFT < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Aqua Hue Control"; + ui_tooltip = "Green <= ... Aqua ... => Blue"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_BLUE_HUESHIFT < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Blue Hue Control"; + ui_tooltip = "Aqua <= ... Blue ... => Magenta"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_MAGENTA_HUESHIFT < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Magenta Hue Control"; + ui_tooltip = "Blue <= ... Magenta ... => Red"; + ui_category = "Palette"; +> = 0.00; + +//============================================================================= + +uniform float LIGHTROOM_RED_EXPOSURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Red Exposure"; + ui_tooltip = "Exposure control of Red colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_ORANGE_EXPOSURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Orange Exposure"; + ui_tooltip = "Exposure control of Orange colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_YELLOW_EXPOSURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Yellow Exposure"; + ui_tooltip = "Exposure control of Yellow colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_GREEN_EXPOSURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Green Exposure"; + ui_tooltip = "Exposure control of Green colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_AQUA_EXPOSURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Aqua Exposure"; + ui_tooltip = "Exposure control of Aqua colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_BLUE_EXPOSURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Blue Exposure"; + ui_tooltip = "Exposure control of Blue colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_MAGENTA_EXPOSURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Magenta Exposure"; + ui_tooltip = "Exposure control of Magenta colors"; + ui_category = "Palette"; +> = 0.00; + +//============================================================================= + +uniform float LIGHTROOM_RED_SATURATION < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Red Saturation"; + ui_tooltip = "Saturation control of Red colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_ORANGE_SATURATION < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Orange Saturation"; + ui_tooltip = "Saturation control of Orange colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_YELLOW_SATURATION < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Yellow Saturation"; + ui_tooltip = "Saturation control of Yellow colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_GREEN_SATURATION < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Green Saturation"; + ui_tooltip = "Saturation control of Green colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_AQUA_SATURATION < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Aqua Saturation"; + ui_tooltip = "Saturation control of Aqua colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_BLUE_SATURATION < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Blue Saturation"; + ui_tooltip = "Saturation control of Blue colors"; + ui_category = "Palette"; +> = 0.00; + +uniform float LIGHTROOM_MAGENTA_SATURATION < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Magenta Saturation"; + ui_tooltip = "Saturation control of Magenta colors"; + ui_category = "Palette"; +> = 0.00; + +//============================================================================= + +uniform float LIGHTROOM_GLOBAL_BLACK_LEVEL < + ui_type = "drag"; + ui_min = 0; ui_max = 512; + ui_step = 1; + ui_label = "Global Black Level"; + ui_tooltip = "Scales input HSL value. Everything darker than this is mapped to black."; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_WHITE_LEVEL < + ui_type = "drag"; + ui_min = 0; ui_max = 512; + ui_step = 1; + ui_label = "Global White Level"; + ui_tooltip = "Scales input HSL value. "; + ui_category = "Curves"; +> = 255.00; + +uniform float LIGHTROOM_GLOBAL_EXPOSURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Exposure"; + ui_tooltip = "Global Exposure Control"; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_GAMMA < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Gamma"; + ui_tooltip = "Global Gamma Control"; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_BLACKS_CURVE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Blacks Curve"; + ui_tooltip = "Global Blacks Curve Control"; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_SHADOWS_CURVE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Shadows Curve"; + ui_tooltip = "Global Shadows Curve Control"; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_MIDTONES_CURVE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Midtones Curve"; + ui_tooltip = "Global Midtones Curve Control"; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_HIGHLIGHTS_CURVE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Highlights Curve"; + ui_tooltip = "Global Highlights Curve Control"; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_WHITES_CURVE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Whites Curve"; + ui_tooltip = "Global Whites Curve Control"; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_CONTRAST < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Contrast"; + ui_tooltip = "Global Contrast Control"; + ui_category = "Curves"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_SATURATION < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Saturation"; + ui_tooltip = "Global Saturation Control"; + ui_category = "Color & Saturation"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_VIBRANCE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global Vibrance"; + ui_tooltip = "Global Vibrance Control"; + ui_category = "Color & Saturation"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_TEMPERATURE < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global White Balance: Temperature"; + ui_tooltip = "Global Temperature Control"; + ui_category = "Color & Saturation"; +> = 0.00; + +uniform float LIGHTROOM_GLOBAL_TINT < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Global White Balance: Tint"; + ui_tooltip = "Global Tint Control"; + ui_category = "Color & Saturation"; +> = 0.00; + +//============================================================================= + +uniform bool LIGHTROOM_ENABLE_VIGNETTE < + ui_label = "Enable Vignette Effect"; + ui_tooltip = "This enables a vignette effect (corner darkening)."; + ui_category = "Vignette"; +> = false; + +uniform bool LIGHTROOM_VIGNETTE_SHOW_RADII < + ui_label = "Show Vignette Inner and Outer radius"; + ui_tooltip = "This makes the inner and outer radius setting visible.\nVignette intensity builds up from green (no vignetting) to red (full vignetting)."; + ui_category = "Vignette"; +> = false; + +uniform float2 LIGHTROOM_VIGNETTE_OFFS < + ui_type = "drag"; + ui_min = -1.00; ui_max = 1.00; + ui_label = "Vignette Center"; + ui_category = "Vignette"; +> = float2(0.0, 0.0); + +uniform float LIGHTROOM_VIGNETTE_RADIUS_INNER < + ui_type = "drag"; + ui_min = 0.00; ui_max = 2.00; + ui_label = "Inner Vignette Radius"; + ui_tooltip = "Anything closer to the screen center than this is not affected by vignette."; + ui_category = "Vignette"; +> = 0.00; + +uniform float LIGHTROOM_VIGNETTE_RADIUS_OUTER < + ui_type = "drag"; + ui_min = 0.00; ui_max = 3.00; + ui_label = "Outer Vignette Radius"; + ui_tooltip = "Anything farther from the screen center than this gets fully vignette'd."; + ui_category = "Vignette"; +> = 1.00; + +uniform float LIGHTROOM_VIGNETTE_WIDTH < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Vignette Width"; + ui_tooltip = "Higher values stretch the vignette horizontally."; + ui_category = "Vignette"; +> = 0.00; + +uniform float LIGHTROOM_VIGNETTE_HEIGHT < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Vignette Height"; + ui_tooltip = "Higher values stretch the vignette vertically."; + ui_category = "Vignette"; +> = 0.00; + +uniform float LIGHTROOM_VIGNETTE_AMOUNT < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Vignette Amount"; + ui_tooltip = "Intensity of vignette effect."; + ui_category = "Vignette"; +> = 1.00; + +uniform float LIGHTROOM_VIGNETTE_CURVE < + ui_type = "drag"; + ui_min = 0.00; ui_max = 10.00; + ui_label = "Vignette Curve"; + ui_tooltip = "Curve of gradient between inner and outer radius. 1.0 means linear."; + ui_category = "Vignette"; +> = 1.00; + +uniform float3 LIGHTROOM_VIGNETTE_COLOR < + ui_type = "color"; + ui_label="Vignette Color"; + ui_category = "Vignette"; +> = float3(0.0, 0.0, 0.0); + +uniform int LIGHTROOM_VIGNETTE_BLEND_MODE < + ui_type = "combo"; + ui_items = "Multiply\0Subtract\0Screen\0LumaPreserving\0Alpha Blend\0"; + ui_tooltip = "Select between different ways of applying vignette"; + ui_label = "Vignette Blend Mode"; + ui_category = "Vignette"; +> = 1; + +/*============================================================================= + Textures, Samplers, Globals +=============================================================================*/ + +#define RESHADE_QUINT_COMMON_VERSION_REQUIRE 200 +#include "qUINT_common.fxh" + +#if(ENABLE_HISTOGRAM == 1) +texture2D HistogramTex { Width = HISTOGRAM_BINS_NUM; Height = 1; Format = RGBA16F; }; +sampler2D sHistogramTex { Texture = HistogramTex; }; +#endif + +texture2D LutTexInternal { Width = 4096; Height = 64; Format = RGBA8; }; +sampler2D sLutTexInternal { Texture = LutTexInternal; }; + +/*============================================================================= + Vertex Shader +=============================================================================*/ + +void VS_Lightroom(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 uv : TEXCOORD0, out nointerpolation float huefactors[7] : TEXCOORD1) +{ + uv.x = (id == 2) ? 2.0 : 0.0; + uv.y = (id == 1) ? 2.0 : 0.0; + position = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); + + static const float originalHue[8] = {0.0,0.0833333333333,0.1666666666666,0.3333333333333,0.5,0.6666666666666,0.8333333333333,1.0}; + + huefactors[0] = (LIGHTROOM_RED_HUESHIFT > 0) ? lerp(originalHue[0], originalHue[1], LIGHTROOM_RED_HUESHIFT) : lerp(originalHue[7], originalHue[6], -LIGHTROOM_RED_HUESHIFT); + huefactors[1] = (LIGHTROOM_ORANGE_HUESHIFT > 0) ? lerp(originalHue[1], originalHue[2], LIGHTROOM_ORANGE_HUESHIFT) : lerp(originalHue[1], originalHue[0], -LIGHTROOM_ORANGE_HUESHIFT); + huefactors[2] = (LIGHTROOM_YELLOW_HUESHIFT > 0) ? lerp(originalHue[2], originalHue[3], LIGHTROOM_YELLOW_HUESHIFT) : lerp(originalHue[2], originalHue[1], -LIGHTROOM_YELLOW_HUESHIFT); + huefactors[3] = (LIGHTROOM_GREEN_HUESHIFT > 0) ? lerp(originalHue[3], originalHue[4], LIGHTROOM_GREEN_HUESHIFT) : lerp(originalHue[3], originalHue[2], -LIGHTROOM_GREEN_HUESHIFT); + huefactors[4] = (LIGHTROOM_AQUA_HUESHIFT > 0) ? lerp(originalHue[4], originalHue[5], LIGHTROOM_AQUA_HUESHIFT) : lerp(originalHue[4], originalHue[3], -LIGHTROOM_AQUA_HUESHIFT); + huefactors[5] = (LIGHTROOM_BLUE_HUESHIFT > 0) ? lerp(originalHue[5], originalHue[6], LIGHTROOM_BLUE_HUESHIFT) : lerp(originalHue[5], originalHue[4], -LIGHTROOM_BLUE_HUESHIFT); + huefactors[6] = (LIGHTROOM_MAGENTA_HUESHIFT > 0) ? lerp(originalHue[6], originalHue[7], LIGHTROOM_MAGENTA_HUESHIFT) : lerp(originalHue[6], originalHue[5], -LIGHTROOM_MAGENTA_HUESHIFT); +} + +/*============================================================================= + Functions +=============================================================================*/ + +struct CurvesStruct +{ + float2 levels; + float exposure; + float gamma; + float contrast; + float blacks; + float shadows; + float midtones; + float highlights; + float whites; +}; + +struct PaletteStruct +{ + float hue[7]; + float saturation[7]; + float exposure[7]; +}; + +struct VignetteStruct +{ + float2 ratio; + float2 radii; + float amount; + float curve; + int blend; + bool debug; +}; + +CurvesStruct setup_curves() +{ + CurvesStruct Curves; + Curves.levels = float2(LIGHTROOM_GLOBAL_BLACK_LEVEL, LIGHTROOM_GLOBAL_WHITE_LEVEL) * rcp(255.0); + Curves.exposure = exp2(LIGHTROOM_GLOBAL_EXPOSURE); + Curves.gamma = exp2(-LIGHTROOM_GLOBAL_GAMMA); + Curves.contrast = LIGHTROOM_GLOBAL_CONTRAST; + Curves.blacks = exp2(-LIGHTROOM_GLOBAL_BLACKS_CURVE); + Curves.shadows = exp2(-LIGHTROOM_GLOBAL_SHADOWS_CURVE); + Curves.midtones = exp2(-LIGHTROOM_GLOBAL_MIDTONES_CURVE); + Curves.highlights = exp2(-LIGHTROOM_GLOBAL_HIGHLIGHTS_CURVE); + Curves.whites = exp2(-LIGHTROOM_GLOBAL_WHITES_CURVE); + return Curves; +} + +PaletteStruct setup_palette() +{ + PaletteStruct Palette; + Palette.hue[0] = LIGHTROOM_RED_HUESHIFT; + Palette.hue[1] = LIGHTROOM_ORANGE_HUESHIFT; + Palette.hue[2] = LIGHTROOM_YELLOW_HUESHIFT; + Palette.hue[3] = LIGHTROOM_GREEN_HUESHIFT; + Palette.hue[4] = LIGHTROOM_AQUA_HUESHIFT; + Palette.hue[5] = LIGHTROOM_BLUE_HUESHIFT; + Palette.hue[6] = LIGHTROOM_MAGENTA_HUESHIFT; + Palette.saturation[0] = LIGHTROOM_RED_SATURATION; + Palette.saturation[1] = LIGHTROOM_ORANGE_SATURATION; + Palette.saturation[2] = LIGHTROOM_YELLOW_SATURATION; + Palette.saturation[3] = LIGHTROOM_GREEN_SATURATION; + Palette.saturation[4] = LIGHTROOM_AQUA_SATURATION; + Palette.saturation[5] = LIGHTROOM_BLUE_SATURATION; + Palette.saturation[6] = LIGHTROOM_MAGENTA_SATURATION; + Palette.exposure[0] = LIGHTROOM_RED_EXPOSURE; + Palette.exposure[1] = LIGHTROOM_ORANGE_EXPOSURE; + Palette.exposure[2] = LIGHTROOM_YELLOW_EXPOSURE; + Palette.exposure[3] = LIGHTROOM_GREEN_EXPOSURE; + Palette.exposure[4] = LIGHTROOM_AQUA_EXPOSURE; + Palette.exposure[5] = LIGHTROOM_BLUE_EXPOSURE; + Palette.exposure[6] = LIGHTROOM_MAGENTA_EXPOSURE; + return Palette; +} + +VignetteStruct setup_vignette() +{ + VignetteStruct Vignette; + Vignette.ratio = float2(LIGHTROOM_VIGNETTE_WIDTH,LIGHTROOM_VIGNETTE_HEIGHT); + Vignette.radii = float2(LIGHTROOM_VIGNETTE_RADIUS_INNER, LIGHTROOM_VIGNETTE_RADIUS_OUTER); + Vignette.amount = LIGHTROOM_VIGNETTE_AMOUNT; + Vignette.curve = LIGHTROOM_VIGNETTE_CURVE; + Vignette.blend = LIGHTROOM_VIGNETTE_BLEND_MODE; + Vignette.debug = LIGHTROOM_VIGNETTE_SHOW_RADII; + return Vignette; +} + +float3 rgb_to_hcv(in float3 RGB) +{ + RGB = saturate(RGB); + float Epsilon = 1e-10; + // Based on work by Sam Hocevar and Emil Persson + float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0/3.0) : float4(RGB.gb, 0.0, -1.0/3.0); + float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx); + float C = Q.x - min(Q.w, Q.y); + float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z); + return float3(H, C, Q.x); +} + +float3 rgb_to_hsl(in float3 RGB) +{ + float3 HCV = rgb_to_hcv(RGB); + float L = HCV.z - HCV.y * 0.5; + float S = HCV.y / (1.0000001 - abs(L * 2 - 1)); + return float3(HCV.x, S, L); +} + +float3 hsl_to_rgb(in float3 HSL) +{ + HSL = saturate(HSL); + float3 RGB = saturate(float3(abs(HSL.x * 6.0 - 3.0) - 1.0,2.0 - abs(HSL.x * 6.0 - 2.0),2.0 - abs(HSL.x * 6.0 - 4.0))); + float C = (1 - abs(2 * HSL.z - 1)) * HSL.y; + return (RGB - 0.5) * C + HSL.z; +} + +float linearstep(float lower, float upper, float value) +{ + return saturate((value-lower)/(upper-lower)); +} + +float3 get_function_graph(float2 coords, float F, float3 origcolor, float thickness) +{ + F -= coords.y; + float DistanceField = abs(F) / length(float2(ddx(F) / ddx(coords.x), -1.0)); + return lerp(origcolor, 1 - origcolor, smoothstep(qUINT::PIXEL_SIZE.y*thickness, 0.0, DistanceField)); +} + +float3 get_vignette(float3 color, float2 uv, VignetteStruct v) +{ + float2 vign_uv = uv * 2 - 1; + vign_uv += LIGHTROOM_VIGNETTE_OFFS; + vign_uv -= vign_uv * v.ratio; + float vign_gradient = length(vign_uv); + float vignette = linearstep(v.radii.x, v.radii.y, vign_gradient); + vignette = pow(vignette, v.curve + 1e-6) * v.amount; + + vignette = saturate(vignette); + + color = (v.blend == 0) ? lerp(color, color * LIGHTROOM_VIGNETTE_COLOR, vignette) : color; + color = (v.blend == 1) ? saturate(color - vignette.xxx) : color; + color = (v.blend == 2) ? 1 - (1 - color) * (vignette + 1) : color; + color = (v.blend == 3) ? color * saturate(lerp(1 - vignette * 2 , 1, dot(color, 0.333))) : color; + color = (v.blend == 4) ? lerp(color, LIGHTROOM_VIGNETTE_COLOR, vignette) : color; + + //can't use the graph function here, as it's not a y=f(x) function (at least not a real one) + if(v.debug) + { + float2 radii_sdf = abs(vign_gradient - v.radii); + radii_sdf *= qUINT::PIXEL_SIZE.yy / fwidth(radii_sdf); + radii_sdf = saturate(1 - 200 * radii_sdf); + + color = lerp(color, float3(0.0,1.0,0.0), radii_sdf.x); + color = lerp(color, float3(1.0,0.0,0.0), radii_sdf.y); + } + + return color; +} + +float curves(in float x, in CurvesStruct c) +{ + x = linearstep(c.levels.x, c.levels.y, x); + x = saturate(pow(x * c.exposure, c.gamma)); + + float blacks_mult = smoothstep(0.25, 0.00, x); + float shadows_mult = smoothstep(0.00, 0.25, x) * smoothstep(0.50, 0.25, x); + float midtones_mult = smoothstep(0.25, 0.50, x) * smoothstep(0.75, 0.50, x); + float highlights_mult = smoothstep(0.50, 0.75, x) * smoothstep(1.00, 0.75, x); + float whites_mult = smoothstep(0.75, 1.00, x); + + x = pow(x, exp2(blacks_mult * c.blacks + + shadows_mult * c.shadows + + midtones_mult * c.midtones + + highlights_mult * c.highlights + + whites_mult * c.whites + - 1)); + + x = lerp(x, x * x * (3 - 2 * x), c.contrast); + return saturate(x); +} + +void draw_lut(inout float3 color, in float2 vpos, in float tile_size, in float tile_amount, in float scroll) +{ + float2 pixelcoord = vpos.xy; // - 0.5; + pixelcoord.x += scroll * BUFFER_WIDTH; + + if(pixelcoord.x < tile_size * tile_amount && pixelcoord.y < tile_size) + { + color.rg = frac(pixelcoord.xy / tile_size) - 0.5 / tile_size; + color.rg /= 1.0 - rcp(tile_size); + color.b = floor(pixelcoord.x / tile_size)/(tile_amount - 1); + color.rgb = floor(color.rgb * 255.0) / 255.0; + } +} + +void draw_lut_4096x64(inout float3 color, in float2 vpos) +{ + color.rgb = vpos.xyx / 64.0; + color.rg = frac(color.rg) - 0.5 / 64.0; + color.rg /= 1.0 - 1.0 / 64.0; + color.b = floor(color.b) / (64.0 - 1); +} + +void read_lut_4096x64(inout float3 color) +{ + float4 lut_coord; + lut_coord.xyz = color.rgb * 63.0; + lut_coord.xy = (lut_coord.xy + 0.5) / float2(4096.0, 64.0); + lut_coord.x += floor(lut_coord.z) / 64.0; + lut_coord.z = frac(lut_coord.z); + lut_coord.w = lut_coord.x + 0.015625; + + color.rgb = lerp(tex2D(sLutTexInternal, lut_coord.xy).rgb, tex2D(sLutTexInternal, lut_coord.wy).rgb, lut_coord.z); +} + +float3 palette(in float3 hsl_color, in PaletteStruct p, in float huefactors[7]) +{ + float huemults[7] = + { + max(saturate(1.0 - abs((hsl_color.x - 0.0/12) * 12.0)), //red left side - need this due to 360 degrees -> 0 degrees + saturate(1.0 - abs((hsl_color.x - 12.0/12) * 6.0))), //red right side + saturate(1.0 - abs((hsl_color.x - 1.0/12) * 12.0)), //orange both sides + max(saturate(1.0 - abs((hsl_color.x - 2.0/12) * 12.0)) * step(hsl_color.x,2.0/12.0), //yellow left side - need this because hues are not evenly distributed around color wheel, it's 1/12 from orange to yellow but 1/6 from yellow to green + saturate(1.0 - abs((hsl_color.x - 2.0/12) * 6.0)) * step(2.0/12.0,hsl_color.x)), //yellow right side + saturate(1.0 - abs((hsl_color.x - 4.0/12) * 6.0)), //green both sides + saturate(1.0 - abs((hsl_color.x - 6.0/12) * 6.0)), //aqua both sides + saturate(1.0 - abs((hsl_color.x - 8.0/12) * 6.0)), //blue both sides + saturate(1.0 - abs((hsl_color.x - 10.0/12) * 6.0)) //magenta both sides + }; + + float3 tcolor = 0; + for(int i=0; i < 7; i++) + tcolor += huemults[i] * hsl_to_rgb(float3(huefactors[i], saturate(hsl_color.y + hsl_color.y * p.saturation[i]), hsl_color.z * exp2(sqrt(hsl_color.y) * p.exposure[i] * (1 - hsl_color.z) * hsl_color.y))); + + return tcolor; +} + +/*============================================================================= + Pixel Shaders +=============================================================================*/ + +#if(ENABLE_HISTOGRAM == 1) +void PS_HistogramGenerate(float4 vpos : SV_Position, float2 uv : TEXCOORD, out float4 res : SV_Target0) +{ + res = 0;float4 coord = 0; + coord.z = rcp(LIGHTROOM_HISTOGRAM_SAMPLES); + + float2 histogram_data = float2(HISTOGRAM_BINS_NUM, vpos.x) / LIGHTROOM_HISTOGRAM_SMOOTHNESS; + + [loop] + for(int x = 0; x < LIGHTROOM_HISTOGRAM_SAMPLES; x++) + { + coord.y = 0; + [loop] + for(int y = 0; y < LIGHTROOM_HISTOGRAM_SAMPLES; y++) + { + res.xyz += saturate(1.0 - abs(tex2Dlod(qUINT::sBackBufferTex,coord).xyz * histogram_data.xxx - histogram_data.yyy)); + coord.y += coord.z; + } + coord.x += coord.z; + } + res.xyz /= LIGHTROOM_HISTOGRAM_SMOOTHNESS; +} +#endif + +void PS_ProcessLUT(float4 vpos : SV_Position, float2 uv : TEXCOORD0, nointerpolation float huefactors[7] : TEXCOORD1, out float4 color : SV_Target0) +{ + //ReShade bug :( can't initialize structs the old fashioned/C way + const CurvesStruct Curves = setup_curves(); + const PaletteStruct Palette = setup_palette(); + + draw_lut_4096x64(color.rgb, vpos.xy); + + color.a = 1; + + color.r = curves(color.r, Curves); + color.g = curves(color.g, Curves); + color.b = curves(color.b, Curves); + float3 hsl_color = rgb_to_hsl(color.rgb); + color.rgb = LIGHTROOM_GLOBAL_TEMPERATURE > 0 ? lerp(color.rgb, hsl_to_rgb(float3(0.06111, 1.0, hsl_color.z)), LIGHTROOM_GLOBAL_TEMPERATURE) : lerp(color.rgb, hsl_to_rgb(float3(0.56111, 1.0, hsl_color.z)), -LIGHTROOM_GLOBAL_TEMPERATURE); + color.rgb = LIGHTROOM_GLOBAL_TEMPERATURE > 0 ? lerp(color.rgb, hsl_to_rgb(float3(0.31111, 1.0, hsl_color.z)), LIGHTROOM_GLOBAL_TINT) : lerp(color.rgb, hsl_to_rgb(float3(0.81111, 1.0, hsl_color.z)), -LIGHTROOM_GLOBAL_TINT); + hsl_color = rgb_to_hsl(color.rgb); + hsl_color.y = saturate(hsl_color.y + hsl_color.y * LIGHTROOM_GLOBAL_SATURATION); + hsl_color.y = pow(hsl_color.y,exp2(-LIGHTROOM_GLOBAL_VIBRANCE)); + hsl_color = saturate(hsl_color); + + color.rgb = palette(hsl_color, Palette, huefactors); +} + +float3 dither(in int2 pos, int bit_depth) +{ + const float2 magicdot = float2(0.75487766624669276, 0.569840290998); + const float3 magicadd = float3(0, 0.025, 0.0125) * dot(magicdot, 1); + + const float lsb = exp2(bit_depth) - 1; + + float3 dither = frac(dot(pos, magicdot) + magicadd); + dither = dither - 0.5; + dither *= 0.99; //so if added to source color, it just does not spill over to next bucket + dither /= lsb; + return dither; +} + +void PS_ApplyLUT(float4 vpos : SV_Position, float2 uv : TEXCOORD0, nointerpolation float huefactors[7] : TEXCOORD1, out float4 color : SV_Target0) +{ + color = tex2D(qUINT::sBackBufferTex, uv); + + if(LIGHTROOM_ENABLE_LUT) + draw_lut(color.rgb, vpos.xy, LIGHTROOM_LUT_TILE_SIZE, LIGHTROOM_LUT_TILE_COUNT, LIGHTROOM_LUT_SCROLL); + + read_lut_4096x64(color.rgb); +} + +void PS_DisplayStatistics(float4 vpos : SV_Position, float2 uv : TEXCOORD0, nointerpolation float huefactors[7] : TEXCOORD1, out float4 res : SV_Target0) +{ + const CurvesStruct Curves = setup_curves(); + const VignetteStruct Vignette = setup_vignette(); + + float4 color = tex2D(qUINT::sBackBufferTex,uv); + if(LIGHTROOM_ENABLE_VIGNETTE) color.rgb = get_vignette(color.rgb, uv, Vignette); + + float2 vposfbl = float2(vpos.x, BUFFER_HEIGHT-vpos.y); + float2 vposfbl_n = vposfbl / 255.0; + + color.rgb = (LIGHTROOM_ENABLE_CLIPPING_DISPLAY && dot(color.rgb, 1.0) >= 3.0) ? float3(1.0,0.0,0.0) : color.rgb; + color.rgb = (LIGHTROOM_ENABLE_CLIPPING_DISPLAY && dot(color.rgb, 1.0) <= 0.0) ? float3(0.0,0.0,1.0) : color.rgb; + +#if(ENABLE_HISTOGRAM == 1) + if(LIGHTROOM_ENABLE_HISTOGRAM || LIGHTROOM_ENABLE_CURVE_DISPLAY) + { + float luma_curve = curves(vposfbl_n.x, Curves); + float3 histogram = tex2Dlod(sHistogramTex, vposfbl_n.xyxy).xyz / (LIGHTROOM_HISTOGRAM_SAMPLES * LIGHTROOM_HISTOGRAM_SAMPLES) * LIGHTROOM_HISTOGRAM_HEIGHT; + + if(all(saturate(-vposfbl_n * vposfbl_n + vposfbl_n))) + { + color.rgb = LIGHTROOM_ENABLE_HISTOGRAM ? vposfbl_n.yyy < histogram.xyz : color.rgb; + color.rgb = LIGHTROOM_ENABLE_CURVE_DISPLAY ? get_function_graph(vposfbl_n.xy, luma_curve, color.rgb, 20.0) : color.rgb; + } + } +#else + if(LIGHTROOM_ENABLE_CURVE_DISPLAY) + { + float luma_curve = curves(vposfbl_n.x, Curves); + + if(all(saturate(-vposfbl_n * vposfbl_n + vposfbl_n))) + color.rgb = LIGHTROOM_ENABLE_CURVE_DISPLAY ? get_function_graph(vposfbl_n.xy, luma_curve, color.rgb, 20.0) : color.rgb; + } +#endif + + res.xyz = color.xyz; + res.w = 1.0; +} + +/*============================================================================= + Techniques +=============================================================================*/ + +technique Lightroom +< ui_tooltip = " >> qUINT::Lightroom <<\n\n" + "Lightroom is a color grading toolbox that offers a multitude\n" + "of features commonly found in color grading software.\n" + "You can do deep color modifications, adjust contrast and levels,\n" + "tweak color balance, view a histogram and bake the CC into a 3D LUT.\n" + "\nLightroom is written by Marty McFly / Pascal Gilcher"; > +{ + pass PProcessLUT + { + VertexShader = VS_Lightroom; + PixelShader = PS_ProcessLUT; + RenderTarget = LutTexInternal; + } + pass PApplyLUT + { + VertexShader = VS_Lightroom; + PixelShader = PS_ApplyLUT; + } + + #if(ENABLE_HISTOGRAM == 1) + pass PHistogramGenerate + { + VertexShader = PostProcessVS; + PixelShader = PS_HistogramGenerate; + RenderTarget = HistogramTex; + } + #endif + pass PHistogram + { + VertexShader = VS_Lightroom; + PixelShader = PS_DisplayStatistics; + } +} diff --git a/data_from_portwine/Reshade/Shaders/qUINT_mxao.fx b/data_from_portwine/Reshade/Shaders/qUINT_mxao.fx new file mode 100644 index 00000000..3ee08000 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/qUINT_mxao.fx @@ -0,0 +1,706 @@ +/*============================================================================= + + ReShade 4 effect file + github.com/martymcmodding + + Support me: + paypal.me/mcflypg + patreon.com/mcflypg + + Ambient Obscurance with Indirect Lighting "MXAO" + by Marty McFly / P.Gilcher + part of qUINT shader library for ReShade 4 + + Copyright (c) Pascal Gilcher / Marty McFly. All rights reserved. + +=============================================================================*/ + +/*============================================================================= + Preprocessor settings +=============================================================================*/ + +#ifndef MXAO_MIPLEVEL_AO + #define MXAO_MIPLEVEL_AO 0 //[0 to 2] Miplevel of AO texture. 0 = fullscreen, 1 = 1/2 screen width/height, 2 = 1/4 screen width/height and so forth. Best results: IL MipLevel = AO MipLevel + 2 +#endif + +#ifndef MXAO_MIPLEVEL_IL + #define MXAO_MIPLEVEL_IL 2 //[0 to 4] Miplevel of IL texture. 0 = fullscreen, 1 = 1/2 screen width/height, 2 = 1/4 screen width/height and so forth. +#endif + +#ifndef MXAO_ENABLE_IL + #define MXAO_ENABLE_IL 0 //[0 or 1] Enables Indirect Lighting calculation. Will cause a major fps hit. +#endif + +#ifndef MXAO_SMOOTHNORMALS + #define MXAO_SMOOTHNORMALS 0 //[0 or 1] This feature makes low poly surfaces smoother, especially useful on older games. +#endif + +#ifndef MXAO_TWO_LAYER + #define MXAO_TWO_LAYER 0 //[0 or 1] Splits MXAO into two separate layers that allow for both large and fine AO. +#endif + +#ifndef MXAO_HIGH_QUALITY + #define MXAO_HIGH_QUALITY 0 //[0 or 1] Enables a different, more physically accurate but slower SSAO mode. Based on Ground Truth Ambient Occlusion by Activision. No IL yet. +#endif + +/*============================================================================= + UI Uniforms +=============================================================================*/ + +uniform int MXAO_GLOBAL_SAMPLE_QUALITY_PRESET < + ui_type = "combo"; + ui_label = "Sample Quality"; + ui_items = "Very Low (4 samples)\0Low (8 samples)\0Medium (16 samples)\0High (24 samples)\0Very High (32 samples)\0Ultra (64 samples)\0Maximum (255 samples)\0Auto (variable)\0"; + ui_tooltip = "Global quality control, main performance knob. Higher radii might require higher quality."; + ui_category = "Global"; +> = 2; + +uniform float MXAO_SAMPLE_RADIUS < + ui_type = "drag"; + ui_min = 0.5; ui_max = 20.0; + ui_label = "Sample Radius"; + ui_tooltip = "Sample radius of MXAO, higher means more large-scale occlusion with less fine-scale details."; + ui_category = "Global"; +> = 2.5; + +#if (MXAO_HIGH_QUALITY==0) + uniform float MXAO_SAMPLE_NORMAL_BIAS < + ui_type = "drag"; + ui_min = 0.0; ui_max = 0.8; + ui_label = "Normal Bias"; + ui_tooltip = "Occlusion Cone bias to reduce self-occlusion of surfaces that have a low angle to each other."; + ui_category = "Global"; + > = 0.2; +#else + #define MXAO_SAMPLE_NORMAL_BIAS 0 //don't break PS which needs this, cleaner this way +#endif + +uniform float MXAO_GLOBAL_RENDER_SCALE < + ui_type = "drag"; + ui_label = "Render Size Scale"; + ui_min = 0.50; ui_max = 1.00; + ui_tooltip = "Factor of MXAO resolution, lower values greatly reduce performance overhead but decrease quality.\n1.0 = MXAO is computed in original resolution\n0.5 = MXAO is computed in 1/2 width 1/2 height of original resolution\n..."; + ui_category = "Global"; +> = 1.0; + +uniform float MXAO_SSAO_AMOUNT < + ui_type = "drag"; + ui_min = 0.00; ui_max = 4.00; + ui_label = "Ambient Occlusion Amount"; + ui_tooltip = "Intensity of AO effect. Can cause pitch black clipping if set too high."; + ui_category = "Ambient Occlusion"; +> = 1.00; + +#if(MXAO_ENABLE_IL != 0) +uniform float MXAO_SSIL_AMOUNT < + ui_type = "drag"; + ui_min = 0.00; ui_max = 12.00; + ui_label = "Indirect Lighting Amount"; + ui_tooltip = "Intensity of IL effect. Can cause overexposured white spots if set too high."; + ui_category = "Indirect Lighting"; +> = 4.00; + +uniform float MXAO_SSIL_SATURATION < + ui_type = "drag"; + ui_min = 0.00; ui_max = 3.00; + ui_label = "Indirect Lighting Saturation"; + ui_tooltip = "Controls color saturation of IL effect."; + ui_category = "Indirect Lighting"; +> = 1.00; +#endif + +#if (MXAO_TWO_LAYER != 0) + uniform float MXAO_SAMPLE_RADIUS_SECONDARY < + ui_type = "drag"; + ui_min = 0.1; ui_max = 1.00; + ui_label = "Fine AO Scale"; + ui_tooltip = "Multiplier of Sample Radius for fine geometry. A setting of 0.5 scans the geometry at half the radius of the main AO."; + ui_category = "Double Layer"; + > = 0.2; + + uniform float MXAO_AMOUNT_FINE < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Fine AO intensity multiplier"; + ui_tooltip = "Intensity of small scale AO / IL."; + ui_category = "Double Layer"; + > = 1.0; + + uniform float MXAO_AMOUNT_COARSE < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Coarse AO intensity multiplier"; + ui_tooltip = "Intensity of large scale AO / IL."; + ui_category = "Double Layer"; + > = 1.0; +#endif + +uniform int MXAO_BLEND_TYPE < + ui_type = "slider"; + ui_min = 0; ui_max = 3; + ui_label = "Blending Mode"; + ui_tooltip = "Different blending modes for merging AO/IL with original color.\0Blending mode 0 matches formula of MXAO 2.0 and older."; + ui_category = "Blending"; +> = 0; + +uniform float MXAO_FADE_DEPTH_START < + ui_type = "drag"; + ui_label = "Fade Out Start"; + ui_min = 0.00; ui_max = 1.00; + ui_tooltip = "Distance where MXAO starts to fade out. 0.0 = camera, 1.0 = sky. Must be less than Fade Out End."; + ui_category = "Blending"; +> = 0.05; + +uniform float MXAO_FADE_DEPTH_END < + ui_type = "drag"; + ui_label = "Fade Out End"; + ui_min = 0.00; ui_max = 1.00; + ui_tooltip = "Distance where MXAO completely fades out. 0.0 = camera, 1.0 = sky. Must be greater than Fade Out Start."; + ui_category = "Blending"; +> = 0.4; + +uniform int MXAO_DEBUG_VIEW_ENABLE < + ui_type = "combo"; + ui_label = "Enable Debug View"; + ui_items = "None\0AO/IL channel\0Normal vectors\0"; + ui_tooltip = "Different debug outputs"; + ui_category = "Debug"; +> = 0; + +/*============================================================================= + Textures, Samplers, Globals +=============================================================================*/ + +#define RESHADE_QUINT_COMMON_VERSION_REQUIRE 202 +#define RESHADE_QUINT_EFFECT_DEPTH_REQUIRE //effect requires depth access +#include "qUINT_common.fxh" + +texture2D MXAO_ColorTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 3+MXAO_MIPLEVEL_IL;}; +texture2D MXAO_DepthTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R16F; MipLevels = 3+MXAO_MIPLEVEL_AO;}; +texture2D MXAO_NormalTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 3+MXAO_MIPLEVEL_IL;}; + +sampler2D sMXAO_ColorTex { Texture = MXAO_ColorTex; }; +sampler2D sMXAO_DepthTex { Texture = MXAO_DepthTex; }; +sampler2D sMXAO_NormalTex { Texture = MXAO_NormalTex; }; + +texture2D CommonTex0 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; +sampler2D sCommonTex0 { Texture = CommonTex0; }; + +texture2D CommonTex1 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; +sampler2D sCommonTex1 { Texture = CommonTex1; }; + +#if(MXAO_ENABLE_IL != 0) + #define BLUR_COMP_SWIZZLE xyzw +#else + #define BLUR_COMP_SWIZZLE w +#endif + +/*============================================================================= + Vertex Shader +=============================================================================*/ + +struct MXAO_VSOUT +{ + float4 vpos : SV_Position; + float4 uv : TEXCOORD0; + nointerpolation float samples : TEXCOORD1; + nointerpolation float3 uvtoviewADD : TEXCOORD4; + nointerpolation float3 uvtoviewMUL : TEXCOORD5; +}; + +struct BlurData +{ + float4 key; + float4 mask; +}; + +MXAO_VSOUT VS_MXAO(in uint id : SV_VertexID) +{ + MXAO_VSOUT MXAO; + + MXAO.uv.x = (id == 2) ? 2.0 : 0.0; + MXAO.uv.y = (id == 1) ? 2.0 : 0.0; + MXAO.uv.zw = MXAO.uv.xy / MXAO_GLOBAL_RENDER_SCALE; + MXAO.vpos = float4(MXAO.uv.xy * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); + + static const int samples_per_preset[8] = {4, 8, 16, 24, 32, 64, 255, 8 /*overridden*/}; + MXAO.samples = samples_per_preset[MXAO_GLOBAL_SAMPLE_QUALITY_PRESET]; + + MXAO.uvtoviewADD = float3(-1.0,-1.0,1.0); + MXAO.uvtoviewMUL = float3(2.0,2.0,0.0); + +#if 0 + static const float FOV = 75; //vertical FoV + MXAO.uvtoviewADD = float3(-tan(radians(FOV * 0.5)).xx,1.0) * qUINT::ASPECT_RATIO.yxx; + MXAO.uvtoviewMUL = float3(-2.0 * MXAO.uvtoviewADD.xy,0.0); +#endif + + return MXAO; +} + +/*============================================================================= + Functions +=============================================================================*/ + +float3 get_position_from_uv(in float2 uv, in MXAO_VSOUT MXAO) +{ + return (uv.xyx * MXAO.uvtoviewMUL + MXAO.uvtoviewADD) * qUINT::linear_depth(uv) * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE; +} + +float3 get_position_from_uv_mipmapped(in float2 uv, in MXAO_VSOUT MXAO, in int miplevel) +{ + return (uv.xyx * MXAO.uvtoviewMUL + MXAO.uvtoviewADD) * tex2Dlod(sMXAO_DepthTex, float4(uv.xyx, miplevel)).x; +} + +void spatial_blur_data(inout BlurData o, in sampler inputsampler, in float inputscale, in float4 uv) +{ + o.key = tex2Dlod(inputsampler, uv * inputscale); + o.mask = tex2Dlod(sMXAO_NormalTex, uv); + o.mask.xyz = o.mask.xyz * 2 - 1; +} + +float compute_spatial_tap_weight(in BlurData center, in BlurData tap) +{ + float depth_term = saturate(1 - abs(tap.mask.w - center.mask.w)); + float normal_term = saturate(dot(tap.mask.xyz, center.mask.xyz) * 16 - 15); + return depth_term * normal_term; +} + +float4 blur_filter(in MXAO_VSOUT MXAO, in sampler inputsampler, in float inputscale, in float radius, in int blursteps) +{ + float4 blur_uv = float4(MXAO.uv.xy, 0, 0); + + BlurData center, tap; + spatial_blur_data(center, inputsampler, inputscale, blur_uv); + + float4 blursum = center.key; + float4 blursum_noweight = center.key; + float blurweight = 1; + + static const float2 offsets[8] = + { + float2(1.5,0.5),float2(-1.5,-0.5),float2(-0.5,1.5),float2(0.5,-1.5), + float2(1.5,2.5),float2(-1.5,-2.5),float2(-2.5,1.5),float2(2.5,-1.5) + }; + + float2 blur_offsetscale = qUINT::PIXEL_SIZE / inputscale * radius; + + [unroll] + for(int i = 0; i < blursteps; i++) + { + blur_uv.xy = MXAO.uv.xy + offsets[i] * blur_offsetscale; + spatial_blur_data(tap, inputsampler, inputscale, blur_uv); + + float tap_weight = compute_spatial_tap_weight(center, tap); + + blurweight += tap_weight; + blursum.BLUR_COMP_SWIZZLE += tap.key.BLUR_COMP_SWIZZLE * tap_weight; + blursum_noweight.BLUR_COMP_SWIZZLE += tap.key.BLUR_COMP_SWIZZLE; + } + + blursum.BLUR_COMP_SWIZZLE /= blurweight; + blursum_noweight.BLUR_COMP_SWIZZLE /= 1 + blursteps; + + return lerp(blursum.BLUR_COMP_SWIZZLE, blursum_noweight.BLUR_COMP_SWIZZLE, blurweight < 2); +} + +void sample_parameter_setup(in MXAO_VSOUT MXAO, in float scaled_depth, in float layer_id, out float scaled_radius, out float falloff_factor) +{ + scaled_radius = 0.25 * MXAO_SAMPLE_RADIUS / (MXAO.samples * (scaled_depth + 2.0)); + falloff_factor = -1.0/(MXAO_SAMPLE_RADIUS * MXAO_SAMPLE_RADIUS); + + #if(MXAO_TWO_LAYER != 0) + scaled_radius *= lerp(1.0, MXAO_SAMPLE_RADIUS_SECONDARY + 1e-6, layer_id); + falloff_factor *= lerp(1.0, 1.0 / (MXAO_SAMPLE_RADIUS_SECONDARY * MXAO_SAMPLE_RADIUS_SECONDARY + 1e-6), layer_id); + #endif +} + +void smooth_normals(inout float3 normal, in float3 position, in MXAO_VSOUT MXAO) +{ + float2 scaled_radius = 0.018 / position.z * qUINT::ASPECT_RATIO; + float3 neighbour_normal[4] = {normal, normal, normal, normal}; + + [unroll] + for(int i = 0; i < 4; i++) + { + float2 direction; + sincos(6.28318548 * 0.25 * i, direction.y, direction.x); + + [unroll] + for(int direction_step = 1; direction_step <= 5; direction_step++) + { + float search_radius = exp2(direction_step); + float2 tap_uv = MXAO.uv.zw + direction * search_radius * scaled_radius; + + float3 temp_normal = tex2Dlod(sMXAO_NormalTex, float4(tap_uv, 0, 0)).xyz * 2.0 - 1.0; + float3 temp_position = get_position_from_uv_mipmapped(tap_uv, MXAO, 0); + + float3 position_delta = temp_position - position; + float distance_weight = saturate(1.0 - dot(position_delta, position_delta) * 20.0 / search_radius); + float normal_angle = dot(normal, temp_normal); + float angle_weight = smoothstep(0.3, 0.98, normal_angle) * smoothstep(1.0, 0.98, normal_angle); //only take normals into account that are NOT equal to the current normal. + + float total_weight = saturate(3.0 * distance_weight * angle_weight / search_radius); + + neighbour_normal[i] = lerp(neighbour_normal[i], temp_normal, total_weight); + } + } + + normal = normalize(neighbour_normal[0] + neighbour_normal[1] + neighbour_normal[2] + neighbour_normal[3]); +} + +/*============================================================================= + Pixel Shaders +=============================================================================*/ + +void PS_InputBufferSetup(in MXAO_VSOUT MXAO, out float4 color : SV_Target0, out float4 depth : SV_Target1, out float4 normal : SV_Target2) +{ + float3 single_pixel_offset = float3(qUINT::PIXEL_SIZE.xy, 0); + + float3 position = get_position_from_uv(MXAO.uv.xy, MXAO); + float3 position_delta_x1 = - position + get_position_from_uv(MXAO.uv.xy + single_pixel_offset.xz, MXAO); + float3 position_delta_x2 = position - get_position_from_uv(MXAO.uv.xy - single_pixel_offset.xz, MXAO); + float3 position_delta_y1 = - position + get_position_from_uv(MXAO.uv.xy + single_pixel_offset.zy, MXAO); + float3 position_delta_y2 = position - get_position_from_uv(MXAO.uv.xy - single_pixel_offset.zy, MXAO); + + position_delta_x1 = lerp(position_delta_x1, position_delta_x2, abs(position_delta_x1.z) > abs(position_delta_x2.z)); + position_delta_y1 = lerp(position_delta_y1, position_delta_y2, abs(position_delta_y1.z) > abs(position_delta_y2.z)); + + float deltaz = abs(position_delta_x1.z * position_delta_x1.z - position_delta_x2.z * position_delta_x2.z) + + abs(position_delta_y1.z * position_delta_y1.z - position_delta_y2.z * position_delta_y2.z); + + normal = float4(normalize(cross(position_delta_y1, position_delta_x1)) * 0.5 + 0.5, deltaz); + color = tex2D(qUINT::sBackBufferTex, MXAO.uv.xy); + depth = qUINT::linear_depth(MXAO.uv.xy) * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE; +} + +void PS_StencilSetup(in MXAO_VSOUT MXAO, out float4 color : SV_Target0) +{ + if( qUINT::linear_depth(MXAO.uv.zw) >= MXAO_FADE_DEPTH_END + || 0.25 * 0.5 * MXAO_SAMPLE_RADIUS / (tex2D(sMXAO_DepthTex, MXAO.uv.zw).x + 2.0) * BUFFER_HEIGHT < 1.0 + || MXAO.uv.z > 1.0 + || MXAO.uv.w > 1.0 + ) discard; + + color = 1.0; +} + +void PS_AmbientObscurance(in MXAO_VSOUT MXAO, out float4 color : SV_Target0) +{ + float3 position = get_position_from_uv_mipmapped(MXAO.uv.zw, MXAO, 0); + float3 normal = tex2D(sMXAO_NormalTex, MXAO.uv.zw).xyz * 2.0 - 1.0; + + float sample_jitter = dot(floor(MXAO.vpos.xy % 4 + 0.1), float2(0.0625, 0.25)) + 0.0625; + + float layer_id = (MXAO.vpos.x + MXAO.vpos.y) % 2.0; + +#if(MXAO_SMOOTHNORMALS != 0) + smooth_normals(normal, position, MXAO); +#endif + float linear_depth = position.z / RESHADE_DEPTH_LINEARIZATION_FAR_PLANE; + position += normal * linear_depth; + + if(MXAO_GLOBAL_SAMPLE_QUALITY_PRESET == 7) MXAO.samples = 2 + floor(0.05 * MXAO_SAMPLE_RADIUS / linear_depth); + + float scaled_radius; + float falloff_factor; + sample_parameter_setup(MXAO, position.z, layer_id, scaled_radius, falloff_factor); + + float2 tap_uv, sample_dir; + sincos(2.3999632 * 16 * sample_jitter, sample_dir.x, sample_dir.y); //2.3999632 * 16 + sample_dir *= scaled_radius; + + color = 0.0; + + [loop] + for(int i = 0; i < MXAO.samples; i++) + { + tap_uv = MXAO.uv.zw + sample_dir.xy * qUINT::ASPECT_RATIO * (i + sample_jitter); + sample_dir.xy = mul(sample_dir.xy, float2x2(0.76465, -0.64444, 0.64444, 0.76465)); //cos/sin 2.3999632 * 16 + + float sample_mip = saturate(scaled_radius * i * 20.0) * 3.0; + + float3 delta_v = -position + get_position_from_uv_mipmapped(tap_uv, MXAO, sample_mip + MXAO_MIPLEVEL_AO); + float v2 = dot(delta_v, delta_v); + float vn = dot(delta_v, normal) * rsqrt(v2); + + float sample_ao = saturate(1.0 + falloff_factor * v2) * saturate(vn - MXAO_SAMPLE_NORMAL_BIAS); +#if(MXAO_ENABLE_IL != 0) + [branch] + if(sample_ao > 0.1) + { + float3 sample_il = tex2Dlod(sMXAO_ColorTex, float4(tap_uv, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz; + float3 sample_normal = tex2Dlod(sMXAO_NormalTex, float4(tap_uv, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz * 2.0 - 1.0; + + sample_il *= sample_ao; + sample_il *= 0.5 + 0.5*saturate(dot(sample_normal, -delta_v * v2)); + + color += float4(sample_il, sample_ao); + } +#else + color.w += sample_ao; +#endif + } + + color = saturate(color / ((1.0 - MXAO_SAMPLE_NORMAL_BIAS) * MXAO.samples) * 2.0); + color = color.BLUR_COMP_SWIZZLE; + color = sqrt(color); + +#if(MXAO_TWO_LAYER != 0) + color *= lerp(MXAO_AMOUNT_COARSE, MXAO_AMOUNT_FINE, layer_id); +#endif +} + +void PS_AmbientObscuranceHQ(in MXAO_VSOUT MXAO, out float4 color : SV_Target0) +{ + float3 position = get_position_from_uv_mipmapped(MXAO.uv.zw, MXAO, 0); + float3 normal = normalize(tex2D(sMXAO_NormalTex, MXAO.uv.zw).xyz * 2.0 - 1.0); //fixes black lines + +#if(MXAO_SMOOTHNORMALS != 0) + smooth_normals(normal, position, MXAO); +#endif + + float3 viewdir = normalize(-position); + + int directions = 2 + floor(MXAO.samples / 32) * 2; + int stepshalf = MXAO.samples / (directions * 2); + + float angle_correct = 1 - viewdir.z * viewdir.z; + float scaled_radius = MXAO_SAMPLE_RADIUS / position.z / stepshalf * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE; + float falloff_factor = 0.25 * rcp(MXAO_SAMPLE_RADIUS * MXAO_SAMPLE_RADIUS); + + float sample_jitter = dot(floor(MXAO.vpos.xy % 4 + 0.1), float2(0.0625, 0.25)) + 0.0625; + + float dir_phi = 3.14159265 / directions; + float2 sample_dir; sincos(dir_phi * sample_jitter * 6, sample_dir.y, sample_dir.x); + float2x2 rot_dir = float2x2(cos(dir_phi),-sin(dir_phi), + sin(dir_phi),cos(dir_phi)); + + color = 0; + + [loop] + for(float i = 0; i < directions; i++) + { + sample_dir = mul(sample_dir, rot_dir); + float2 start = sample_dir * sample_jitter; + + float3 sliceDir = float3(sample_dir, 0); + float2 h = -1.0; + +#if(MXAO_ENABLE_IL != 0) + float3 il[2];il[0] = 0;il[1] = 0; +#endif + [loop] + for(int j = 0; j < stepshalf; j++) + { + float4 tap_uv = MXAO.uv.zwzw + scaled_radius * qUINT::PIXEL_SIZE.xyxy * start.xyxy * float4(1,1,-1,-1); + float sample_mip = saturate(scaled_radius * j * 0.01) * 3.0; + + float3 delta_v[2]; + delta_v[0] = -position + get_position_from_uv_mipmapped(tap_uv.xy, MXAO, sample_mip + MXAO_MIPLEVEL_AO); + delta_v[1] = -position + get_position_from_uv_mipmapped(tap_uv.zw, MXAO, sample_mip + MXAO_MIPLEVEL_AO); + + float2 v2 = float2(dot(delta_v[0], delta_v[0]), + dot(delta_v[1], delta_v[1])); + + float2 inv_distance = rsqrt(v2); + + float2 sample_h = float2(dot(delta_v[0], viewdir), + dot(delta_v[1], viewdir)) * inv_distance; + + float2 falloff = saturate(v2 * falloff_factor); + sample_h = lerp(sample_h, h, falloff); + +#if(MXAO_ENABLE_IL != 0) + float3 sample_il[2], sample_normal[2]; sample_il[0] = 0; sample_il[1] = 0; + + [branch] + if(falloff.x < 0.8) + { + sample_il[0] = tex2Dlod(sMXAO_ColorTex, float4(tap_uv.xy, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz; + sample_normal[0] = tex2Dlod(sMXAO_NormalTex, float4(tap_uv.xy, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz * 2.0 - 1.0; + sample_il[0] *= saturate(-inv_distance.x * dot(delta_v[0], sample_normal[0])); + sample_il[0] = lerp(sample_il[0], il[0], saturate( v2.x * falloff_factor)); + } + [branch] + if(falloff.y < 0.8) + { + sample_il[1] = tex2Dlod(sMXAO_ColorTex, float4(tap_uv.zw, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz; + sample_normal[1] = tex2Dlod(sMXAO_NormalTex, float4(tap_uv.zw, 0, sample_mip + MXAO_MIPLEVEL_IL)).xyz * 2.0 - 1.0; + sample_il[1] *= saturate(-inv_distance.y * dot(delta_v[1], sample_normal[1])); + sample_il[1] = lerp(sample_il[1], il[1], saturate( v2.y * falloff_factor)); + } +#endif + + h.xy = (sample_h > h) ? sample_h : lerp(sample_h, h, 0.75); + +#if(MXAO_ENABLE_IL != 0) + il[0] = (sample_h.x > h.x) ? sample_il[0] : lerp(sample_il[0], il[0], 0.75); + il[1] = (sample_h.y > h.y) ? sample_il[1] : lerp(sample_il[1], il[1], 0.75); +#endif + start += sample_dir; + } + + float3 normal_slice_plane = normalize(cross(sliceDir, viewdir)); + float3 tangent = cross(viewdir, normal_slice_plane); + float3 proj_normal = normal - normal_slice_plane * dot(normal, normal_slice_plane); + + float proj_length = length(proj_normal); + float cos_gamma = clamp(dot(proj_normal, viewdir) * rcp(proj_length), -1.0, 1.0); + float gamma = -sign(dot(proj_normal, tangent)) * acos(cos_gamma); + + h = acos(min(h, 1)); + + h.x = gamma + max(-h.x - gamma, -1.5707963); + h.y = gamma + min( h.y - gamma, 1.5707963); + + h *= 2; + + float2 sample_ao = cos_gamma + h * sin(gamma) - cos(h - gamma); + color.w += proj_length * dot(sample_ao, 0.25); +#if(MXAO_ENABLE_IL != 0) + color.rgb += proj_length * sample_ao.x * 0.25 * il[0]; + color.rgb += proj_length * sample_ao.y * 0.25 * il[1]; +#endif + } + + color /= directions; + color.w = 1 - color.w; + color = color.BLUR_COMP_SWIZZLE; + color = sqrt(color); +} + +void PS_SpatialFilter1(in MXAO_VSOUT MXAO, out float4 color : SV_Target0) +{ + color = blur_filter(MXAO, sCommonTex0, MXAO_GLOBAL_RENDER_SCALE, 0.75, 4); +} + +void PS_SpatialFilter2(MXAO_VSOUT MXAO, out float4 color : SV_Target0) +{ + float4 ssil_ssao = blur_filter(MXAO, sCommonTex1, 1, 1.0 / MXAO_GLOBAL_RENDER_SCALE, 8); + ssil_ssao *= ssil_ssao; + color = tex2D(sMXAO_ColorTex, MXAO.uv.xy); + + static const float3 lumcoeff = float3(0.2126, 0.7152, 0.0722); + float scenedepth = qUINT::linear_depth(MXAO.uv.xy); + float colorgray = dot(color.rgb, lumcoeff); + float blendfact = 1.0 - colorgray; + +#if(MXAO_ENABLE_IL != 0) + ssil_ssao.xyz = lerp(dot(ssil_ssao.xyz, lumcoeff), ssil_ssao.xyz, MXAO_SSIL_SATURATION) * MXAO_SSIL_AMOUNT * 2.0; +#else + ssil_ssao.xyz = 0.0; +#endif + +#if(MXAO_HIGH_QUALITY == 0) + ssil_ssao.w = 1.0 - pow(saturate(1.0 - ssil_ssao.w), MXAO_SSAO_AMOUNT * 2.0); +#else + ssil_ssao.w = 1.0 - pow(saturate(1.0 - ssil_ssao.w), MXAO_SSAO_AMOUNT); +#endif + ssil_ssao *= 1.0 - smoothstep(MXAO_FADE_DEPTH_START, MXAO_FADE_DEPTH_END, scenedepth * float4(2.0, 2.0, 2.0, 1.0)); + + if(MXAO_BLEND_TYPE == 0) + { + color.rgb -= (ssil_ssao.www - ssil_ssao.xyz) * blendfact * color.rgb; + } + else if(MXAO_BLEND_TYPE == 1) + { + color.rgb = color.rgb * saturate(1.0 - ssil_ssao.www * blendfact * 1.2) + ssil_ssao.xyz * blendfact * colorgray * 2.0; + } + else if(MXAO_BLEND_TYPE == 2) + { + float colordiff = saturate(2.0 * distance(normalize(color.rgb + 1e-6),normalize(ssil_ssao.rgb + 1e-6))); + color.rgb = color.rgb + ssil_ssao.rgb * lerp(color.rgb, dot(color.rgb, 0.3333), colordiff) * blendfact * blendfact * 4.0; + color.rgb = color.rgb * (1.0 - ssil_ssao.www * (1.0 - dot(color.rgb, lumcoeff))); + } + else if(MXAO_BLEND_TYPE == 3) + { + color.rgb *= color.rgb; + color.rgb -= (ssil_ssao.www - ssil_ssao.xyz) * color.rgb; + color.rgb = sqrt(color.rgb); + } + + if(MXAO_DEBUG_VIEW_ENABLE == 1) + { + color.rgb = max(0.0, 1.0 - ssil_ssao.www + ssil_ssao.xyz); + color.rgb *= (MXAO_ENABLE_IL != 0) ? 0.5 : 1.0; + } + else if(MXAO_DEBUG_VIEW_ENABLE == 2) + { + color.rgb = tex2D(sMXAO_NormalTex, MXAO.uv.xy).xyz; + color.b = 1-color.b; //looks nicer + } + + color.a = 1.0; +} + +/*============================================================================= + Techniques +=============================================================================*/ + +technique MXAO +< ui_tooltip = " >> qUINT::MXAO <<\n\n" + "MXAO is a screen-space ambient occlusion shader.\n" + "It adds diffuse shading to object corners to give more depth\n" + "and detail to the scene. Check out the preprocessor options to\n" + "get access to more functionality.\n" + "\nMake sure to move MXAO to the very top of your shader list for\n" + "maximum compatibility with other shaders.\n" + "\nMXAO is written by Marty McFly / Pascal Gilcher"; > +{ + pass + { + VertexShader = VS_MXAO; + PixelShader = PS_InputBufferSetup; + RenderTarget0 = MXAO_ColorTex; + RenderTarget1 = MXAO_DepthTex; + RenderTarget2 = MXAO_NormalTex; + } + pass + { + VertexShader = VS_MXAO; + PixelShader = PS_StencilSetup; + /*Render Target is Backbuffer*/ + ClearRenderTargets = true; + StencilEnable = true; + StencilPass = REPLACE; + StencilRef = 1; + } +#if(MXAO_HIGH_QUALITY != 0) + pass + { + VertexShader = VS_MXAO; + PixelShader = PS_AmbientObscuranceHQ; + RenderTarget = CommonTex0; + ClearRenderTargets = true; + StencilEnable = true; + StencilPass = KEEP; + StencilFunc = EQUAL; + StencilRef = 1; + } +#else + pass + { + VertexShader = VS_MXAO; + PixelShader = PS_AmbientObscurance; + RenderTarget = CommonTex0; + ClearRenderTargets = true; + StencilEnable = true; + StencilPass = KEEP; + StencilFunc = EQUAL; + StencilRef = 1; + } +#endif + pass + { + VertexShader = VS_MXAO; + PixelShader = PS_SpatialFilter1; + RenderTarget = CommonTex1; + } + pass + { + VertexShader = VS_MXAO; + PixelShader = PS_SpatialFilter2; + /*Render Target is Backbuffer*/ + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/qUINT_sharp.fx b/data_from_portwine/Reshade/Shaders/qUINT_sharp.fx new file mode 100644 index 00000000..1f188399 --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/qUINT_sharp.fx @@ -0,0 +1,191 @@ +/*============================================================================= + + ReShade 4 effect file + github.com/martymcmodding + + Support me: + paypal.me/mcflypg + patreon.com/mcflypg + + Depth enhanced local contrast sharpen + + by Marty McFly / P.Gilcher + part of qUINT shader library for ReShade 4 + + Copyright (c) Pascal Gilcher / Marty McFly. All rights reserved. + +=============================================================================*/ + +/*============================================================================= + Preprocessor settings +=============================================================================*/ + +/*============================================================================= + UI Uniforms +=============================================================================*/ + +uniform float SHARP_STRENGTH < + ui_type = "slider"; + ui_label = "Sharpen Strength"; + ui_min = 0.0; + ui_max = 1.0; +> = 0.7; + +uniform bool DEPTH_MASK_ENABLE < + ui_label = "Use Depth Mask"; +> = true; + +uniform bool RMS_MASK_ENABLE < + ui_label = "Use Local Contrast Enhancer"; +> = true; + +uniform int SHARPEN_MODE < + ui_type = "radio"; + ui_label = "Sharpen Mode"; + ui_category = "Sharpen Mode"; + ui_items = "Chroma\0Luma\0"; +> = 1; + +/*============================================================================= + Textures, Samplers, Globals +=============================================================================*/ + +#define RESHADE_QUINT_COMMON_VERSION_REQUIRE 202 +#define RESHADE_QUINT_EFFECT_DEPTH_REQUIRE //effect requires depth access +#include "qUINT_common.fxh" + +/*============================================================================= + Vertex Shader +=============================================================================*/ + +struct VSOUT +{ + float4 vpos : SV_Position; + float2 uv : TEXCOORD0; +}; + +VSOUT VS_Sharp(in uint id : SV_VertexID) +{ + VSOUT o; + + o.uv.x = (id == 2) ? 2.0 : 0.0; + o.uv.y = (id == 1) ? 2.0 : 0.0; + + o.vpos = float4(o.uv.xy * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); + return o; +} + +/*============================================================================= + Functions +=============================================================================*/ + +float color_to_lum(float3 color) +{ + return dot(color, float3(0.3, 0.59, 0.11)); +} + +float3 blend_overlay(float3 a, float3 b) +{ + float3 c = 1.0 - a; + float3 d = 1.0 - b; + + return a < 0.5 ? (2.0 * a * b) : (1.0 - 2.0 * c * d); +} + +float4 fetch_color_and_depth(float2 uv) +{ + return float4( tex2D(qUINT::sBackBufferTex, uv).rgb, + qUINT::linear_depth(uv)); +} + +/*============================================================================= + Pixel Shaders +=============================================================================*/ + +void PS_Sharp(in VSOUT i, out float3 o : SV_Target0) +{ + // A B C + // D E F + // G H I + + float4 A, B, C, D, E, F, G, H, I; + + float3 offsets = float3(1, 0, -1); + + A = fetch_color_and_depth(i.uv + offsets.zz * qUINT::PIXEL_SIZE); + B = fetch_color_and_depth(i.uv + offsets.yz * qUINT::PIXEL_SIZE); + C = fetch_color_and_depth(i.uv + offsets.xz * qUINT::PIXEL_SIZE); + D = fetch_color_and_depth(i.uv + offsets.zy * qUINT::PIXEL_SIZE); + E = fetch_color_and_depth(i.uv + offsets.yy * qUINT::PIXEL_SIZE); + F = fetch_color_and_depth(i.uv + offsets.xy * qUINT::PIXEL_SIZE); + G = fetch_color_and_depth(i.uv + offsets.zx * qUINT::PIXEL_SIZE); + H = fetch_color_and_depth(i.uv + offsets.yx * qUINT::PIXEL_SIZE); + I = fetch_color_and_depth(i.uv + offsets.xx * qUINT::PIXEL_SIZE); + + float4 corners = (A + C) + (G + I); + float4 neighbours = (B + D) + (F + H); + float4 center = E; + + float4 edge = corners + 2.0 * neighbours - 12.0 * center; + float3 sharpen = edge.rgb; + + //measures root mean square as local contrast measurement + //to adjust the intensity of the sharpener at edges with + //high local contrast to restrict sharpen to texture detail + //only while leaving object and detail outlines mostly alone. + [branch] + if(RMS_MASK_ENABLE) + { + float3 mean = (corners.rgb + neighbours.rgb + center.rgb) / 9.0; + float3 RMS = (mean - A.rgb) * (mean - A.rgb); + RMS += (mean - B.rgb) * (mean - B.rgb); + RMS += (mean - C.rgb) * (mean - C.rgb); + RMS += (mean - D.rgb) * (mean - D.rgb); + RMS += (mean - E.rgb) * (mean - E.rgb); + RMS += (mean - F.rgb) * (mean - F.rgb); + RMS += (mean - G.rgb) * (mean - G.rgb); + RMS += (mean - H.rgb) * (mean - H.rgb); + RMS += (mean - I.rgb) * (mean - I.rgb); + + //sharpen /= RMS * 16.0 + 0.025 * 16.0; //wrapped the div / 9 in here + sharpen *= rsqrt(RMS + 0.001) * 0.1; + } + + //Remove sharpen completely from depth edges, as these never look good + //with any kind of sharpening and always create exaggerated halos that + //ruin any strong sharpening which would otherwise enhance textures + sharpen *= DEPTH_MASK_ENABLE ? saturate(1.0 - abs(edge.w) * 4000.0) : 1; + + //grayscale sharpen mask, helps if some color artifacts arise, red-blue + //is mostly prone to create weirdly colored spots. + if(SHARPEN_MODE == 1) + sharpen = color_to_lum(sharpen); + + sharpen = -sharpen * SHARP_STRENGTH * 0.1; + //smooth falloff, cheaper than pow() with little error + sharpen = sign(sharpen) * log(abs(sharpen) * 10.0 + 1.0)*0.3; + + o = blend_overlay(center.rgb, (0.5 + sharpen)); +} + +/*============================================================================= + Techniques +=============================================================================*/ + + + +technique DELC_Sharpen +< ui_tooltip = " >> qUINT::DELCS <<\n\n" + "DELCS is an advanced sharpen filter made to enhance texture detail.\n" + "It offers a local contrast detection method and allows to suppress\n" + "oversharpening on depth edges to combat common sharpen artifacts.\n" + "get access to more functionality.\n" + "\nDELCS is best positioned after most shaders but before film grain or such.\n" + "\DELCS is written by Marty McFly / Pascal Gilcher"; > +{ + pass + { + VertexShader = VS_Sharp; + PixelShader = PS_Sharp; + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Shaders/qUINT_ssr.fx b/data_from_portwine/Reshade/Shaders/qUINT_ssr.fx new file mode 100644 index 00000000..6002a42e --- /dev/null +++ b/data_from_portwine/Reshade/Shaders/qUINT_ssr.fx @@ -0,0 +1,447 @@ +/*============================================================================= + + ReShade 4 effect file + github.com/martymcmodding + + Support me: + paypal.me/mcflypg + patreon.com/mcflypg + + Screen-Space Reflections + by Marty McFly / P.Gilcher + part of qUINT shader library for ReShade 4 + + Copyright (c) Pascal Gilcher / Marty McFly. All rights reserved. + +=============================================================================*/ + +/*============================================================================= + Preprocessor settings +=============================================================================*/ + + +/*============================================================================= + UI Uniforms +=============================================================================*/ + +uniform float SSR_FIELD_OF_VIEW < + ui_type = "drag"; + ui_min = 0.00; ui_max = 100.00; + ui_label = "Vertical Field of View"; + ui_tooltip = "Vertical FoV, should match camera FoV but since ReShade's\ndepth linearization is not always precise, this value\nmight differ from the actual value. Just set to what looks best."; + ui_category = "Global"; +> = 50.0; + +uniform float SSR_REFLECTION_INTENSITY < + ui_type = "drag"; + ui_min = 0.00; ui_max = 1.00; + ui_label = "Reflection Intensity"; + ui_tooltip = "Amount of reflection."; + ui_category = "Global"; +> = 1.0; + +uniform float SSR_FRESNEL_EXP < + ui_type = "drag"; + ui_min = 1.00; ui_max = 10.00; + ui_label = "Reflection Exponent"; + ui_tooltip = "qUINT uses Schlick's fresnel approximation.\nThis parameter represents the power of the angle falloff.\nHigher values restrict reflections to very flat angles.\nOriginal Schlick value: 5.\nThe Fresnel Coefficient is set to 0 to match most surfaces."; + ui_category = "Global"; +> = 5.0; + +uniform float SSR_FADE_DIST < + ui_type = "drag"; + ui_min = 0.001; ui_max = 1.00; + ui_label = "Fade Distance"; + ui_tooltip = "Distance where reflection is completely faded out.\n1 means infinite distance."; + ui_category = "Global"; +> = 0.8; + +uniform float SSR_RAY_INC < + ui_type = "drag"; + ui_min = 1.01; ui_max = 3.00; + ui_label = "Ray Increment"; + ui_tooltip = "Rate of ray step size growth.\nA parameter of 1.0 means same sized steps,\n2.0 means the step size doubles each iteration.\nIncrease if not the entire scene is represented (e.g. sky missing) at the cost of precision."; + ui_category = "Ray Tracing"; +> = 1.6; + +uniform float SSR_ACCEPT_RANGE < + ui_type = "drag"; + ui_min = 0.0; ui_max = 12.00; + ui_label = "Acceptance Range"; + ui_tooltip = "Acceptable error for ray intersection. Larger values will cause more coherent but incorrect reflections."; + ui_category = "Ray Tracing"; +> = 2.5; + +uniform float SSR_JITTER_AMOUNT < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "Ray Jitter Amount"; + ui_tooltip = "Changes ray step size randomly per pixel to produce\na more coherent reflection at the cost of noise that needs to be filtered away."; + ui_category = "Ray Tracing"; +> = 0.25; + +uniform float SSR_FILTER_SIZE < + ui_type = "drag"; + ui_min = 0.0; ui_max = 5.00; + ui_label = "Filter Kernel Size"; + ui_tooltip = "Size of spatial filter, higher values create more blurry reflections at the cost of detail."; + ui_category = "Filtering and Details"; +> = 0.5; + +uniform float SSR_RELIEF_AMOUNT < + ui_type = "drag"; + ui_min = 0.0; ui_max = 1.00; + ui_label = "Surface Relief Height"; + ui_tooltip = "Strength of embossed texture relief. Higher values cause more bumpy surfaces."; + ui_category = "Filtering and Details"; +> = 0.05; + +uniform float SSR_RELIEF_SCALE < + ui_type = "drag"; + ui_min = 0.1; ui_max = 1.00; + ui_label = "Surface Relief Scale"; + ui_tooltip = "Scale of embossed texture relief, lower values cause more high frequency relief."; + ui_category = "Filtering and Details"; +> = 0.35; + +/*============================================================================= + Textures, Samplers, Globals +=============================================================================*/ + +#define RESHADE_QUINT_COMMON_VERSION_REQUIRE 202 +#define RESHADE_QUINT_EFFECT_DEPTH_REQUIRE //effect requires depth access +#include "qUINT_common.fxh" + +texture2D SSR_ColorTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; +sampler2D sSSR_ColorTex { Texture = SSR_ColorTex; AddressU = MIRROR;}; + +texture2D CommonTex0 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; +sampler2D sCommonTex0 { Texture = CommonTex0; }; + +texture2D CommonTex1 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; +sampler2D sCommonTex1 { Texture = CommonTex1; }; + +/*============================================================================= + Vertex Shader +=============================================================================*/ + +struct SSR_VSOUT +{ + float4 vpos : SV_Position; + float2 uv : TEXCOORD0; + float3 uvtoviewADD : TEXCOORD4; + float3 uvtoviewMUL : TEXCOORD5; +}; + +SSR_VSOUT VS_SSR(in uint id : SV_VertexID) +{ + SSR_VSOUT o; + o.uv.x = (id == 2) ? 2.0 : 0.0; + o.uv.y = (id == 1) ? 2.0 : 0.0; + o.vpos = float4(o.uv.xy * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); + + //o.uvtoviewADD = float3(-1.0,-1.0,1.0); + //o.uvtoviewMUL = float3(2.0,2.0,0.0); + + o.uvtoviewADD = float3(-tan(radians(SSR_FIELD_OF_VIEW * 0.5)).xx,1.0) * qUINT::ASPECT_RATIO.yxx; + o.uvtoviewMUL = float3(-2.0 * o.uvtoviewADD.xy,0.0); + + return o; +} + +/*============================================================================= + Functions +=============================================================================*/ + +float3 get_position_from_uv(in float2 uv, in SSR_VSOUT i) +{ + return (uv.xyx * i.uvtoviewMUL + i.uvtoviewADD) * qUINT::linear_depth(uv) * RESHADE_DEPTH_LINEARIZATION_FAR_PLANE; +} + +float2 get_uv_from_position(in float3 pos, in SSR_VSOUT i) +{ + return pos.xy / (i.uvtoviewMUL.xy * pos.z) - i.uvtoviewADD.xy/i.uvtoviewMUL.xy; +} + +float4 get_normal_and_edges_from_depth(in SSR_VSOUT i) +{ + float3 single_pixel_offset = float3(qUINT::PIXEL_SIZE, 0); + + float3 position = get_position_from_uv(i.uv, i); + float3 position_delta_x1 = - position + get_position_from_uv(i.uv + single_pixel_offset.xz, i); + float3 position_delta_x2 = position - get_position_from_uv(i.uv - single_pixel_offset.xz, i); + float3 position_delta_y1 = - position + get_position_from_uv(i.uv + single_pixel_offset.zy, i); + float3 position_delta_y2 = position - get_position_from_uv(i.uv - single_pixel_offset.zy, i); + + position_delta_x1 = lerp(position_delta_x1, position_delta_x2, abs(position_delta_x1.z) > abs(position_delta_x2.z)); + position_delta_y1 = lerp(position_delta_y1, position_delta_y2, abs(position_delta_y1.z) > abs(position_delta_y2.z)); + + float deltaz = abs(position_delta_x1.z * position_delta_x1.z - position_delta_x2.z * position_delta_x2.z) + + abs(position_delta_y1.z * position_delta_y1.z - position_delta_y2.z * position_delta_y2.z); + + return float4(normalize(cross(position_delta_y1, position_delta_x1)), deltaz); +} + +float3 get_normal_from_color(float2 uv, float2 offset, float scale, float sharpness) +{ + float3 offset_swiz = float3(offset.xy, 0); + float hpx = dot(tex2Dlod(qUINT::sBackBufferTex, float4(uv + offset_swiz.xz,0,0)).xyz, 0.333) * scale; + float hmx = dot(tex2Dlod(qUINT::sBackBufferTex, float4(uv - offset_swiz.xz,0,0)).xyz, 0.333) * scale; + float hpy = dot(tex2Dlod(qUINT::sBackBufferTex, float4(uv + offset_swiz.zy,0,0)).xyz, 0.333) * scale; + float hmy = dot(tex2Dlod(qUINT::sBackBufferTex, float4(uv - offset_swiz.zy,0,0)).xyz, 0.333) * scale; + + float dpx = qUINT::linear_depth(uv + offset_swiz.xz); + float dmx = qUINT::linear_depth(uv - offset_swiz.xz); + float dpy = qUINT::linear_depth(uv + offset_swiz.zy); + float dmy = qUINT::linear_depth(uv - offset_swiz.zy); + + float2 xymult = float2(abs(dmx - dpx), abs(dmy - dpy)) * sharpness; + xymult = saturate(1.0 - xymult); + + float3 normal; + normal.xy = float2(hmx - hpx, hmy - hpy) * xymult / offset.xy * 0.5; + normal.z = 1.0; + + return normalize(normal); +} + +float3 blend_normals(float3 n1, float3 n2) +{ + //return normalize(float3(n1.xy*n2.z + n2.xy*n1.z, n1.z*n2.z)); + n1 += float3( 0, 0, 1); + n2 *= float3(-1, -1, 1); + return n1*dot(n1, n2)/n1.z - n2; +} + +float bayer(float2 vpos, int max_level) +{ + float finalBayer = 0.0; + float finalDivisor = 0.0; + float layerMult = 1.0; + + for(float bayerLevel = max_level; bayerLevel >= 1.0; bayerLevel--) + { + layerMult *= 4.0; + + float2 bayercoord = floor(vpos.xy * exp2(1 - bayerLevel)) % 2; + float line0202 = bayercoord.x*2.0; + + finalBayer += lerp(line0202, 3.0 - line0202, bayercoord.y) / 3.0 * layerMult; + finalDivisor += layerMult; + } + + return finalBayer / finalDivisor; +} + +/*============================================================================= + Pixel Shaders +=============================================================================*/ + +struct Ray +{ + float3 origin; + float3 dir; + float step; + float3 pos; +}; + +struct SceneData +{ + float3 eyedir; + float3 normal; + float3 position; + float depth; +}; + +struct TraceData +{ + int num_steps; + int num_refines; + float2 uv; + float3 error; + bool hit; +}; + +struct BlurData +{ + float4 key; + float4 mask; +}; + +void PS_PrepareColor(in SSR_VSOUT i, out float4 o : SV_Target0) +{ + o = tex2D(qUINT::sBackBufferTex, i.uv); +} +void PS_SSR(in SSR_VSOUT i, out float4 reflection : SV_Target0, out float4 blurbuffer : SV_Target1) +{ + blurbuffer = get_normal_and_edges_from_depth(i); + float jitter = bayer(i.vpos.xy,3) - 0.5; + + SceneData scene; + scene.position = get_position_from_uv(i.uv, i); + scene.eyedir = normalize(scene.position); //not the direction where the eye it but where it looks at + scene.normal = blend_normals(blurbuffer.xyz, get_normal_from_color(i.uv, 40.0 * qUINT::PIXEL_SIZE / scene.position.z * SSR_RELIEF_SCALE, 0.005 * SSR_RELIEF_AMOUNT, 1000.0)); + scene.depth = scene.position.z / RESHADE_DEPTH_LINEARIZATION_FAR_PLANE; + + Ray ray; + ray.origin = scene.position; + ray.dir = reflect(scene.eyedir, scene.normal); + ray.step = (0.2 + 0.05 * jitter * SSR_JITTER_AMOUNT) * sqrt(scene.depth) * rcp(1e-3 + saturate(1 - dot(ray.dir, scene.eyedir))); //<-ensure somewhat uniform step size in screen percentage + ray.pos = ray.origin + ray.dir * ray.step; + + TraceData trace; + trace.uv = i.uv; + trace.hit = 0; + trace.num_steps = 20; + trace.num_refines = 3; + + int j = 0; + int k = 0; + bool uv_inside_screen; + + while(j++ < trace.num_steps) + { + trace.uv = get_uv_from_position(ray.pos, i); + trace.error = get_position_from_uv(trace.uv, i) - ray.pos; + + if(trace.error.z < 0 && trace.error.z > -SSR_ACCEPT_RANGE * ray.step) + { + j = 0; //ensure we have enough steps left to complete our refinement + + if(k < trace.num_refines) + { + //step back + ray.step /= SSR_RAY_INC; + ray.pos -= ray.dir * ray.step; + //decrease stepsize by magic amount - at some point the increased + //resolution is too small to notice and just adds up to the render cost + ray.step *= SSR_RAY_INC * rcp(trace.num_steps); + } + else + { + j += trace.num_steps; //algebraic "break" - much faster + } + k++; + } + + ray.pos += ray.dir * ray.step; + ray.step *= SSR_RAY_INC; + + uv_inside_screen = all(saturate(-trace.uv.y * trace.uv.y + trace.uv.y)); + j += trace.num_steps * !uv_inside_screen; + } + + trace.hit = k != 0; //we did refinements -> we initially found an intersection + + float SSR_FRESNEL_K = 0.04; //matches most surfaces + //Van Damme between physically correct and total artistic nonsense + float schlick = lerp(SSR_FRESNEL_K, 1, pow(saturate(1 - dot(-scene.eyedir, scene.normal)), SSR_FRESNEL_EXP)) * SSR_REFLECTION_INTENSITY; + float fade = saturate(dot(scene.eyedir, ray.dir)) * saturate(1 - dot(-scene.eyedir, scene.normal)); + + reflection.a = trace.hit * schlick * fade; + reflection.rgb = tex2D(sSSR_ColorTex, trace.uv).rgb * reflection.a; + + blurbuffer.xyz = blurbuffer.xyz * 0.5 + 0.5; +} + +void spatial_blur_data(inout BlurData o, in sampler inputsampler, in float4 uv) +{ + o.key = tex2Dlod(inputsampler, uv); + o.mask = tex2Dlod(sCommonTex1, uv); + o.mask.xyz = o.mask.xyz * 2 - 1; +} + +float compute_spatial_tap_weight(in BlurData center, in BlurData tap) +{ + float depth_term = saturate(1 - abs(tap.mask.w - center.mask.w) * 50); + float normal_term = saturate(dot(tap.mask.xyz, center.mask.xyz) * 50 - 49); + return depth_term * normal_term; +} + +float4 blur_filter(in SSR_VSOUT i, in sampler inputsampler, in float radius, in float2 axis) +{ + float4 blur_uv = float4(i.uv.xy, 0, 0); + + BlurData center, tap; + spatial_blur_data(center, inputsampler, blur_uv); + + if(SSR_FILTER_SIZE == 0) return center.key; + + float kernel_size = radius; + float k = -2.0 * rcp(kernel_size * kernel_size + 1e-3); + + float4 blursum = 0; + float4 blursum_noweight = 0; + float blursum_weight = 1e-3; + float blursum_noweight_weight = 1e-3; //lel + + [loop] + for(float j = -floor(kernel_size); j <= floor(kernel_size); j++) + { + spatial_blur_data(tap, inputsampler, float4(i.uv + axis * (2.0 * j - 0.5), 0, 0)); + float tap_weight = compute_spatial_tap_weight(center, tap); + + blursum += tap.key * tap_weight * exp(j * j * k) * tap.key.w; + blursum_weight += tap_weight * exp(j * j * k) * tap.key.w; + blursum_noweight += tap.key * exp(j * j * k) * tap.key.w; + blursum_noweight_weight += exp(j * j * k) * tap.key.w; + } + + blursum /= blursum_weight; + blursum_noweight /= blursum_noweight_weight; + + return lerp(center.key, blursum, saturate(blursum_weight * 2)); +} + +void PS_FilterH(in SSR_VSOUT i, out float4 o : SV_Target0) +{ + o = blur_filter(i, sCommonTex0, SSR_FILTER_SIZE, float2(0, 1) * qUINT::PIXEL_SIZE); +} + +void PS_FilterV(in SSR_VSOUT i, out float4 o : SV_Target0) +{ + float4 reflection = blur_filter(i, sSSR_ColorTex, SSR_FILTER_SIZE, float2(1, 0) * qUINT::PIXEL_SIZE); + float alpha = reflection.w; //tex2D(sCommonTex0, i.uv).w; + + float fade = saturate(1 - qUINT::linear_depth(i.uv) / SSR_FADE_DIST); + o = tex2D(qUINT::sBackBufferTex, i.uv); + + o.rgb = lerp(o.rgb, reflection.rgb, alpha * fade); +} + +/*============================================================================= + Techniques +=============================================================================*/ + +technique SSR +< ui_tooltip = " >> qUINT::SSR <<\n\n" + "SSR adds screen-space reflections to the scene. This shader is\n" + "intended to only be used in screenshots as it will add reflections\n" + "to _everything_ - ReShade limitation.\n" + "\nSSR is written by Marty McFly / Pascal Gilcher"; > +{ + pass + { + VertexShader = VS_SSR; + PixelShader = PS_PrepareColor; + RenderTarget = SSR_ColorTex; + } + pass + { + VertexShader = VS_SSR; + PixelShader = PS_SSR; + RenderTarget0 = CommonTex0; + RenderTarget1 = CommonTex1; + } + pass + { + VertexShader = VS_SSR; + PixelShader = PS_FilterH; + RenderTarget = SSR_ColorTex; + } + pass + { + VertexShader = VS_SSR; + PixelShader = PS_FilterV; + } +} \ No newline at end of file diff --git a/data_from_portwine/Reshade/Textures/AreaTex.png b/data_from_portwine/Reshade/Textures/AreaTex.png new file mode 100644 index 00000000..d0184f77 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/AreaTex.png differ diff --git a/data_from_portwine/Reshade/Textures/FontAtlas.png b/data_from_portwine/Reshade/Textures/FontAtlas.png new file mode 100644 index 00000000..edbc79e7 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/FontAtlas.png differ diff --git a/data_from_portwine/Reshade/Textures/Layer.png b/data_from_portwine/Reshade/Textures/Layer.png new file mode 100644 index 00000000..6ac5d75c Binary files /dev/null and b/data_from_portwine/Reshade/Textures/Layer.png differ diff --git a/data_from_portwine/Reshade/Textures/SearchTex.png b/data_from_portwine/Reshade/Textures/SearchTex.png new file mode 100644 index 00000000..8d3dd964 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/SearchTex.png differ diff --git a/data_from_portwine/Reshade/Textures/dummy b/data_from_portwine/Reshade/Textures/dummy new file mode 100644 index 00000000..e69de29b diff --git a/data_from_portwine/Reshade/Textures/lut.png b/data_from_portwine/Reshade/Textures/lut.png new file mode 100644 index 00000000..f2d85df0 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/lut.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_bluenoise.png b/data_from_portwine/Reshade/Textures/pd80_bluenoise.png new file mode 100644 index 00000000..e7d91737 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_bluenoise.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_bluenoise_rgba.png b/data_from_portwine/Reshade/Textures/pd80_bluenoise_rgba.png new file mode 100644 index 00000000..d1c768d3 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_bluenoise_rgba.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_cinelut.png b/data_from_portwine/Reshade/Textures/pd80_cinelut.png new file mode 100644 index 00000000..5054ca1d Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_cinelut.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut.png b/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut.png new file mode 100644 index 00000000..630a895b Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut.psd b/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut.psd new file mode 100644 index 00000000..230fc6c8 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut.psd differ diff --git a/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut_square.png b/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut_square.png new file mode 100644 index 00000000..865e53aa Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut_square.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut_square.psd b/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut_square.psd new file mode 100644 index 00000000..ad1d6fe1 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_clean_64tile_lut_square.psd differ diff --git a/data_from_portwine/Reshade/Textures/pd80_clean_lut.png b/data_from_portwine/Reshade/Textures/pd80_clean_lut.png new file mode 100644 index 00000000..1f3078f7 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_clean_lut.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_example-lut.png b/data_from_portwine/Reshade/Textures/pd80_example-lut.png new file mode 100644 index 00000000..7f3031b6 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_example-lut.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_gaussnoise.png b/data_from_portwine/Reshade/Textures/pd80_gaussnoise.png new file mode 100644 index 00000000..77771240 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_gaussnoise.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_neutral-lut.png b/data_from_portwine/Reshade/Textures/pd80_neutral-lut.png new file mode 100644 index 00000000..e24ed6b7 Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_neutral-lut.png differ diff --git a/data_from_portwine/Reshade/Textures/pd80_permtexture.png b/data_from_portwine/Reshade/Textures/pd80_permtexture.png new file mode 100644 index 00000000..b630a79c Binary files /dev/null and b/data_from_portwine/Reshade/Textures/pd80_permtexture.png differ diff --git a/data_from_portwine/scripts/functions_helper b/data_from_portwine/scripts/functions_helper index a70e395a..8bb32ce1 100755 --- a/data_from_portwine/scripts/functions_helper +++ b/data_from_portwine/scripts/functions_helper @@ -510,30 +510,32 @@ pw_reshade_check () { portwine_exe_arch=64 fi if [[ "$portwine_exe_arch" == "64" ]] ; then - export needed_dll="dxgi.dll" - export WINEDLLOVERRIDES="d3dcompiler_47=n,dxgi=n,b" - ln -is /run/pressure-vessel/pv-from-host/reshade/ReShade64.dll "$portwine_exe/$needed_dll" + export needed_dll="dxgi.dll" + #export WINEDLLOVERRIDES="d3dcompiler_47=n,dxgi=n,b" + ln -is "${PORT_WINE_PATH}/data/Reshade/ReShade64.dll" "${PATH_TO_GAME}/$needed_dll" else - export needed_dll="d3d9.dll" + export needed_dll="d3d9.dll" export WINEDLLOVERRIDES="d3dcompiler_47=n,d3d9=n.b" - ln -is /run/pressure-vessel/pv-from-host/reshade/ReShade32.dll "$portwine_exe/$needed_dll" + ln -is "${PORT_WINE_PATH}/data/Reshade/ReShade32.dll" "${PATH_TO_GAME}/$needed_dll" fi LINKS="ReShade32.json ReShade64.json ReShade.ini textures reshade $needed_dll" for link in $LINKS; do - ln -is /run/pressure-vessel/pv-from-host/"$link" "$portwine_exe/" + if [[ -L "${PATH_TO_GAME}/$link" ]] ; then + unlink "${PATH_TO_GAME}/$link" + fi done print_info "Reshade is enabled" else export DISABLE_RESHADE=1 for link in $LINKS; do - if [[ -L "$portwine_exe/$link" ]] ; then - unlink "$portwine_exe/$link" + if [[ -L "${PATH_TO_GAME}/$link" ]] ; then + unlink "${PATH_TO_GAME}/$link" fi done - unset WINEDLLOVERRIDES + #unset WINEDLLOVERRIDES print_info "Reshade is disabled" fi return 0