SweetFX Settings DB
Latest forum threads
40 minutes ago
by Chloeg
1 hour, 38 minutes ago
1 hour, 50 minutes ago
2 hours, 57 minutes ago

Global Illumination SSDO Mod

Created by Corvinc
Added April 10, 2015
Shader used: Other
Preset description:
///Only for test\\\ This shader pack includes: Screen Space Directional Occlusion BLOOM GODRAYS TONEMAP UNSHARPMASK FILMGRAIN VIBRANCE LIFTGAMMAGAIN TECHNICOLOR
Download preset Show / Hide settings
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++ // *** PPFX Post-Processing Suite 1.03.29 for ReShade // *** SHADER AUTHOR: Pascal Matthäus ( Euda ) // ++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++ // DEV_NOTES //+++++++++++++++++++++++++++++ //+++++++++++++++++++++++++++++ // USED EFFECTS //+++++++++++++++++++++++++++++ #define ENABLE_SSDO 1 // Screen Space Directional Occlusion | Ambient Occlusion simulates diffuse shadows/self-shadowing of geometry. Indirect Lighting brightens objects that are exposed to a certain "light source" you may specify in the parameters below. This approach takes directional information into account and simulates indirect light bounces, approximating global illumination. #define ENABLE_BLOOM 1 // Bloom | This effect lets bright pixels bleed their light into their surroundings. It is fast, highly customizable and fits to many games. I suggest you take a look and play around with the configs. #define ENABLE_GODRAYS 0 // Godrays | Lets bright areas cast rays on the screen. #define ENABLE_TONEMAP 0 // Tonemap | As brightness-increasing effects like bloom will push colors above the maximum brightness of standard displays and thus oversaturate colors and lead to ugly white "patches" in bright areas, the colors have to be "remapped" into the displays range. Several techniques exist for that, actually it's a whole scientific field. Configurable of course. #define ENABLE_UNSHARPMASK 1 // Unsharp Masking | Applies a common technique to sharpen the image. Two versions exist: One is only avaiable if you activated bloom and increases the contrast of "surfaces" (Wikipedia advised, sir.) The second one only sharps edges. #define ENABLE_FILMGRAIN 0 // Filmgrain | Adds temporal noise to the image. May be great if you'd like to simulate old movies or create a certain, distinctive look. Of course nobody likes to play with a bunch of noise overlayed so keep it subtle. #define ENABLE_VIBRANCE 0 // Vibrance | Vibrance is a color saturation control which considers the pixel's original saturation in order to prevent oversaturation and other artifacts. Yields a vivid, well, vibrant look. #define ENABLE_LIFTGAMMAGAIN 0 // LiftGammaGain | This effect adds an individual color filter for three brightness levels (Lift = Shadows, dark tones | Gamma = Midtones | Gain = Lights, bright tones) #define ENABLE_TECHNICOLOR 0 // Technicolor 3-Strip | Simulates the look of old movies produced with the Technicolor Process 4 (3-Strip). This approach is based on the Photoshop "3Strip"-LUT. Stylistically fits some games. #define ENABLE_LENSDIRT 0 // Lensdirt | Simulates a dirty lens. This effect was introduced in Battlefield 3 back in 2011 and since then was used by many further gamestudios. #define ENABLE_LETTERBOX 0 // Letterbox | Adds black bars on top & bottom of the screen. Some people hate it, some say it leads to a "cineastic experience". Try and see for yourself. #define ENABLE_LOGGAMMA 1 // Alternative Gamma-Correction | Abuses a common, detail-preserving alternative for standard Gamma-encoding (sRGB) to achieve a higher contrast. Can look nice on washed-out-looking visuals. //+++++++++++++++++++++++++++++ // CUSTOM PARAMETERS //+++++++++++++++++++++++++++++ // ** SSDO ** #define ssdoIntensity 2.000 // SSDO Intensity - The intensity curve applied to the effect. High values may produce banding when used along with RGBA8 FilterPrecision. As increasing the precision to RGBA16F will heavily affect performance, rather combine Intensity and Amount if you want high visibility | 0.001 - 20.000 #define ssdoAmount 2.000 // SSDO Amount - A multiplier applied to occlusion/lighting factors when they are calculated. High values increase the effect's visibilty but may expose artifacts and noise | 0.001 - 20.000 #define ssdoAOMix 1.000 // SSDO Ambient Occlusion Mix - Ambient occlusion darkens geometry if it is occluded relative to the camera's point of view. This simulates the fact that "blocked" light can't reach geometry behind the blocker. This results in diffuse, blurry shadows. | This value controls the darkening amount | 0.000 - 1.000 #define ssdoILMix 1.000 // SSDO Indirect Lighting Mix - Geometry that is exposed to the static light source (specified below with ssdoLightPos) gets brightened. This value controls the brightening amount | 0.000 - 1.000 #define ssdoBounceMultiplier 0.900 // SSDO Indirect Bounce Color Multiplier - SSDO includes an indirect bounce of light which means that colors of objects may interact with each other. This value controls the effects' visibility | 0.000 - 1.000 #define ssdoBounceSaturation 0.000 // SSDO Indirect Bounce Color Saturation - High values may look strange | 0.000 - 20.000 #define ssdoSampleAmount 16 // SSDO Sample Count - The amount of samples taken to accumulate SSDO. Affects quality, reduces noise and almost linearly affects performance. Current high-end systems should max out at ~32 samples at Full HD to reach desirable framerates | 2 - 250 #define ssdoSampleRange 150.5 // SSDO Sample Range - Maximum 3D-distance (in pixels) for occluders to occlude geometry. High values reduce cache coherence, lead to cache misses and thus decrease performance so keep this below ~150. You may prevent this performance drop by increasing ssdoSourceLOD | 4.000 - 400.000 #define ssdoSamplePrecision RGBA16F // SSDO Sample Precision - The texture format of the source texture used to calculate the effect. RGBA8 is generally too low, RGBA16F should be the sweet-spot. RGBA32F is overkill and heavily kills your FPS. #define ssdoSourceLOD 0 // SSDO Source LOD - The Mipmap-level of the source texture used to calculate the occlusion/indirect light. 0 = full resolution, 1 = half-axis resolution, 2 = quarter-axis resolution etc. Combined with high SampleRange-values, this may improve performance with a slight loss of quality | 0 - 3 #define ssdoBounceLOD 3 // SSDO Source LOD - The Mipmap-level of the color texture used to calculate the light bounces. 0 = full resolution, 1 = half-axis resolution, 2 = quarter-axis resolution etc. Combined with high SampleRange-values, this may improve performance with a slight loss of quality | 0 - 3 #define ssdoLOD 0 // SSDO LOD - The resolution which the effect is calculated in. 0 = full-screen, 1 = half, 2 = quarter, 3 = one-eighth #define ssdoFilterScale 0.8 // SSDO Filter Scale Factor - Resolution control for the filter where noise the technique produces gets removed. Performance-affective. 0.5 means half resolution, 0.25 = quarter res, 1 = full-res. etc. Values above 1.0 yield a downsampled blur which doesn't make sense and is not recommended | 0.1 - 4.0 #define ssdoFilterRadius 12 // SSDO Filter Radius - The blur radius that is used to filter out the noise the technique produces. Don't push this too high, everything between 8 - 24 is recommended (depending from SampleAmount, SampleRange, Intensity and Amount) | 2 - 100 #define ssdoFilterPrecision RGBA16 // SSDO Filter Precision - The texture format used when filtering out the SSDO's noise. Use this to prevent banding artifacts that you may see in combination with very high ssdoIntensity values. RGBA16F, RGBA32F or, standard, RGBA8. Strongly suggest the latter to keep high framerates #define ssdoFilterStep 1 // SSDO Filter Step - A performance optimization for the filter, introducing interleaved sampling. Leave it at 1 and rather use FilterScale to improve the filter performance | 1 - 16 #define ssdoLightPos float3(0.0,0.2,0.8) // SSDO Light Position - The view-space position of the virtual light-source used to calculate occlusion in XYZ-axis'. (0.0,0.0,1.0) means the light is located on the camera. Values should sum 1.0 together. High Z-axis-values recommended. | 0.0 - 1.0 #define ssdoMixMode 1 // SSDO Mix Mode - 1 = Multiply (visually best imo), 2 = Additive (use with very low ssdoAmount & ssdoIntensity), generally not recommended #define ssdoDebugMode 0 // SSDO Debug Mode - 0 = debug-mode off. 1 outputs the filtered SSDO component, 2 shows you the raw, noisy SSDO right after scattering the occlusion/lighting // ** BLOOM ** #define bloomIntensity 0.500 // Bloom Overall-Intensity - The bloom's exposure, I strongly suggest combining this with a tonemap if you choose a high value here | 0.000 - 10.000 #define bloomRadius 64 // Bloom Sample Radius - Maximum distance within pixels affect each other - directly affetcs performance: Combine with bloomDownsampling to increase your effective radius while keeping a high framerate | 2 - 250 #define bloomDownsampling 4 // Bloom Downsampling Factor - Downscales the image before calculating the bloom, thus drastically increasing performance. '1' is fullscreen which doesn't really make sense. I suggest 2-4. High values will cause temporal aliasing | 1 - 16 #define bloomPrecision RGBA8 // Bloom Sampling Precision - Options: RGBA8 (low quality, high performance) / RGBA16 (high quality, slightly slower depending on your system) / RGBA32F (overkill) #define bloomBlendMode 1 // Bloom Blend Mode - Controls how the bloom is mixed with the original frame - (1: Additive (recommended with tonemaps), 2: Lighten (great for night scenes), 3: Cover (for configuring/debugging)) #define bloomThreshold 0.400 // Bloom Threshold - Pixels darker than this value won't cast bloom | 0.000 - 1.000 #define bloomCurve 1.500 // Bloom Curve - The effect's gamma curve - the higher, the more will bloom be damped in dark areas - and vice versa | 0.100 - 4.000 #define bloomSaturation 2.000 // Bloom Saturation - The effect's color saturation. 0 means white, uncolored bloom, 1.500-3.000 yields a vibrant effect while everything above should make your eyes bleed | 0.000 - 10.000 // ** GODRAYS ** #define godraysSampleAmount 64 // Godrays Sample Amount - Effectively the ray's resolution. Low values may look coarse but yield a higher framerate. | 8 - 250 #define godraysSource float2(0.500,0.400) // Godrays Light Source - The vanishing point of the godrays in screen-space. 0.500,0.500 is the middle of your screen. #define godraysExposure 0.100 // Godrays Exposure - Contribution exposure of each single light patch to the final ray. 0.100 should generally be enough. | 0.010 - 1.000 #define godraysFreq 1.200 // Godrays Frequency - Higher values result in a higher density of the single rays. '1.000' leads to rays that'll always cover the whole screen. Balance between falloff, samples and this value. | 1.000 - 10.000 #define godraysThreshold 0.650 // Godrays Threshold - Pixels darker than this value won't cast rays | 0.000 - 1.000 #define godraysFalloff 1.060 // Godrays Falloff - Lets the rays' brightness fade/falloff with their distance from the light source specified in 'godraysSource' | 1.000 - 2.000 // ** TONEMAP ** #define tonemapMode 3 // Tonemap Mode - choose a tonemapping algorithm fitting your personal taste (1: Linear, recommended for really low bloomIntensity-values, 2: Square, 3: Log10-logarithmic + exposure correction) #define tonemapCurve 3.000 // Tonemap Curve - How 'aggressive' bright colors are compressed. High values may darken the shadows and mid-tones while preserving details in bright regions (almost-bright skies, for instance) | 1.000 - 100.000 #define tonemapExposure 1.200 // Tonemap Exposure Adjustment - Every pixel is multiplied by this value before being tonemapped. You can use this as a brightness control or to specify a mid-gray value for tonemapContrast | 0.001 - 10.000 #define tonemapContrast 1.020 // Tonemap Contrast Intensity - Pixels darker than 1 are darkened, pixels above are exposed by this option. Combine with higher (2 - 7) tonemapExposure-values to create get a desirable look. Don't crank this up too far either | 0.100 - 10.000 #define tonemapSaturateBlacks 0.000 // Tonemap Black Saturation - Some tonemapping algorithms may desaturate your shadows - this option corrects this issue. Dont's use too high values, it is purposed to be a subtle correction | 0.010 - 1.000 // ** UNSHARP MASK ** #define unsharpMaskA 1 // Unsharp Mask A - Small Radius, performs best for edge sharpening #define unsharpMaskB 1 // Unsharp Mask B - Radius = bloomRadius - performs best at local contrast enhancement, bloom has to be enabled! #define unsharpMaskAIntensity 0.150 // Unsharp Mask A Sharpening Intensity - the effects' intensity, be careful - I wouldn't push it futher than 0.500 #define unsharpMaskBIntensity 0.150 // Unsharp Mask B Sharpening Intensity - the effects' intensity, be careful - I wouldn't push it futher than 0.500 #define unsharpMaskAMode 1 // Unsharp Mask A Mode - Controls edge detection (1: RGB, 2: Luma) // ** FILMGRAIN ** #define grainAmount 0.001 // Grain Amount - Visibility of the filmgrain on your screen #define grainPower 1.000 // Grain Power - the noise's exposure #define grainFreq 1.000 // Grain Frequency - how fast the noise will change. Zero disables the frequency, thus just showing a grain-texture #define grainSize 0.300 // Grain Scale - the scale of the grain-texture. Too low values will let you see the tiled pattern of the noise. Too high one's are not realistic // ** VIBRANCE ** #define vibranceAmount 0.700 // Vibrance Amount - The effect's intensity | 0.001 - 10.000 #define vibranceCurve 1.500 // Vibrance Curve - The higher this value, the more the saturation increase will be limited to unsaturated patches (pixels) and vice versa. I suggest values around 1.000 - 1.500, combining high values with high vibranceAmounts will not lead to good results | 0.100 - 4.000 // ** LIFTGAMMAGAIN ** #define lggLiftColor float3(0.100,0.450,1.000) // LiftGammaGain Lift Color - Color filter for Shadows (dark tones) in RGB | 0.000 - 1.000 #define lggGammaColor float3(1.000,0.800,0.850) // LiftGammaGain Gamma Color - Color filter for midtones in RGB | 0.000 - 1.000 #define lggGainColor float3(1.000,0.800,0.700) // LiftGammaGain Gain Color - Color filter for Lights (bright tones) in RGB | 0.000 - 1.000 #define lggMultiplier 0.400 // LiftGammaGain Multiplier - the color filters' intensity. | 0.001 - 4.000 // ** TECHNICOLOR 3-STRIP ** #define techniAmount 0.200 // Technicolor Strength - This parameter controls how strong the Technicolor-effect is applied. Too high values will not lead to UB4R-T3CHNiiC0LOR but very strange frames. Keep it between 0.200 and 2.000 | 0.001 - 10.000 #define techniPunch 0.100 // Technicolor Punch - Normally the effect's only visible on high-chroma pixels - this value helps to punch bright&dark pixels to prevent that | Simulates artifacts produced in the course of colour grading/processing methods back in the day. | 0.000 - 2.000 // ** LENSDIRT ** #define lensdirtIntensity 1.000 // Lensdirt Intensity - The dirt texture's maximum intensity #define lensdirtCurve 1.200 // Lensdirt Curve - The curve which the dirt texture's intensity scales with - try higher values to limit visibility solely to bright/almost-white scenes #define lensdirtSmoothmode 1 // Lensdirt Smooth-mode - If enabled, the bloom texture will be used for brightness check, thus scaling the intensity with the local luma instead of the current pixels' one (bloom has to be enabled!) // ** LETTERBOX ** #define letterboxSize 0.020 // Letterbox Size - The vertical range of the letterbox, 0.5 = black screen // ** LOGGAMMA ** #define logGammaValue 2.200 // Gamma Value - Should match your display's gamma value. The international standard used for almost every consumer display device is 2.2. I would not suggest another value | 0.100 - 4.000 /* * +++++++++++++++++++++++++ DOCS +++++++++++++++++++++++++ * -------------------- * __RESHADE__ (version of the injector) * __VENDOR__ (vendor id) * __DEVICE__ (device id) * __RENDERER__ (Direct3D9: 0xD3D9 / Direct3D10: 0xD3D10 / Direct3D11: 0xD3D11 / OpenGL: 0x061) * * __DATE_YEAR__ (current year) * __DATE_MONTH__ (current month) * __DATE_DAY__ (current day in month) * * BUFFER_WIDTH (screen width) * BUFFER_HEIGHT (screen height) * BUFFER_RCP_WIDTH (reciprocal screen width) * BUFFER_RCP_HEIGHT (reciprocal screen height) * texture imageTex < source = "path/to/image.bmp"; > { ... }; * uniform float frametime < source = "frametime"; >; // Time in milliseconds it took for the last frame to complete. * uniform int framecount < source = "framecount"; >; // Total amount of frames since the game started. * uniform float4 date < source = "date"; >; // float4(year, month (1 - 12), day of month (1 - 31), time in seconds) * uniform float timer < source = "timer"; >; // Timer counting time in milliseconds since game start. * uniform float timeleft < source = "timeleft"; >; // Time in milliseconds that is left until the current technique timeout is reached. * uniform float2 pingpong < source = "pingpong"; min = 0; max = 10; step = 1; >; // Counter that counts up and down between min and max using step as increase value. The second component is either +1 or -1 depending on the direction it currently goes. * uniform int random < source = "random"; min = 0; max = 10; >; // Gets a new random value between min and max every pass. * uniform bool keydown < source = "key"; keycode = 0x20; >; // True if specified keycode (in this case the spacebar) is pressed and false otherwise. * * technique tech1 < enabled = true; > { ... } // Enable this technique by default. * technique tech2 < timeout = 1000; > { ... } // Auto-toggle this technique off 1000 milliseconds after it was enabled. * technique tech3 < toggle = 0x20; > { ... } // Toggle this technique when the specified keycode (in this case the spacebar) is pressed. * technique tech3 < toggleTime = 100; > { ... } // Toggle this technique at the specified time (in seconds after midnight). */ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ TEXTURES +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // *** ESSENTIALS *** texture2D texColor : COLOR; texture texColorHDRA { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; texture texColorHDRB { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA16F; }; texture texColorLOD { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = RGBA8; MipLevels = 4; }; texture texDepth : DEPTH; // *** FX RTs *** texture texBloomA { Width = BUFFER_WIDTH/bloomDownsampling; Height = BUFFER_HEIGHT/bloomDownsampling; // Available formats: R8, R32F, RG8, RGBA8, RGBA16, RGBA16F, RGBA32F --- Available compressed formats: DXT1 or BC1, DXT3 or BC2, DXT5 or BC3, LATC1 or BC4, LATC2 or BC5 Format = bloomPrecision; }; texture texBloomB { Width = BUFFER_WIDTH/bloomDownsampling; Height = BUFFER_HEIGHT/bloomDownsampling; Format = bloomPrecision; }; texture texViewSpace { Width = BUFFER_WIDTH; Height = BUFFER_HEIGHT; Format = ssdoSamplePrecision; MipLevels = 4; }; texture texSSDOA { Width = BUFFER_WIDTH/pow(2.0,ssdoLOD); Height = BUFFER_HEIGHT/pow(2.0,ssdoLOD); Format = ssdoFilterPrecision; }; texture texSSDOB { Width = BUFFER_WIDTH*ssdoFilterScale; Height = BUFFER_HEIGHT*ssdoFilterScale; Format = ssdoFilterPrecision; }; texture texSSDOC { Width = BUFFER_WIDTH*ssdoFilterScale; Height = BUFFER_HEIGHT*ssdoFilterScale; Format = ssdoFilterPrecision; }; // *** EXTERNAL TEXTURES *** texture texNoise < source = "ppfx/noise.png"; > { Width = 256; Height = 256; #define NOISE_SCREENSCALE float2((BUFFER_WIDTH/pow(2.0,ssdoLOD))/256.0,(BUFFER_HEIGHT/pow(2.0,ssdoLOD))/256.0) }; texture texDirt < source = "ppfx/dirt.png"; > { Width = 1024; Height = 1024; }; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ SAMPLERS +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // *** ESSENTIALS *** sampler2D SamplerColor { Texture = texColor; AddressU = BORDER; AddressV = BORDER; MinFilter = LINEAR; MagFilter = LINEAR; SRGBTexture = TRUE; }; sampler SamplerColorHDRA { Texture = texColorHDRA; AddressU = BORDER; AddressV = BORDER; MinFilter = LINEAR; MagFilter = LINEAR; }; sampler SamplerColorHDRB { Texture = texColorHDRB; AddressU = BORDER; AddressV = BORDER; MinFilter = LINEAR; MagFilter = LINEAR; }; sampler SamplerColorLOD { Texture = texColorLOD; }; sampler2D SamplerDepth { Texture = texDepth; }; // *** FX RTs *** sampler SamplerBloomA { Texture = texBloomA; }; sampler SamplerBloomB { Texture = texBloomB; }; sampler SamplerViewSpace { Texture = texViewSpace; MipFilter = NONE; }; sampler SamplerSSDOA { Texture = texSSDOA; }; sampler SamplerSSDOB { Texture = texSSDOB; }; sampler SamplerSSDOC { Texture = texSSDOC; }; // *** EXTERNAL TEXTURES *** sampler SamplerNoise { Texture = texNoise; MipFilter = NONE; MinFilter = NONE; MagFilter = NONE; }; sampler SamplerDirt { Texture = texDirt; SRGBTexture = TRUE; }; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ VARIABLES +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #pragma message "PPFX Graphics Enhancement 1.03.29 | Author: Pascal Matthäus (Euda)" static const float2 pxSize = float2(BUFFER_RCP_WIDTH,BUFFER_RCP_HEIGHT); static const float3 lumaCoeff = float3(0.2126f,0.7152f,0.0722f); #define ZNEAR 0.3 #define ZFAR 50.0 uniform float timer < source = "timer"; >; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ STRUCTS +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ struct VS_OUTPUT_POST { float4 vpos : SV_Position; float2 txcoord : TEXCOORD0; }; struct VS_INPUT_POST { uint id : SV_VertexID; }; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ HELPERS +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ float3 threshold(float3 pxInput, float colThreshold) { return pxInput*max(0.0,sign(max(pxInput.x,max(pxInput.y,pxInput.z))-colThreshold)); } float linearDepth(float2 txCoords) { return (2.0*ZNEAR)/(ZFAR+ZNEAR-tex2D(SamplerDepth,txCoords).x*(ZFAR-ZNEAR)); } float4 viewSpace(float2 txCoords) { const float2 offsetS = txCoords+float2(0.0,1.0)*pxSize; const float2 offsetE = txCoords+float2(1.0,0.0)*pxSize; float depth = linearDepth(txCoords); float depthS = linearDepth(offsetS); float depthE = linearDepth(offsetE); float3 vsNormal = cross(normalize(float3(offsetS-txCoords,depthS-depth)),normalize(float3(offsetE-txCoords,depthE-depth))); return float4(vsNormal.x,-vsNormal.y,-vsNormal.z,depth); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ EFFECTS +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // *** SSDO *** #if (ENABLE_SSDO == 1) #define SSDO_CONTRIB_RANGE (ssdoSampleRange*pxSize.y) #define SSDO_BLUR_DEPTH_DISCONTINUITY_THRESH_MULTIPLIER 0.05 // SSDO - Scatter Illumination float4 FX_ssdoScatter( float2 txCoords ) { float sourceAxisDiv = pow(2.0,ssdoSourceLOD); float2 texelSize = pxSize*pow(2.0,ssdoSourceLOD); float4 vsOrig = tex2D(SamplerViewSpace,txCoords); float3 ssdo = 0.0; float2 randomDir = tex2D(SamplerNoise,frac(txCoords*NOISE_SCREENSCALE)).xy; [loop] for (float offs=1.0;offs<=ssdoSampleAmount;offs++) { float2 fetchCoords = txCoords+(frac(randomDir*11.139795*offs)*2.0-1.0)*offs*(ssdoSampleRange/(ssdoSampleAmount*sourceAxisDiv))*texelSize; float4 vsFetch = tex2Dlod(SamplerViewSpace,float4(fetchCoords,0,ssdoSourceLOD)); float3 albedoFetch = tex2Dlod(SamplerColorLOD,float4(fetchCoords,0,ssdoBounceLOD)).xyz; albedoFetch = lerp(dot(albedoFetch,lumaCoeff),albedoFetch,ssdoBounceSaturation); albedoFetch /= max(1.0,max(albedoFetch.x,max(albedoFetch.y,albedoFetch.z))); float3 dirVec = float3(fetchCoords.x-txCoords.x,txCoords.y-fetchCoords.y,vsOrig.w-vsFetch.w); float illuminationFact = dot(normalize(dirVec),ssdoLightPos); float visibility = (illuminationFact > 0.0) ? max(0.0,sign(dot(normalize(float3(dirVec.xy,abs(dirVec.z))),vsOrig.xyz))) : 1.0; float normalDiff = length(vsFetch.xyz-vsOrig.xyz); if (illuminationFact < 0.0) albedoFetch = 1.0-albedoFetch; ssdo += clamp(sign(illuminationFact),-ssdoILMix,ssdoAOMix) * (1.0-albedoFetch*ssdoBounceMultiplier) * visibility * (max(0.0,SSDO_CONTRIB_RANGE-length(dirVec))/SSDO_CONTRIB_RANGE) * sign(max(0.0,normalDiff-0.3)); } return float4(saturate(0.5-(ssdo/ssdoSampleAmount*ssdoAmount)*smoothstep(0.1,0.3,1.0-vsOrig.w)),vsOrig.w); } // Depth-Bilateral Gaussian Blur - Horizontal float4 FX_BlurBilatH( float2 txCoords, float radius ) { float texelSize = pxSize.x/ssdoFilterScale; float4 pxInput = tex2D(SamplerSSDOB,txCoords); pxInput.xyz *= 0.5; float sampleSum = 0.5; float weightDiv = 1.0+2.0/radius; [unroll] for (float hOffs=1.5; hOffs<radius; hOffs+=2.0*ssdoFilterStep) { float weight = 1.0/pow(weightDiv,hOffs*hOffs/radius); float2 fetchCoords = txCoords; fetchCoords.x += texelSize * hOffs; float4 fetch = tex2D(SamplerSSDOB,fetchCoords); float contribFact = max(0.0,sign(SSDO_CONTRIB_RANGE*SSDO_BLUR_DEPTH_DISCONTINUITY_THRESH_MULTIPLIER-abs(pxInput.w-fetch.w))) * weight; pxInput.xyz+=fetch.xyz * contribFact; sampleSum += contribFact; fetchCoords = txCoords; fetchCoords.x -= texelSize * hOffs; fetch = tex2D(SamplerSSDOB,fetchCoords); contribFact = max(0.0,sign(SSDO_CONTRIB_RANGE*SSDO_BLUR_DEPTH_DISCONTINUITY_THRESH_MULTIPLIER-abs(pxInput.w-fetch.w))) * weight; pxInput.xyz+=fetch.xyz * contribFact; sampleSum += contribFact; } pxInput.xyz /= sampleSum; return pxInput; } // Depth-Bilateral Gaussian Blur - Vertical float3 FX_BlurBilatV( float2 txCoords, float radius ) { float texelSize = pxSize.y/ssdoFilterScale; float4 pxInput = tex2D(SamplerSSDOC,txCoords); pxInput.xyz *= 0.5; float sampleSum = 0.5; float weightDiv = 1.0+2.0/radius; [unroll] for (float vOffs=1.5; vOffs<radius; vOffs+=2.0*ssdoFilterStep) { float weight = 1.0/pow(weightDiv,vOffs*vOffs/radius); float2 fetchCoords = txCoords; fetchCoords.y += texelSize * vOffs; float4 fetch = tex2D(SamplerSSDOC,fetchCoords); float contribFact = max(0.0,sign(SSDO_CONTRIB_RANGE*SSDO_BLUR_DEPTH_DISCONTINUITY_THRESH_MULTIPLIER-abs(pxInput.w-fetch.w))) * weight; pxInput.xyz+=fetch.xyz * contribFact; sampleSum += contribFact; fetchCoords = txCoords; fetchCoords.y -= texelSize * vOffs; fetch = tex2D(SamplerSSDOC,fetchCoords); contribFact = max(0.0,sign(SSDO_CONTRIB_RANGE*SSDO_BLUR_DEPTH_DISCONTINUITY_THRESH_MULTIPLIER-abs(pxInput.w-fetch.w))) * weight; pxInput.xyz+=fetch.xyz * contribFact; sampleSum += contribFact; } pxInput /= sampleSum; return pxInput.xyz; } #endif // *** Gaussian Blur *** #if (ENABLE_BLOOM == 1) // Gaussian Blur - Horizontal float3 FX_BlurH( float3 pxInput, sampler source, float2 txCoords, float radius, float downsampling ) { float texelSize = pxSize.x*downsampling; float2 fetchCoords = txCoords; float weight; float weightDiv = 1.0+5.0/radius; float sampleSum = 0.5; pxInput+=tex2D(source,txCoords).xyz*0.5; [unroll] for (float hOffs=1.5; hOffs<radius; hOffs+=2.0) { weight = 1.0/pow(weightDiv,hOffs*hOffs/radius); fetchCoords = txCoords; fetchCoords.x += texelSize * hOffs; pxInput+=tex2D(source, fetchCoords).xyz * weight; fetchCoords = txCoords; fetchCoords.x -= texelSize * hOffs; pxInput+=tex2D(source, fetchCoords).xyz * weight; sampleSum += 2.0 * weight; } pxInput /= sampleSum; return pxInput; } // Gaussian Blur - Vertical float3 FX_BlurV( float3 pxInput, sampler source, float2 txCoords, float radius, float downsampling ) { float texelSize = pxSize.y*downsampling; float2 fetchCoords = txCoords; float weight; float weightDiv = 1.0+5.0/radius; float sampleSum = 0.5; pxInput+=tex2D(source,txCoords).xyz*0.5; [unroll] for (float vOffs=1.5; vOffs<radius; vOffs+=2.0) { weight = 1.0/pow(weightDiv,vOffs*vOffs/radius); fetchCoords = txCoords; fetchCoords.y += texelSize * vOffs; pxInput+=tex2D(source, fetchCoords).xyz * weight; fetchCoords = txCoords; fetchCoords.y -= texelSize * vOffs; pxInput+=tex2D(source, fetchCoords).xyz * weight; sampleSum += 2.0 * weight; } pxInput /= sampleSum; return pxInput; } #endif // *** Bloom *** #if (ENABLE_BLOOM == 1) // Bloom - Mix-pass float4 FX_BloomMix( float3 pxInput, float2 txCoords ) { float3 blurTexture = tex2D(SamplerBloomA,txCoords).xyz; #if (ENABLE_UNSHARPMASK == 1) && (unsharpMaskB == 1) pxInput += (pxInput-blurTexture)*unsharpMaskBIntensity; #endif #if (ENABLE_LENSDIRT == 1) && (lensdirtSmoothmode == 1) pxInput += tex2D(SamplerDirt, txCoords).xyz*pow(dot(blurTexture,lumaCoeff),lensdirtCurve)*lensdirtIntensity; #endif blurTexture = pow(blurTexture,bloomCurve); blurTexture = lerp(dot(blurTexture.xyz,lumaCoeff.xyz),blurTexture,bloomSaturation); blurTexture /= max(1.0,max(blurTexture.x,max(blurTexture.y,blurTexture.z))); #if (bloomBlendMode == 1) pxInput = pxInput+blurTexture*bloomIntensity; return float4(pxInput,1.0+bloomIntensity); #elif (bloomBlendMode == 2) pxInput = max(pxInput,blurTexture*bloomIntensity); return float4(pxInput,max(1.0,bloomIntensity)); #elif (bloomBlendMode == 3) pxInput = blurTexture; return float4(pxInput,bloomIntensity); #endif } #endif // *** Godrays *** #if (ENABLE_GODRAYS == 1) float4 FX_Godrays( float4 pxInput, float2 txCoords ) { float2 stepSize = (txCoords-godraysSource) / (godraysSampleAmount*godraysFreq); float3 rayMask = 0.0; float rayWeight = 1.0; float finalWhitePoint = pxInput.w; for (int i=1;i<(int)godraysSampleAmount;i++) { rayMask += max(0.0, saturate(tex2D(SamplerColorHDRB, txCoords-stepSize*(float)i).xyz) - godraysThreshold) * rayWeight * godraysExposure; finalWhitePoint += rayWeight * godraysExposure; rayWeight /= godraysFalloff; } rayMask.xyz = dot(rayMask.xyz,lumaCoeff.xyz) / (finalWhitePoint-godraysThreshold); return float4(pxInput.xyz+rayMask.xyz,finalWhitePoint); } #endif // *** Custom Tonemapping *** #if (ENABLE_TONEMAP == 1) float3 FX_Tonemap( float3 pxInput, float whitePoint ) { pxInput = pow(pxInput*tonemapExposure,tonemapContrast); whitePoint = pow(whitePoint*tonemapExposure,tonemapContrast); #if (tonemapMode == 1) return saturate(pxInput.xyz/(whitePoint*tonemapCurve)); #endif #if (tonemapMode == 2) return saturate(lerp(pxInput,pow(pxInput.xyz/whitePoint,whitePoint-pxInput),dot(pxInput/whitePoint,lumaCoeff))); #endif #if (tonemapMode == 3) float exposureDiv = log10(whitePoint+1.0)/log10(whitePoint+1.0+tonemapCurve); pxInput.xyz = (log10(pxInput+1.0)/log10(pxInput+1.0+tonemapCurve))/exposureDiv; return saturate(lerp(pow(pxInput.xyz, 1.0 + tonemapSaturateBlacks), pxInput.xyz, sqrt( pxInput.xyz ) ) ); #endif } #endif // *** Vibrance *** #if (ENABLE_VIBRANCE == 1) float3 FX_Vibrance( float3 pxInput ) { float origLuma = dot(pxInput.xyz,lumaCoeff.xyz); float origChroma = max(pxInput.x,max(pxInput.y,pxInput.z)) - min(pxInput.x,min(pxInput.y,pxInput.z)); pxInput = lerp(origLuma.xxx, pxInput.xyz, 1.0+vibranceAmount*pow(origChroma,vibranceCurve)); return pxInput.xyz / max(1.0,max(pxInput.x,max(pxInput.y,pxInput.z))); } #endif // *** LiftGammaGain *** #if (ENABLE_LIFTGAMMAGAIN == 1) float3 FX_LiftGammaGain( float3 pxInput ) { float origLuma = dot(pxInput.xyz, lumaCoeff.xyz); pxInput.xyz *= lerp(1.0, lggLiftColor.xyz, pow(1.0-origLuma,8.0) * lggMultiplier); pxInput.xyz *= lerp(1.0, lggGammaColor.xyz, pow(1.0-abs(pxInput.xyz-0.5)*2.0,8.0) * lggMultiplier); pxInput.xyz *= lerp(1.0, lggGainColor.xyz, pow(origLuma,8.0) * lggMultiplier); pxInput.xyz *= (origLuma / max(0.000001,dot(pxInput.xyz,lumaCoeff))); pxInput.xyz /= max(1.0,max(pxInput.x,max(pxInput.y,pxInput.z))); return pxInput; } #endif // *** Technicolor *** #if (ENABLE_TECHNICOLOR == 1) float3 FX_Technicolor( float3 pxInput ) { float3 origColor = pxInput; float origChroma = max(origColor.x,max(origColor.y,origColor.z))-min(origColor.x,min(origColor.y,origColor.z)); float redPower = pxInput.x*(origChroma+techniPunch); float greenPower = pxInput.y*(origChroma+techniPunch); float bluePower = pxInput.z*(origChroma+techniPunch); pxInput.yz = pow(pxInput.yz,clamp(2.0*redPower,1.0,2.0)); pxInput.xz = pow(pxInput.xz,clamp(1.2*greenPower,1.0,1.2)); pxInput.xy = pow(pxInput.xy,clamp(1.75*bluePower,1.0,1.75)); pxInput.z *= 0.99; return lerp(origColor.xyz,pxInput,techniAmount); } #endif // *** Unsharp Mask *** #if (ENABLE_UNSHARPMASK == 1) && (unsharpMaskA == 1) float3 FX_UnsharpMask( float3 pxInput, float2 txCoords ) { #if (unsharpMaskAMode == 1) #define UNSHARPMASK_MODE (pxInput-blurTex) #elif (unsharpMaskAMode == 2) #define UNSHARPMASK_MODE (dot(pxInput,lumaCoeff)-dot(blurTex,lumaCoeff)) #elif (unsharpMaskAMode == 3) #define UNSHARPMASK_MODE (max(pxInput.x,max(pxInput.y,pxInput.z))-min(pxInput.x,min(pxInput.y,pxInput.z))-max(blurTex.x,max(blurTex.y,blurTex.z))-min(blurTex.x,min(blurTex.y,blurTex.z))) #endif float2 blurKernel[2] = { float2(-1.5 , 0.0), float2( 0.5 , 1.5) }; float3 blurTex = pxInput; for (float i = 0.0; i<2.0; i++) { blurTex += tex2D(SamplerColorHDRB,txCoords.xy+blurKernel[i]*pxSize.xy).xyz/(i+1.0); } blurTex /= 2.5; return saturate( pxInput + UNSHARPMASK_MODE * unsharpMaskAIntensity); } #endif // *** Filmgrain *** #if (ENABLE_FILMGRAIN == 1) float3 FX_Filmgrain( float3 pxInput, float2 txCoords ) { return pxInput.xyz+pow(tex2D(SamplerNoise,frac(txCoords*NOISE_SCREENSCALE*(1.0-grainSize)+frac(timer/100.0*grainFreq))).x,grainPower)*grainAmount; } #endif // *** Letterbox *** #if (ENABLE_LETTERBOX == 1) float FX_Letterbox( float2 txCoords ) { return max(0.0,sign(0.5-abs(txCoords.y-0.5)-letterboxSize)); } #endif // *** Log-Gamma *** #if (ENABLE_LOGGAMMA == 1) float3 FX_LogGamma( float3 pxInput ) { return lerp(pxInput,-0.0039*pow(1.0/0.0039, 1.0-pxInput.xyz)+1.0,0.7*(logGammaValue/2.2)); } #endif //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ VERTEX-SHADERS +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VS_OUTPUT_POST VS_PostProcess(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; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ PIXEL-SHADERS +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // *** Shader Structure *** float4 PS_SetOriginal(VS_OUTPUT_POST IN) : COLOR { return float4(tex2D(SamplerColor,IN.txcoord.xy).xyz,1.0); } // *** SSDO *** #if (ENABLE_SSDO == 1) float4 PS_ssdoViewSpace(VS_OUTPUT_POST IN) : COLOR { return viewSpace(IN.txcoord.xy); } float4 PS_ssdoScatter(VS_OUTPUT_POST IN) : COLOR { return FX_ssdoScatter(IN.txcoord.xy); } float4 PS_ssdoBlurScale(VS_OUTPUT_POST IN) : COLOR { return tex2D(SamplerSSDOA,IN.txcoord.xy); } float4 PS_ssdoBlurH(VS_OUTPUT_POST IN) : COLOR { return FX_BlurBilatH(IN.txcoord.xy,ssdoFilterRadius/ssdoFilterStep*ssdoFilterScale); } float4 PS_ssdoBlurV(VS_OUTPUT_POST IN) : COLOR { return float4(FX_BlurBilatV(IN.txcoord.xy,ssdoFilterRadius/ssdoFilterStep*ssdoFilterScale).xyz,1.0); } float4 PS_ssdoMix(VS_OUTPUT_POST IN) : COLOR { #if (ssdoMixMode == 2) #define SSDO_MIX_MODE +pow(tex2D(SamplerSSDOB,IN.txcoord.xy).xyz*2.0,ssdoIntensity)-1.0 #else #define SSDO_MIX_MODE *pow(tex2D(SamplerSSDOB,IN.txcoord.xy).xyz*2.0,ssdoIntensity) #endif #if (ssdoDebugMode == 1) return float4(saturate(0.5 SSDO_MIX_MODE),1.0); #elif (ssdoDebugMode == 2) return float4(tex2D(SamplerSSDOA,IN.txcoord.xy).xyz,1.0); #else return float4(saturate(tex2D(SamplerColor,IN.txcoord.xy).xyz SSDO_MIX_MODE),1.0); #endif } #endif // *** Bloom *** #if (ENABLE_BLOOM == 1) float4 PS_BloomThreshold(VS_OUTPUT_POST IN) : COLOR { return float4(threshold(tex2D(SamplerColorHDRA,IN.txcoord.xy).xyz,bloomThreshold),1.0); } float4 PS_BloomH_RadA(VS_OUTPUT_POST IN) : COLOR { return float4(FX_BlurH(0.0,SamplerBloomA,IN.txcoord.xy,bloomRadius,bloomDownsampling),1.0); } float4 PS_BloomV_RadA(VS_OUTPUT_POST IN) : COLOR { return float4(FX_BlurV(0.0,SamplerBloomB,IN.txcoord.xy,bloomRadius,bloomDownsampling),1.0); } float4 PS_BloomMix(VS_OUTPUT_POST IN) : COLOR { return FX_BloomMix(tex2D(SamplerColorHDRA,IN.txcoord.xy).xyz,IN.txcoord.xy); } #endif // *** Further FX *** float4 PS_LightFX(VS_OUTPUT_POST IN) : COLOR { float2 pxCoord = IN.txcoord.xy; float4 res = tex2D(SamplerColorHDRB,pxCoord); #if (ENABLE_GODRAYS == 1) res = FX_Godrays(res,pxCoord.xy); #endif return res; } float4 PS_ColorFX(VS_OUTPUT_POST IN) : COLOR { float2 pxCoord = IN.txcoord.xy; float4 res = tex2D(SamplerColorHDRA,pxCoord); #if (ENABLE_TONEMAP == 1) res.xyz = FX_Tonemap(res.xyz,res.w); #endif #if (ENABLE_VIBRANCE == 1) res.xyz = FX_Vibrance(res.xyz); #endif #if (ENABLE_LIFTGAMMAGAIN == 1) res.xyz = FX_LiftGammaGain(res.xyz); #endif #if (ENABLE_TECHNICOLOR == 1) res.xyz = FX_Technicolor(res.xyz); #endif return float4(res.xyz,1.0); } float4 PS_ImageFX(VS_OUTPUT_POST IN) : COLOR { float2 pxCoord = IN.txcoord.xy; float4 res = tex2D(SamplerColorHDRB,pxCoord); #if (ENABLE_UNSHARPMASK == 1) && (unsharpMaskA == 1) res.xyz = FX_UnsharpMask(res.xyz,pxCoord); #endif #if (ENABLE_FILMGRAIN == 1) res.xyz = FX_Filmgrain(res.xyz,pxCoord); #endif #if (ENABLE_LETTERBOX == 1) res.xyz *= FX_Letterbox(pxCoord); #endif #if (ENABLE_LOGGAMMA == 1) res.xyz = FX_LogGamma(res.xyz); #endif return float4(res.xyz,1.0); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // +++++ TECHNIQUES +++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ technique PPFX < bool toggle = 0x61; bool enabled = 1; > { pass setOriginal { VertexShader = VS_PostProcess; PixelShader = PS_SetOriginal; #if (ENABLE_SSDO == 1) RenderTarget0 = texColorLOD; #else #if (ENABLE_BLOOM == 1) RenderTarget0 = texColorHDRA; #else RenderTarget0 = texColorHDRB; #endif #endif } #if (ENABLE_SSDO == 1) pass ssdoViewSpace { VertexShader = VS_PostProcess; PixelShader = PS_ssdoViewSpace; RenderTarget0 = texViewSpace; } pass ssdoScatter { VertexShader = VS_PostProcess; PixelShader = PS_ssdoScatter; RenderTarget0 = texSSDOA; } pass ssdoBlurScale { VertexShader = VS_PostProcess; PixelShader = PS_ssdoBlurScale; RenderTarget0 = texSSDOB; } pass ssdoBlurH { VertexShader = VS_PostProcess; PixelShader = PS_ssdoBlurH; RenderTarget0 = texSSDOC; } pass ssdoBlurV { VertexShader = VS_PostProcess; PixelShader = PS_ssdoBlurV; RenderTarget0 = texSSDOB; } pass ssdoMix { VertexShader = VS_PostProcess; PixelShader = PS_ssdoMix; #if (ENABLE_BLOOM == 1) RenderTarget0 = texColorHDRA; #else RenderTarget0 = texColorHDRB; #endif } #endif #if (ENABLE_BLOOM == 1) pass bloomThresh { VertexShader = VS_PostProcess; PixelShader = PS_BloomThreshold; RenderTarget0 = texBloomA; } pass bloomH_RadA { VertexShader = VS_PostProcess; PixelShader = PS_BloomH_RadA; RenderTarget0 = texBloomB; } pass bloomV_RadA { VertexShader = VS_PostProcess; PixelShader = PS_BloomV_RadA; RenderTarget0 = texBloomA; } pass bloomMix { VertexShader = VS_PostProcess; PixelShader = PS_BloomMix; RenderTarget0 = texColorHDRB; } #endif pass lightFX { VertexShader = VS_PostProcess; PixelShader = PS_LightFX; RenderTarget0 = texColorHDRA; } pass colorFX { VertexShader = VS_PostProcess; PixelShader = PS_ColorFX; RenderTarget0 = texColorHDRB; } pass imageFX { VertexShader = VS_PostProcess; PixelShader = PS_ImageFX; #if (ENABLE_LOGGAMMA != 1) SRGBWriteEnable = TRUE; #endif } }

Comments

You need to be logged in to post a comment