/*----------------------------. | :: 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.xorigCoC.z && sampleCoC.xorigCoC.z && sampleCoC1.xorigCoC.z && sampleCoC2.xorigCoC.z && sampleCoC.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; } }