SweetFX Settings DB
Latest forum threads
1 hour, 7 minutes ago
by mailto
2 hours, 1 minute ago
2 hours, 17 minutes ago
by Esha
2 hours, 24 minutes ago

Dr_Patrik's Realistic Shader

Preset for Guild Wars 2
Created by Dr_Patrik
Added Nov. 14, 2015
Updated 11 Dec 21:45 CET
Shader used: ReShade
Preset description:
Description: This preset is an attempt to make Guild Wars 2 look as realistic as possible. Granted not all areas are going to look as good as others. Also, I am not the best at taking screenshots of the game so to judge it best I recommend at least trying it out for a little bit. Feedback is greatly appreciated. ToggleKey: F9 For help with the installation of MasterEffect and ReShade check out WoodenPotatoes ReShade tutorial video as it will help with the first few steps in the installation. If you are having trouble installing the preset, feel free to leave a comment outlining the problem and I will try to help as best as I can. WoodenPotatoes Reshade Tutorial: https://www.youtube.com/watch?v=a5i5-2X4wMA In-Game Settings: Important: Turn postprocessing and antialiasing off as they are taken care of by the preset. Animation: High Antialiasing: Off Environment: High LOD Distance: High Reflections: All Textures: High Render Sampling: Supersample Shadows: High Shaders: High Postprocessing: None Ambient Occlusion: On Best Texture Filtering: Off Depth Blur: Off Effect LOD: Off High-Res Character Textures: On Light Adaptation: Off Vertical Sync: Off Installation: Step 1. Download ReShade Framework and copy the folder "ReShade" and either "ReShade32.dll" or "ReShade64.dll" (depending on your client version) and put them into your bin folder. ReShade Framework: http://reshade.me/ Step 2. Rename the "ReShade32.dll" or "ReShade64.dll", depending on which one you have, to "d3d9.dll" Step 3. Download MasterEffect and open the zip folder. Open the folder "MasterEffect ReBorn 1.1.287" and copy the folder called "MasterEffect" into your bin folder. MasterEffect: http://reshade.me/forum/shader-presentation/161-mastereffect-reborn-official-thread Step 4. Download the preset (text file) from this page, put it in your bin folder, and rename it to "ReShade.fx" Step 5. Download the text file from the link below, put it in your bin folder, and rename it to "MasterEffect.h" Mastereffect.h: https://sfx.thelazy.net/games/preset/4698/ Step 6. Download the text file from the link below, put it in the ReShade folder that is inside the bin folder, and rename it to "GemFX.cgf" (replace the file that is already in there) GemFX.cfg: https://sfx.thelazy.net/games/preset/4699/ Step 7. Download the text file from the link below, put it in the ReShade folder that is inside the bin folder, and rename it to "SweetFX.cgf" (replace the file that is already in there) SweetFX.cfg: https://sfx.thelazy.net/games/preset/4700/ Step 8. Download the text file from the link below, put it in the ReShade folder that is inside the bin folder, and rename it to "Common.cgf" (replace the file that is already in there) Common.cfg: https://sfx.thelazy.net/games/preset/4852/
Download preset Show / Hide settings
/*----------------------------. | :: Framework Initializer :: | '----------------------------*/ // Global Settings #include "ReShade\PersonalFiles\KeyCodes.h" #include "ReShade\Common.cfg" #if RFX_Screenshot_Format != 2 #pragma reshade screenshot_format bmp #else #pragma reshade screenshot_format png #endif #if RFX_ShowFPS == 1 #pragma reshade showfps #endif #if RFX_ShowClock == 1 #pragma reshade showclock #endif #if RFX_ShowStatistics == 1 #pragma reshade showstatistics #endif #if RFX_ShowToggleMessage == 1 #pragma reshade showtogglemessage #endif // Global Variables #define RFX_pixelSize RFX_PixelSize #define RFX_PixelSize float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) #define RFX_ScreenSize float2(BUFFER_WIDTH, BUFFER_HEIGHT) #define RFX_ScreenSizeFull float4(BUFFER_WIDTH, BUFFER_RCP_WIDTH, float(BUFFER_WIDTH) / float(BUFFER_HEIGHT), float(BUFFER_HEIGHT) / float(BUFFER_WIDTH)) // x = Width, y = 1 / Width, z = ScreenScaleY, w = 1 / ScreenScaleY uniform float RFX_timer < string source = "timer"; >; uniform float RFX_timeleft < string source = "timeleft"; >; uniform float RFX_frametime < source = "frametime"; >; // Global Textures and Samplers texture RFX_depthBufferTex : DEPTH; texture RFX_depthTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = R32F; }; texture RFX_backbufferTex : COLOR; #if RFX_InitialStorage texture RFX_originalTex { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; }; #else texture RFX_originalTex : COLOR; #endif sampler RFX_depthColor { Texture = RFX_depthBufferTex; }; sampler RFX_depthTexColor { Texture = RFX_depthTex; }; sampler RFX_backbufferColor { Texture = RFX_backbufferTex; }; sampler RFX_originalColor { Texture = RFX_originalTex; }; // Fullscreen Triangle Vertex Shader void RFX_VS_PostProcess(in uint id : SV_VertexID, out float4 pos : SV_Position, out float2 texcoord : TEXCOORD) { texcoord.x = (id == 2) ? 2.0 : 0.0; texcoord.y = (id == 1) ? 2.0 : 0.0; pos = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); } #if RFX_InitialStorage float4 RFX_PS_StoreColor(float4 vpos : SV_Position, float2 texcoord : TEXCOORD) : SV_Target { return tex2D(RFX_backbufferColor, texcoord); } #endif #if RFX_DepthBufferCalc float RFX_PS_StoreDepth(in float4 position : SV_Position, in float2 texcoord : TEXCOORD0) : SV_Target { float depth = tex2D(RFX_depthColor, texcoord).x; // Linearize depth #if RFX_LogDepth depth = saturate(1.0f - depth); depth = (exp(pow(depth, 150 * pow(depth, 55) + 32.75f / pow(depth, 5) - 1850f * (pow((1 - depth), 2)))) - 1) / (exp(depth) - 1); // Made by LuciferHawk ;-) #else const float zFarPlane = RFX_Depth_z_far; const float zNearPlane = RFX_Depth_z_near; depth = 1.0 / ((depth * ((zFarPlane - zNearPlane) / (-zFarPlane * zNearPlane)) + zFarPlane / (zFarPlane * zNearPlane))); #endif // SweetFX Dither Method #1 const float dither_bit = 8.0; float dither_shift = 0.25 * (1.0 / (pow(2, dither_bit) - 1.0)); dither_shift = lerp(2.0 * dither_shift, -2.0 * dither_shift, frac(dot(texcoord, RFX_ScreenSize * float2(1.0 / 16.0, 10.0 / 36.0)) + 0.25)); return depth + dither_shift; } #endif #if RFX_InitialStorage || RFX_DepthBufferCalc technique RFX_Setup_Tech < enabled = true; > { #if RFX_InitialStorage pass StoreColor { VertexShader = RFX_VS_PostProcess; PixelShader = RFX_PS_StoreColor; RenderTarget = RFX_originalTex; } #endif #if RFX_DepthBufferCalc pass StoreDepth { VertexShader = RFX_VS_PostProcess; PixelShader = RFX_PS_StoreDepth; RenderTarget = RFX_depthTex; } #endif } #endif // Global Defines #if defined(__RESHADE__) && __RESHADE__ >= 1700 #define NAMESPACE_ENTER(name) namespace name { #define NAMESPACE_LEAVE() } #else #define NAMESPACE_ENTER(name) #define NAMESPACE_LEAVE() #endif #define STR(name) #name #define EFFECT(l,n) STR(ReShade/l/##n.h) /*----------------------------. | :: Effect Pipeline :: | '----------------------------*/ #include "ReShade\Pipeline.cfg" /*----------------------------. | :: Framework Finalizer :: | '----------------------------*/ #if RFX_ShowToggleMessage float4 RFX_PS_ToggleMessage(in float4 position : SV_Position, in float2 texcoord : TEXCOORD0) : SV_Target { return tex2D(RFX_backbufferColor, texcoord); } technique Framework < enabled = RFX_Start_Enabled; toggle = RFX_ToggleKey; > { pass { VertexShader = RFX_VS_PostProcess; PixelShader = RFX_PS_ToggleMessage; } } #endif #include "MasterEffect.h" //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // END OF TWEAKING VARIABLES // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //global vars #define ScreenSize float4(BUFFER_WIDTH, BUFFER_RCP_WIDTH, float(BUFFER_WIDTH) / float(BUFFER_HEIGHT), float(BUFFER_HEIGHT) / float(BUFFER_WIDTH)) //x=Width, y=1/Width, z=ScreenScaleY, w=1/ScreenScaleY #define PixelSize float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) #define PI 3.1415972 #define PIOVER180 0.017453292 #define AUTHOR MartyMcFly #define FOV 75 #define LumCoeff float3(0.212656, 0.715158, 0.072186) #define zFarPlane 1 #define zNearPlane 0.001 //I know, weird values but ReShade's depthbuffer is ... odd #define aspect (BUFFER_RCP_HEIGHT/BUFFER_RCP_WIDTH) #define InvFocalLen float2(tan(0.5f*radians(FOV)) / (float)BUFFER_RCP_HEIGHT * (float)BUFFER_RCP_WIDTH, tan(0.5f*radians(FOV))) uniform float4 Timer < source = "timer"; >; #pragma message "MasterEffect ReBorn 1.1.287 by Marty McFly" #if( USE_HDR_LEVEL == 0) #define RENDERMODE RGBA8 #endif #if( USE_HDR_LEVEL == 1) #define RENDERMODE RGBA16F #endif #if( USE_HDR_LEVEL == 2) #define RENDERMODE RGBA32F #endif //textures texture texBloom1 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RENDERMODE;}; texture texBloom2 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RENDERMODE;}; texture texBloom3 { Width = BUFFER_WIDTH/2; Height = BUFFER_HEIGHT/2; Format = RENDERMODE;}; texture texBloom4 { Width = BUFFER_WIDTH/4; Height = BUFFER_HEIGHT/4; Format = RENDERMODE;}; texture texBloom5 { Width = BUFFER_WIDTH/8; Height = BUFFER_HEIGHT/8; Format = RENDERMODE;}; texture texLens1 { Width = BUFFER_WIDTH/2; Height = BUFFER_HEIGHT/2; Format = RENDERMODE;}; texture texLens2 { Width = BUFFER_WIDTH/2; Height = BUFFER_HEIGHT/2; Format = RENDERMODE;}; texture2D texLDR : COLOR; texture texHDR1 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; MipLevels = 5; Format = RENDERMODE;}; texture texHDR2 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; MipLevels = 5; Format = RENDERMODE;}; texture texOcclusion1 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F;}; //MUST be at least 16, 8 gives heavy artifacts when blurring. texture texOcclusion2 { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F;}; //"Optimizations" can be done elsewhere, not here. texture texCoC { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; MipLevels = 5; Format = RGBA16F;}; texture2D texDepth : DEPTH; texture texNoise < string source = "MasterEffect/internal/mcnoise.png"; > {Width = BUFFER_WIDTH;Height = BUFFER_HEIGHT;Format = RGBA8;}; texture texSprite < string source = "MasterEffect/mcsprite.png"; > {Width = BUFFER_WIDTH;Height = BUFFER_HEIGHT;Format = RGBA8;}; texture texDirt < string source = "MasterEffect/mcdirt.png"; > {Width = BUFFER_WIDTH;Height = BUFFER_HEIGHT;Format = RGBA8;}; texture texLUT < string source = "MasterEffect/mclut.png"; > {Width = 256; Height = 1; Format = RGBA8;}; texture texLUT3D < string source = "MasterEffect/mclut3d.png"; > {Width = 256; Height = 16; Format = RGBA8;}; texture texMask < string source = "MasterEffect/mcmask.png"; > {Width = BUFFER_WIDTH;Height = BUFFER_HEIGHT;Format = R8;}; texture texHeat < string source = "MasterEffect/internal/mcheat.png"; > {Width = 512;Height = 512;Format = RGBA8;}; //samplers sampler SamplerBloom1 { Texture = texBloom1; }; sampler SamplerBloom2 { Texture = texBloom2; }; sampler SamplerBloom3 { Texture = texBloom3; }; sampler SamplerBloom4 { Texture = texBloom4; }; sampler SamplerBloom5 { Texture = texBloom5; }; sampler SamplerLens1 { Texture = texLens1; }; sampler SamplerLens2 { Texture = texLens2; }; sampler2D SamplerLDR { Texture = texLDR; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerHDR1 { Texture = texHDR1; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerHDR2 { Texture = texHDR2; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerOcclusion1 { Texture = texOcclusion1; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerOcclusion2 { Texture = texOcclusion2; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerCoC { Texture = texCoC; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerDepth { Texture = texDepth; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerNoise { Texture = texNoise; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; sampler2D SamplerSprite { Texture = texSprite; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerDirt { Texture = texDirt; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerLUT { Texture = texLUT; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerLUT3D { Texture = texLUT3D; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerMask { Texture = texMask; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; sampler2D SamplerHeat { Texture = texHeat; MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = LINEAR; AddressU = Repeat; AddressV = Repeat; }; struct VS_OUTPUT_POST { float4 vpos : SV_Position; float2 txcoord : TEXCOORD0; }; struct VS_INPUT_POST { uint id : SV_VertexID; }; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Vertex Shaders // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VS_OUTPUT_POST VS_MasterEffect(VS_INPUT_POST IN) { VS_OUTPUT_POST OUT; OUT.txcoord.x = (IN.id == 2) ? 2.0 : 0.0; OUT.txcoord.y = (IN.id == 1) ? 2.0 : 0.0; OUT.vpos = float4(OUT.txcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); return OUT; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // SMAA // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #include "MasterEffect/internal/mcsmaa.hlsl" //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Functions // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float GetLinearDepth(float depth) { return 1 / ((depth * ((zFarPlane - zNearPlane) / (-zFarPlane * zNearPlane)) + zFarPlane / (zFarPlane * zNearPlane))); } float3 GetNormalFromDepth(float fDepth, float2 vTexcoord) { const float2 offset1 = float2(0.0,0.001); const float2 offset2 = float2(0.001,0.0); float depth1 = GetLinearDepth(tex2Dlod(SamplerDepth, float4(vTexcoord + offset1,0,0)).x); float depth2 = GetLinearDepth(tex2Dlod(SamplerDepth, float4(vTexcoord + offset2,0,0)).x); float3 p1 = float3(offset1, depth1 - fDepth); float3 p2 = float3(offset2, depth2 - fDepth); float3 normal = cross(p1, p2); normal.z = -normal.z; return normalize(normal); } float GetRandom(float2 co){ return frac(sin(dot(co, float2(12.9898, 78.233))) * 43758.5453); } float3 GetRandomVector(float2 vTexCoord) { return 2 * normalize(float3(GetRandom(vTexCoord - 0.5f), GetRandom(vTexCoord + 0.5f), GetRandom(vTexCoord))) - 1; } float4 GetAtlasTex(sampler tex, float2 coord, float spaltenzahl, float reihenzahl, float spalte, float reihe) { return tex2Dlod(tex, float4(coord.xy/float2(spaltenzahl, reihenzahl)+float2((spalte-1)/spaltenzahl,(reihe-1)/reihenzahl),0,0)); } float4 GaussBlur22(float2 coord, sampler tex, float mult, float lodlevel, bool isBlurVert) //texcoord, texture, blurmult in pixels, tex2dlod level, axis (0=horiz, 1=vert) { float4 sum = 0; float2 axis = (isBlurVert) ? float2(0, 1) : float2(1, 0); float weight[11] = {0.082607, 0.080977, 0.076276, 0.069041, 0.060049, 0.050187, 0.040306, 0.031105, 0.023066, 0.016436, 0.011254}; for(int i=-10; i < 11; i++) { float currweight = weight[abs(i)]; sum += tex2Dlod(tex, float4(coord.xy + axis.xy * (float)i * PixelSize * mult,0,lodlevel)) * currweight; } return sum; } float4 GaussBlurGeneric(float2 coord, sampler tex, float mult, float lodlevel, bool isBlurVert, float Radius, float Quality) //texcoord, texture, blurmult in pixels, tex2dlod level, axis (0=horiz, 1=vert), offset count, quality { float2 axis = (isBlurVert) ? float2(0, 1) : float2(1, 0); float4 Sigma = 0; Sigma.x = 1.0f / ( sqrt( 2.0f * PI ) * Radius ); Sigma.y = exp( -0.5f / ( Radius * Radius )); Sigma.z = Sigma.y * Sigma.y; Sigma.w = Sigma.x; Sigma.xy *= Sigma.yz; float4 sum = tex2Dlod(tex, float4(coord.xy,0,lodlevel))*Sigma.x; for(int i = 1; i < 150 && Sigma.w < Quality; i++) { sum += tex2Dlod(tex, float4(coord.xy + axis.xy * (float)i * PixelSize * mult,0,lodlevel)) * Sigma.x; sum += tex2Dlod(tex, float4(coord.xy - axis.xy * (float)i * PixelSize * mult,0,lodlevel)) * Sigma.x; Sigma.w += 2.0 * Sigma.x; Sigma.xy *= Sigma.yz; } sum /= Sigma.w; return sum; } float smootherstep(float edge0, float edge1, float x) { x = clamp((x - edge0)/(edge1 - edge0), 0.0, 1.0); return x*x*x*(x*(x*6 - 15) + 10); } float3 Hue(in float3 RGB) { // Based on work by Sam Hocevar and Emil Persson float Epsilon = 1e-10; 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); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Passes // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float4 BorderPass( float4 colorInput, float2 tex ) { float3 fBorderColor_float = fBorderColor; float2 screen_size = float2(BUFFER_WIDTH, BUFFER_HEIGHT); float screen_ratio = (BUFFER_WIDTH/BUFFER_HEIGHT); float2 fBorderWidth_variable = fBorderWidth; // -- calculate the right fBorderWidth for a given fBorderRatio -- //if (!any(fBorderWidth)) //if fBorderWidth is not used if (fBorderWidth.x == -fBorderWidth.y) //if fBorderWidth is not used if (screen_ratio < fBorderRatio) fBorderWidth_variable = float2(0.0, (screen_size.y - (screen_size.x / fBorderRatio)) * 0.5); else fBorderWidth_variable = float2((screen_size.x - (screen_size.y * fBorderRatio)) * 0.5, 0.0); float2 border = (PixelSize.xy * fBorderWidth_variable); //Translate integer pixel width to floating point float2 within_border = saturate((-tex * tex + tex) - (-border * border + border)); //becomes positive when inside the border and 0 when outside colorInput.rgb = all(within_border) ? colorInput.rgb : fBorderColor_float ; //if the pixel is within the border use the original color, if not use the fBorderColor return colorInput; //return the pixel } float3 CartoonPass( float3 colorInput, float2 tex, float2 pixelsize, sampler colorsampler ) { float diff1 = dot(LumCoeff,tex2D(colorsampler, tex + pixelsize).rgb); diff1 = dot(float4(LumCoeff,-1.0),float4(tex2D(colorsampler, tex - pixelsize).rgb , diff1)); float diff2 = dot(LumCoeff,tex2D(colorsampler, tex +float2(pixelsize.x,-pixelsize.y)).rgb); diff2 = dot(float4(LumCoeff,-1.0),float4(tex2D(colorsampler, tex +float2(-pixelsize.x,pixelsize.y)).rgb , diff2)); float edge = dot(float2(diff1,diff2),float2(diff1,diff2)); colorInput.rgb = pow(edge,CartoonEdgeSlope) * -CartoonPower + colorInput.rgb; return saturate(colorInput); } float3 LevelsPass( float3 colorInput ) { #define black_point_float ( Levels_black_point / 255.0 ) #define white_point_float ( 255.0 / (Levels_white_point - Levels_black_point)) colorInput.rgb = colorInput.rgb * white_point_float - (black_point_float * white_point_float); return colorInput; } float3 TechniPass_prod80(float3 colorInput) { float3 colStrength = float3(ColStrengthR,ColStrengthG,ColStrengthB); float3 tsource = saturate(colorInput.rgb); float3 ttemp = 1 - tsource; float3 ttarget = ttemp.grg; float3 ttarget2 = ttemp.bbr; float3 ttemp2 = tsource.rgb * ttarget.rgb; ttemp2.rgb *= ttarget2.rgb; ttemp.rgb = ttemp2.rgb * colStrength; ttemp2.rgb *= TechniBrightness; ttarget.rgb = ttemp.grg; ttarget2.rgb = ttemp.bbr; ttemp.rgb = tsource.rgb - ttarget.rgb; ttemp.rgb += ttemp2.rgb; ttemp2.rgb = ttemp.rgb - ttarget2.rgb; colorInput.rgb = lerp(tsource.rgb, ttemp2.rgb, TechniStrength); colorInput.rgb = lerp(dot(colorInput.rgb, 0.333), colorInput.rgb, TechniSat); return colorInput.rgb; } float3 TechnicolorPass( float3 colorInput ) { #define cyanfilter float3(0.0, 1.30, 1.0) #define magentafilter float3(1.0, 0.0, 1.05) #define yellowfilter float3(1.6, 1.6, 0.05) #define redorangefilter float2(1.05, 0.620) //RG_ #define greenfilter float2(0.30, 1.0) //RG_ #define magentafilter2 magentafilter.rb //R_B float3 tcol = colorInput.rgb; float2 rednegative_mul = tcol.rg * (1.0 / (redNegativeAmount * TechniPower)); float2 greennegative_mul = tcol.rg * (1.0 / (greenNegativeAmount * TechniPower)); float2 bluenegative_mul = tcol.rb * (1.0 / (blueNegativeAmount * TechniPower)); float rednegative = dot( redorangefilter, rednegative_mul ); float greennegative = dot( greenfilter, greennegative_mul ); float bluenegative = dot( magentafilter2, bluenegative_mul ); float3 redoutput = rednegative.rrr + cyanfilter; float3 greenoutput = greennegative.rrr + magentafilter; float3 blueoutput = bluenegative.rrr + yellowfilter; float3 result = redoutput * greenoutput * blueoutput; colorInput.rgb = lerp(tcol, result, TechniAmount); return colorInput; } float3 DPXPass(float3 InputColor){ float3x3 RGB = float3x3( 2.67147117265996,-1.26723605786241,-0.410995602172227, -1.02510702934664,1.98409116241089,0.0439502493584124, 0.0610009456429445,-0.223670750812863,1.15902104167061 ); float3x3 XYZ = float3x3( 0.500303383543316,0.338097573222739,0.164589779545857, 0.257968894274758,0.676195259144706,0.0658358459823868, 0.0234517888692628,0.1126992737203,0.866839673124201 ); float DPXContrast = 0.1; float DPXGamma = 1.0; float RedCurve = DPXRed; float GreenCurve = DPXGreen; float BlueCurve = DPXBlue; float3 RGB_Curve = float3(DPXRed,DPXGreen,DPXBlue); float3 RGB_C = float3(DPXRedC,DPXGreenC,DPXBlueC); float3 B = InputColor.rgb; B = pow(B, 1.0/DPXGamma); B = B * (1.0 - DPXContrast) + (0.5 * DPXContrast); 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 = saturate(color); color = pow(color, 1.0/DPXColorGamma); float3 c0 = color * value; c0 = mul(XYZ, c0); float luma = dot(c0, float3(0.30, 0.59, 0.11)); //Use BT 709 instead? c0 = (1.0 - DPXSaturation) * luma + DPXSaturation * c0; c0 = mul(RGB, c0); InputColor.rgb = lerp(InputColor.rgb, c0, DPXBlend); return InputColor; } float3 LiftGammaGainPass( float3 colorInput ) { // -- Get input -- float3 color = colorInput.rgb; // -- Lift -- color = color * (1.5-0.5 * RGB_Lift) + 0.5 * RGB_Lift - 0.5; color = saturate(color); //isn't strictly necessary, but doesn't cost performance. // -- Gain -- color *= RGB_Gain; // -- Gamma -- colorInput.rgb = pow(color, 1.0 / RGB_Gamma); //Gamma // -- Return output -- //return (colorInput); return saturate(colorInput); } float3 TonemapPass( float3 colorInput ) { float3 color = colorInput.rgb; color = saturate(color - Defog * FogColor); // Defog color *= pow(2.0f, Exposure); // Exposure color = pow(color, Gamma); // Gamma -- roll into the first gamma correction in main.h ? float lum = dot(LumCoeff, color.rgb); float3 blend = lum.rrr; //dont use float3 float L = saturate( 10.0 * (lum - 0.45) ); float3 result1 = 2.0f * color.rgb * blend; float3 result2 = 1.0f - 2.0f * (1.0f - blend) * (1.0f - color.rgb); float3 newColor = lerp(result1, result2, L); float3 A2 = Bleach * color.rgb; //why use a float for A2 here and then multiply by color.rgb (a float3)? float3 mixRGB = A2 * newColor; color.rgb += ((1.0f - A2) * mixRGB); float3 middlegray = dot(color,(1.0/3.0)); //1fps slower than the original on nvidia, 2 fps faster on AMD float3 diffcolor = color - middlegray; //float 3 here colorInput.rgb = (color + diffcolor * Saturation)/(1+(diffcolor*Saturation)); //saturation return colorInput; } float3 VibrancePass( float3 colorInput ) { #define Vibrance_coeff float3(Vibrance_RGB_balance * Vibrance) float3 color = colorInput; //original input color float3 lumCoeff = float3(0.212656, 0.715158, 0.072186); //Values to calculate luma with float luma = dot(LumCoeff, color.rgb); //calculate luma (grey) float max_color = max(colorInput.r, max(colorInput.g,colorInput.b)); //Find the strongest color float min_color = min(colorInput.r, min(colorInput.g,colorInput.b)); //Find the weakest color float color_saturation = max_color - min_color; //The difference between the two is the saturation color.rgb = lerp(luma, color.rgb, (1.0 + (Vibrance_coeff * (1.0 - (sign(Vibrance_coeff) * color_saturation))))); //extrapolate between luma and original by 1 + (1-saturation) - current return color; //return the result } float3 CurvesPass( float3 colorInput ) { float Curves_contrast_blend = Curves_contrast; /*-----------------------------------------------------------. / Separation of Luma and Chroma / '-----------------------------------------------------------*/ // -- Calculate Luma and Chroma if needed -- #if Curves_mode != 2 //calculate luma (grey) float luma = dot(LumCoeff, colorInput.rgb); //calculate chroma float3 chroma = colorInput.rgb - luma; #endif // -- 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 #if Curves_mode == 2 float3 x = colorInput.rgb; //if the curve should be applied to both Luma and Chroma #elif Curves_mode == 1 float3 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 // Curves_mode == 0 float x = luma; //if the curve should be applied to Luma #endif /*-----------------------------------------------------------. / Contrast formulas / '-----------------------------------------------------------*/ // -- Curve 1 -- #if Curves_formula == 1 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; #endif // -- Curve 2 -- #if Curves_formula == 2 x = x - 0.5; x = ( x / (0.5 + abs(x)) ) + 0.5; //x = ( (x - 0.5) / (0.5 + abs(x-0.5)) ) + 0.5; #endif // -- Curve 3 -- #if Curves_formula == 3 //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 #endif // -- Curve 4 -- #if Curves_formula == 4 x = (1.0524 * exp(6.0 * x) - 1.05248) / (20.0855 + exp(6.0 * x)); //exp formula #endif // -- Curve 5 -- #if Curves_formula == 5 //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 Curves_contrast_blend = Curves_contrast * 2.0; //I multiply by two to give it a strength closer to the other curves. #endif // -- Curve 6 -- #if Curves_formula == 6 x = x*x*x*(x*(x*6.0 - 15.0) + 10.0); //Perlins smootherstep #endif // -- Curve 7 -- #if Curves_formula == 7 //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; #endif // -- Curve 8 -- #if Curves_formula == 8 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 #endif // -- Curve 9 -- #if Curves_formula == 9 x = -0.5 * (x*2.0-1.0) * (abs(x*2.0-1.0)-2.0) + 0.5; //parabola #endif // -- Curve 10 -- #if Curves_formula == 10 //Half-circles #if Curves_mode == 0 float xstep = step(x,0.5); float xstep_shift = (xstep - 0.5); float shifted_x = x + xstep_shift; #else float3 xstep = step(x,0.5); float3 xstep_shift = (xstep - 0.5); float3 shifted_x = x + xstep_shift; #endif 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 Curves_contrast_blend = Curves_contrast * 0.5; //I divide by two to give it a strength closer to the other curves. #endif // -- Curve 11 -- #if Curves_formula == 11 //Cubic catmull float a = 1.00; //control point 1 float b = 0.00; //start point float c = 1.00; //endpoint float d = 0.20; //control point 2 x = 0.5 * ((-a + 3*b -3*c + d)*x*x*x + (2*a -5*b + 4*c - d)*x*x + (-a+c)*x + 2*b); //A customizable cubic catmull-rom spline #endif // -- Curve 12 -- #if Curves_formula == 12 //Cubic Bezier spline float a = 0.00; //start point float b = 0.00; //control point 1 float c = 1.00; //control point 2 float d = 1.00; //endpoint float r = (1-x); float r2 = r*r; float r3 = r2 * r; float x2 = x*x; float x3 = x2*x; //x = dot(float4(a,b,c,d),float4(r3,3*r2*x,3*r*x2,x3)); //x = a * r*r*r + r * (3 * b * r * x + 3 * c * x*x) + d * x*x*x; //x = a*(1-x)*(1-x)*(1-x) +(1-x) * (3*b * (1-x) * x + 3 * c * x*x) + d * x*x*x; x = a*(1-x)*(1-x)*(1-x) + 3*b*(1-x)*(1-x)*x + 3*c*(1-x)*x*x + d*x*x*x; #endif // -- Curve 13 -- #if Curves_formula == 13 //Cubic Bezier spline - alternative implementation. float3 a = float3(0.00,0.00,0.00); //start point float3 b = float3(0.25,0.15,0.85); //control point 1 float3 c = float3(0.75,0.85,0.15); //control point 2 float3 d = float3(1.00,1.00,1.00); //endpoint float3 ab = lerp(a,b,x); // point between a and b float3 bc = lerp(b,c,x); // point between b and c float3 cd = lerp(c,d,x); // point between c and d float3 abbc = lerp(ab,bc,x); // point between ab and bc float3 bccd = lerp(bc,cd,x); // point between bc and cd float3 dest = lerp(abbc,bccd,x); // point on the bezier-curve x = dest; #endif // -- Curve 14 -- #if Curves_formula == 14 x = 1.0 / (1.0 + exp(-(x * 10.0 - 5.0))); //alternative exp formula #endif /*-----------------------------------------------------------. / Joining of Luma and Chroma / '-----------------------------------------------------------*/ #if Curves_mode == 2 //Both Luma and Chroma float3 color = x; //if the curve should be applied to both Luma and Chroma colorInput.rgb = lerp(colorInput.rgb, color, Curves_contrast_blend); //Blend by Curves_contrast #elif Curves_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, Curves_contrast_blend); //Blend by Curves_contrast #else // Curves_mode == 0 //Only Luma x = lerp(luma, x, Curves_contrast_blend); //Blend by Curves_contrast colorInput.rgb = x + chroma; //Luma + Chroma #endif //Return the result return colorInput; } float3 SepiaPass( float3 colorInput ) { float3 sepia = colorInput.rgb; // calculating amounts of input, grey and sepia colors to blend and combine float grey = dot(sepia, LumCoeff); sepia *= ColorTone; float3 blend2 = (grey * GreyPower) + (colorInput.rgb / (GreyPower + 1)); colorInput.rgb = lerp(blend2, sepia, SepiaPower); // returning the final color return colorInput; } float3 SkyrimTonemapPass( float3 color ) { float grayadaptation = dot(color.xyz, LumCoeff); #if (POSTPROCESS==1) color.xyz = color.xyz / (grayadaptation * EAdaptationMaxV1 + EAdaptationMinV1); float cgray = dot( color.xyz, LumCoeff); cgray = pow(cgray, EContrastV1); float3 poweredcolor = pow( abs(color.xyz), EColorSaturationV1); float newgray = dot(poweredcolor.xyz, LumCoeff); color.xyz = poweredcolor.xyz * cgray / (newgray + 0.0001); float3 luma = color.xyz; float lumamax = 300.0; color.xyz = ( color.xyz * (1.0 + color.xyz / lumamax)) / ( color.xyz + EToneMappingCurveV1); #endif #if (POSTPROCESS==2) color.xyz = color.xyz / (grayadaptation * EAdaptationMaxV2 + EAdaptationMinV2); float3 xncol = normalize( color.xyz); float3 scl = color.xyz / xncol.xyz; scl = pow(scl, EIntensityContrastV2); xncol.xyz = pow(xncol.xyz, EColorSaturationV2); color.xyz = scl*xncol.xyz; float lumamax = EToneMappingOversaturationV2; color.xyz = ( color.xyz * (1.0 + color.xyz / lumamax)) / ( color.xyz + EToneMappingCurveV2); color.xyz*=4; #endif #if (POSTPROCESS==3) color.xyz *= 35; float lumamax = EToneMappingOversaturationV3; color.xyz = ( color.xyz * (1.0 + color.xyz / lumamax)) / ( color.xyz + EToneMappingCurveV3); #endif #if (POSTPROCESS == 4) color.xyz = color.xyz / (grayadaptation * EAdaptationMaxV4 + EAdaptationMinV4); float Y = dot( color.xyz, float3(0.299, 0.587, 0.114)); //0.299 * R + 0.587 * G + 0.114 * B; float U = dot( color.xyz, float3(-0.14713, -0.28886, 0.436)); //-0.14713 * R - 0.28886 * G + 0.436 * B; float V = dot( color.xyz, float3(0.615, -0.51499, -0.10001)); //0.615 * R - 0.51499 * G - 0.10001 * B; Y = pow(Y, EBrightnessCurveV4); Y = Y * EBrightnessMultiplierV4; color.xyz = V * float3(1.13983, -0.58060, 0.0) + U * float3(0.0, -0.39465, 2.03211) + Y; color.xyz = max( color.xyz, 0.0); color.xyz = color.xyz / ( color.xyz + EBrightnessToneMappingCurveV4); #endif #if (POSTPROCESS == 5) float hnd = 1; float2 hndtweak = float2( 3.1 , 1.5 ); color.xyz *= lerp( hndtweak.x, hndtweak.y, hnd ); float3 xncol = normalize( color.xyz); float3 scl = color.xyz/xncol.xyz; scl = pow(scl, EIntensityContrastV5); xncol.xyz = pow(xncol.xyz, EColorSaturationV5); color.xyz = scl*xncol.xyz; color.xyz *= HCompensateSatV5; // compensate for darkening caused my EcolorSat above color.xyz = color.xyz / ( color.xyz + EToneMappingCurveV5); color.xyz *= 4; #endif #if (POSTPROCESS==6) //Postprocessing V6 by Kermles //tuned by the master himself for ME 1.4, thanks man!!! //hd6/ppv2/////////////////////////////////////////// float EIntensityContrastV6 = EIntensityContrastV6Day; float EColorSaturationV6 = EColorSaturationV6Day; float HCompensateSatV6 = HCompensateSatV6Day; float EToneMappingCurveV6 = EToneMappingCurveV6Day; float EBrightnessV6 = EBrightnessV6Day; float EToneMappingOversaturationV6 = EToneMappingOversaturationV6Day; float EAdaptationMaxV6 = EAdaptationMaxV6Day; float EAdaptationMinV6 = EAdaptationMinV6Day; float lumamax = EToneMappingOversaturationV6; //kermles//////////////////////////////////////////// float4 ncolor; //temporary variable for color adjustments //begin pp code///////////////////////////////////////////////// //ppv2 modified by kermles////////////////////////////////////// grayadaptation = clamp(grayadaptation, 0, 50); color.xyz *= EBrightnessV6; float3 xncol = normalize( color.xyz); float3 scl = color.xyz/xncol.xyz; scl = pow(saturate(scl), EIntensityContrastV6); xncol.xyz = pow(xncol.xyz, EColorSaturationV6); color.xyz = scl*xncol.xyz; color.xyz *= HCompensateSatV6; color.xyz = ( color.xyz * (1.0 + color.xyz/lumamax))/( color.xyz + EToneMappingCurveV6); color.xyz /= grayadaptation*EAdaptationMaxV6+EAdaptationMinV6; //rerun ppv2//////////////////////////////////////////////////// color.xyz *= EBrightnessV6; xncol = normalize( color.xyz); scl = color.xyz/xncol.xyz; scl = saturate(scl); scl = pow(scl, EIntensityContrastV6); xncol.xyz = pow(xncol.xyz, EColorSaturationV6); color.xyz = scl*xncol.xyz; color.xyz *= HCompensateSatV6; color.xyz = ( color.xyz * (1.0 + color.xyz/lumamax))/( color.xyz + EToneMappingCurveV6); #endif return color; } float3 MoodPass( float3 colorInput ) { float3 colInput = colorInput; float3 colMood = 1.0f; colMood.r = moodR; colMood.g = moodG; colMood.b = moodB; float fLum = ( colInput.r + colInput.g + colInput.b ) / 3; colMood = lerp(0, colMood, saturate(fLum * 2.0)); colMood = lerp(colMood, 1, saturate(fLum - 0.5) * 2.0); float3 colOutput = lerp(colInput, colMood, saturate(fLum * fRatio)); colorInput=max(0, colOutput); return colorInput; } float3 CrossPass(float3 color) { float2 CrossMatrix [3] = { float2 (1.03, 0.04), float2 (1.09, 0.01), float2 (0.78, 0.13), }; float3 image1 = color; float3 image2 = color; float gray = dot(float3(0.5,0.5,0.5), image1); image1 = lerp (gray, image1,CrossSaturation); image1 = lerp (0.35, image1,CrossContrast); image1 +=CrossBrightness; image2.r = image1.r * CrossMatrix[0].x + CrossMatrix[0].y; image2.g = image1.g * CrossMatrix[1].x + CrossMatrix[1].y; image2.b = image1.b * CrossMatrix[2].x + CrossMatrix[2].y; color = lerp(image1, image2, CrossAmount); return color; } float3 FilmPass(float3 B) { float3 G = B; float3 H = 0.01; B = saturate(B); B = pow(B, Linearization); B = lerp(H, B, Contrast); float A = dot(B.rgb, LumCoeff); float3 D = A; B = pow(B, 1.0 / BaseGamma); float a = FRedCurve; float b = FGreenCurve; float c = FBlueCurve; float d = BaseCurve; float y = 1.0 / (1.0 + exp(a / 2.0)); float z = 1.0 / (1.0 + exp(b / 2.0)); float w = 1.0 / (1.0 + exp(c / 2.0)); float v = 1.0 / (1.0 + exp(d / 2.0)); float3 C = B; D.r = (1.0 / (1.0 + exp(-a * (D.r - 0.5))) - y) / (1.0 - 2.0 * y); D.g = (1.0 / (1.0 + exp(-b * (D.g - 0.5))) - z) / (1.0 - 2.0 * z); D.b = (1.0 / (1.0 + exp(-c * (D.b - 0.5))) - w) / (1.0 - 2.0 * w); D = pow(D, 1.0 / EffectGamma); float3 Di = 1.0 - D; D = lerp(D, Di, FBleach); D.r = pow(abs(D.r), 1.0 / EffectGammaR); D.g = pow(abs(D.g), 1.0 / EffectGammaG); D.b = pow(abs(D.b), 1.0 / EffectGammaB); if (D.r < 0.5) C.r = (2.0 * D.r - 1.0) * (B.r - B.r * B.r) + B.r; else C.r = (2.0 * D.r - 1.0) * (sqrt(B.r) - B.r) + B.r; if (D.g < 0.5) C.g = (2.0 * D.g - 1.0) * (B.g - B.g * B.g) + B.g; else C.g = (2.0 * D.g - 1.0) * (sqrt(B.g) - B.g) + B.g; //if (AgainstAllAutority) if (D.b < 0.5) C.b = (2.0 * D.b - 1.0) * (B.b - B.b * B.b) + B.b; else C.b = (2.0 * D.b - 1.0) * (sqrt(B.b) - B.b) + B.b; float3 F = lerp(B, C, Strenght); F = (1.0 / (1.0 + exp(-d * (F - 0.5))) - v) / (1.0 - 2.0 * v); float r2R = 1.0 - FSaturation; float g2R = 0.0 + FSaturation; float b2R = 0.0 + FSaturation; float r2G = 0.0 + FSaturation; float g2G = (1.0 - Fade) - FSaturation; float b2G = (0.0 + Fade) + FSaturation; float r2B = 0.0 + FSaturation; float g2B = (0.0 + Fade) + FSaturation; float b2B = (1.0 - Fade) - FSaturation; float3 iF = F; F.r = (iF.r * r2R + iF.g * g2R + iF.b * b2R); F.g = (iF.r * r2G + iF.g * g2G + iF.b * b2G); F.b = (iF.r * r2B + iF.g * g2B + iF.b * b2B); float N = dot(F.rgb, LumCoeff); float3 Cn = F; if (N < 0.5) Cn = (2.0 * N - 1.0) * (F - F * F) + F; else Cn = (2.0 * N - 1.0) * (sqrt(F) - F) + F; Cn = pow(max(Cn,0), 1.0 / Linearization); float3 Fn = lerp(B, Cn, Strenght); return Fn; } float3 ReinhardToneMapping(in float3 x) { const float W = ReinhardWhitepoint; // Linear White Point Value const float K = ReinhardScale; // Scale // gamma space or not? return (1 + K * x / (W * W)) * x / (x + K); } float3 ReinhardLinearToneMapping(in float3 x) { const float W = ReinhardLinearWhitepoint; // Linear White Point Value const float L = ReinhardLinearPoint; // Linear point const float C = ReinhardLinearSlope; // Slope of the linear section const float K = (1 - L * C) / C; // Scale (fixed so that the derivatives of the Reinhard and linear functions are the same at x = L) float3 reinhard = L * C + (1 - L * C) * (1 + K * (x - L) / ((W - L) * (W - L))) * (x - L) / (x - L + K); // gamma space or not? return (x > L) ? reinhard : C * x; } float3 HaarmPeterDuikerFilmicToneMapping(in float3 x) { x = max( (float3)0.0f, x - 0.004f ); return pow( abs( ( x * ( 6.2f * x + 0.5f ) ) / ( x * ( 6.2f * x + 1.7f ) + 0.06 ) ), 2.2f ); } float3 CustomToneMapping(in float3 x) { const float A = 0.665f; const float B = 0.09f; const float C = 0.004f; const float D = 0.445f; const float E = 0.26f; const float F = 0.025f; const float G = 0.16f;//0.145f; const float H = 1.1844f;//1.15f; // gamma space or not? return (((x*(A*x+B)+C)/(x*(D*x+E)+F))-G) / H; } float3 ColorFilmicToneMapping(in float3 x) { // Filmic tone mapping const float3 A = float3(0.55f, 0.50f, 0.45f); // Shoulder strength const float3 B = float3(0.30f, 0.27f, 0.22f); // Linear strength const float3 C = float3(0.10f, 0.10f, 0.10f); // Linear angle const float3 D = float3(0.10f, 0.07f, 0.03f); // Toe strength const float3 E = float3(0.01f, 0.01f, 0.01f); // Toe Numerator const float3 F = float3(0.30f, 0.30f, 0.30f); // Toe Denominator const float3 W = float3(2.80f, 2.90f, 3.10f); // Linear White Point Value const float3 F_linearWhite = ((W*(A*W+C*B)+D*E)/(W*(A*W+B)+D*F))-(E/F); float3 F_linearColor = ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-(E/F); // gamma space or not? return pow(saturate(F_linearColor * 1.25 / F_linearWhite),1.25); } float3 ColormodPass( float3 color ) { color.xyz = (color.xyz - dot(color.xyz, 0.333)) * ColormodChroma + dot(color.xyz, 0.333); color.xyz = saturate(color.xyz); color.x = (pow(color.x, ColormodGammaR) - 0.5) * ColormodContrastR + 0.5 + ColormodBrightnessR; color.y = (pow(color.y, ColormodGammaG) - 0.5) * ColormodContrastG + 0.5 + ColormodBrightnessB; color.z = (pow(color.z, ColormodGammaB) - 0.5) * ColormodContrastB + 0.5 + ColormodBrightnessB; return color; } float3 SphericalPass( float3 color ) { float3 signedColor = color.rgb * 2.0 - 1.0; float3 sphericalColor = sqrt(1.0 - signedColor.rgb * signedColor.rgb); sphericalColor = sphericalColor * 0.5 + 0.5; sphericalColor *= color.rgb; color.rgb += sphericalColor.rgb * sphericalAmount; color.rgb *= 0.95; return color; } float3 SincityPass(float3 color) { float sinlumi = dot(color.rgb, float3(0.30f,0.59f,0.11f)); if(color.r > (color.g + 0.2f) && color.r > (color.b + 0.025f)) { color.rgb = float3(sinlumi, 0, 0)*1.5; } else { color.rgb = sinlumi; } return color; } float3 colorhuefx_prod80( float3 color ) { float3 fxcolor = saturate( color.xyz ); float greyVal = dot( fxcolor.xyz, LumCoeff.xyz ); float3 HueSat = Hue( fxcolor.xyz ); float colorHue = HueSat.x; float colorInt = HueSat.z - HueSat.y * 0.5; float colorSat = HueSat.y / ( 1.0 - abs( colorInt * 2.0 - 1.0 ) * 1e-10 ); //When color intensity not based on original saturation level if ( USE_COLORSAT == 0 ) colorSat = 1.0f; float hueMin_1 = hueMid - hueRange; float hueMax_1 = hueMid + hueRange; float hueMin_2 = 0.0f; float hueMax_2 = 0.0f; if ( hueMin_1 < 0.0 ) { hueMin_2 = 1.0f + hueMin_1; hueMax_2 = 1.0f + hueMid; if ( colorHue >= hueMin_1 && colorHue <= hueMid ) fxcolor.xyz = lerp( greyVal.xxx, fxcolor.xyz, smootherstep( hueMin_1, hueMid, colorHue ) * ( colorSat * satLimit )); else if ( colorHue >= hueMid && colorHue <= hueMax_1 ) fxcolor.xyz = lerp( greyVal.xxx, fxcolor.xyz, ( 1.0f - smootherstep( hueMid, hueMax_1, colorHue )) * ( colorSat * satLimit )); else if ( colorHue >= hueMin_2 && colorHue <= hueMax_2 ) fxcolor.xyz = lerp( greyVal.xxx, fxcolor.xyz, smootherstep( hueMin_2, hueMax_2, colorHue ) * ( colorSat * satLimit )); else fxcolor.xyz = greyVal.xxx; } else if ( hueMax_1 > 1.0 ) { hueMin_2 = 0.0f - ( 1.0f - hueMid ); hueMax_2 = hueMax_1 - 1.0f; if ( colorHue >= hueMin_1 && colorHue <= hueMid ) fxcolor.xyz = lerp( greyVal.xxx, fxcolor.xyz, smootherstep( hueMin_1, hueMid, colorHue ) * ( colorSat * satLimit )); else if ( colorHue >= hueMid && colorHue <= hueMax_1 ) fxcolor.xyz = lerp( greyVal.xxx, fxcolor.xyz, ( 1.0f - smootherstep( hueMid, hueMax_1, colorHue )) * ( colorSat * satLimit )); else if ( colorHue >= hueMin_2 && colorHue <= hueMax_2 ) fxcolor.xyz = lerp( greyVal.xxx, fxcolor.xyz, ( 1.0f - smootherstep( hueMin_2, hueMax_2, colorHue )) * ( colorSat * satLimit )); else fxcolor.xyz = greyVal.xxx; } else { if ( colorHue >= hueMin_1 && colorHue <= hueMid ) fxcolor.xyz = lerp( greyVal.xxx, fxcolor.xyz, smootherstep( hueMin_1, hueMid, colorHue ) * ( colorSat * satLimit )); else if ( colorHue > hueMid && colorHue <= hueMax_1 ) fxcolor.xyz = lerp( greyVal.xxx, fxcolor.xyz, ( 1.0f - smootherstep( hueMid, hueMax_1, colorHue )) * ( colorSat * satLimit )); else fxcolor.xyz = greyVal.xxx; } color.xyz = lerp( color.xyz, fxcolor.xyz, fxcolorMix ); return color.xyz; } float3 SharpPass( float3 colorInput, float2 tex, sampler colorsampler) { float3 blur_ori = tex2D(colorsampler, tex + float2(0.5 * PixelSize.x,-PixelSize.y * fSharpBias)).rgb*0.25; // South South East blur_ori += tex2D(colorsampler, tex + float2(fSharpBias * -PixelSize.x,0.5 * -PixelSize.y)).rgb*0.25; // West South West blur_ori += tex2D(colorsampler, tex + float2(fSharpBias * PixelSize.x,0.5 * PixelSize.y)).rgb*0.25; // East North East blur_ori += tex2D(colorsampler, tex + float2(0.5 * -PixelSize.x,PixelSize.y * fSharpBias)).rgb*0.25; // North North West float3 sharp = colorInput - blur_ori; float sharp_luma = dot(sharp, fSharpStrength); sharp_luma = clamp(sharp_luma, -fSharpClamp, fSharpClamp); float3 done = tex2D(colorsampler, tex).rgb + sharp_luma; colorInput = done; return colorInput; } float3 ExplosionPass( float3 colorInput, float2 tex, sampler colorsampler ) { // -- pseudo random number generator -- float2 sine_cosine; sincos(dot(tex, float2(12.9898,78.233)),sine_cosine.x,sine_cosine.y); sine_cosine = sine_cosine * 43758.5453 + tex; float2 noise = frac(sine_cosine); tex = (-fExplosionRadius * PixelSize) + tex; //Slightly faster this way because it can be calculated while we calculate noise. colorInput.rgb = tex2D(colorsampler, (2.0 * fExplosionRadius * PixelSize) * noise + tex).rgb; return colorInput; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Initializing pass which converts LDR image to HDR space // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float4 PS_ME_Init(VS_OUTPUT_POST IN) : COLOR { float mask = 1.0f; #if(USE_HUD_MASKING==1) mask = tex2D(SamplerMask, IN.txcoord.xy).x; #endif return tex2D(SamplerLDR, IN.txcoord.xy)*mask; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Ambient Occlusion // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float4 PS_ME_SSAO(VS_OUTPUT_POST IN) : COLOR { IN.txcoord.xy /= AO_TEXSCALE; if(IN.txcoord.x > 1.0 || IN.txcoord.y > 1.0) discard; //global variables float depth = tex2D(SamplerDepth, IN.txcoord.xy).x; float fSceneDepthP = GetLinearDepth(depth); #if( AO_SHARPNESS_DETECT == 1) float blurkey = fSceneDepthP; #else float blurkey = dot(GetNormalFromDepth(fSceneDepthP, IN.txcoord.xy).xyz,0.333)*0.1; #endif if(fSceneDepthP > min(0.9999,AO_FADE_END)) return float4(0.5,0.5,0.5,blurkey); float offsetScale = fSSAOSamplingRange/10000; float fSSAODepthClip = 10000000.0; float3 vRotation = tex2Dlod(SamplerNoise, float4(IN.txcoord.xy, 0, 0)).rgb - 0.5f; float3x3 matRotate; float hao = 1.0f / (1.0f + vRotation.z); matRotate._m00 = hao * vRotation.y * vRotation.y + vRotation.z; matRotate._m01 = -hao * vRotation.y * vRotation.x; matRotate._m02 = -vRotation.x; matRotate._m10 = -hao * vRotation.y * vRotation.x; matRotate._m11 = hao * vRotation.x * vRotation.x + vRotation.z; matRotate._m12 = -vRotation.y; matRotate._m20 = vRotation.x; matRotate._m21 = vRotation.y; matRotate._m22 = vRotation.z; float fOffsetScaleStep = 1.0f + 2.4f / iSSAOSamples; float fAccessibility = 0; int Sample_Scaled = iSSAOSamples; #if(SSAO_SmartSampling==1) if(fSceneDepthP > 0.5) Sample_Scaled=max(8,round(Sample_Scaled*0.5)); if(fSceneDepthP > 0.8) Sample_Scaled=max(8,round(Sample_Scaled*0.5)); #endif float fAtten = 5000.0/fSSAOSamplingRange/(1.0+fSceneDepthP*10.0); [loop] for (int i = 0 ; i < (Sample_Scaled / 8) ; i++) for (int x = -1 ; x <= 1 ; x += 2) for (int y = -1 ; y <= 1 ; y += 2) for (int z = -1 ; z <= 1 ; z += 2) { //Create offset vector float3 vOffset = normalize(float3(x, y, z)) * (offsetScale *= fOffsetScaleStep); //Rotate the offset vector float3 vRotatedOffset = mul(vOffset, matRotate); //Center pixel's coordinates in screen space float3 vSamplePos = float3(IN.txcoord.xy, fSceneDepthP); //Offset sample point vSamplePos += float3(vRotatedOffset.xy, vRotatedOffset.z * fSceneDepthP); //Read sample point depth float fSceneDepthS = GetLinearDepth(tex2Dlod(SamplerDepth, float4(vSamplePos.xy,0,0)).x); //Discard if depth equals max if (fSceneDepthS >= fSSAODepthClip) fAccessibility += 1.0f; else { //Compute accessibility factor float fDepthDist = abs(fSceneDepthP - fSceneDepthS); float fRangeIsInvalid = saturate(fDepthDist*fAtten); fAccessibility += lerp(fSceneDepthS > vSamplePos.z, 0.5f, fRangeIsInvalid); } } //Compute average accessibility fAccessibility = fAccessibility / Sample_Scaled; return float4(fAccessibility.xxx,blurkey); } float4 PS_ME_RayAO(VS_OUTPUT_POST IN) : COLOR { IN.txcoord.xy /= AO_TEXSCALE; if(IN.txcoord.x > 1.0 || IN.txcoord.y > 1.0) discard; float3 avOffsets [78] = { float3(0.2196607,0.9032637,0.2254677), float3(0.05916681,0.2201506,-0.1430302), float3(-0.4152246,0.1320857,0.7036734), float3(-0.3790807,0.1454145,0.100605), float3(0.3149606,-0.1294581,0.7044517), float3(-0.1108412,0.2162839,0.1336278), float3(0.658012,-0.4395972,-0.2919373), float3(0.5377914,0.3112189,0.426864), float3(-0.2752537,0.07625949,-0.1273409), float3(-0.1915639,-0.4973421,-0.3129629), float3(-0.2634767,0.5277923,-0.1107446), float3(0.8242752,0.02434147,0.06049098), float3(0.06262707,-0.2128643,-0.03671562), float3(-0.1795662,-0.3543862,0.07924347), float3(0.06039629,0.24629,0.4501176), float3(-0.7786345,-0.3814852,-0.2391262), float3(0.2792919,0.2487278,-0.05185341), float3(0.1841383,0.1696993,-0.8936281), float3(-0.3479781,0.4725766,-0.719685), float3(-0.1365018,-0.2513416,0.470937), float3(0.1280388,-0.563242,0.3419276), float3(-0.4800232,-0.1899473,0.2398808), float3(0.6389147,0.1191014,-0.5271206), float3(0.1932822,-0.3692099,-0.6060588), float3(-0.3465451,-0.1654651,-0.6746758), float3(0.2448421,-0.1610962,0.13289366), float3(0.2448421,0.9032637,0.24254677), float3(0.2196607,0.2201506,-0.18430302), float3(0.05916681,0.1320857,0.70036734), float3(-0.4152246,0.1454145,0.1800605), float3(-0.3790807,-0.1294581,0.78044517), float3(0.3149606,0.2162839,0.17336278), float3(-0.1108412,-0.4395972,-0.269619373), float3(0.658012,0.3112189,0.4267864), float3(0.5377914,0.07625949,-0.12773409), float3(-0.2752537,-0.4973421,-0.31629629), float3(-0.1915639,0.5277923,-0.17107446), float3(-0.2634767,0.02434147,0.086049098), float3(0.8242752,-0.2128643,-0.083671562), float3(0.06262707,-0.3543862,0.007924347), float3(-0.1795662,0.24629,0.44501176), float3(0.06039629,-0.3814852,-0.248391262), float3(-0.7786345,0.2487278,-0.065185341), float3(0.2792919,0.1696993,-0.84936281), float3(0.1841383,0.4725766,-0.7419685), float3(-0.3479781,-0.2513416,0.670937), float3(-0.1365018,-0.563242,0.36419276), float3(0.1280388,-0.1899473,0.23948808), float3(-0.4800232,0.1191014,-0.5271206), float3(0.6389147,-0.3692099,-0.5060588), float3(0.1932822,-0.1654651,-0.62746758), float3(-0.3465451,-0.1610962,0.4289366), float3(0.2448421,-0.1610962,0.2254677), float3(0.2196607,0.9032637,-0.1430302), float3(0.05916681,0.2201506,0.7036734), float3(-0.4152246,0.1320857,0.100605), float3(-0.3790807,0.3454145,0.7044517), float3(0.3149606,-0.4294581,0.1336278), float3(-0.1108412,0.3162839,-0.2919373), float3(0.658012,-0.2395972,0.426864), float3(0.5377914,0.33112189,-0.1273409), float3(-0.2752537,0.47625949,-0.3129629), float3(-0.1915639,-0.3973421,-0.1107446), float3(-0.2634767,0.2277923,0.06049098), float3(0.8242752,-0.3434147,-0.03671562), float3(0.06262707,-0.4128643,0.07924347), float3(-0.1795662,-0.3543862,0.4501176), float3(0.06039629,0.24629,-0.2391262), float3(-0.7786345,-0.3814852,-0.05185341), float3(0.2792919,0.4487278,-0.8936281), float3(0.1841383,0.3696993,-0.719685), float3(-0.3479781,0.2725766,0.470937), float3(-0.1365018,-0.5513416,0.3419276), float3(0.1280388,-0.163242,0.2398808), float3(-0.4800232,-0.3899473,-0.5271206), float3(0.6389147,0.3191014,-0.6060588), float3(0.1932822,-0.1692099,-0.6746758), float3(-0.3465451,-0.2654651,0.1289366) }; float2 vOutSum; float3 vRandom, vReflRay, vViewNormal; float fCurrDepth, fSampleDepth, fDepthDelta, fAO; float depth = tex2D(SamplerDepth, IN.txcoord.xy).x; fCurrDepth = GetLinearDepth(depth); #if( AO_SHARPNESS_DETECT == 1) float blurkey = fCurrDepth; #else float blurkey = dot(GetNormalFromDepth(fCurrDepth, IN.txcoord.xy).xyz,0.333)*0.1; #endif if(fCurrDepth>min(0.9999,AO_FADE_END)) return float4(1.0,1.0,1.0,blurkey); vViewNormal = GetNormalFromDepth(fCurrDepth, IN.txcoord.xy); vRandom = GetRandomVector(IN.txcoord); fAO = 0; for(int s = 0; s < iRayAOSamples; s++) { vReflRay = reflect(avOffsets[s], vRandom); float fFlip = sign(dot(vViewNormal,vReflRay)); vReflRay *= fFlip; float sD = fCurrDepth - (vReflRay.z * fRayAOSamplingRange); fSampleDepth = GetLinearDepth(tex2Dlod(SamplerDepth, float4(saturate(IN.txcoord.xy + (fRayAOSamplingRange * vReflRay.xy / fCurrDepth)),0,0)).x); fDepthDelta = saturate(sD - fSampleDepth); fDepthDelta *= 1-smoothstep(0,fRayAOMaxDepth,fDepthDelta); if ( fDepthDelta > fRayAOMinDepth && fDepthDelta < fRayAOMaxDepth) fAO += pow(1 - fDepthDelta, 2.5); } vOutSum.x = saturate(1 - (fAO / (float)iRayAOSamples) + fRayAOSamplingRange); return float4(vOutSum.xxx,blurkey); } float3 GetEyePosition(in float2 uv, in float eye_z) { uv = (uv * float2(2.0, -2.0) - float2(1.0, -1.0)); float3 pos = float3(uv * InvFocalLen * eye_z, eye_z); return pos; } float2 GetRandom2_10(in float2 uv) { float noiseX = (frac(sin(dot(uv, float2(12.9898,78.233) * 2.0)) * 43758.5453)); float noiseY = sqrt(1 - noiseX * noiseX); return float2(noiseX, noiseY); } float4 PS_ME_HBAO(VS_OUTPUT_POST IN) : COLOR { IN.txcoord.xy /= AO_TEXSCALE; if(IN.txcoord.x > 1.0 || IN.txcoord.y > 1.0) discard; float depth = GetLinearDepth(tex2D(SamplerDepth, IN.txcoord.xy).x); #if( AO_SHARPNESS_DETECT == 1) float blurkey = depth; #else float blurkey = dot(GetNormalFromDepth(depth, IN.txcoord.xy).xyz,0.333)*0.1; #endif if(depth > min(0.9999,AO_FADE_END)) return float4(1.0,1.0,1.0,blurkey); float2 sample_offset[8] = { float2(1, 0), float2(0.7071f, 0.7071f), float2(0, 1), float2(-0.7071f, 0.7071f), float2(-1, 0), float2(-0.7071f, -0.7071f), float2(0, -1), float2(0.7071f, -0.7071f) }; float3 pos = GetEyePosition(IN.txcoord.xy, depth); float3 dx = ddx(pos); float3 dy = ddy(pos); float3 norm = normalize(cross(dx,dy)); float sample_depth=0; float3 sample_pos=0; float ao=0; float s=0.0; float2 rand_vec = GetRandom2_10(IN.txcoord.xy); float2 sample_vec_divisor = InvFocalLen*depth/(fHBAOSamplingRange*float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT)); float2 sample_center = IN.txcoord.xy; for (int i = 0; i < 8; i++) { float theta,temp_theta,temp_ao,curr_ao = 0; float3 occlusion_vector = 0.0; float2 sample_vec = reflect(sample_offset[i], rand_vec); sample_vec /= sample_vec_divisor; float2 sample_coords = (sample_vec*float2(1,(float)BUFFER_WIDTH/(float)BUFFER_HEIGHT))/iHBAOSamples; for (int k = 1; k <= iHBAOSamples; k++) { sample_depth = GetLinearDepth(tex2Dlod(SamplerDepth, float4(sample_center + sample_coords*(k-0.5*(i%2)),0,0)).x); sample_pos = GetEyePosition(sample_center + sample_coords*(k-0.5*(i%2)), sample_depth); occlusion_vector = sample_pos - pos; temp_theta = dot( norm, normalize(occlusion_vector) ); if (temp_theta > theta) { theta = temp_theta; temp_ao = 1-sqrt(1 - theta*theta ); ao += (1/ (1 + fHBAOAttenuation * pow(length(occlusion_vector)/fHBAOSamplingRange*5000,2)) )*(temp_ao-curr_ao); curr_ao = temp_ao; } } s += 1; } ao /= max(0.00001,s); ao = 1.0-ao*fHBAOAmount; ao = clamp(ao,fHBAOClamp,1); return float4(ao.xxx, blurkey); } float tangent(float3 P, float3 S) { return (P.z - S.z) / length(S.xy - P.xy); } float3 uv_to_eye(float2 uv, float eye_z) { uv = uv * float2(2.0, -2.0) - float2(1.0, -1.0); // uv (0, 1) to (-1, 1) return float3(uv /* invFocalLength */ * eye_z, eye_z); // Position in view space } float3 fetch_eye_pos(float2 uv) { float z = GetLinearDepth(tex2Dlod(SamplerDepth, float4(uv, 0, 0)).x); // Single channel zbuffer texture return uv_to_eye(uv, z); } float3 min_diff(float3 P, float3 Pr, float3 Pl) { float3 V1 = Pr - P; float3 V2 = P - Pl; return (dot(V1,V1) < dot(V2,V2)) ? V1 : V2; } float Falloff(float r) { return 1.0f - fRayHBAO_Attenuation * r * r; } float2 snap_uv_offset(float2 uv) { return round(uv * float2(BUFFER_WIDTH, BUFFER_HEIGHT)) * float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); } float2 snap_uv_coord(float2 uv) { return uv - (frac(uv * float2(BUFFER_WIDTH, BUFFER_HEIGHT)) - 0.5f) * float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); } float tan_to_sin(float x) { return x / sqrt(1.0f + x*x); } float tangent(float3 T) { return -T.z / length(T.xy); } float2 rotate_direction(float2 Dir, float2 CosSin) { return float2(Dir.x * CosSin.x - Dir.y * CosSin.y, Dir.x * CosSin.y + Dir.y * CosSin.x); } float AccumulatedHorizonOcclusionHighQuality(float2 deltaUV, float2 uv0, float3 P, float numSteps, float randstep, float3 dPdu, float3 dPdv) { // Jitter starting point within the first sample distance float2 uv = (uv0 + deltaUV) + randstep * deltaUV; // Snap first sample uv and initialize horizon tangent float2 snapped_duv = snap_uv_offset(uv - uv0); float3 T = snapped_duv.xxx * dPdu + snapped_duv.yyy * dPdv; float tanH = tangent(T) + fRayHBAO_AngleBiasTan; float ao = 0; float h0 = 0; float3 occluderRadiance = 0; [loop] for(float j = 0; j < numSteps; ++j) { float2 snapped_uv = snap_uv_coord(uv); float3 S = fetch_eye_pos(snapped_uv); // next uv in image space. uv += deltaUV; // Ignore any samples outside the radius of influence float d2 = dot(S-P,S-P); [flatten] if (d2 < fRayHBAO_SampleRadius) { float tanS = tangent(P, S); [flatten] if (tanS > tanH) // Is this height is bigger than the bigger height of this direction so far then { // Compute tangent vector associated with snapped_uv float2 snapped_duv2 = snapped_uv - uv0; float3 T2 = snapped_duv2.xxx * dPdu + snapped_duv2.yyy * dPdv; //2 for faster compilation. float tanT = tangent(T2) + fRayHBAO_AngleBiasTan; // Compute AO between tangent T and sample S float sinS = tan_to_sin(tanS); float sinT = tan_to_sin(tanT); float r = sqrt(d2) / fRayHBAO_SampleRadius; float h = sinS - sinT; float falloff = Falloff(r); ao += falloff * (h - h0); h0 = h; // Update the current horizon angle tanH = tanS; } } } return ao; } float4 PS_ME_RayHBAO(VS_OUTPUT_POST IN) : COLOR { IN.txcoord.xy /= AO_TEXSCALE; if(IN.txcoord.x > 1.0 || IN.txcoord.y > 1.0) discard; float depth = GetLinearDepth(tex2D(SamplerDepth, IN.txcoord.xy).x); #if( AO_SHARPNESS_DETECT == 1) float blurkey = depth; #else float blurkey = dot(GetNormalFromDepth(depth, IN.txcoord.xy).xyz,0.333)*0.1; #endif if(depth > min(0.9999,AO_FADE_END)) return float4(1.0,1.0,1.0,blurkey); float3 P = uv_to_eye(IN.txcoord.xy, depth); float2 step_size = 0.5 * fRayHBAO_SampleRadius / P.z; // Project radius float numSteps = min (iRayHBAO_StepCount, min(step_size.x * BUFFER_WIDTH, step_size.y * BUFFER_HEIGHT)); step_size = step_size / ( numSteps + 1 ); float3 Pr, Pl, Pt, Pb; // Doesn't use normals Pr = fetch_eye_pos(IN.txcoord.xy + float2( BUFFER_RCP_WIDTH, 0)); Pl = fetch_eye_pos(IN.txcoord.xy + float2(-BUFFER_RCP_WIDTH, 0)); Pt = fetch_eye_pos(IN.txcoord.xy + float2(0, BUFFER_RCP_HEIGHT)); Pb = fetch_eye_pos(IN.txcoord.xy + float2(0, -BUFFER_RCP_HEIGHT)); // Screen-aligned basis for the tangent plane float3 dPdu = min_diff(P, Pr, Pl); float3 dPdv = min_diff(P, Pt, Pb) * (BUFFER_HEIGHT * BUFFER_RCP_WIDTH); // (cos(alpha),sin(alpha),jitter) float3 rand = tex2D(SamplerNoise, IN.txcoord.xy*5).rgb; float ao = 0; float alpha = 2.0f * 3.1416 / iRayHBAO_StepDirections; // High Quality for (int d = 0; d < iRayHBAO_StepDirections; d++) { float angle = alpha * d; float2 dir = float2(cos(angle), sin(angle)); float2 deltaUV = rotate_direction(dir, rand.xy) * step_size.xy; ao += AccumulatedHorizonOcclusionHighQuality(deltaUV, IN.txcoord.xy, P, numSteps, rand.z, dPdu, dPdv); } float result = saturate(1.0 - ao / iRayHBAO_StepDirections * 2.0); return float4(result.xxx,blurkey); } float3 GetSAO_CSPosition(float2 S, float z) { //hardcoded FoV. Don't ask me but even single degree differences HEAVILY affect visual result //to a point where AO isn't applied or it's way too strong or whatever. Better leave it. float nearZ = 0.1; float farZ = 100.0; float vFOV = 68.0; float4x4 matProjection = float4x4( 1.0f / (aspect * tan(vFOV / 2.0f)), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f / tan(vFOV / 2.0f), 0.0f, 0.0f, 0.0f, 0.0f, farZ / (farZ - nearZ), 1.0f, 0.0f, 0.0f, (farZ * nearZ) / (nearZ - farZ), 0.0f ); float4 projInfo; projInfo.x = -2.0f / ((float)BUFFER_WIDTH * matProjection._11); projInfo.y = -2.0f / ((float)BUFFER_HEIGHT * matProjection._22), projInfo.z = ((1.0f - matProjection._13) / matProjection._11) + projInfo.x * 0.5f; projInfo.w = ((1.0f + matProjection._23) / matProjection._22) + projInfo.y * 0.5f; return float3(( (S.xy * float2(BUFFER_WIDTH,BUFFER_HEIGHT)) * projInfo.xy + projInfo.zw) * z, z); } float2 GetSAO_TapLocation(int sampleNumber, float spinAngle, out float ssR) { uint ROTATIONS [98] = { 1, 1, 2, 3, 2, 5, 2, 3, 2, 3, 3, 5, 5, 3, 4, 7, 5, 5, 7, 9, 8, 5, 5, 7, 7, 7, 8, 5, 8, 11, 12, 7, 10, 13, 8, 11, 8, 7, 14, 11, 11, 13, 12, 13, 19, 17, 13, 11, 18, 19, 11, 11, 14, 17, 21, 15, 16, 17, 18, 13, 17, 11, 17, 19, 18, 25, 18, 19, 19, 29, 21, 19, 27, 31, 29, 21, 18, 17, 29, 31, 31, 23, 18, 25, 26, 25, 23, 19, 34, 19, 27, 21, 25, 39, 29, 17, 21, 27 }; uint NUM_SPIRAL_TURNS = ROTATIONS[iSAOSamples-1]; // Radius relative to ssR float alpha = float(sampleNumber + 0.5) * (1.0 / iSAOSamples); float angle = alpha * (NUM_SPIRAL_TURNS * 6.28) + spinAngle; ssR = alpha; float sin_v, cos_v; sincos(angle, sin_v, cos_v); return float2(cos_v, sin_v); } float GetSAO_CurveDepth(float depth) { return 202.0 / (-99.0 * depth + 101.0); } float3 GetSAO_Position(float2 ssPosition) { float3 Position; Position.z = GetSAO_CurveDepth(tex2Dlod(SamplerDepth, float4(ssPosition.xy,0,0)).x); Position = GetSAO_CSPosition(ssPosition, Position.z); return Position; } float3 GetSAO_OffsetPosition(float2 ssC, float2 unitOffset, float ssR) { float2 ssP = ssR*unitOffset + ssC; float3 P; P.z = GetSAO_CurveDepth(tex2Dlod(SamplerDepth, float4(ssP.xy,0,0)).x); P = GetSAO_CSPosition(ssP, P.z); return P; } float GetSAO_SampleAO(in float2 ssC, in float3 C, in float3 n_C, in float ssDiskRadius, in int tapIndex, in float randomPatternRotationAngle) { float ssR; float2 unitOffset = GetSAO_TapLocation(tapIndex, randomPatternRotationAngle, ssR); ssR *= ssDiskRadius; float3 Q = GetSAO_OffsetPosition(ssC, unitOffset, ssR); float3 v = Q - C; float vv = dot(v, v); float vn = dot(v, n_C); float f = max(1.0 - vv * (1.0 / fSAORadius), 0.0); return f * max((vn - fSAOBias) * rsqrt( vv), 0.0); } float4 PS_ME_SAO(VS_OUTPUT_POST IN) : COLOR { IN.txcoord.xy /= AO_TEXSCALE; if(IN.txcoord.x > 1.0 || IN.txcoord.y > 1.0) discard; float depth = GetLinearDepth(tex2D(SamplerDepth, IN.txcoord.xy).x); #if( AO_SHARPNESS_DETECT == 1) float blurkey = depth; #else float blurkey = dot(GetNormalFromDepth(depth, IN.txcoord.xy).xyz,0.333)*0.1; #endif if(depth > min(0.9999,AO_FADE_END)) return float4(1.0,1.0,1.0,blurkey); float3 ssPosition = GetSAO_Position(IN.txcoord.xy); float rotAngle = frac(sin(IN.txcoord.xy.x + IN.txcoord.xy.y * 543.31) * 493013.0) * 10.0; float3 ssNormals = normalize(cross(normalize(ddy(ssPosition)), normalize(ddx(ssPosition)))); float ssDiskRadius = fSAORadius / max(ssPosition.z,0.1f); float sum = 0.0; [unroll] for (int i = 0; i < iSAOSamples; ++i) { sum += GetSAO_SampleAO(IN.txcoord.xy, ssPosition, ssNormals, ssDiskRadius, i, rotAngle); } sum /= pow(fSAORadius,6.0); float A = pow(max(0.0, 1.0 - sqrt(sum * (3.0 / iSAOSamples))), fSAOIntensity); A = (pow(A, 0.2) + 1.2 * A*A*A*A) / 2.2; float ao = lerp(1.0, A, fSAOClamp); return float4(ao.xxx,blurkey); } float4 PS_ME_AOBlurV(VS_OUTPUT_POST IN) : COLOR { //It's better to do this here, upscaling must produce artifacts and upscale-> blur is better than blur -> upscale //besides: code is easier an I'm very lazy :P IN.txcoord.xy *= AO_TEXSCALE; float sum,totalweight=0; float4 base = tex2D(SamplerOcclusion1, IN.txcoord.xy), temp=0; [loop] for (int r = -AO_BLUR_STEPS; r <= AO_BLUR_STEPS; ++r) { float2 axis = float2(0.0, 1.0); temp = tex2D(SamplerOcclusion1, IN.txcoord.xy + axis * PixelSize * r); float weight = AO_BLUR_STEPS-abs(r); weight *= max(0.0, 1.0 - (1000.0 * AO_SHARPNESS) * abs(temp.w - base.w)); sum += temp.x * weight; totalweight += weight; } return float4(sum / (totalweight+0.0001),0,0,base.w); } float4 PS_ME_AOBlurH(VS_OUTPUT_POST IN) : COLOR { float sum,totalweight=0; float4 base = tex2D(SamplerOcclusion2, IN.txcoord.xy), temp=0; [loop] for (int r = -AO_BLUR_STEPS; r <= AO_BLUR_STEPS; ++r) { float2 axis = float2(1.0, 0.0); temp = tex2D(SamplerOcclusion2, IN.txcoord.xy + axis * PixelSize * r); float weight = AO_BLUR_STEPS-abs(r); weight *= max(0.0, 1.0 - (1000.0 * AO_SHARPNESS) * abs(temp.w - base.w)); sum += temp.x * weight; totalweight += weight; } return float4(sum / (totalweight+0.0001),0,0,base.w); } float4 PS_ME_AOCombine(VS_OUTPUT_POST IN) : COLOR { float4 color = tex2D(SamplerHDR1, IN.txcoord.xy); float ao = tex2D(SamplerOcclusion1, IN.txcoord.xy).x; #if( AO_METHOD == 1) //SSAO ao -= 0.5; if(ao < 0) ao *= fSSAODarkeningAmount; if(ao > 0) ao *= fSSAOBrighteningAmount; ao = 2 * saturate(ao+0.5); #endif #if( AO_METHOD == 2) ao = pow(ao, fRayAOPower); #endif #if( AO_DEBUG == 1) #if(AO_METHOD == 1) ao *= 0.5; #endif return ao; #endif #if(AO_LUMINANCE_CONSIDERATION == 1) float origlum = dot(color.xyz, 0.333); float aomult = smoothstep(AO_LUMINANCE_LOWER, AO_LUMINANCE_UPPER, origlum); ao = lerp(ao, 1.0, aomult); #endif float depth = GetLinearDepth(tex2D(SamplerDepth, IN.txcoord.xy).x); ao = lerp(ao,1.0,smoothstep(AO_FADE_START,AO_FADE_END,depth)); color.xyz *= ao; return color; } float4 PS_ME_SSGI(VS_OUTPUT_POST IN) : COLOR { IN.txcoord.xy /= AO_TEXSCALE; if(IN.txcoord.x > 1.0 || IN.txcoord.y > 1.0) discard; float depth = tex2D(SamplerDepth, IN.txcoord.xy).x; depth = GetLinearDepth(depth); if(depth > min(0.9999,AO_FADE_END)) return float4(0.0,0.0,0.0,1.0); float giClamp = 0.0; float2 sample_offset[24] = { float2(-0.1376476f, 0.2842022f ),float2(-0.626618f , 0.4594115f ), float2(-0.8903138f, -0.05865424f),float2( 0.2871419f, 0.8511679f ), float2(-0.1525251f, -0.3870117f ),float2( 0.6978705f, -0.2176773f ), float2( 0.7343006f, 0.3774331f ),float2( 0.1408805f, -0.88915f ), float2(-0.6642616f, -0.543601f ),float2(-0.324815f, -0.093939f ), float2(-0.1208579f , 0.9152063f ),float2(-0.4528152f, -0.9659424f ), float2(-0.6059740f, 0.7719080f ),float2(-0.6886246f, -0.5380305f ), float2( 0.5380307f, -0.2176773f ),float2( 0.7343006f, 0.9999345f ), float2(-0.9976073f, -0.7969264f ),float2(-0.5775355f, 0.2842022f ), float2(-0.626618f , 0.9115176f ),float2(-0.29818942f, -0.0865424f), float2( 0.9161239f, 0.8511679f ),float2(-0.1525251f, -0.07103951f ), float2( 0.7022788f, -0.823825f ),float2(0.60250657f, 0.64525909f ) }; float sample_radius[24] = { 0.5162497,0.2443335, 0.1014819,0.1574599, 0.6538922,0.5637644, 0.6347278,0.2467654, 0.5642318,0.0035689, 0.6384532,0.3956547, 0.7049623,0.3482861, 0.7484038,0.2304858, 0.0043161,0.5423726, 0.5025704,0.4066662, 0.2654198,0.8865175, 0.9505567,0.9936577 }; float3 pos = GetEyePosition(IN.txcoord.xy, depth); float3 dx = ddx(pos); float3 dy = ddy(pos); float3 norm = normalize(cross(dx, dy)); norm.y *= -1; float sample_depth; float4 gi = float4(0, 0, 0, 0); float is = 0, as = 0; float rangeZ = 5000; float2 rand_vec = GetRandom2_10(IN.txcoord.xy); float2 rand_vec2 = GetRandom2_10(-IN.txcoord.xy); float2 sample_vec_divisor = InvFocalLen * depth / (fSSGISamplingRange * PixelSize.xy); float2 sample_center = IN.txcoord.xy + norm.xy / sample_vec_divisor * float2(1, aspect); float ii_sample_center_depth = depth * rangeZ + norm.z * fSSGISamplingRange * 20; float ao_sample_center_depth = depth * rangeZ + norm.z * fSSGISamplingRange * 5; [fastopt] for (int i = 0; i < iSSGISamples; i++) { float2 sample_vec = reflect(sample_offset[i], rand_vec) / sample_vec_divisor; float2 sample_coords = sample_center + sample_vec * float2(1, aspect); float sample_depth = rangeZ * GetLinearDepth(tex2Dlod(SamplerDepth,float4(sample_coords.xy,0,0)).x); float ii_curr_sample_radius = sample_radius[i] * fSSGISamplingRange * 20; float ao_curr_sample_radius = sample_radius[i] * fSSGISamplingRange * 5; gi.a += clamp(0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth, 2 * ao_curr_sample_radius); gi.a -= clamp(0, ao_sample_center_depth + ao_curr_sample_radius - sample_depth - fSSGIModelThickness, 2 * ao_curr_sample_radius); if ((sample_depth < ii_sample_center_depth + ii_curr_sample_radius) && (sample_depth > ii_sample_center_depth - ii_curr_sample_radius)) { float3 sample_pos = GetEyePosition(sample_coords, sample_depth); float3 unit_vector = normalize(pos - sample_pos); gi.rgb += tex2Dlod(SamplerLDR, float4(sample_coords,0,0)).rgb; } is += 1.0f; as += 2.0f * ao_curr_sample_radius; } gi.rgb /= is * 5.0f; gi.a /= as; gi.rgb = 0.0 + gi.rgb * fSSGIIlluminationMult; gi.a = 1.0 - gi.a * fSSGIOcclusionMult; gi.rgb = lerp(dot(gi.rgb, 0.333), gi.rgb, fSSGISaturation); return gi; } float4 PS_ME_GIBlurV(VS_OUTPUT_POST IN) : COLOR { IN.txcoord.xy *= AO_TEXSCALE; float4 sum=0; float totalweight=0; float4 base = tex2D(SamplerOcclusion1, IN.txcoord.xy), temp = 0; float depth = GetLinearDepth(tex2Dlod(SamplerDepth, float4(IN.txcoord.xy,0,0)).x); #if( AO_SHARPNESS_DETECT == 1) float blurkey = depth; #else float blurkey = dot(GetNormalFromDepth(depth, IN.txcoord.xy).xyz,0.333)*0.1; #endif [loop] for (int r = -AO_BLUR_STEPS; r <= AO_BLUR_STEPS; ++r) { float2 axis = float2(0, 1); temp = tex2D(SamplerOcclusion1, IN.txcoord.xy + axis * PixelSize * r); float tempdepth = GetLinearDepth(tex2Dlod(SamplerDepth, float4(IN.txcoord.xy + axis * PixelSize * r,0,0)).x); #if( AO_SHARPNESS_DETECT == 1) float tempkey = tempdepth; #else float tempkey = dot(GetNormalFromDepth(tempdepth, IN.txcoord.xy + axis * PixelSize * r).xyz,0.333)*0.1; #endif float weight = AO_BLUR_STEPS-abs(r); weight *= max(0.0, 1.0 - (1000.0 * AO_SHARPNESS) * abs(tempkey - blurkey)); sum += temp * weight; totalweight += weight; } return sum / (totalweight+0.0001); } float4 PS_ME_GIBlurH(VS_OUTPUT_POST IN) : COLOR { float4 sum=0; float totalweight=0; float4 base = tex2D(SamplerOcclusion2, IN.txcoord.xy), temp = 0; float depth = GetLinearDepth(tex2Dlod(SamplerDepth, float4(IN.txcoord.xy,0,0)).x); #if( AO_SHARPNESS_DETECT == 1) float blurkey = depth; #else float blurkey = dot(GetNormalFromDepth(depth, IN.txcoord.xy).xyz,0.333)*0.1; #endif [loop] for (int r = -AO_BLUR_STEPS; r <= AO_BLUR_STEPS; ++r) { float2 axis = float2(1, 0); temp = tex2D(SamplerOcclusion2, IN.txcoord.xy + axis * PixelSize * r); float tempdepth = GetLinearDepth(tex2Dlod(SamplerDepth, float4(IN.txcoord.xy + axis * PixelSize * r,0,0)).x); #if( AO_SHARPNESS_DETECT == 1) float tempkey = tempdepth; #else float tempkey = dot(GetNormalFromDepth(tempdepth, IN.txcoord.xy + axis * PixelSize * r).xyz,0.333)*0.1; #endif float weight = AO_BLUR_STEPS-abs(r); weight *= max(0.0, 1.0 - (1000.0 * AO_SHARPNESS) * abs(tempkey - blurkey)); sum += temp * weight; totalweight += weight; } return sum / (totalweight+0.0001); } float4 PS_ME_GICombine(VS_OUTPUT_POST IN) : COLOR { float4 color = tex2D(SamplerHDR1, IN.txcoord.xy); float4 gi = tex2D(SamplerOcclusion1, IN.txcoord.xy); #if( AO_DEBUG == 1) return gi.wwww; //AO #endif #if( AO_DEBUG == 2) return gi.xyzz; //GI color #endif #if(AO_LUMINANCE_CONSIDERATION == 1) float origlum = dot(color.xyz, 0.333); float aomult = smoothstep(AO_LUMINANCE_LOWER, AO_LUMINANCE_UPPER, origlum); gi.w = lerp(gi.w, 1.0, aomult); gi.xyz = lerp(gi.xyz,0.0, aomult); #endif float depth = GetLinearDepth(tex2D(SamplerDepth, IN.txcoord.xy).x); gi.xyz = lerp(gi.xyz,0.0,smoothstep(AO_FADE_START,AO_FADE_END,depth)); gi.w = lerp(gi.w,1.0,smoothstep(AO_FADE_START,AO_FADE_END,depth)); color.xyz = (color.xyz+gi.xyz)*gi.w; return color; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Blurring/DOF/TiltShift // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float GetFocalDepth(float2 focalpoint) { float depthsum = 0; float fcRadius = 0.00; for(int r=0;r<6;r++) { float t = (float)r; t *= 3.1415*2/6; float2 coord = float2(cos(t),sin(t)); coord.y *= ScreenSize.z; coord *= fcRadius; float depth = GetLinearDepth(tex2Dlod(SamplerDepth,float4(coord+focalpoint,0,0)).x); depthsum+=depth; } depthsum = depthsum/6; #if(DOF_MANUALFOCUS == 1) depthsum = DOF_MANUALFOCUSDEPTH; #endif return depthsum; } float4 PS_ME_CoC(VS_OUTPUT_POST IN) : COLOR //schreibt nach HDR2 { float scenedepth = GetLinearDepth(tex2D(SamplerDepth, IN.txcoord.xy).x); float scenefocus = GetFocalDepth(DOF_FOCUSPOINT); float depthdiff = abs(scenedepth-scenefocus); depthdiff = (scenedepth < scenefocus) ? pow(depthdiff, DOF_NEARBLURCURVE) : depthdiff; depthdiff = (scenedepth > scenefocus) ? pow(depthdiff, DOF_FARBLURCURVE) : depthdiff; float mask = 1.0f; #if(USE_HUD_MASKING == 1) mask = tex2D(SamplerMask, IN.txcoord.xy).x; #endif return saturate(float4(depthdiff,scenedepth,scenefocus,0))*mask; } //RING DOF float4 GetColorDOF(sampler tex, float2 coords,float blur) //processing the sample { float4 colDF = float4(1,1,1,1); colDF.x = tex2Dlod(tex,float4(coords + float2(0.0,1.0)*fRingDOFFringe*blur,0,0)).x; colDF.y = tex2Dlod(tex,float4(coords + float2(-0.866,-0.5)*fRingDOFFringe*blur,0,0)).y; colDF.z = tex2Dlod(tex,float4(coords + float2(0.866,-0.5)*fRingDOFFringe*blur,0,0)).z; return colDF; } float4 GetDOF(sampler tex, float2 coords, float blur) //processing the sample { float4 colDF = tex2Dlod(tex,float4(coords,0,0)); float lum = dot(colDF.xyz,LumCoeff); float thresh = max((lum-fRingDOFThreshold)*fRingDOFGain, 0.0); float3 nullcol = float3(0,0,0); colDF.xyz +=max(0,lerp(nullcol.xyz,colDF.xyz,thresh*blur)); return colDF; } float4 PS_ME_RingDOF1(VS_OUTPUT_POST IN) : COLOR { float3 origCoC = tex2D(SamplerCoC, IN.txcoord.xy).xyz; float2 discRadius = DOF_BLURRADIUS*PixelSize.xy*origCoC.x/iRingDOFRings; return GetColorDOF(SamplerHDR2,IN.txcoord.xy, discRadius.x); } float4 PS_ME_RingDOF2(VS_OUTPUT_POST IN) : COLOR { float CoC = tex2D(SamplerCoC, IN.txcoord.xy).x; float2 discRadius = DOF_BLURRADIUS*PixelSize.xy*CoC/iRingDOFRings; float4 col = tex2D(SamplerHDR1, IN.txcoord.xy); if(discRadius.x/PixelSize.x > 0.25) //some optimization thingy { float s = 1.0; int ringsamples; float3 origCoC = tex2D(SamplerCoC, IN.txcoord.xy).xyz; [loop] for (int g = 1; g <= iRingDOFRings; g += 1) { ringsamples = g * iRingDOFSamples; [loop] for (int j = 0 ; j < ringsamples ; j += 1) { float step = PI*2.0 / ringsamples; float2 sampleoffset = discRadius.xy * float2(cos(j*step)*g, sin(j*step)*g); float3 sampleCoC = tex2Dlod(SamplerCoC, float4(IN.txcoord.xy + sampleoffset,0,0)).xyz; if(origCoC.y>origCoC.z && sampleCoC.x<CoC) sampleoffset = sampleoffset/CoC*sampleCoC.x; col.xyz += GetDOF(SamplerHDR1,IN.txcoord.xy + sampleoffset,CoC).xyz*lerp(1.0,g/iRingDOFRings,fRingDOFBias); s += 1.0*lerp(1.0,g/iRingDOFRings,fRingDOFBias); } } col = col/s; //divide by sample count } return col; } //MAGIC DOF float4 PS_ME_MagicDOF1(VS_OUTPUT_POST IN) : COLOR { float4 res,tapres; float totalweight=0; res = tex2D(SamplerHDR2, IN.txcoord.xy); float3 origCoC = tex2D(SamplerCoC, IN.txcoord.xy).xyz; float2 discRadius = origCoC.x*PixelSize.xy*DOF_BLURRADIUS/iMagicDOFBlurQuality; int passnum = iMagicDOFBlurQuality; //Wilham Anggowo please keep your Fingers from this shader, I don't want to see it in ENB! res.xyz = 0; [loop] for (int i = -iMagicDOFBlurQuality; i <= iMagicDOFBlurQuality; ++i) { float2 tapoffset = float2((float)i,0)*discRadius.xy; float3 sampleCoC = tex2Dlod(SamplerCoC, float4(IN.txcoord.xy + tapoffset,0,0)).xyz; if(origCoC.y>origCoC.z && sampleCoC.x<origCoC.x) tapoffset = tapoffset/origCoC.x*sampleCoC.x; tapres = tex2Dlod(SamplerHDR2, float4(IN.txcoord.xy+tapoffset,0,0)); res.xyz += tapres.xyz; totalweight+=1; } res.xyz /= totalweight; return float4(res.xyz,1); } float4 PS_ME_MagicDOF2(VS_OUTPUT_POST IN) : COLOR { float4 res,tapres1,tapres2; float totalweight=0; res = tex2D(SamplerHDR1, IN.txcoord.xy); float3 origcolor = res.xyz; float3 origCoC = tex2D(SamplerCoC, IN.txcoord.xy).xyz; float2 discRadius = origCoC.x*PixelSize.xy*DOF_BLURRADIUS/iMagicDOFBlurQuality; int passnum = iMagicDOFBlurQuality; int lodlevel = clamp(round(discRadius.x/6),0,3); res.xyz = 0; [loop] for (int i = -iMagicDOFBlurQuality; i <= iMagicDOFBlurQuality; ++i) { float2 tapoffset1 = float2((float)i*discRadius.x*0.5,(float)i*discRadius.y*0.5*tan(60*PIOVER180)); float2 tapoffset2 = float2(-tapoffset1.x,tapoffset1.y); float3 sampleCoC1 = tex2Dlod(SamplerCoC, float4(IN.txcoord.xy + tapoffset1,0,0)).xyz; float3 sampleCoC2 = tex2Dlod(SamplerCoC, float4(IN.txcoord.xy + tapoffset2,0,0)).xyz; if(origCoC.y>origCoC.z && sampleCoC1.x<origCoC.x) tapoffset1 = tapoffset1/origCoC.x*sampleCoC1.x; //never ask why I cam up with this. It works. Better than any masking I found but still not flawless. if(origCoC.y>origCoC.z && sampleCoC2.x<origCoC.x) tapoffset2 = tapoffset2/origCoC.x*sampleCoC2.x; tapres1 = tex2Dlod(SamplerHDR1, float4(IN.txcoord.xy+tapoffset1,0,lodlevel)); tapres2 = tex2Dlod(SamplerHDR1, float4(IN.txcoord.xy+tapoffset2,0,lodlevel)); totalweight += 1; res.xyz += pow(min(tapres1.xyz, tapres2.xyz),fMagicDOFColorCurve); } res.xyz /= totalweight; res.xyz = saturate(pow(saturate(res.xyz), 1/fMagicDOFColorCurve)); return res; } //GP65CJ042 DOF float4 PS_ME_GPDOF1(VS_OUTPUT_POST IN) : COLOR { float4 res=tex2D(SamplerHDR2, IN.txcoord.xy); float4 origcolor=0; float3 origCoC = tex2D(SamplerCoC, IN.txcoord.xy).xyz; float2 discRadius = DOF_BLURRADIUS*PixelSize.xy*max(0,origCoC.x-0.1);//optimization to clean focus areas a bit float3 distortion=float3(-1.0, 0.0, 1.0); distortion*=fGPDOFChromaAmount; origcolor=tex2D(SamplerHDR2, IN.txcoord.xy + discRadius.xy*distortion.x); origcolor.w=smoothstep(0.0, origCoC.y, origcolor.w); res.x=lerp(res.x, origcolor.x, origcolor.w); origcolor=tex2D(SamplerHDR2, IN.txcoord.xy + discRadius.xy*distortion.z); origcolor.w=smoothstep(0.0, origCoC.y, origcolor.w); res.z=lerp(res.z, origcolor.z, origcolor.w); return res; } float4 PS_ME_GPDOF2(VS_OUTPUT_POST IN) : COLOR { float4 res; float4 origcolor=tex2D(SamplerHDR1, IN.txcoord.xy); float3 origCoC = tex2D(SamplerCoC, IN.txcoord.xy).xyz; float2 discRadius = origCoC.x*DOF_BLURRADIUS*PixelSize.xy; res.xyz=origcolor.xyz; res.w=dot(res.xyz, 0.3333); res.w=max((res.w - fGPDOFBrightnessThreshold) * fGPDOFBrightnessMultiplier, 0.0); res.xyz*=(1.0 + res.w*origCoC.x); res.xyz*=lerp(1.0,0.0,fGPDOFBias); res.w=1.0; int sampleCycle=0; int sampleCycleCounter=0; int sampleCounterInCycle=0; #if ( bGPDOFPolygonalBokeh == 1) float basedAngle=360.0 / iGPDOFPolygonCount; float2 currentVertex; float2 nextVertex; int dofTaps=iGPDOFQuality * (iGPDOFQuality + 1) * iGPDOFPolygonCount / 2.0; #else int dofTaps=iGPDOFQuality * (iGPDOFQuality + 1) * 4; #endif for(int i=0; i < dofTaps; i++) { //dumb step incoming bool dothatstep=0; if(sampleCounterInCycle==0) dothatstep=1; if(sampleCycle!=0) { if(sampleCounterInCycle % sampleCycle == 0) dothatstep=1; } //until here //ask yourself why so complicated? if(sampleCounterInCycle % sampleCycle == 0 ) gives warnings when sampleCycle=0 //but it can only be 0 when sampleCounterInCycle is also 0 so it essentially is no division through 0 even if //the compiler believes it, it's 0/0 actually but without disabling shader optimizations this is the only way to workaround that. if(dothatstep==1) { sampleCounterInCycle=0; sampleCycleCounter++; #if ( bGPDOFPolygonalBokeh == 1) sampleCycle+=iGPDOFPolygonCount; currentVertex.xy=float2(1.0 , 0.0); sincos(basedAngle* 0.017453292, nextVertex.y, nextVertex.x); #else sampleCycle+=8; #endif } sampleCounterInCycle++; #if (bGPDOFPolygonalBokeh==1) float sampleAngle=basedAngle / float(sampleCycleCounter) * sampleCounterInCycle; float remainAngle=frac(sampleAngle / basedAngle) * basedAngle; if(remainAngle < 0.000001) { currentVertex=nextVertex; sincos((sampleAngle + basedAngle) * 0.017453292, nextVertex.y, nextVertex.x); } float2 sampleOffset=lerp(currentVertex.xy, nextVertex.xy, remainAngle / basedAngle); #else float sampleAngle=0.78539816 / float(sampleCycleCounter) * sampleCounterInCycle; float2 sampleOffset; sincos(sampleAngle, sampleOffset.y, sampleOffset.x); #endif sampleOffset*=sampleCycleCounter / float(iGPDOFQuality); sampleOffset*=discRadius; float3 sampleCoC = tex2Dlod(SamplerCoC, float4(IN.txcoord.xy+sampleOffset.xy,0,0)).xyz; if(origCoC.y>origCoC.z && sampleCoC.x<origCoC.x) sampleOffset = sampleOffset/origCoC.x*sampleCoC.x; float4 tap=tex2Dlod(SamplerHDR1, float4(IN.txcoord.xy+sampleOffset.xy,0,0)); tap.w=dot(tap.xyz, 0.3333); float brightMultipiler=max((tap.w - fGPDOFBrightnessThreshold) * fGPDOFBrightnessMultiplier, 0.0); tap.xyz*=(1.0 + brightMultipiler*origCoC.x); //res.w+=1.0 + fGPDOFBias * pow(float(sampleCycleCounter)/float(iGPDOFQuality), fGPDOFBiasCurve); float curvemult = lerp(1.0,pow(float(sampleCycleCounter)/float(iGPDOFQuality), fGPDOFBiasCurve),fGPDOFBias); res.xyz += tap.xyz*curvemult; res.w += curvemult; } res.xyz /= res.w; return res; } //MATSO DOF float4 GetMatsoDOFCA(sampler col, float2 tex, float CoC) { float3 chroma = pow(float3(0.5, 1.0, 1.5), fMatsoDOFChromaPow * CoC); float2 tr = ((2.0 * tex - 1.0) * chroma.r) * 0.5 + 0.5; float2 tg = ((2.0 * tex - 1.0) * chroma.g) * 0.5 + 0.5; float2 tb = ((2.0 * tex - 1.0) * chroma.b) * 0.5 + 0.5; float3 color = float3(tex2D(col, tr).r, tex2D(col, tg).g, tex2D(col, tb).b) * (1.0 - CoC); return float4(color, 1.0); } float4 GetMatsoDOFBlur(int axis, float2 coord, sampler SamplerHDRX) { float4 res; float4 tcol = tex2D(SamplerHDRX, coord.xy); float3 origCoC = tex2D(SamplerCoC, coord.xy).xyz; float2 discRadius = origCoC.x*DOF_BLURRADIUS*PixelSize.xy*0.5/iMatsoDOFBokehQuality; int passnumber=1; float sf = 0; float2 tdirs[4] = { float2(-0.306, 0.739), float2(0.306, 0.739), float2(-0.739, 0.306), float2(-0.739, -0.306) }; #if (bMatsoDOFBokehEnable==1) float wValue = (1.0 + pow(length(tcol.rgb) + 0.1, fMatsoDOFBokehCurve)) * (1.0 - fMatsoDOFBokehLight); // special recipe from papa Matso ;) #else float wValue = 1.0; #endif for (int i = -iMatsoDOFBokehQuality; i < iMatsoDOFBokehQuality; i++) { float2 taxis = tdirs[axis]; taxis.x = cos(fMatsoDOFBokehAngle*PIOVER180)*taxis.x-sin(fMatsoDOFBokehAngle*PIOVER180)*taxis.y; taxis.y = sin(fMatsoDOFBokehAngle*PIOVER180)*taxis.x+cos(fMatsoDOFBokehAngle*PIOVER180)*taxis.y; float2 tdir = (float)i * taxis * discRadius; float2 tcoord = coord.xy + tdir.xy; #if(bMatsoDOFChromaEnable == 1) float4 ct = GetMatsoDOFCA(SamplerHDRX, tcoord.xy, discRadius.x); #else float4 ct = tex2D(SamplerHDRX, tcoord.xy); #endif #if (bMatsoDOFBokehEnable == 0) float w = 1.0 + abs(offset[i]); // weight blur for better effect #else // my own pseudo-bokeh weighting float b = dot(ct.rgb,0.333) + length(ct.rgb) + 0.1; float w = pow(b, fMatsoDOFBokehCurve) + abs((float)i); #endif tcol += ct * w; wValue += w; } tcol /= wValue; res.xyz = tcol.xyz; res.w = 1.0; return res; } float4 PS_ME_MatsoDOF1(VS_OUTPUT_POST IN) : COLOR { return GetMatsoDOFBlur(2, IN.txcoord.xy, SamplerHDR2); } float4 PS_ME_MatsoDOF2(VS_OUTPUT_POST IN) : COLOR { return GetMatsoDOFBlur(3, IN.txcoord.xy, SamplerHDR1); } float4 PS_ME_MatsoDOF3(VS_OUTPUT_POST IN) : COLOR { return GetMatsoDOFBlur(0, IN.txcoord.xy, SamplerHDR2); } float4 PS_ME_MatsoDOF4(VS_OUTPUT_POST IN) : COLOR { return GetMatsoDOFBlur(1, IN.txcoord.xy, SamplerHDR1); } float4 PS_ME_Blur(VS_OUTPUT_POST IN) : COLOR { return tex2D(SamplerHDR1, IN.txcoord.xy); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Bloom // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float4 PS_ME_BloomPrePass(VS_OUTPUT_POST IN) : COLOR { float4 bloom=0.0; float2 bloomuv; float2 offset[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++) { bloomuv.xy=offset[i]*PixelSize.xy*2; bloomuv.xy=IN.txcoord.xy + bloomuv.xy; float4 tempbloom=tex2Dlod(SamplerLDR, float4(bloomuv.xy, 0, 0)); tempbloom.w = max(0,dot(tempbloom.xyz,0.333)-fAnamFlareThreshold); tempbloom.xyz = max(0, tempbloom.xyz-fBloomThreshold); #if(USE_HUD_MASKING == 1) float mask = tex2Dlod(SamplerMask, float4(bloomuv.xy, 0, 0)).x; tempbloom *= mask; #endif bloom+=tempbloom; } bloom *= 0.25; return bloom; } float4 PS_ME_BloomPass1(VS_OUTPUT_POST IN) : COLOR { float4 bloom=0.0; float2 bloomuv; float2 offset[8]= { float2(1.0, 1.0), float2(0.0, -1.0), float2(-1.0, 1.0), float2(-1.0, -1.0), float2(0.0, 1.0), float2(0.0, -1.0), float2(1.0, 0.0), float2(-1.0, 0.0) }; for (int i=0; i<8; i++) { bloomuv.xy=offset[i]*PixelSize.xy*4; bloomuv.xy=IN.txcoord.xy + bloomuv.xy; float4 tempbloom=tex2Dlod(SamplerBloom1, float4(bloomuv.xy, 0, 0)); bloom+=tempbloom; } bloom *= 0.125; return bloom; } float4 PS_ME_BloomPass2(VS_OUTPUT_POST IN) : COLOR { float4 bloom=0.0; float2 bloomuv; float2 offset[8]= { float2(0.707, 0.707), float2(0.707, -0.707), float2(-0.707, 0.707), float2(-0.707, -0.707), float2(0.0, 1.0), float2(0.0, -1.0), float2(1.0, 0.0), float2(-1.0, 0.0) }; for (int i=0; i<8; i++) { bloomuv.xy=offset[i]*PixelSize.xy*8; bloomuv.xy=IN.txcoord.xy + bloomuv.xy; float4 tempbloom=tex2Dlod(SamplerBloom2, float4(bloomuv.xy, 0, 0)); bloom+=tempbloom; } bloom *= 0.5; //to brighten up the sample, it will lose brightness in H/V gaussian blur return bloom; } float4 PS_ME_BloomPass3(VS_OUTPUT_POST IN) : COLOR { float4 bloom; bloom = GaussBlur22(IN.txcoord.xy, SamplerBloom3, 16, 0, 0); bloom.a *= fAnamFlareAmount; bloom.xyz *= fBloomAmount; return bloom; } float4 PS_ME_BloomPass4(VS_OUTPUT_POST IN) : COLOR { float4 bloom; bloom.xyz = GaussBlur22(IN.txcoord.xy, SamplerBloom4, 16, 0, 1).xyz*2.5; bloom.w = GaussBlur22(IN.txcoord.xy, SamplerBloom4, 32*fAnamFlareWideness, 0, 0).w*2.5; //to have anamflare texture (bloom.w) avoid vertical blur return bloom; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Lensflares // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float3 GetDnB (sampler2D tex, float2 coords) { float3 Color = max(0,dot(tex2Dlod(tex,float4(coords.xy,0,4)).rgb,0.333) - ChapFlareTreshold)*ChapFlareIntensity; #if(CHAPMANDEPTHCHECK == 1) if(tex2Dlod(SamplerDepth,float4(coords.xy,0,3)).x<0.99999) Color = 0; #endif return Color; } float2 GetFlippedTC(float2 texcoords) { return -texcoords + 1.0; } float3 GetDistortedTex( sampler2D tex, float2 sample_center, // where we'd normally sample float2 sample_vector, float3 distortion // per-channel distortion coeffs ) { float2 final_vector = sample_center + sample_vector * min(min(distortion.r, distortion.g),distortion.b); if(final_vector.x > 1.0 || final_vector.y > 1.0 || final_vector.x < -1.0 || final_vector.y < -1.0) return 0; else return float3( GetDnB(tex,sample_center + sample_vector * distortion.r).r, GetDnB(tex,sample_center + sample_vector * distortion.g).g, GetDnB(tex,sample_center + sample_vector * distortion.b).b ); } float3 GetBrightPass(float2 tex) { float3 c = tex2D(SamplerHDR1, tex).rgb; float3 bC = max(c - float3(fFlareLuminance, fFlareLuminance, fFlareLuminance), 0.0); float bright = dot(bC, 1.0); bright = smoothstep(0.0f, 0.5, bright); float3 result = lerp(0.0, c, bright); #if (bFlareDepthCheckEnable == 1) float checkdepth = tex2D(SamplerDepth, tex).x; if(checkdepth < 0.99999) result = 0; #endif return result; } float3 GetAnamorphicSample(int axis, float2 tex, float blur) { tex = 2.0 * tex - 1.0; tex.x /= -blur; tex = 0.5 * tex + 0.5; return GetBrightPass(tex); } float4 PS_ME_LensPrepass(VS_OUTPUT_POST IN) : COLOR { float4 lens=0; #if (USE_LENZFLARE == 1) float3 lfoffset[19]={ float3(0.9, 0.01, 4), float3(0.7, 0.25, 25), float3(0.3, 0.25, 15), float3(1, 1.0, 5), float3(-0.15, 20, 1), float3(-0.3, 20, 1), float3(6, 6, 6), float3(7, 7, 7), float3(8, 8, 8), float3(9, 9, 9), float3(0.24, 1, 10), float3(0.32, 1, 10), float3(0.4, 1, 10), float3(0.5, -0.5, 2), float3(2, 2, -5), float3(-5, 0.2, 0.2), float3(20, 0.5, 0), float3(0.4, 1, 10), float3(0.00001, 10, 20) }; float3 lffactors[19]={ float3(1.5, 1.5, 0), float3(0, 1.5, 0), float3(0, 0, 1.5), float3(0.2, 0.25, 0), float3(0.15, 0, 0), float3(0, 0, 0.15), float3(1.4, 0, 0), float3(1, 1, 0), float3(0, 1, 0), float3(0, 0, 1.4), float3(1, 0.3, 0), float3(1, 1, 0), float3(0, 2, 4), float3(0.2, 0.1, 0), float3(0, 0, 1), float3(1, 1, 0), float3(1, 1, 0), float3(0, 0, 0.2), float3(0.012,0.313,0.588) }; float3 lenstemp = 0; float2 lfcoord = float2(0,0); float2 distfact=(IN.txcoord.xy-0.5); distfact.x *= ScreenSize.z; for (int i=0; i<19; i++) { lfcoord.xy=lfoffset[i].x*distfact; lfcoord.xy*=pow(2.0*length(float2(distfact.x,distfact.y)), lfoffset[i].y*3.5); lfcoord.xy*=lfoffset[i].z; lfcoord.xy=0.5-lfcoord.xy; float2 tempfact = (lfcoord.xy-0.5)*2; float templensmult = clamp(1.0-dot(tempfact,tempfact),0,1); float3 lenstemp1 = dot(tex2Dlod(SamplerHDR1, float4(lfcoord.xy,0,1)).xyz,0.333); #if (LENZDEPTHCHECK == 1) float templensdepth = tex2D(SamplerDepth, lfcoord.xy).x; if(templensdepth < 0.99999) lenstemp1 = 0; #endif lenstemp1 = max(0,lenstemp1.xyz - fLenzThreshold); lenstemp1 *= lffactors[i].xyz*templensmult; lenstemp += lenstemp1; } lens.xyz += lenstemp.xyz*fLenzIntensity; #endif #if(USE_CHAPMAN_LENS == 1) float2 sample_vector = (float2(0.5,0.5) - IN.txcoord.xy) * ChapFlareDispersal; float2 halo_vector = normalize(sample_vector) * ChapFlareSize; float3 chaplens = GetDistortedTex(SamplerHDR1, IN.txcoord.xy + halo_vector,halo_vector,ChapFlareCA*2.5f).rgb; for (int i = 0; i < ChapFlareCount; ++i) { float2 foffset = sample_vector * float(i); chaplens += GetDistortedTex(SamplerHDR1, IN.txcoord.xy + foffset,foffset,ChapFlareCA).rgb; } chaplens *= 1/float(ChapFlareCount); lens.xyz += chaplens; #endif #if( USE_GODRAYS == 1) float2 ScreenLightPos = float2(0.5, 0.5); float2 texCoord = IN.txcoord.xy; float2 deltaTexCoord = (texCoord.xy - ScreenLightPos.xy); deltaTexCoord *= 1.0 / (float)iGodraySamples * fGodrayDensity; float illuminationDecay = 1.0; for(int g = 0; g < iGodraySamples; g++) { texCoord -= deltaTexCoord;; float4 sample2 = tex2D(SamplerHDR1, texCoord.xy); float sampledepth = tex2D(SamplerDepth, texCoord.xy).x; sample2.w = saturate(dot(sample2.xyz, 0.3333) - fGodrayThreshold); sample2.r *= 1.0; sample2.g *= 0.95; sample2.b *= 0.85; sample2 *= illuminationDecay * fGodrayWeight; #if (bGodrayDepthCheck == 1) if(sampledepth>0.99999) lens.xyz += sample2.xyz*sample2.w; #else lens.xyz += sample2; #endif illuminationDecay *= fGodrayDecay; } #endif #if(USE_ANAMFLARE == 1) float3 anamFlare=0; float gaussweight[5] = {0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162}; for(int z=-4; z < 5; z++) { anamFlare+=GetAnamorphicSample(0, IN.txcoord.xy + float2(0, z * PixelSize.y * 2), fFlareBlur) * fFlareTint* gaussweight[abs(z)]; } lens.xyz += anamFlare * fFlareIntensity; #endif return lens; } float4 PS_ME_LensPass1(VS_OUTPUT_POST IN) : COLOR { return GaussBlur22(IN.txcoord.xy, SamplerLens1, 2, 0, 1); } float4 PS_ME_LensPass2(VS_OUTPUT_POST IN) : COLOR { return GaussBlur22(IN.txcoord.xy, SamplerLens2, 2, 0, 0); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Lighting combine // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float4 PS_ME_LightingCombine(VS_OUTPUT_POST IN) : COLOR { float4 color = tex2D(SamplerHDR2, IN.txcoord.xy); #if (USE_BLOOM == 1) float3 colorbloom=0; colorbloom.xyz += tex2D(SamplerBloom3, IN.txcoord.xy).xyz*1.0; colorbloom.xyz += tex2D(SamplerBloom5, IN.txcoord.xy).xyz*9.0; colorbloom.xyz *= 0.1; colorbloom.xyz = saturate(colorbloom.xyz); float colorbloomgray = dot(colorbloom.xyz, 0.333); colorbloom.xyz = lerp(colorbloomgray, colorbloom.xyz, fBloomSaturation); colorbloom.xyz *= fBloomTint; float colorgray = dot(color.xyz, 0.333); if(iBloomMixmode == 1) color.xyz = color.xyz + colorbloom.xyz; if(iBloomMixmode == 2) color.xyz = 1-(1-color.xyz)*(1-colorbloom.xyz); if(iBloomMixmode == 3) color.xyz = max(0.0f,max(color.xyz,lerp(color.xyz,(1.0f - (1.0f - saturate(colorbloom.xyz)) *(1.0f - saturate(colorbloom.xyz * 1.0))),1.0))); if(iBloomMixmode == 4) color.xyz = max(color.xyz, colorbloom.xyz); #endif #if(USE_GAUSSIAN_ANAMFLARE == 1) float3 anamflare = tex2D(SamplerBloom5, IN.txcoord.xy).w*2*fAnamFlareColor; anamflare.xyz = max(anamflare.xyz,0); color.xyz += pow(anamflare.xyz,1/fAnamFlareCurve); #endif #if(USE_LENSDIRT == 1) float lensdirtmult = dot(tex2D(SamplerBloom5, IN.txcoord.xy).xyz,0.333); float3 dirttex = tex2D(SamplerDirt, IN.txcoord.xy).xyz; float3 lensdirt = dirttex.xyz*lensdirtmult*fLensdirtIntensity*fLensdirtTint; lensdirt = lerp(dot(lensdirt.xyz,0.333), lensdirt.xyz, fLensdirtSaturation); if(iLensdirtMixmode == 1) color.xyz = color.xyz + lensdirt.xyz; if(iLensdirtMixmode == 2) color.xyz = 1-(1-color.xyz)*(1-lensdirt.xyz); if(iLensdirtMixmode == 3) color.xyz = max(0.0f,max(color.xyz,lerp(color.xyz,(1.0f - (1.0f - saturate(lensdirt.xyz)) *(1.0f - saturate(lensdirt.xyz * 1.0))),1.0))); if(iLensdirtMixmode == 4) color.xyz = max(color.xyz, lensdirt.xyz); #endif float3 LensflareSample = tex2D(SamplerLens1, IN.txcoord.xy).xyz; float3 LensflareMask = tex2D(SamplerSprite, IN.txcoord.xy+float2(0.5,0.5)*PixelSize.xy).xyz; LensflareMask += tex2D(SamplerSprite, IN.txcoord.xy+float2(-0.5,0.5)*PixelSize.xy).xyz; LensflareMask += tex2D(SamplerSprite, IN.txcoord.xy+float2(0.5,-0.5)*PixelSize.xy).xyz; LensflareMask += tex2D(SamplerSprite, IN.txcoord.xy+float2(-0.5,-0.5)*PixelSize.xy).xyz; color.xyz += LensflareMask*0.25*LensflareSample; return color; } float4 PS_ME_Colors(VS_OUTPUT_POST IN) : COLOR { float4 color = tex2D(SamplerHDR1, IN.txcoord.xy); #if(USE_LED_SHADER == 1 ) float LEDradius = fLEDCircleSize * 0.375; float2 quadPos = floor(IN.txcoord.xy * float2(BUFFER_WIDTH,BUFFER_HEIGHT) / fLEDCircleSize) * fLEDCircleSize; float2 quad = quadPos/float2(BUFFER_WIDTH,BUFFER_HEIGHT); float2 quadCenter = (quadPos + fLEDCircleSize/2.0); float quaddist = length(quadCenter - IN.txcoord.xy * float2(BUFFER_WIDTH,BUFFER_HEIGHT)); float4 LEDtexel = tex2D(SamplerHDR1, quad); float LEDtexellum = saturate(dot(LEDtexel.xyz,0.333)-0.75)*fLEDCircleSize*0.33; color.xyz = lerp(fLEDBackgroundColor, LEDtexel.xyz, smoothstep(1.5*(1.0+LEDtexellum),-1.5*(1.0+LEDtexellum), quaddist-LEDradius)); #endif #if(USE_LUT == 1) float3 LUTcolor = 0.0; #if(iLookupTableMode == 1) LUTcolor.x = tex2D(SamplerLUT, float2(saturate(color.x),0)).x; LUTcolor.y = tex2D(SamplerLUT, float2(saturate(color.y),0)).y; LUTcolor.z = tex2D(SamplerLUT, float2(saturate(color.z),0)).z; #elif (iLookupTableMode == 2) float2 GridSize = float2(0.00390625, 0.0625); float3 coord3D = saturate(color.xyz); coord3D.z *= 15; float shift = floor(coord3D.z); coord3D.xy = coord3D.xy * 15 * GridSize + 0.5 * GridSize; coord3D.x += shift * 0.0625; LUTcolor.xyz = lerp( tex2D(SamplerLUT3D, coord3D.xy).xyz, tex2D(SamplerLUT3D, coord3D.xy + float2(GridSize.y, 0)).xyz, coord3D.z - shift); #endif color.xyz = lerp(color.xyz, LUTcolor.xyz, fLookupTableMix); #endif #if (USE_CARTOON == 1) color.xyz = CartoonPass(color.xyz, IN.txcoord.xy, PixelSize.xy, SamplerHDR1); #endif #if (USE_LEVELS== 1) color.xyz = LevelsPass(color.xyz); #endif #if (USE_TECHNICOLOR == 1) color.xyz = TechniPass_prod80(color.xyz); #endif #if (USE_SWFX_TECHNICOLOR == 1) color.xyz = TechnicolorPass(color.xyz); #endif #if (USE_DPX == 1) color.xyz = DPXPass(color.xyz); #endif #if (USE_MONOCHROME == 1) color.xyz = dot(color.xyz, 0.333); #endif #if (USE_LIFTGAMMAGAIN == 1) color.xyz = LiftGammaGainPass(color.xyz); #endif #if (USE_TONEMAP == 1) color.xyz = TonemapPass(color.xyz); #endif #if (USE_VIBRANCE == 1) color.xyz = VibrancePass(color.xyz); #endif #if (USE_CURVES == 1) color.xyz = CurvesPass(color.xyz); #endif #if (USE_SEPIA == 1) color.xyz = SepiaPass(color.xyz); #endif #if (USE_SKYRIMTONEMAP == 1) color.xyz = SkyrimTonemapPass(color.xyz); #endif #if (USE_COLORMOOD == 1) color.xyz = MoodPass(color.xyz); #endif #if (USE_CROSSPROCESS == 1) color.xyz = CrossPass(color.xyz); #endif #if (USE_FILMICPASS == 1) color.xyz = FilmPass(color.xyz); #endif #if (USE_REINHARD == 1) color.xyz = ReinhardToneMapping(color.xyz); #endif #if (USE_REINHARDLINEAR == 1) color.xyz = ReinhardLinearToneMapping(color.xyz); #endif #if (USE_HPD == 1) color.xyz = HaarmPeterDuikerFilmicToneMapping(color.xyz); #endif #if (USE_FILMICCURVE == 1) color.xyz = CustomToneMapping(color.xyz); #endif #if(USE_WATCHDOG_TONEMAP == 1) color.xyz = ColorFilmicToneMapping(color.xyz); #endif #if (USE_COLORMOD == 1) color.xyz = ColormodPass(color.xyz); #endif #if (USE_SPHERICALTONEMAP == 1) color.xyz = SphericalPass(color.xyz); #endif #if (USE_SINCITY == 1) color.xyz = SincityPass(color.xyz); #endif #if (USE_COLORHUEFX == 1) color.xyz = colorhuefx_prod80(color.xyz); #endif return color; } float4 PS_ME_PostFX(VS_OUTPUT_POST IN) : COLOR { #if (USE_SMAA == 1) #define SamplerCurrent SamplerHDR1 #else #define SamplerCurrent SamplerHDR2 #endif float4 color = tex2D(SamplerCurrent, IN.txcoord.xy); #if(USE_FISHEYE_CA == 1) float4 coord=0.0; coord.xy=IN.txcoord.xy; coord.w=0.0; float3 eta = float3(1.0+fFisheyeColorshift*0.9,1.0+fFisheyeColorshift*0.6,1.0+fFisheyeColorshift*0.3); float2 center; center.x = coord.x-0.5; center.y = coord.y-0.5; float LensZoom = 1.0/fFisheyeZoom; float r2 = (IN.txcoord.x-0.5) * (IN.txcoord.x-0.5) + (IN.txcoord.y-0.5) * (IN.txcoord.y-0.5); float f = 0; if( fFisheyeDistortionCubic == 0.0){ f = 1 + r2 * fFisheyeDistortion; }else{ f = 1 + r2 * (fFisheyeDistortion + fFisheyeDistortionCubic * sqrt(r2)); }; float x = f*LensZoom*(coord.x-0.5)+0.5; float y = f*LensZoom*(coord.y-0.5)+0.5; float2 rCoords = (f*eta.r)*LensZoom*(center.xy*0.5)+0.5; float2 gCoords = (f*eta.g)*LensZoom*(center.xy*0.5)+0.5; float2 bCoords = (f*eta.b)*LensZoom*(center.xy*0.5)+0.5; color.x = tex2D(SamplerCurrent,rCoords).r; color.y = tex2D(SamplerCurrent,gCoords).g; color.z = tex2D(SamplerCurrent,bCoords).b; #endif #undef SamplerCurrent return color; } float4 PS_ME_Overlay(VS_OUTPUT_POST IN) : COLOR { #if (USE_SMAA == 1) #define SamplerCurrent SamplerHDR2 #else #define SamplerCurrent SamplerHDR1 #endif float4 color = tex2D(SamplerCurrent, IN.txcoord.xy); #if( USE_HEATHAZE == 1) float3 heatnormal = tex2Dlod(SamplerHeat, float4(IN.txcoord.xy*fHeatHazeTextureScale+float2(0.0,Timer.x*0.0001*fHeatHazeSpeed),0,0)).rgb - 0.5; float2 heatoffset = normalize(heatnormal.xy) * pow(length(heatnormal.xy), 0.5); float3 heathazecolor = 0; heathazecolor.y = tex2D(SamplerCurrent, IN.txcoord.xy + heatoffset.xy * 0.001 * fHeatHazeOffset).y; heathazecolor.x = tex2D(SamplerCurrent, IN.txcoord.xy + heatoffset.xy * 0.001 * fHeatHazeOffset * (1.0+fHeatHazeChromaAmount)).x; heathazecolor.z = tex2D(SamplerCurrent, IN.txcoord.xy + heatoffset.xy * 0.001 * fHeatHazeOffset * (1.0-fHeatHazeChromaAmount)).z; color.xyz = heathazecolor; #if(bHeatHazeDebug == 1) color.xyz = heatnormal.xyz+0.5; #endif #endif /* xyz Must be moved elsewhere in order to be used correctly. Reminder to me: Enable CoC for FOG, too. #define USE_FOG 1 #define fFogStart 0.1 #define fFogEnd 0.7 #define fFogAmount 1.0 #define fFogColor float3(0.67,0.67,0.67) #if( USE_FOG == 1) float lineardepth = tex2Dlod(SamplerCoC, float4(IN.txcoord.xy,0,0)).y; float fogdepth=0; fogdepth += tex2Dlod(SamplerCoC, float4(IN.txcoord.xy,0,2)).y; fogdepth += tex2Dlod(SamplerCoC, float4(IN.txcoord.xy,0,3)).y; fogdepth += tex2Dlod(SamplerCoC, float4(IN.txcoord.xy,0,4)).y; fogdepth /= 3; fogdepth = lerp(lineardepth, fogdepth, saturate(lineardepth*3)); float fogamount = saturate(smoothstep(fFogStart, fFogEnd, fogdepth)*fFogAmount); float3 fogblur=0; fogblur += tex2Dlod(SamplerCurrent, float4(IN.txcoord.xy,0,2)).xyz; fogblur += tex2Dlod(SamplerCurrent, float4(IN.txcoord.xy,0,3)).xyz; fogblur += tex2Dlod(SamplerCurrent, float4(IN.txcoord.xy,0,4)).xyz; fogblur /= 3; float3 fogcolor = fFogColor; fogblur = (fogblur - fogcolor) * 0.75 + fogcolor; color.xyz = lerp(color.xyz, fogblur, saturate(fogamount*2)); color.xyz = lerp(color.xyz, fogcolor, fogamount); #endif */ #if(USE_SHARPENING == 1) color.xyz = SharpPass(color.xyz, IN.txcoord.xy, SamplerCurrent); #endif #if (USE_EXPLOSION == 1) color.xyz = ExplosionPass(color.xyz, IN.txcoord.xy, SamplerCurrent); #endif #if(USE_GRAIN == 1) float3 noisesample = tex2D(SamplerNoise, IN.txcoord.xy).xyz; float noisegray = dot(noisesample, 0.333); noisesample.xyz = lerp(noisegray.xxx, noisesample.xyz, fGrainSaturation); float colorgray = dot(color.xyz, 0.333); float fGrainAmount = fGrainIntensityMid; if(colorgray > 0.5) fGrainAmount = lerp(fGrainIntensityMid, fGrainIntensityBright, saturate(colorgray-0.5)*2); if(colorgray < 0.5) fGrainAmount = lerp(fGrainIntensityDark, fGrainIntensityMid, colorgray*2); noisesample.xyz = (noisesample.xyz-0.5)*fGrainAmount; color.xyz = max(0, color.xyz + noisesample.xyz); #endif #if (USE_COLORVIGNETTE==1) float2 uv=(IN.txcoord-0.5)*fVignetteRadius; float vignetteold=saturate(dot(uv.xy, uv.xy)); vignetteold=pow(vignetteold, fVignetteCurve); float3 EVignetteColor=fVignetteColor; color.xyz=lerp(color.xyz, EVignetteColor, vignetteold*fVignetteAmount); #endif #if (USE_HD6_VIGNETTE==1) float rovigpwr = fHD6VignetteRoundness; //for a circular vignette float2 sqvigpwr = float2( fHD6VignetteTop, fHD6VignetteBottom ); // for the top and bottom of the screen float vsatstrength = fHD6VignetteColorDistort; // color distortion float vignettepow = fHD6VignetteContrast; // increases the contrast and sharpness float vstrengthatnight = fHD6VignetteBorder; float2 inTex = IN.txcoord; float vhnd = 0.5; float4 voriginal = color; float4 vcolor = voriginal; vcolor.xyz=1; inTex -= 0.5; // center inTex.y += 0.01; // offset from the center float vignette = saturate(1.0 - dot( inTex, inTex )); vcolor *= pow( vignette, vignettepow ); float4 rvigtex = vcolor; rvigtex.xyz = pow( vcolor.xyz, 1 ); rvigtex.xyz = lerp(float3(0.5, 0.5, 0.5), rvigtex.xyz, 2.25); // contrast rvigtex.xyz = lerp(float3(1,1,1),rvigtex.xyz,rovigpwr); // strength of the circular vinetty //darken the top and bottom float4 vigtex = vcolor; vcolor.xyz = float3(1,1,1); #if (fHD6VignetteMode==1) float3 topv = min((inTex.x+0.5)*2,1.5) * 2; // top float3 botv = min(((0-inTex.x)+0.5)*2,1.5) * 2; // botton topv= lerp(float3(1,1,1), topv, sqvigpwr.x); botv= lerp(float3(1,1,1), botv, sqvigpwr.y); vigtex.xyz = (topv)*(botv); #endif #if (fHD6VignetteMode==2) float3 topv = min((inTex.y+0.5)*2,1.5) * 2; // top float3 botv = min(((0-inTex.y)+0.5)*2,1.5) * 2; // botton topv= lerp(float3(1,1,1), topv, sqvigpwr.x); botv= lerp(float3(1,1,1), botv, sqvigpwr.y); vigtex.xyz = (topv)*(botv); #endif #if (fHD6VignetteMode==3) float3 rightv = min((inTex.x+0.5)*2,1.5) * 2; float3 leftv = min(((0-inTex.x)+0.5)*2,1.5) * 2; float3 topv = min((inTex.y+0.5)*2,1.5) * 2; float3 botv = min(((0-inTex.y)+0.5)*2,1.5) * 2; rightv= lerp(float3(1,1,1), rightv, sqvigpwr.y); leftv= lerp(float3(1,1,1), leftv, sqvigpwr.x); topv= lerp(float3(1,1,1), topv, sqvigpwr.x); botv= lerp(float3(1,1,1), botv, sqvigpwr.y); vigtex.xyz = (topv)*(botv)*(rightv)*(leftv); #endif // mix the two types of vignettes vigtex.xyz*=rvigtex.xyz; vigtex.xyz = lerp(vigtex.xyz,float3(1,1,1),(vhnd-vstrengthatnight*vhnd)); //for a dark screen vigtex.xyz = min(vigtex.xyz,1); vigtex.xyz = max(vigtex.xyz,0); float3 vtintensity = dot(voriginal.xyz, float3(0.2125, 0.7154, 0.0721)); color.xyz = lerp(vtintensity, voriginal.xyz, ((((1-(vigtex.xyz*2))+2)-1)*vsatstrength)+1 ); color.xyz *= (vigtex.xyz); #endif #if (USE_BORDER==1) color.xyz = BorderPass(color, IN.txcoord.xy).xyz; #endif #if (USE_MOVIEBARS == 1) color.xyz = IN.txcoord.y > 0.12 && IN.txcoord.y < 0.88 ? color.xyz : 0.0; #endif #if(USE_DEPTHBUFFER_OUTPUT == 1) color.xyz = GetLinearDepth(tex2D(SamplerDepth, IN.txcoord.xy).x); #endif #if(USE_SPLITSCREEN == 1) if(IN.txcoord.x > 0.5) color.xyz = tex2D(SamplerLDR, IN.txcoord.xy).xyz; #endif #if(USE_HUD_MASKING == 1) float HUDMaskSample = tex2D(SamplerMask, IN.txcoord.xy).x; float3 origcolor = tex2D(SamplerLDR, IN.txcoord.xy).xyz; color.xyz = lerp(origcolor.xyz, color.xyz, saturate(HUDMaskSample)); #endif return color; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ technique MasterEffect < bool enabled = 1; toggle = MASTEREFFECT_TOGGLEKEY; > { pass ME_Init { VertexShader = VS_MasterEffect; PixelShader = PS_ME_Init; RenderTarget = texHDR1; } //so both HDR1 and HDR2 textures are filled with input color pass ME_Init //later, numerous DOF shaders have different passnumber but later passes depend { //on fixed HDR1 HDR2 HDR1 HDR2... sequence so a 2 pass DOF outputs HDR1 in pass 1 and VertexShader = VS_MasterEffect; //HDR2 in second pass, a 3 pass DOF outputs HDR2, HDR1, HDR2 so last pass outputs always HDR2 PixelShader = PS_ME_Init; RenderTarget = texHDR2; } #if(USE_AMBIENTOCCLUSION == 1) #if(AO_METHOD==1) pass ME_SSAO { VertexShader = VS_MasterEffect; PixelShader = PS_ME_SSAO; RenderTarget = texOcclusion1; } #endif #if(AO_METHOD==2) pass ME_RayAO { VertexShader = VS_MasterEffect; PixelShader = PS_ME_RayAO; RenderTarget = texOcclusion1; } #endif #if(AO_METHOD==3) pass ME_HBAO { VertexShader = VS_MasterEffect; PixelShader = PS_ME_HBAO; RenderTarget = texOcclusion1; } #endif #if(AO_METHOD==5) pass ME_HBAO { VertexShader = VS_MasterEffect; PixelShader = PS_ME_RayHBAO; RenderTarget = texOcclusion1; } #endif #if(AO_METHOD==6) pass ME_HBAO { VertexShader = VS_MasterEffect; PixelShader = PS_ME_SAO; RenderTarget = texOcclusion1; } #endif #if(AO_METHOD != 4) pass ME_AOBlurV { VertexShader = VS_MasterEffect; PixelShader = PS_ME_AOBlurV; RenderTarget = texOcclusion2; } pass ME_AOBlurH { VertexShader = VS_MasterEffect; PixelShader = PS_ME_AOBlurH; RenderTarget = texOcclusion1; } pass ME_AOCombine { VertexShader = VS_MasterEffect; PixelShader = PS_ME_AOCombine; RenderTarget = texHDR2; } #endif #if(AO_METHOD == 4) pass ME_SSGI { VertexShader = VS_MasterEffect; PixelShader = PS_ME_SSGI; RenderTarget = texOcclusion1; } pass ME_GIBlurV { VertexShader = VS_MasterEffect; PixelShader = PS_ME_GIBlurV; RenderTarget = texOcclusion2; } pass ME_GIBlurH { VertexShader = VS_MasterEffect; PixelShader = PS_ME_GIBlurH; RenderTarget = texOcclusion1; } pass ME_GICombine { VertexShader = VS_MasterEffect; PixelShader = PS_ME_GICombine; RenderTarget = texHDR2; } #endif #endif #if (USE_BLOOM == 1 || USE_GAUSSIAN_ANAMFLARE == 1 || USE_LENSDIRT == 1) pass BloomPrePass { VertexShader = VS_MasterEffect; PixelShader = PS_ME_BloomPrePass; RenderTarget = texBloom1; } pass BloomPass1 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_BloomPass1; RenderTarget = texBloom2; } pass BloomPass2 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_BloomPass2; RenderTarget = texBloom3; } pass BloomPass3 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_BloomPass3; RenderTarget = texBloom4; } pass BloomPass4 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_BloomPass4; RenderTarget = texBloom5; } #endif #if (USE_LENZFLARE == 1 || USE_CHAPMAN_LENS == 1 || USE_GODRAYS == 1 || USE_ANAMFLARE == 1) pass ME_LensPrepass { VertexShader = VS_MasterEffect; PixelShader = PS_ME_LensPrepass; RenderTarget = texLens1; } pass ME_LensPass1 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_LensPass1; RenderTarget = texLens2; } pass ME_LensPass2 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_LensPass2; RenderTarget = texLens1; } #endif #if(USE_DEPTHOFFIELD == 1) pass ME_CoC { VertexShader = VS_MasterEffect; PixelShader = PS_ME_CoC; RenderTarget = texCoC; } #endif #if(USE_DEPTHOFFIELD==1) #if(DOF_METHOD==1) pass ME_RingDOF1 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_RingDOF1; RenderTarget = texHDR1; } pass ME_RingDOF2 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_RingDOF2; RenderTarget = texHDR2; } #endif #if(DOF_METHOD==2) pass ME_MagicDOF1 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_MagicDOF1; RenderTarget = texHDR1; } pass ME_MagicDOF2 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_MagicDOF2; RenderTarget = texHDR2; } #endif #if(DOF_METHOD==3) pass ME_GPDOF1 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_GPDOF1; RenderTarget = texHDR1; } pass ME_GPDOF2 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_GPDOF2; RenderTarget = texHDR2; } #endif #if(DOF_METHOD==4) pass ME_MatsoDOF1 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_MatsoDOF1; RenderTarget = texHDR1; } pass ME_MatsoDOF2 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_MatsoDOF2; RenderTarget = texHDR2; } pass ME_MatsoDOF3 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_MatsoDOF3; RenderTarget = texHDR1; } pass ME_MatsoDOF4 { VertexShader = VS_MasterEffect; PixelShader = PS_ME_MatsoDOF4; RenderTarget = texHDR2; } #endif #endif pass ME_LightingCombine { VertexShader = VS_MasterEffect; PixelShader = PS_ME_LightingCombine; RenderTarget = texHDR1; } pass ME_Colors { VertexShader = VS_MasterEffect; PixelShader = PS_ME_Colors; RenderTarget = texHDR2; } #if (USE_SMAA == 1) pass SMAA_EdgeDetection //First SMAA Pass { VertexShader = SMAAEdgeDetectionVSWrap; #if (iSMAAEdgeDetectionMode == 1) PixelShader = SMAALumaEdgeDetectionPSWrap; #elif (iSMAAEdgeDetectionMode == 3) PixelShader = SMAADepthEdgeDetectionPSWrap; #else PixelShader = SMAAColorEdgeDetectionPSWrap; //Probably the best in most cases so I default to this. #endif StencilEnable = true; StencilPass = REPLACE; StencilRef = 1; RenderTarget = texEdges; } pass SMAA_BlendWeightCalculation //Second SMAA Pass { VertexShader = SMAABlendingWeightCalculationVSWrap; PixelShader = SMAABlendingWeightCalculationPSWrap; StencilEnable = true; StencilPass = KEEP; StencilFunc = EQUAL; StencilRef = 1; RenderTarget = texBlend; } pass SMAA_NeighborhoodBlending //Third SMAA Pass { VertexShader = SMAANeighborhoodBlendingVSWrap; PixelShader = SMAANeighborhoodBlendingPSWrap; #if (iSMAADebugOutput == 5) // Use the stencil so we can show it. StencilEnable = true; StencilPass = KEEP; StencilFunc = EQUAL; StencilRef = 1; #else // Process all the pixels. StencilEnable = false; #endif RenderTarget = texHDR1; } #endif pass ME_PostFX { VertexShader = VS_MasterEffect; PixelShader = PS_ME_PostFX; #if (USE_SMAA == 1) //exactly what I wanted to prevent with new system :( RenderTarget = texHDR2; //but I see now, first AA and then chromatic abberation gives smoother result... #else //this of course eliminates the option to use 2 AA's together because with each count RenderTarget = texHDR1; //this here would get more and more complicated...damn #endif //Noone will ever read this so I'm basically talking to a text file. Hello text file. } pass ME_Overlay { VertexShader = VS_MasterEffect; PixelShader = PS_ME_Overlay; } }

Comments

Dr_Patrik
11 Dec 21:11 CET

I have added another step to the installation to fix the 'RFX_Depth_z_far' error that many people were having. I was unaware that the latest version of ReShade didn't have the variable declaration in it for all the depth variables (even though they are not used) and I have added a copy of the updated file to fix this issue. Sorry for the long wait as I don't have as much time to check up on this page very often.

JDChaos
4 Dec 12:00 CET

I get the same error. C:\Games\Guild Wars 2\bin64\ReShade.fx(81, 28): error X3004: undeclared identifier 'RFX_Depth_z_far'

A fix would be nice. Thank you.

THORGAL
21 Nov 17:43 CET

when starting the game , i get this error

C:\Games\Guild Wars 2\bin64\ReShade.fx(81, 28): error X3004: undeclared identifier 'RFX_Depth_z_far'

You need to be logged in to post a comment