├── Textures ├── lut.png └── FontAtlas.png ├── README.md ├── Shaders ├── Daltonize.fx ├── LUT.fx ├── TriDither.fxh ├── ReShade.fxh ├── UIMask.fx ├── DrawText.fxh ├── Deband.fx ├── ReShadeUI.fxh ├── DisplayDepth.fx ├── Blending.fxh └── Macros.fxh └── REFERENCE.md /Textures/lut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crosire/reshade-shaders/HEAD/Textures/lut.png -------------------------------------------------------------------------------- /Textures/FontAtlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crosire/reshade-shaders/HEAD/Textures/FontAtlas.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ReShade FX shaders 2 | ================== 3 | 4 | This repository aims to collect post-processing shaders written in the ReShade FX shader language. 5 | 6 | Installation 7 | ------------ 8 | 9 | 1. [Download](https://github.com/crosire/reshade-shaders/archive/master.zip) this repository 10 | 2. Extract the downloaded archive file somewhere 11 | 3. Start your game, open the ReShade in-game menu and switch to the "Settings" tab 12 | 4. Add the path to the extracted [Shaders](/Shaders) folder to "Effect Search Paths" 13 | 5. Add the path to the extracted [Textures](/Textures) folder to "Texture Search Paths" 14 | 6. Switch back to the "Home" tab and click on "Reload" to load the shaders 15 | 16 | Contributing 17 | ------------ 18 | 19 | Check out [the language reference document](REFERENCE.md) to get started on how to write your own! 20 | -------------------------------------------------------------------------------- /Shaders/Daltonize.fx: -------------------------------------------------------------------------------- 1 | /** 2 | * Daltonization algorithm by daltonize.org 3 | * http://www.daltonize.org/2010/05/lms-daltonization-algorithm.html 4 | * Originally ported to ReShade by IDDQD, modified for ReShade 3.0 by crosire 5 | */ 6 | 7 | uniform int Type < 8 | ui_type = "combo"; 9 | ui_items = "Protanopia\0Deuteranopia\0Tritanopia\0"; 10 | > = 0; 11 | 12 | #include "ReShade.fxh" 13 | 14 | float3 PS_DaltonizeFXmain(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target 15 | { 16 | float3 input = tex2D(ReShade::BackBuffer, texcoord).rgb; 17 | 18 | // RGB to LMS matrix conversion 19 | float OnizeL = (17.8824f * input.r) + (43.5161f * input.g) + (4.11935f * input.b); 20 | float OnizeM = (3.45565f * input.r) + (27.1554f * input.g) + (3.86714f * input.b); 21 | float OnizeS = (0.0299566f * input.r) + (0.184309f * input.g) + (1.46709f * input.b); 22 | 23 | // Simulate color blindness 24 | float Daltl, Daltm, Dalts; 25 | 26 | if (Type == 0) // Protanopia - reds are greatly reduced (1% men) 27 | { 28 | Daltl = 0.0f * OnizeL + 2.02344f * OnizeM + -2.52581f * OnizeS; 29 | Daltm = 0.0f * OnizeL + 1.0f * OnizeM + 0.0f * OnizeS; 30 | Dalts = 0.0f * OnizeL + 0.0f * OnizeM + 1.0f * OnizeS; 31 | } 32 | else if (Type == 1) // Deuteranopia - greens are greatly reduced (1% men) 33 | { 34 | Daltl = 1.0f * OnizeL + 0.0f * OnizeM + 0.0f * OnizeS; 35 | Daltm = 0.494207f * OnizeL + 0.0f * OnizeM + 1.24827f * OnizeS; 36 | Dalts = 0.0f * OnizeL + 0.0f * OnizeM + 1.0f * OnizeS; 37 | } 38 | else if (Type == 2) // Tritanopia - blues are greatly reduced (0.003% population) 39 | { 40 | Daltl = 1.0f * OnizeL + 0.0f * OnizeM + 0.0f * OnizeS; 41 | Daltm = 0.0f * OnizeL + 1.0f * OnizeM + 0.0f * OnizeS; 42 | Dalts = -0.395913f * OnizeL + 0.801109f * OnizeM + 0.0f * OnizeS; 43 | } 44 | 45 | // LMS to RGB matrix conversion 46 | float3 error; 47 | error.r = (0.0809444479f * Daltl) + (-0.130504409f * Daltm) + (0.116721066f * Dalts); 48 | error.g = (-0.0102485335f * Daltl) + (0.0540193266f * Daltm) + (-0.113614708f * Dalts); 49 | error.b = (-0.000365296938f * Daltl) + (-0.00412161469f * Daltm) + (0.693511405f * Dalts); 50 | 51 | // Isolate invisible colors to color vision deficiency (calculate error matrix) 52 | error = (input - error); 53 | 54 | // Shift colors towards visible spectrum (apply error modifications) 55 | float3 correction; 56 | correction.r = 0; // (error.r * 0.0) + (error.g * 0.0) + (error.b * 0.0); 57 | correction.g = (error.r * 0.7) + (error.g * 1.0); // + (error.b * 0.0); 58 | correction.b = (error.r * 0.7) + (error.b * 1.0); // + (error.g * 0.0); 59 | 60 | // Add compensation to original values 61 | correction = input + correction; 62 | 63 | return correction; 64 | } 65 | 66 | technique Daltonize 67 | { 68 | pass 69 | { 70 | VertexShader = PostProcessVS; 71 | PixelShader = PS_DaltonizeFXmain; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Shaders/LUT.fx: -------------------------------------------------------------------------------- 1 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 | // ReShade effect file 3 | // visit facebook.com/MartyMcModding for news/updates 4 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 | // Marty's LUT shader 1.0 for ReShade 3.0 6 | // Copyright © 2008-2016 Marty McFly 7 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 | 9 | #ifndef fLUT_TextureName 10 | #define fLUT_TextureName "lut.png" 11 | #endif 12 | #ifndef fLUT_TileSizeXY 13 | #define fLUT_TileSizeXY 32 14 | #endif 15 | #ifndef fLUT_TileAmount 16 | #define fLUT_TileAmount 32 17 | #endif 18 | 19 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 20 | // 21 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 22 | 23 | #include "ReShadeUI.fxh" 24 | 25 | uniform float fLUT_AmountChroma < __UNIFORM_SLIDER_FLOAT1 26 | ui_min = 0.00; ui_max = 1.00; 27 | ui_label = "LUT chroma amount"; 28 | ui_tooltip = "Intensity of color/chroma change of the LUT."; 29 | > = 1.00; 30 | 31 | uniform float fLUT_AmountLuma < __UNIFORM_SLIDER_FLOAT1 32 | ui_min = 0.00; ui_max = 1.00; 33 | ui_label = "LUT luma amount"; 34 | ui_tooltip = "Intensity of luma change of the LUT."; 35 | > = 1.00; 36 | 37 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 38 | // 39 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 40 | 41 | #include "ReShade.fxh" 42 | texture texLUT < source = fLUT_TextureName; > { Width = fLUT_TileSizeXY*fLUT_TileAmount; Height = fLUT_TileSizeXY; Format = RGBA8; }; 43 | sampler SamplerLUT { Texture = texLUT; }; 44 | 45 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 46 | // 47 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 48 | 49 | void PS_LUT_Apply(float4 vpos : SV_Position, float2 texcoord : TEXCOORD, out float4 res : SV_Target0) 50 | { 51 | float4 color = tex2D(ReShade::BackBuffer, texcoord.xy); 52 | float2 texelsize = 1.0 / fLUT_TileSizeXY; 53 | texelsize.x /= fLUT_TileAmount; 54 | 55 | float3 lutcoord = float3((color.xy*fLUT_TileSizeXY-color.xy+0.5)*texelsize.xy,color.z*fLUT_TileSizeXY-color.z); 56 | float lerpfact = frac(lutcoord.z); 57 | lutcoord.x += (lutcoord.z-lerpfact)*texelsize.y; 58 | 59 | float3 lutcolor = lerp(tex2D(SamplerLUT, lutcoord.xy).xyz, tex2D(SamplerLUT, float2(lutcoord.x+texelsize.y,lutcoord.y)).xyz,lerpfact); 60 | 61 | color.xyz = lerp(normalize(color.xyz), normalize(lutcolor.xyz), fLUT_AmountChroma) * 62 | lerp(length(color.xyz), length(lutcolor.xyz), fLUT_AmountLuma); 63 | 64 | res.xyz = color.xyz; 65 | res.w = 1.0; 66 | } 67 | 68 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 69 | // 70 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 71 | 72 | 73 | technique LUT 74 | { 75 | pass LUT_Apply 76 | { 77 | VertexShader = PostProcessVS; 78 | PixelShader = PS_LUT_Apply; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Shaders/TriDither.fxh: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Triangular Dither // 3 | // By The Sandvich Maker // 4 | // Ported to ReShade by TreyM // 5 | //////////////////////////////////////////////////////////////////////////////// 6 | 7 | //////////////////////////////////////////////////////////////////////////////// 8 | // // 9 | // Usage: // 10 | // Include this file in your shader like so: #include "TriDither.fx" // 11 | // // 12 | // For shader developers, use this syntax to do a function call in your // 13 | // code as the last thing before exiting a given shader. You should dither // 14 | // anytime data is going to be truncated to a lower bitdepth. Color input // 15 | // must be a float3 value. // 16 | // // 17 | // input.rgb += TriDither(input.rgb, uv, bits); // 18 | // // 19 | // "bits" is an integer number that determines the bit depth // 20 | // being dithered to. Usually 8, sometimes 10 // 21 | // You can automate this by letting Reshade decide like so: // 22 | // // 23 | // input += TriDither(input, uv, BUFFER_COLOR_BIT_DEPTH); // 24 | // // 25 | // Manual setup looks something like this for an 8-bit backbuffer: // 26 | // // 27 | // input.rgb += TriDither(input.rgb, uv, 8); // 28 | // // 29 | //////////////////////////////////////////////////////////////////////////////// 30 | 31 | uniform float DitherTimer < source = "timer"; >; 32 | #define remap(v, a, b) (((v) - (a)) / ((b) - (a))) 33 | 34 | float rand21(float2 uv) 35 | { 36 | float2 noise = frac(sin(dot(uv, float2(12.9898, 78.233) * 2.0)) * 43758.5453); 37 | return (noise.x + noise.y) * 0.5; 38 | } 39 | 40 | float rand11(float x) 41 | { 42 | return frac(x * 0.024390243); 43 | } 44 | 45 | float permute(float x) 46 | { 47 | return ((34.0 * x + 1.0) * x) % 289.0; 48 | } 49 | 50 | float3 TriDither(float3 color, float2 uv, int bits) 51 | { 52 | float bitstep = exp2(bits) - 1.0; 53 | float lsb = 1.0 / bitstep; 54 | float lobit = 0.5 / bitstep; 55 | float hibit = (bitstep - 0.5) / bitstep; 56 | 57 | float3 m = float3(uv, rand21(uv + (DitherTimer * 0.001))) + 1.0; 58 | float h = permute(permute(permute(m.x) + m.y) + m.z); 59 | 60 | float3 noise1, noise2; 61 | noise1.x = rand11(h); h = permute(h); 62 | noise2.x = rand11(h); h = permute(h); 63 | noise1.y = rand11(h); h = permute(h); 64 | noise2.y = rand11(h); h = permute(h); 65 | noise1.z = rand11(h); h = permute(h); 66 | noise2.z = rand11(h); 67 | 68 | float3 lo = saturate(remap(color.xyz, 0.0, lobit)); 69 | float3 hi = saturate(remap(color.xyz, 1.0, hibit)); 70 | float3 uni = noise1 - 0.5; 71 | float3 tri = noise1 - noise2; 72 | return lerp(uni, tri, min(lo, hi)) * lsb; 73 | } 74 | -------------------------------------------------------------------------------- /Shaders/ReShade.fxh: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: CC0-1.0 3 | */ 4 | 5 | #pragma once 6 | 7 | #if !defined(__RESHADE__) || __RESHADE__ < 30000 8 | #error "ReShade 3.0+ is required to use this header file" 9 | #endif 10 | 11 | #ifndef RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 12 | #define RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 0 13 | #endif 14 | #ifndef RESHADE_DEPTH_INPUT_IS_REVERSED 15 | #define RESHADE_DEPTH_INPUT_IS_REVERSED 1 16 | #endif 17 | #ifndef RESHADE_DEPTH_INPUT_IS_MIRRORED 18 | #define RESHADE_DEPTH_INPUT_IS_MIRRORED 0 19 | #endif 20 | #ifndef RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 21 | #define RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 0 22 | #endif 23 | 24 | #ifndef RESHADE_DEPTH_MULTIPLIER 25 | #define RESHADE_DEPTH_MULTIPLIER 1 26 | #endif 27 | #ifndef RESHADE_DEPTH_LINEARIZATION_FAR_PLANE 28 | #define RESHADE_DEPTH_LINEARIZATION_FAR_PLANE 1000.0 29 | #endif 30 | 31 | // Above 1 expands coordinates, below 1 contracts and 1 is equal to no scaling on any axis 32 | #ifndef RESHADE_DEPTH_INPUT_Y_SCALE 33 | #define RESHADE_DEPTH_INPUT_Y_SCALE 1 34 | #endif 35 | #ifndef RESHADE_DEPTH_INPUT_X_SCALE 36 | #define RESHADE_DEPTH_INPUT_X_SCALE 1 37 | #endif 38 | // An offset to add to the Y coordinate, (+) = move up, (-) = move down 39 | #ifndef RESHADE_DEPTH_INPUT_Y_OFFSET 40 | #define RESHADE_DEPTH_INPUT_Y_OFFSET 0 41 | #endif 42 | #ifndef RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET 43 | #define RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET 0 44 | #endif 45 | // An offset to add to the X coordinate, (+) = move right, (-) = move left 46 | #ifndef RESHADE_DEPTH_INPUT_X_OFFSET 47 | #define RESHADE_DEPTH_INPUT_X_OFFSET 0 48 | #endif 49 | #ifndef RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET 50 | #define RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET 0 51 | #endif 52 | 53 | #define BUFFER_PIXEL_SIZE float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT) 54 | #define BUFFER_SCREEN_SIZE float2(BUFFER_WIDTH, BUFFER_HEIGHT) 55 | #define BUFFER_ASPECT_RATIO (BUFFER_WIDTH * BUFFER_RCP_HEIGHT) 56 | 57 | namespace ReShade 58 | { 59 | #if defined(__RESHADE_FXC__) 60 | float GetAspectRatio() { return BUFFER_WIDTH * BUFFER_RCP_HEIGHT; } 61 | float2 GetPixelSize() { return float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); } 62 | float2 GetScreenSize() { return float2(BUFFER_WIDTH, BUFFER_HEIGHT); } 63 | #define AspectRatio GetAspectRatio() 64 | #define PixelSize GetPixelSize() 65 | #define ScreenSize GetScreenSize() 66 | #else 67 | // These are deprecated and will be removed eventually. 68 | static const float AspectRatio = BUFFER_WIDTH * BUFFER_RCP_HEIGHT; 69 | static const float2 PixelSize = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); 70 | static const float2 ScreenSize = float2(BUFFER_WIDTH, BUFFER_HEIGHT); 71 | #endif 72 | 73 | // Global textures and samplers 74 | texture BackBufferTex : COLOR; 75 | texture DepthBufferTex : DEPTH; 76 | 77 | sampler BackBuffer { Texture = BackBufferTex; }; 78 | sampler DepthBuffer { Texture = DepthBufferTex; }; 79 | 80 | // Helper functions 81 | float GetLinearizedDepth(float2 texcoord) 82 | { 83 | #if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 84 | texcoord.y = 1.0 - texcoord.y; 85 | #endif 86 | #if RESHADE_DEPTH_INPUT_IS_MIRRORED 87 | texcoord.x = 1.0 - texcoord.x; 88 | #endif 89 | texcoord.x /= RESHADE_DEPTH_INPUT_X_SCALE; 90 | texcoord.y /= RESHADE_DEPTH_INPUT_Y_SCALE; 91 | #if RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET 92 | texcoord.x -= RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET * BUFFER_RCP_WIDTH; 93 | #else // Do not check RESHADE_DEPTH_INPUT_X_OFFSET, since it may be a decimal number, which the preprocessor cannot handle 94 | texcoord.x -= RESHADE_DEPTH_INPUT_X_OFFSET / 2.000000001; 95 | #endif 96 | #if RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET 97 | texcoord.y += RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET * BUFFER_RCP_HEIGHT; 98 | #else 99 | texcoord.y += RESHADE_DEPTH_INPUT_Y_OFFSET / 2.000000001; 100 | #endif 101 | float depth = tex2Dlod(DepthBuffer, float4(texcoord, 0, 0)).x * RESHADE_DEPTH_MULTIPLIER; 102 | 103 | #if RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 104 | const float C = 0.01; 105 | depth = (exp(depth * log(C + 1.0)) - 1.0) / C; 106 | #endif 107 | #if RESHADE_DEPTH_INPUT_IS_REVERSED 108 | depth = 1.0 - depth; 109 | #endif 110 | const float N = 1.0; 111 | depth /= RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - depth * (RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - N); 112 | 113 | return depth; 114 | } 115 | } 116 | 117 | // Vertex shader generating a triangle covering the entire screen 118 | // See also https://www.reddit.com/r/gamedev/comments/2j17wk/a_slightly_faster_bufferless_vertex_shader_trick/ 119 | void PostProcessVS(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD) 120 | { 121 | texcoord.x = (id == 2) ? 2.0 : 0.0; 122 | texcoord.y = (id == 1) ? 2.0 : 0.0; 123 | position = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0); 124 | } 125 | -------------------------------------------------------------------------------- /Shaders/UIMask.fx: -------------------------------------------------------------------------------- 1 | /* 2 | Simple UIMask shader by luluco250 3 | 4 | I have no idea why this was never ported back to ReShade 3.0 from 2.0, 5 | but if you missed it, here it is. 6 | 7 | It doesn't feature the auto mask from the original shader. 8 | 9 | It does feature a new multi-channnel masking feature. UI masks can now contain 10 | separate 'modes' within each of the three color channels. 11 | 12 | For example, you can have the regular hud on the red channel (the default one), 13 | a mask for an inventory screen on the green channel and a mask for a quest menu 14 | on the blue channel. You can then use keyboard keys to toggle each channel on or off. 15 | 16 | Multiple channels can be active at once, they'll just add up to mask the image. 17 | 18 | Simple/legacy masks are not affected by this, they'll work just as you'd expect, 19 | so you can still make simple black and white masks that use all color channels, it'll 20 | be no different than just having it on a single channel. 21 | 22 | Tips: 23 | 24 | --You can adjust how much it will affect your HUD by changing "Mask Intensity". 25 | 26 | --You don't actually need to place the UIMask_Bottom technique at the bottom of 27 | your shader pipeline, if you have any effects that don't necessarily affect 28 | the visibility of the HUD you can place it before that. 29 | For instance, if you use color correction shaders like LUT, you might want 30 | to place UIMask_Bottom just before that. 31 | 32 | --Preprocessor flags: 33 | --UIMASK_MULTICHANNEL: 34 | Enables having up to three different masks on each color channel. 35 | 36 | --Refer to this page for keycodes: 37 | https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx 38 | 39 | --To make a custom mask: 40 | 41 | 1-Take a screenshot of your game with the HUD enabled, 42 | preferrably with any effects disabled for maximum visibility. 43 | 44 | 2-Open the screenshot with your preferred image editor program, I use GIMP. 45 | 46 | 3-Make a background white layer if there isn't one already. 47 | Be sure to leave it behind your actual screenshot for the while. 48 | 49 | 4-Make an empty layer for the mask itself, you can call it "mask". 50 | 51 | 5-Having selected the mask layer, paint the places where HUD constantly is, 52 | such as health bars, important messages, minimaps etc. 53 | 54 | 6-Delete or make your screenshot layer invisible. 55 | 56 | 7-Before saving your mask, let's do some gaussian blurring to improve it's look and feel: 57 | For every step of blurring you want to do, make a new layer, such as: 58 | Mask - Blur16x16 59 | Mask - Blur8x8 60 | Mask - Blur4x4 61 | Mask - Blur2x2 62 | Mask - NoBlur 63 | You should use your image editor's default gaussian blurring filter, if there is one. 64 | This avoids possible artifacts and makes the mask blend more easily on the eyes. 65 | You may not need this if your mask is accurate enough and/or the HUD is simple enough. 66 | 67 | 8-Now save the final image with a unique name such as "MyUIMask.png" in your textures folder. 68 | 69 | 9-Set the preprocessor definition UIMASK_TEXTURE to the unique name of your image, with quotes. 70 | You're done! 71 | 72 | 73 | MIT Licensed: 74 | 75 | Copyright (c) 2017 Lucas Melo 76 | 77 | Permission is hereby granted, free of charge, to any person obtaining a copy 78 | of this software and associated documentation files (the "Software"), to deal 79 | in the Software without restriction, including without limitation the rights 80 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 81 | copies of the Software, and to permit persons to whom the Software is 82 | furnished to do so, subject to the following conditions: 83 | 84 | The above copyright notice and this permission notice shall be included in all 85 | copies or substantial portions of the Software. 86 | 87 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 88 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 89 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 90 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 91 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 92 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 93 | SOFTWARE. 94 | */ 95 | 96 | //#region Preprocessor 97 | 98 | #include "ReShade.fxh" 99 | #include "ReShadeUI.fxh" 100 | 101 | #ifndef UIMASK_MULTICHANNEL 102 | #define UIMASK_MULTICHANNEL 0 103 | #endif 104 | 105 | #if !UIMASK_MULTICHANNEL 106 | #define TEXFORMAT R8 107 | #else 108 | #define TEXFORMAT RGBA8 109 | #endif 110 | 111 | #ifndef UIMASK_TEXTURE 112 | #define UIMASK_TEXTURE "UIMask.png" 113 | #endif 114 | 115 | //#endregion 116 | 117 | namespace UIMask 118 | { 119 | 120 | //#region Uniforms 121 | 122 | uniform int _Help 123 | < 124 | ui_label = " "; 125 | ui_text = 126 | "For more detailed instructions, see the text at the top of this " 127 | "effect's shader file (UIMask.fx).\n" 128 | "\n" 129 | "Available preprocessor definitions:\n" 130 | " UIMASK_MULTICHANNEL:\n" 131 | " If set to 1, each of the RGB color channels in the texture is " 132 | "treated as a separate mask.\n" 133 | "\n" 134 | "How to create a mask:\n" 135 | "\n" 136 | "1. Take a screenshot with the game's UI appearing.\n" 137 | "2. Open the screenshot in an image editor, GIMP or Photoshop are " 138 | "recommended.\n" 139 | "3. Create a new layer over the screenshot layer, fill it with black.\n" 140 | "4. Reduce the layer opacity so you can see the screenshot layer " 141 | "below.\n" 142 | "5. Cover the UI with white to mask it from effects. The stronger the " 143 | "mask white color, the more opaque the mask will be.\n" 144 | "6. Set the mask layer opacity back to 100%.\n" 145 | "7. Save the image in one of your texture folders, making sure to " 146 | "use a unique name such as: \"MyUIMask.png\"\n" 147 | "8. Set the preprocessor definition UIMASK_TEXTURE to the name of " 148 | "your image, with quotes: \"MyUIMask.png\"\n" 149 | ; 150 | ui_category = "Help"; 151 | ui_category_closed = true; 152 | ui_type = "radio"; 153 | >; 154 | 155 | uniform float fMask_Intensity 156 | < 157 | __UNIFORM_SLIDER_FLOAT1 158 | 159 | ui_label = "Mask Intensity"; 160 | ui_tooltip = 161 | "How much to mask effects from affecting the original image.\n" 162 | "\nDefault: 1.0"; 163 | ui_min = 0.0; 164 | ui_max = 1.0; 165 | ui_step = 0.001; 166 | > = 1.0; 167 | 168 | uniform bool bDisplayMask < 169 | ui_label = "Display Mask"; 170 | ui_tooltip = 171 | "Display the mask texture.\n" 172 | "Useful for testing multiple channels or simply the mask itself.\n" 173 | "\nDefault: Off"; 174 | > = false; 175 | 176 | #if UIMASK_MULTICHANNEL 177 | 178 | uniform bool bToggleRed < 179 | ui_label = "Toggle Red Channel"; 180 | ui_tooltip = "Toggle UI masking for the red channel.\n" 181 | "Right click to assign a hotkey.\n" 182 | "\nDefault: On"; 183 | > = true; 184 | 185 | uniform bool bToggleGreen < 186 | ui_label = "Toggle Green Channel"; 187 | ui_tooltip = "Toggle UI masking for the green channel.\n" 188 | "Right click to assign a hotkey." 189 | "\nDefault: On"; 190 | > = true; 191 | 192 | uniform bool bToggleBlue < 193 | ui_label = "Toggle Blue Channel"; 194 | ui_tooltip = "Toggle UI masking for the blue channel.\n" 195 | "Right click to assign a hotkey." 196 | "\nDefault: On"; 197 | > = true; 198 | 199 | #endif 200 | 201 | //#endregion 202 | 203 | //#region Textures 204 | 205 | texture BackupTex 206 | { 207 | Width = BUFFER_WIDTH; 208 | Height = BUFFER_HEIGHT; 209 | }; 210 | sampler Backup 211 | { 212 | Texture = BackupTex; 213 | }; 214 | 215 | texture MaskTex 216 | { 217 | Width = BUFFER_WIDTH; 218 | Height = BUFFER_HEIGHT; 219 | Format = TEXFORMAT; 220 | }; 221 | sampler Mask 222 | { 223 | Texture = MaskTex; 224 | }; 225 | 226 | //#endregion 227 | 228 | //#region Shaders 229 | 230 | float4 BackupPS(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target { 231 | return tex2D(ReShade::BackBuffer, uv); 232 | } 233 | 234 | float4 MainPS(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target { 235 | float4 color = tex2D(ReShade::BackBuffer, uv); 236 | float4 backup = tex2D(Backup, uv); 237 | 238 | #if !UIMASK_MULTICHANNEL 239 | float mask = tex2D(Mask, uv).r; 240 | #else 241 | float3 mask_rgb = tex2D(Mask, uv).rgb; 242 | 243 | // This just works, it basically adds masking with each channel that has 244 | // been toggled. 245 | float mask = saturate( 246 | 1.0 - dot(1.0 - mask_rgb, 247 | float3(bToggleRed, bToggleGreen, bToggleBlue))); 248 | #endif 249 | 250 | color = lerp(color, backup, mask * fMask_Intensity); 251 | color = bDisplayMask ? mask : color; 252 | 253 | return color; 254 | } 255 | 256 | //#endregion 257 | 258 | //#region Techniques 259 | 260 | technique UIMask_Top 261 | < 262 | ui_tooltip = "Place this *above* the effects to be masked."; 263 | > 264 | { 265 | pass 266 | { 267 | VertexShader = PostProcessVS; 268 | PixelShader = BackupPS; 269 | RenderTarget = BackupTex; 270 | } 271 | } 272 | 273 | technique UIMask_Bottom 274 | < 275 | ui_tooltip = 276 | "Place this *below* the effects to be masked.\n" 277 | "If you want to add a toggle key for the effect, set it to this one."; 278 | > 279 | { 280 | pass 281 | { 282 | VertexShader = PostProcessVS; 283 | PixelShader = MainPS; 284 | } 285 | } 286 | 287 | //#endregion 288 | 289 | } // Namespace. 290 | -------------------------------------------------------------------------------- /Shaders/DrawText.fxh: -------------------------------------------------------------------------------- 1 | #ifndef _DRAWTEXT_H_ 2 | #define _DRAWTEXT_H_ 3 | 4 | #define _DRAWTEXT_GRID_X 14.0 5 | #define _DRAWTEXT_GRID_Y 7.0 6 | 7 | 8 | /////////////////////////////////////////////////////////////////////////////////////////////////////// 9 | // // 10 | // DrawText.fxh by kingreic1992 ( update: Sep.28.2019 ) // 11 | // // 12 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// 13 | // // 14 | // Available functions: // 15 | // DrawText_String( offset, text size, xy ratio, input coord, string array, array size, output) // 16 | // float2 offset = top left corner of string, screen hight pixel unit. // 17 | // float text size = text size, screen hight pixel unit. // 18 | // float xy ratio = xy ratio of text. // 19 | // float2 input coord = current texture coord. // 20 | // int string array = string data in float2 array format, ex: "Demo Text" // 21 | // int String0[9] = { __D, __e, __m, __o, __Space, __T, __e, __x, __t}; // 22 | // int string size = size of the string array. // 23 | // float output = output. // 24 | // // 25 | // DrawText_Digit( offset, text size, xy ratio, input coord, precision after dot, data, output) // 26 | // float2 offset = same as DrawText_String. // 27 | // float text size = same as DrawText_String. // 28 | // float xy ratio = same as DrawText_String. // 29 | // float2 input coord = same as DrawText_String. // 30 | // int precision = digits after dot. // 31 | // float data = input float. // 32 | // float output = output. // 33 | // // 34 | // float2 DrawText_Shift(offset, shift, text size, xy ratio) // 35 | // float2 offset = same as DrawText_String. // 36 | // float2 shift = shift line(y) and column. // 37 | // float text size = same as DrawText_String. // 38 | // float xy ratio = same as DrawText_String. // 39 | // // 40 | /////////////////////////////////////////////////////////////////////////////////////////////////////// 41 | 42 | 43 | //Sample Usage 44 | 45 | /* 46 | 47 | #include "DrawText.fxh" 48 | 49 | float4 main_fragment( float4 position : POSITION, 50 | float2 txcoord : TEXCOORD) : COLOR { 51 | float res = 0.0; 52 | 53 | int line0[9] = { __D, __e, __m, __o, __Space, __T, __e, __x, __t }; //Demo Text 54 | int line1[15] = { __b, __y, __Space, __k, __i, __n, __g, __e, __r, __i, __c, __1, __9, __9, __2 }; //by kingeric1992 55 | int line2[6] = { __S, __i, __z, __e, __Colon, __Space }; // Size: %d. 56 | 57 | DrawText_String(float2(100.0 , 100.0), 32, 1, txcoord, line0, 9, res); 58 | DrawText_String(float2(100.0 , 134.0), textSize, 1, txcoord, line1, 15, res); 59 | DrawText_String(DrawText_Shift(float2(100.0 , 134.0), int2(0, 1), textSize, 1), 18, 1, txcoord, line2, 6, res); 60 | DrawText_Digit(DrawText_Shift(DrawText_Shift(float2(100.0 , 134.0), int2(0, 1), textSize, 1), int2(8, 0), 18, 1), 61 | 18, 1, txcoord, 0, textSize, res); 62 | return res; 63 | } 64 | */ 65 | 66 | //Text display 67 | //Character indexing 68 | #define __Space 0 // (space) 69 | #define __Exclam 1 // ! 70 | #define __Quote 2 // " 71 | #define __Pound 3 // # 72 | #define __Dollar 4 // $ 73 | #define __Percent 5 // % 74 | #define __And 6 // & 75 | #define __sQuote 7 // ' 76 | #define __rBrac_O 8 // ( 77 | #define __rBrac_C 9 // ) 78 | #define __Asterisk 10 // * 79 | #define __Plus 11 // + 80 | #define __Comma 12 // , 81 | #define __Minus 13 // - 82 | 83 | #define __Dot 14 // . 84 | #define __Slash 15 // / 85 | #define __0 16 // 0 86 | #define __1 17 // 1 87 | #define __2 18 // 2 88 | #define __3 19 // 3 89 | #define __4 20 // 4 90 | #define __5 21 // 5 91 | #define __6 22 // 6 92 | #define __7 23 // 7 93 | #define __8 24 // 8 94 | #define __9 25 // 9 95 | #define __Colon 26 // : 96 | #define __sColon 27 // ; 97 | 98 | #define __Less 28 // < 99 | #define __Equals 29 // = 100 | #define __Greater 30 // > 101 | #define __Question 31 // ? 102 | #define __at 32 // @ 103 | #define __A 33 // A 104 | #define __B 34 // B 105 | #define __C 35 // C 106 | #define __D 36 // D 107 | #define __E 37 // E 108 | #define __F 38 // F 109 | #define __G 39 // G 110 | #define __H 40 // H 111 | #define __I 41 // I 112 | 113 | #define __J 42 // J 114 | #define __K 43 // K 115 | #define __L 44 // L 116 | #define __M 45 // M 117 | #define __N 46 // N 118 | #define __O 47 // O 119 | #define __P 48 // P 120 | #define __Q 49 // Q 121 | #define __R 50 // R 122 | #define __S 51 // S 123 | #define __T 52 // T 124 | #define __U 53 // U 125 | #define __V 54 // V 126 | #define __W 55 // W 127 | 128 | #define __X 56 // X 129 | #define __Y 57 // Y 130 | #define __Z 58 // Z 131 | #define __sBrac_O 59 // [ 132 | #define __Backslash 60 // \.. 133 | #define __sBrac_C 61 // ] 134 | #define __Caret 62 // ^ 135 | #define __Underscore 63 // _ 136 | #define __Punc 64 // ` 137 | #define __a 65 // a 138 | #define __b 66 // b 139 | #define __c 67 // c 140 | #define __d 68 // d 141 | #define __e 69 // e 142 | 143 | #define __f 70 // f 144 | #define __g 71 // g 145 | #define __h 72 // h 146 | #define __i 73 // i 147 | #define __j 74 // j 148 | #define __k 75 // k 149 | #define __l 76 // l 150 | #define __m 77 // m 151 | #define __n 78 // n 152 | #define __o 79 // o 153 | #define __p 80 // p 154 | #define __q 81 // q 155 | #define __r 82 // r 156 | #define __s 83 // s 157 | 158 | #define __t 84 // t 159 | #define __u 85 // u 160 | #define __v 86 // v 161 | #define __w 87 // w 162 | #define __x 88 // x 163 | #define __y 89 // y 164 | #define __z 90 // z 165 | #define __cBrac_O 91 // { 166 | #define __vBar 92 // | 167 | #define __cBrac_C 93 // } 168 | #define __Tilde 94 // ~ 169 | #define __tridot 95 // (...) 170 | #define __empty0 96 // (null) 171 | #define __empty1 97 // (null) 172 | //Character indexing ends 173 | 174 | texture Texttex < source = "FontAtlas.png"; > { 175 | Width = 512; 176 | Height = 512; 177 | }; 178 | 179 | sampler samplerText { 180 | Texture = Texttex; 181 | }; 182 | 183 | //accomodate for undef array size. 184 | #define DrawText_String( pos, size, ratio, tex, array, arrSize, output ) \ 185 | { float text = 0.0; \ 186 | float2 uv = (tex * float2(BUFFER_WIDTH, BUFFER_HEIGHT) - pos) / size; \ 187 | uv.y = saturate(uv.y); \ 188 | uv.x *= ratio * 2.0; \ 189 | float id = array[int(trunc(uv.x))]; \ 190 | if(uv.x <= arrSize && uv.x >= 0.0) \ 191 | text = tex2D(samplerText, (frac(uv) + float2( id % 14.0, trunc(id / 14.0))) \ 192 | / float2( _DRAWTEXT_GRID_X, _DRAWTEXT_GRID_Y) ).x; \ 193 | output += text; } 194 | 195 | float2 DrawText_Shift( float2 pos, int2 shift, float size, float ratio ) { 196 | return pos + size * shift * float2(0.5, 1.0) / ratio; 197 | } 198 | 199 | void DrawText_Digit( float2 pos, float size, float ratio, float2 tex, int digit, float data, inout float res) { 200 | int digits[13] = { 201 | __0, __1, __2, __3, __4, __5, __6, __7, __8, __9, __Minus, __Space, __Dot 202 | }; 203 | 204 | float2 uv = (tex * float2(BUFFER_WIDTH, BUFFER_HEIGHT) - pos) / size; 205 | uv.y = saturate(uv.y); 206 | uv.x *= ratio * 2.0; 207 | 208 | float t = abs(data); 209 | int radix = floor(t)? ceil(log2(t)/3.32192809):0; 210 | 211 | //early exit: 212 | if(uv.x > digit+1 || -uv.x > radix+1) return; 213 | 214 | float index = t; 215 | if(floor(uv.x) > 0) 216 | for(int i = ceil(-uv.x); i<0; i++) index *= 10.; 217 | else 218 | for(int i = ceil(uv.x); i<0; i++) index /= 10.; 219 | 220 | index = (uv.x >= -radix-!radix)? index%10 : (10+step(0, data)); //adding sign 221 | index = (uv.x > 0 && uv.x < 1)? 12:index; //adding dot 222 | index = digits[(uint)index]; 223 | 224 | res += tex2D(samplerText, (frac(uv) + float2( index % 14.0, trunc(index / 14.0))) / 225 | float2( _DRAWTEXT_GRID_X, _DRAWTEXT_GRID_Y)).x; 226 | } 227 | 228 | #endif -------------------------------------------------------------------------------- /Shaders/Deband.fx: -------------------------------------------------------------------------------- 1 | /** 2 | * Deband shader by haasn 3 | * https://github.com/haasn/gentoo-conf/blob/xor/home/nand/.mpv/shaders/deband-pre.glsl 4 | * 5 | * Copyright (c) 2015 Niklas Haas 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * Modified and optimized for ReShade by JPulowski 26 | * https://reshade.me/forum/shader-presentation/768-deband 27 | * 28 | * Do not distribute without giving credit to the original author(s). 29 | * 30 | * 1.0 - Initial release 31 | * 1.1 - Replaced the algorithm with the one from MPV 32 | * 1.1a - Minor optimizations 33 | * - Removed unnecessary lines and replaced them with ReShadeFX intrinsic counterparts 34 | * 2.0 - Replaced "grain" with CeeJay.dk's ordered dithering algorithm and enabled it by default 35 | * - The configuration is now more simpler and straightforward 36 | * - Some minor code changes and optimizations 37 | * - Improved the algorithm and made it more robust by adding some of the madshi's 38 | * improvements to flash3kyuu_deband which should cause an increase in quality. Higher 39 | * iterations/ranges should now yield higher quality debanding without too much decrease 40 | * in quality. 41 | * - Changed licensing text and original source code URL 42 | * 3.0 - Replaced the entire banding detection algorithm with modified standard deviation and 43 | * Weber ratio analyses which give more accurate and error-free results compared to the 44 | * previous algorithm 45 | * - Added banding map debug view 46 | * - Added and redefined UI categories 47 | * - Added depth detection (credits to spiro) which should be useful when banding only 48 | * occurs in the sky texture for example 49 | * - Fixed a bug in random number generation which was causing artifacts on the upper left 50 | * side of the screen 51 | * - Dithering is now applied only when debanding a pixel as it should be which should 52 | * reduce the overall noise in the final texture 53 | * - Minor code optimizations 54 | * 3.1 - Switched to chroma-based analysis from luma-based analysis which was causing artifacts 55 | * under some scenarios 56 | * - Changed parts of the code which was causing compatibility issues on some renderers 57 | */ 58 | 59 | #include "ReShadeUI.fxh" 60 | #include "ReShade.fxh" 61 | 62 | uniform bool enable_weber < 63 | ui_category = "Banding analysis"; 64 | ui_label = "Weber ratio"; 65 | ui_tooltip = "Weber ratio analysis that calculates the ratio of the each local pixel's intensity to average background intensity of all the local pixels."; 66 | ui_type = "radio"; 67 | > = true; 68 | 69 | uniform bool enable_sdeviation < 70 | ui_category = "Banding analysis"; 71 | ui_label = "Standard deviation"; 72 | ui_tooltip = "Modified standard deviation analysis that calculates nearby pixels' intensity deviation from the current pixel instead of the mean."; 73 | ui_type = "radio"; 74 | > = true; 75 | 76 | uniform bool enable_depthbuffer < 77 | ui_category = "Banding analysis"; 78 | ui_label = "Depth detection"; 79 | ui_tooltip = "Allows depth information to be used when analysing banding, pixels will only be analysed if they are in a certain depth. (e.g. debanding only the sky)"; 80 | ui_type = "radio"; 81 | > = false; 82 | 83 | uniform float t1 < 84 | ui_category = "Banding analysis"; 85 | ui_label = "Standard deviation threshold"; 86 | ui_max = 0.5; 87 | ui_min = 0.0; 88 | ui_step = 0.001; 89 | ui_tooltip = "Standard deviations lower than this threshold will be flagged as flat regions with potential banding."; 90 | ui_type = "slider"; 91 | > = 0.007; 92 | 93 | uniform float t2 < 94 | ui_category = "Banding analysis"; 95 | ui_label = "Weber ratio threshold"; 96 | ui_max = 2.0; 97 | ui_min = 0.0; 98 | ui_step = 0.01; 99 | ui_tooltip = "Weber ratios lower than this threshold will be flagged as flat regions with potential banding."; 100 | ui_type = "slider"; 101 | > = 0.04; 102 | 103 | uniform float banding_depth < 104 | ui_category = "Banding analysis"; 105 | ui_label = "Banding depth"; 106 | ui_max = 1.0; 107 | ui_min = 0.0; 108 | ui_step = 0.001; 109 | ui_tooltip = "Pixels under this depth threshold will not be processed and returned as they are."; 110 | ui_type = "slider"; 111 | > = 1.0; 112 | 113 | uniform float range < 114 | ui_category = "Banding detection & removal"; 115 | ui_label = "Radius"; 116 | ui_max = 32.0; 117 | ui_min = 1.0; 118 | ui_step = 1.0; 119 | ui_tooltip = "The radius increases linearly for each iteration. A higher radius will find more gradients, but a lower radius will smooth more aggressively."; 120 | ui_type = "slider"; 121 | > = 24.0; 122 | 123 | uniform int iterations < 124 | ui_category = "Banding detection & removal"; 125 | ui_label = "Iterations"; 126 | ui_max = 4; 127 | ui_min = 1; 128 | ui_tooltip = "The number of debanding steps to perform per sample. Each step reduces a bit more banding, but takes time to compute."; 129 | ui_type = "slider"; 130 | > = 1; 131 | 132 | uniform int debug_output < 133 | ui_category = "Debug"; 134 | ui_items = "None\0Blurred (LPF) image\0Banding map\0"; 135 | ui_label = "Debug view"; 136 | ui_tooltip = "Blurred (LPF) image: Useful when tweaking radius and iterations to make sure all banding regions are blurred enough.\nBanding map: Useful when tweaking analysis parameters, continuous green regions indicate flat (i.e. banding) regions."; 137 | ui_type = "combo"; 138 | > = 0; 139 | 140 | // Reshade uses C rand for random, max cannot be larger than 2^15-1 141 | uniform int drandom < source = "random"; min = 0; max = 32767; >; 142 | 143 | float rand(float x) 144 | { 145 | return frac(x / 41.0); 146 | } 147 | 148 | float permute(float x) 149 | { 150 | return ((34.0 * x + 1.0) * x) % 289.0; 151 | } 152 | 153 | float3 PS_Deband(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target 154 | { 155 | float3 ori = tex2Dlod(ReShade::BackBuffer, float4(texcoord, 0.0, 0.0)).rgb; 156 | 157 | if (enable_depthbuffer && (ReShade::GetLinearizedDepth(texcoord) < banding_depth)) 158 | return ori; 159 | 160 | // Initialize the PRNG by hashing the position + a random uniform 161 | float3 m = float3(texcoord + 1.0, (drandom / 32767.0) + 1.0); 162 | float h = permute(permute(permute(m.x) + m.y) + m.z); 163 | 164 | // Compute a random angle 165 | float dir = rand(permute(h)) * 6.2831853; 166 | float2 o; 167 | sincos(dir, o.y, o.x); 168 | 169 | // Distance calculations 170 | float2 pt; 171 | float dist; 172 | 173 | for (int i = 1; i <= iterations; ++i) { 174 | dist = rand(h) * range * i; 175 | pt = dist * BUFFER_PIXEL_SIZE; 176 | 177 | h = permute(h); 178 | } 179 | 180 | // Sample at quarter-turn intervals around the source pixel 181 | float3 ref[4] = { 182 | tex2Dlod(ReShade::BackBuffer, float4(mad(pt, o, texcoord), 0.0, 0.0)).rgb, // SE 183 | tex2Dlod(ReShade::BackBuffer, float4(mad(pt, -o, texcoord), 0.0, 0.0)).rgb, // NW 184 | tex2Dlod(ReShade::BackBuffer, float4(mad(pt, float2(-o.y, o.x), texcoord), 0.0, 0.0)).rgb, // NE 185 | tex2Dlod(ReShade::BackBuffer, float4(mad(pt, float2( o.y, -o.x), texcoord), 0.0, 0.0)).rgb // SW 186 | }; 187 | 188 | // Calculate weber ratio 189 | float3 mean = (ori + ref[0] + ref[1] + ref[2] + ref[3]) * 0.2; 190 | float3 k = abs(ori - mean); 191 | for (int j = 0; j < 4; ++j) { 192 | k += abs(ref[j] - mean); 193 | } 194 | 195 | k = k * 0.2 / mean; 196 | 197 | // Calculate std. deviation 198 | float3 sd = 0.0; 199 | 200 | for (int j = 0; j < 4; ++j) { 201 | sd += pow(ref[j] - ori, 2); 202 | } 203 | 204 | sd = sqrt(sd * 0.25); 205 | 206 | // Generate final output 207 | float3 output; 208 | 209 | if (debug_output == 2) 210 | output = float3(0.0, 1.0, 0.0); 211 | else 212 | output = (ref[0] + ref[1] + ref[2] + ref[3]) * 0.25; 213 | 214 | // Generate a binary banding map 215 | bool3 banding_map = true; 216 | 217 | if (debug_output != 1) { 218 | if (enable_weber) 219 | banding_map = banding_map && k <= t2 * iterations; 220 | 221 | if (enable_sdeviation) 222 | banding_map = banding_map && sd <= t1 * iterations; 223 | } 224 | 225 | /*------------------------. 226 | | :: Ordered Dithering :: | 227 | '------------------------*/ 228 | //Calculate grid position 229 | float grid_position = frac(dot(texcoord, (BUFFER_SCREEN_SIZE * float2(1.0 / 16.0, 10.0 / 36.0)) + 0.25)); 230 | 231 | //Calculate how big the shift should be 232 | float dither_shift = 0.25 * (1.0 / (pow(2, BUFFER_COLOR_BIT_DEPTH) - 1.0)); 233 | 234 | //Shift the individual colors differently, thus making it even harder to see the dithering pattern 235 | float3 dither_shift_RGB = float3(dither_shift, -dither_shift, dither_shift); //subpixel dithering 236 | 237 | //modify shift acording to grid position. 238 | dither_shift_RGB = lerp(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position); //shift acording to grid position. 239 | 240 | return banding_map ? output + dither_shift_RGB : ori; 241 | } 242 | 243 | technique Deband < 244 | ui_tooltip = "Alleviates color banding by trying to approximate original color values."; 245 | > 246 | { 247 | pass 248 | { 249 | VertexShader = PostProcessVS; 250 | PixelShader = PS_Deband; 251 | } 252 | } -------------------------------------------------------------------------------- /Shaders/ReShadeUI.fxh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if !defined(__RESHADE__) || __RESHADE__ < 30000 4 | #error "ReShade 3.0+ is required to use this header file" 5 | #endif 6 | 7 | #define RESHADE_VERSION(major,minor,build) (10000 * (major) + 100 * (minor) + (build)) 8 | #define SUPPORTED_VERSION(major,minor,build) (__RESHADE__ >= RESHADE_VERSION(major,minor,build)) 9 | 10 | // >= 3.0.0 11 | // Commit current in-game user interface status 12 | // https://github.com/crosire/reshade/commit/302bacc49ae394faedc2e29a296c1cebf6da6bb2#diff-82cf230afdb2a0d5174111e6f17548a5R1183 13 | // Added various GUI related uniform variable annotations 14 | // https://reshade.me/forum/releases/2341-3-0 15 | #define __UNIFORM_INPUT_ANY ui_type = "input"; 16 | 17 | #define __UNIFORM_INPUT_BOOL1 __UNIFORM_INPUT_ANY 18 | #define __UNIFORM_INPUT_BOOL2 __UNIFORM_INPUT_ANY 19 | #define __UNIFORM_INPUT_BOOL3 __UNIFORM_INPUT_ANY 20 | #define __UNIFORM_INPUT_BOOL4 __UNIFORM_INPUT_ANY 21 | #define __UNIFORM_INPUT_INT1 __UNIFORM_INPUT_ANY 22 | #define __UNIFORM_INPUT_INT2 __UNIFORM_INPUT_ANY 23 | #define __UNIFORM_INPUT_INT3 __UNIFORM_INPUT_ANY 24 | #define __UNIFORM_INPUT_INT4 __UNIFORM_INPUT_ANY 25 | #define __UNIFORM_INPUT_FLOAT1 __UNIFORM_INPUT_ANY 26 | #define __UNIFORM_INPUT_FLOAT2 __UNIFORM_INPUT_ANY 27 | #define __UNIFORM_INPUT_FLOAT3 __UNIFORM_INPUT_ANY 28 | #define __UNIFORM_INPUT_FLOAT4 __UNIFORM_INPUT_ANY 29 | 30 | // >= 4.0.1 31 | // Change slider widget to be used with new "slider" instead of a "drag" type annotation 32 | // https://github.com/crosire/reshade/commit/746229f31cd6f311a3e72a543e4f1f23faa23f11#diff-59405a313bd8cbfb0ca6dd633230e504R1701 33 | // Changed slider widget to be used with < ui_type = "slider"; > instead of < ui_type = "drag"; > 34 | // https://reshade.me/forum/releases/4772-4-0 35 | #if SUPPORTED_VERSION(4,0,1) 36 | #define __UNIFORM_DRAG_ANY ui_type = "drag"; 37 | 38 | // >= 4.0.0 39 | // Rework statistics tab and add drag widgets back 40 | // https://github.com/crosire/reshade/commit/1b2c38795f00efd66c007da1f483f1441b230309 41 | // Changed drag widget to a slider widget (old one is still available via < ui_type = "drag2"; >) 42 | // https://reshade.me/forum/releases/4772-4-0 43 | #elif SUPPORTED_VERSION(4,0,0) 44 | #define __UNIFORM_DRAG_ANY ui_type = "drag2"; 45 | 46 | // >= 3.0.0 47 | // Commit current in-game user interface status 48 | // https://github.com/crosire/reshade/commit/302bacc49ae394faedc2e29a296c1cebf6da6bb2#diff-82cf230afdb2a0d5174111e6f17548a5R1187 49 | // Added various GUI related uniform variable annotations 50 | // https://reshade.me/forum/releases/2341-3-0 51 | #else 52 | #define __UNIFORM_DRAG_ANY ui_type = "drag"; 53 | #endif 54 | 55 | #define __UNIFORM_DRAG_BOOL1 __UNIFORM_DRAG_ANY 56 | #define __UNIFORM_DRAG_BOOL2 __UNIFORM_DRAG_ANY 57 | #define __UNIFORM_DRAG_BOOL3 __UNIFORM_DRAG_ANY 58 | #define __UNIFORM_DRAG_BOOL4 __UNIFORM_DRAG_ANY 59 | #define __UNIFORM_DRAG_INT1 __UNIFORM_DRAG_ANY 60 | #define __UNIFORM_DRAG_INT2 __UNIFORM_DRAG_ANY 61 | #define __UNIFORM_DRAG_INT3 __UNIFORM_DRAG_ANY 62 | #define __UNIFORM_DRAG_INT4 __UNIFORM_DRAG_ANY 63 | #define __UNIFORM_DRAG_FLOAT1 __UNIFORM_DRAG_ANY 64 | #define __UNIFORM_DRAG_FLOAT2 __UNIFORM_DRAG_ANY 65 | #define __UNIFORM_DRAG_FLOAT3 __UNIFORM_DRAG_ANY 66 | #define __UNIFORM_DRAG_FLOAT4 __UNIFORM_DRAG_ANY 67 | 68 | // >= 4.0.1 69 | // Change slider widget to be used with new "slider" instead of a "drag" type annotation 70 | // https://github.com/crosire/reshade/commit/746229f31cd6f311a3e72a543e4f1f23faa23f11#diff-59405a313bd8cbfb0ca6dd633230e504R1699 71 | // Changed slider widget to be used with < ui_type = "slider"; > instead of < ui_type = "drag"; > 72 | // https://reshade.me/forum/releases/4772-4-0 73 | #if SUPPORTED_VERSION(4,0,1) 74 | #define __UNIFORM_SLIDER_ANY ui_type = "slider"; 75 | 76 | // >= 4.0.0 77 | // Rework statistics tab and add drag widgets back 78 | // https://github.com/crosire/reshade/commit/1b2c38795f00efd66c007da1f483f1441b230309 79 | // Changed drag widget to a slider widget (old one is still available via < ui_type = "drag2"; >) 80 | // https://reshade.me/forum/releases/4772-4-0 81 | #elif SUPPORTED_VERSION(4,0,0) 82 | #define __UNIFORM_SLIDER_ANY ui_type = "drag"; 83 | #else 84 | #define __UNIFORM_SLIDER_ANY __UNIFORM_DRAG_ANY 85 | #endif 86 | 87 | #define __UNIFORM_SLIDER_BOOL1 __UNIFORM_SLIDER_ANY 88 | #define __UNIFORM_SLIDER_BOOL2 __UNIFORM_SLIDER_ANY 89 | #define __UNIFORM_SLIDER_BOOL3 __UNIFORM_SLIDER_ANY 90 | #define __UNIFORM_SLIDER_BOOL4 __UNIFORM_SLIDER_ANY 91 | #define __UNIFORM_SLIDER_INT1 __UNIFORM_SLIDER_ANY 92 | #define __UNIFORM_SLIDER_INT2 __UNIFORM_SLIDER_ANY 93 | #define __UNIFORM_SLIDER_INT3 __UNIFORM_SLIDER_ANY 94 | #define __UNIFORM_SLIDER_INT4 __UNIFORM_SLIDER_ANY 95 | #define __UNIFORM_SLIDER_FLOAT1 __UNIFORM_SLIDER_ANY 96 | #define __UNIFORM_SLIDER_FLOAT2 __UNIFORM_SLIDER_ANY 97 | #define __UNIFORM_SLIDER_FLOAT3 __UNIFORM_SLIDER_ANY 98 | #define __UNIFORM_SLIDER_FLOAT4 __UNIFORM_SLIDER_ANY 99 | 100 | // >= 3.0.0 101 | // Add combo box display type for uniform variables and fix displaying of integer variable under Direct3D 9 102 | // https://github.com/crosire/reshade/commit/b025bfae5f7343509ec0cacf6df0cff537c499f2#diff-82cf230afdb2a0d5174111e6f17548a5R1631 103 | // Added various GUI related uniform variable annotations 104 | // https://reshade.me/forum/releases/2341-3-0 105 | #define __UNIFORM_COMBO_ANY ui_type = "combo"; 106 | 107 | // __UNIFORM_COMBO_BOOL1 108 | #define __UNIFORM_COMBO_BOOL2 __UNIFORM_COMBO_ANY 109 | #define __UNIFORM_COMBO_BOOL3 __UNIFORM_COMBO_ANY 110 | #define __UNIFORM_COMBO_BOOL4 __UNIFORM_COMBO_ANY 111 | #define __UNIFORM_COMBO_INT1 __UNIFORM_COMBO_ANY 112 | #define __UNIFORM_COMBO_INT2 __UNIFORM_COMBO_ANY 113 | #define __UNIFORM_COMBO_INT3 __UNIFORM_COMBO_ANY 114 | #define __UNIFORM_COMBO_INT4 __UNIFORM_COMBO_ANY 115 | #define __UNIFORM_COMBO_FLOAT1 __UNIFORM_COMBO_ANY 116 | #define __UNIFORM_COMBO_FLOAT2 __UNIFORM_COMBO_ANY 117 | #define __UNIFORM_COMBO_FLOAT3 __UNIFORM_COMBO_ANY 118 | #define __UNIFORM_COMBO_FLOAT4 __UNIFORM_COMBO_ANY 119 | 120 | // >= 4.0.0 121 | // Add option to display boolean values as combo box instead of checkbox 122 | // https://github.com/crosire/reshade/commit/aecb757c864c9679e77edd6f85a1521c49e489c1#diff-59405a313bd8cbfb0ca6dd633230e504R1147 123 | // https://github.com/crosire/reshade/blob/v4.0.0/source/gui.cpp 124 | // Added option to display boolean values as combo box instead of checkbox (via < ui_type = "combo"; >) 125 | // https://reshade.me/forum/releases/4772-4-0 126 | #define __UNIFORM_COMBO_BOOL1 __UNIFORM_COMBO_ANY 127 | 128 | // >= 4.0.0 129 | // Cleanup GUI code and rearrange some widgets 130 | // https://github.com/crosire/reshade/commit/6751f7bd50ea7c0556cf0670f10a4b4ba912ee7d#diff-59405a313bd8cbfb0ca6dd633230e504R1711 131 | // Added radio button widget (via < ui_type = "radio"; ui_items = "Button 1\0Button 2\0...\0"; >) 132 | // https://reshade.me/forum/releases/4772-4-0 133 | #if SUPPORTED_VERSION(4,0,0) 134 | #define __UNIFORM_RADIO_ANY ui_type = "radio"; 135 | #else 136 | #define __UNIFORM_RADIO_ANY __UNIFORM_COMBO_ANY 137 | #endif 138 | 139 | #define __UNIFORM_RADIO_BOOL1 __UNIFORM_RADIO_ANY 140 | #define __UNIFORM_RADIO_BOOL2 __UNIFORM_RADIO_ANY 141 | #define __UNIFORM_RADIO_BOOL3 __UNIFORM_RADIO_ANY 142 | #define __UNIFORM_RADIO_BOOL4 __UNIFORM_RADIO_ANY 143 | #define __UNIFORM_RADIO_INT1 __UNIFORM_RADIO_ANY 144 | #define __UNIFORM_RADIO_INT2 __UNIFORM_RADIO_ANY 145 | #define __UNIFORM_RADIO_INT3 __UNIFORM_RADIO_ANY 146 | #define __UNIFORM_RADIO_INT4 __UNIFORM_RADIO_ANY 147 | #define __UNIFORM_RADIO_FLOAT1 __UNIFORM_RADIO_ANY 148 | #define __UNIFORM_RADIO_FLOAT2 __UNIFORM_RADIO_ANY 149 | #define __UNIFORM_RADIO_FLOAT3 __UNIFORM_RADIO_ANY 150 | #define __UNIFORM_RADIO_FLOAT4 __UNIFORM_RADIO_ANY 151 | 152 | // >= 4.1.0 153 | // Fix floating point uniforms with unknown "ui_type" not showing up in UI 154 | // https://github.com/crosire/reshade/commit/50e5bf44dfc84bc4220c2b9f19d5f50c7a0fda66#diff-59405a313bd8cbfb0ca6dd633230e504R1788 155 | // Fixed floating point uniforms with unknown "ui_type" not showing up in UI 156 | // https://reshade.me/forum/releases/5021-4-1 157 | #define __UNIFORM_COLOR_ANY ui_type = "color"; 158 | 159 | // >= 3.0.0 160 | // Move technique list to preset configuration file 161 | // https://github.com/crosire/reshade/blob/84bba3aa934c1ebe4c6419b69dfe1690d9ab9d34/source/runtime.cpp#L1328 162 | // Added various GUI related uniform variable annotations 163 | // https://reshade.me/forum/releases/2341-3-0 164 | 165 | #define __UNIFORM_COLOR_BOOL1 __UNIFORM_COLOR_ANY 166 | #define __UNIFORM_COLOR_BOOL2 __UNIFORM_COLOR_ANY 167 | #define __UNIFORM_COLOR_BOOL3 __UNIFORM_COLOR_ANY 168 | #define __UNIFORM_COLOR_BOOL4 __UNIFORM_COLOR_ANY 169 | #define __UNIFORM_COLOR_INT1 __UNIFORM_COLOR_ANY 170 | #define __UNIFORM_COLOR_INT2 __UNIFORM_COLOR_ANY 171 | #define __UNIFORM_COLOR_INT3 __UNIFORM_COLOR_ANY 172 | #define __UNIFORM_COLOR_INT4 __UNIFORM_COLOR_ANY 173 | // __UNIFORM_COLOR_FLOAT1 174 | #define __UNIFORM_COLOR_FLOAT2 __UNIFORM_COLOR_ANY 175 | #define __UNIFORM_COLOR_FLOAT3 __UNIFORM_COLOR_ANY 176 | #define __UNIFORM_COLOR_FLOAT4 __UNIFORM_COLOR_ANY 177 | 178 | // >= 4.2.0 179 | // Add alpha slider widget for single component uniform variables (#86) 180 | // https://github.com/crosire/reshade/commit/87a740a8e3c4dcda1dd4eeec8d5cff7fa35fe829#diff-59405a313bd8cbfb0ca6dd633230e504R1820 181 | // Added alpha slider widget for single component uniform variables 182 | // https://reshade.me/forum/releases/5150-4-2 183 | #if SUPPORTED_VERSION(4,2,0) 184 | #define __UNIFORM_COLOR_FLOAT1 __UNIFORM_COLOR_ANY 185 | #else 186 | #define __UNIFORM_COLOR_FLOAT1 __UNIFORM_SLIDER_ANY 187 | #endif 188 | 189 | // >= 4.3.0 190 | // Add new "list" GUI widget (#103) 191 | // https://github.com/crosire/reshade/commit/515287d20ce615c19cf3d4c21b49f83896f04ddc#diff-59405a313bd8cbfb0ca6dd633230e504R1894 192 | // Added new "list" GUI widget 193 | // https://reshade.me/forum/releases/5417-4-3 194 | #if SUPPORTED_VERSION(4,3,0) 195 | #define __UNIFORM_LIST_ANY ui_type = "list"; 196 | #else 197 | #define __UNIFORM_LIST_ANY __UNIFORM_COMBO_ANY 198 | #endif 199 | 200 | // __UNIFORM_LIST_BOOL1 201 | #define __UNIFORM_LIST_BOOL2 __UNIFORM_LIST_ANY 202 | #define __UNIFORM_LIST_BOOL3 __UNIFORM_LIST_ANY 203 | #define __UNIFORM_LIST_BOOL4 __UNIFORM_LIST_ANY 204 | #define __UNIFORM_LIST_INT1 __UNIFORM_LIST_ANY // >= 4.3.0 205 | #define __UNIFORM_LIST_INT2 __UNIFORM_LIST_ANY 206 | #define __UNIFORM_LIST_INT3 __UNIFORM_LIST_ANY 207 | #define __UNIFORM_LIST_INT4 __UNIFORM_LIST_ANY 208 | #define __UNIFORM_LIST_FLOAT1 __UNIFORM_LIST_ANY 209 | #define __UNIFORM_LIST_FLOAT2 __UNIFORM_LIST_ANY 210 | #define __UNIFORM_LIST_FLOAT3 __UNIFORM_LIST_ANY 211 | #define __UNIFORM_LIST_FLOAT4 __UNIFORM_LIST_ANY 212 | 213 | // For compatible with 'combo' 214 | #define __UNIFORM_LIST_BOOL1 __UNIFORM_COMBO_ANY 215 | -------------------------------------------------------------------------------- /Shaders/DisplayDepth.fx: -------------------------------------------------------------------------------- 1 | /* 2 | DisplayDepth by CeeJay.dk (with many updates and additions by the Reshade community) 3 | 4 | Visualizes the depth buffer. The distance of pixels determine their brightness. 5 | Close objects are dark. Far away objects are bright. 6 | Use this to configure the depth input preprocessor definitions (RESHADE_DEPTH_INPUT_*). 7 | */ 8 | 9 | #include "ReShade.fxh" 10 | 11 | // -- Basic options -- 12 | #if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 13 | #define TEXT_UPSIDE_DOWN "1" 14 | #define TEXT_UPSIDE_DOWN_ALTER "0" 15 | #else 16 | #define TEXT_UPSIDE_DOWN "0" 17 | #define TEXT_UPSIDE_DOWN_ALTER "1" 18 | #endif 19 | #if RESHADE_DEPTH_INPUT_IS_REVERSED 20 | #define TEXT_REVERSED "1" 21 | #define TEXT_REVERSED_ALTER "0" 22 | #else 23 | #define TEXT_REVERSED "0" 24 | #define TEXT_REVERSED_ALTER "1" 25 | #endif 26 | #if RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 27 | #define TEXT_LOGARITHMIC "1" 28 | #define TEXT_LOGARITHMIC_ALTER "0" 29 | #else 30 | #define TEXT_LOGARITHMIC "0" 31 | #define TEXT_LOGARITHMIC_ALTER "1" 32 | #endif 33 | 34 | // "ui_text" was introduced in ReShade 4.5, so cannot show instructions in older versions 35 | 36 | uniform int iUIPresentType < 37 | ui_label = "Present type"; 38 | ui_label_ja_jp = "画面効果"; 39 | ui_type = "combo"; 40 | ui_items = "Depth map\0Normal map\0Show both (Vertical 50/50)\0"; 41 | ui_items_ja_jp = "深度マップ\0法線マップ\0両方を表示 (左右分割)\0"; 42 | #if __RESHADE__ < 40500 43 | ui_tooltip = 44 | #else 45 | ui_text = 46 | #endif 47 | "The right settings need to be set in the dialog that opens after clicking the \"Edit global preprocessor definitions\" button above.\n" 48 | "\n" 49 | "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN is currently set to " TEXT_UPSIDE_DOWN ".\n" 50 | "If the Depth map is shown upside down set it to " TEXT_UPSIDE_DOWN_ALTER ".\n" 51 | "\n" 52 | "RESHADE_DEPTH_INPUT_IS_REVERSED is currently set to " TEXT_REVERSED ".\n" 53 | "If close objects in the Depth map are bright and far ones are dark set it to " TEXT_REVERSED_ALTER ".\n" 54 | "Also try this if you can see the normals, but the depth view is all black.\n" 55 | "\n" 56 | "RESHADE_DEPTH_INPUT_IS_LOGARITHMIC is currently set to " TEXT_LOGARITHMIC ".\n" 57 | "If the Normal map has banding artifacts (extra stripes) set it to " TEXT_LOGARITHMIC_ALTER "."; 58 | ui_text_ja_jp = 59 | #if ADDON_ADJUST_DEPTH 60 | "Adjust Depthアドオンのインストールを検出しました。\n" 61 | "'設定に保存して反映する'ボタンをクリックすると、このエフェクトで調節した全ての変数が共通設定に反映されます。\n" 62 | "または、上の'プリプロセッサの定義を編集'ボタンをクリックした後に開くダイアログで直接編集する事もできます。"; 63 | #else 64 | "調節が終わったら、上の'プリプロセッサの定義を編集'ボタンをクリックした後に開くダイアログに入力する必要があります。\n" 65 | "\n" 66 | "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWNは現在" TEXT_UPSIDE_DOWN "に設定されています。\n" 67 | "深度マップが上下逆さまに表示されている場合は" TEXT_UPSIDE_DOWN_ALTER "に変更して下さい。\n" 68 | "\n" 69 | "RESHADE_DEPTH_INPUT_IS_REVERSEDは現在" TEXT_REVERSED "に設定されています。\n" 70 | "画面効果が深度マップのとき、近くの形状がより白く、遠くの形状がより黒い場合は" TEXT_REVERSED_ALTER "に変更して下さい。\n" 71 | "また、法線マップで形が判別出来るが、深度マップが真っ暗に見えるという場合も、この設定の変更を試して下さい。\n" 72 | "\n" 73 | "RESHADE_DEPTH_INPUT_IS_LOGARITHMICは現在" TEXT_LOGARITHMIC "に設定されています。\n" 74 | "画面効果に実際のレンダリングと合致しない縞模様がある場合は" TEXT_LOGARITHMIC_ALTER "に変更して下さい。"; 75 | #endif 76 | ui_tooltip_ja_jp = 77 | "'深度マップ'は、形状の遠近を白黒で表現します。正しい見え方では、近くの形状ほど黒く、遠くの形状ほど白くなります。\n" 78 | "'法線マップ'は、形状を滑らかに表現します。正しい見え方では、全体的に青緑風で、地平線を見たときに地面が緑掛かった色合いになります。\n" 79 | "'両方を表示 (左右分割)'が選択された場合は、左に法線マップ、右に深度マップを表示します。"; 80 | > = 2; 81 | 82 | uniform bool bUIShowOffset < 83 | ui_label = "Blend Depth map into the image (to help with finding the right offset)"; 84 | ui_label_ja_jp = "透かし比較"; 85 | ui_tooltip_ja_jp = "補正作業を支援するために、画面効果を半透過で適用します。"; 86 | > = false; 87 | 88 | uniform bool bUIUseLivePreview < 89 | ui_category = "Preview settings"; 90 | ui_category_ja_jp = "基本的な補正"; 91 | #if __RESHADE__ <= 50902 92 | ui_category_closed = true; 93 | #elif !ADDON_ADJUST_DEPTH 94 | ui_category_toggle = true; 95 | #endif 96 | ui_label = "Show live preview and ignore preprocessor definitions"; 97 | ui_label_ja_jp = "プリプロセッサの定義を無視 (補正プレビューをオン)"; 98 | ui_tooltip = "Enable this to preview with the current preset settings instead of the global preprocessor settings."; 99 | ui_tooltip_ja_jp = 100 | "共通設定に保存されたプリプロセッサの定義ではなく、これより下のプレビュー設定を使用するには、これを有効にします。\n" 101 | #if ADDON_ADJUST_DEPTH 102 | "設定の準備が出来たら、'設定に保存して反映する'ボタンをクリックしてから、このチェックボックスをオフにして下さい。" 103 | #else 104 | "設定の準備が出来たら、上の'プリプロセッサの定義を編集'ボタンをクリックした後に開くダイアログに入力して下さい。" 105 | #endif 106 | "\n\n" 107 | "プレビューをオンにした場合と比較して画面効果がまったく同じになれば、正しく設定が反映されています。"; 108 | > = false; 109 | 110 | #if __RESHADE__ <= 50902 111 | uniform int iUIUpsideDown < 112 | #else 113 | uniform bool iUIUpsideDown < 114 | #endif 115 | ui_category = "Preview settings"; 116 | ui_label = "Upside Down"; 117 | ui_label_ja_jp = "深度バッファの上下反転を修正"; 118 | #if __RESHADE__ <= 50902 119 | ui_type = "combo"; 120 | ui_items = "Off\0On\0"; 121 | #endif 122 | ui_text_ja_jp = 123 | "\n" 124 | #if ADDON_ADJUST_DEPTH 125 | "項目にカーソルを合わせると、設定が必要な状況の説明が表示されます。" 126 | #else 127 | "項目にカーソルを合わせると、設定が必要な状況の説明と、プリプロセッサの定義が表示されます。" 128 | #endif 129 | ; 130 | ui_tooltip_ja_jp = 131 | "深度マップが上下逆さまに表示されている場合は変更して下さい。" 132 | #if !ADDON_ADJUST_DEPTH 133 | "\n\n" 134 | "定義名は次の通りです。文字は完全に一致する必要があり、半角大文字の英字とアンダーバーを用いなければなりません。\n" 135 | "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN=値\n" 136 | "定義値は次の通りです。オンの場合は1、オフの場合は0を指定して下さい。\n" 137 | "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN=1\n" 138 | "RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN=0" 139 | #endif 140 | ; 141 | > = RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN; 142 | 143 | #if __RESHADE__ <= 50902 144 | uniform int iUIReversed < 145 | #else 146 | uniform bool iUIReversed < 147 | #endif 148 | ui_category = "Preview settings"; 149 | ui_label = "Reversed"; 150 | ui_label_ja_jp = "深度バッファの奥行反転を修正"; 151 | #if __RESHADE__ <= 50902 152 | ui_type = "combo"; 153 | ui_items = "Off\0On\0"; 154 | #endif 155 | ui_tooltip_ja_jp = 156 | "画面効果が深度マップのとき、近くの形状が明るく、遠くの形状が暗い場合は変更して下さい。\n" 157 | "また、法線マップで形が判別出来るが、深度マップが真っ暗に見えるという場合も、この設定の変更を試して下さい。" 158 | #if !ADDON_ADJUST_DEPTH 159 | "\n\n" 160 | "定義名は次の通りです。文字は完全に一致する必要があり、半角大文字の英字とアンダーバーを用いなければなりません。\n" 161 | "RESHADE_DEPTH_INPUT_IS_REVERSED=値\n" 162 | "定義値は次の通りです。オンの場合は1、オフの場合は0を指定して下さい。\n" 163 | "RESHADE_DEPTH_INPUT_IS_REVERSED=1\n" 164 | "RESHADE_DEPTH_INPUT_IS_REVERSED=0" 165 | #endif 166 | ; 167 | > = RESHADE_DEPTH_INPUT_IS_REVERSED; 168 | 169 | #if __RESHADE__ <= 50902 170 | uniform int iUILogarithmic < 171 | #else 172 | uniform bool iUILogarithmic < 173 | #endif 174 | ui_category = "Preview settings"; 175 | ui_label = "Logarithmic"; 176 | ui_label_ja_jp = "深度バッファを対数分布として扱うように修正"; 177 | #if __RESHADE__ <= 50902 178 | ui_type = "combo"; 179 | ui_items = "Off\0On\0"; 180 | #endif 181 | ui_tooltip = "Change this setting if the displayed surface normals have stripes in them."; 182 | ui_tooltip_ja_jp = 183 | "画面効果に実際のゲーム画面と合致しない縞模様がある場合は変更して下さい。" 184 | #if !ADDON_ADJUST_DEPTH 185 | "\n\n" 186 | "定義名は次の通りです。文字は完全に一致する必要があり、半角大文字の英字とアンダーバーを用いなければなりません。\n" 187 | "RESHADE_DEPTH_INPUT_IS_LOGARITHMIC=値\n" 188 | "定義値は次の通りです。オンの場合は1、オフの場合は0を指定して下さい。\n" 189 | "RESHADE_DEPTH_INPUT_IS_LOGARITHMIC=1\n" 190 | "RESHADE_DEPTH_INPUT_IS_LOGARITHMIC=0" 191 | #endif 192 | ; 193 | > = RESHADE_DEPTH_INPUT_IS_LOGARITHMIC; 194 | 195 | // -- Advanced options -- 196 | 197 | uniform float2 fUIScale < 198 | ui_category = "Preview settings"; 199 | ui_label = "Scale"; 200 | ui_label_ja_jp = "拡大率"; 201 | ui_type = "drag"; 202 | ui_text = 203 | "\n" 204 | " * Advanced options\n" 205 | "\n" 206 | "The following settings also need to be set using \"Edit global preprocessor definitions\" above in order to take effect.\n" 207 | "You can preview how they will affect the Depth map using the controls below.\n" 208 | "\n" 209 | "It is rarely necessary to change these though, as their defaults fit almost all games.\n\n"; 210 | ui_text_ja_jp = 211 | "\n" 212 | " * その他の補正 (不定形またはその他)\n" 213 | "\n" 214 | "これより下は、深度バッファが不定形など、特別なケース向けの設定です。\n" 215 | "通常はこれより上の'基本的な補正'のみでほとんどのゲームに適合します。\n" 216 | "また、これらの設定は画質の向上にはまったく役に立ちません。\n\n"; 217 | ui_tooltip = 218 | "Best use 'Present type'->'Depth map' and enable 'Offset' in the options below to set the scale.\n" 219 | "Use these values for:\nRESHADE_DEPTH_INPUT_X_SCALE=\nRESHADE_DEPTH_INPUT_Y_SCALE=\n" 220 | "\n" 221 | "If you know the right resolution of the games depth buffer then this scale value is simply the ratio\n" 222 | "between the correct resolution and the resolution Reshade thinks it is.\n" 223 | "For example:\n" 224 | "If it thinks the resolution is 1920 x 1080, but it's really 1280 x 720 then the right scale is (1.5 , 1.5)\n" 225 | "because 1920 / 1280 is 1.5 and 1080 / 720 is also 1.5, so 1.5 is the right scale for both the x and the y"; 226 | ui_tooltip_ja_jp = 227 | "深度バッファの解像度がクライアント解像度と異なる場合に変更して下さい。\n" 228 | "このスケール値は、深度バッファの解像度とクライアント解像度との単純な比率になります。\n" 229 | "深度バッファの解像度が1280×720でクライアント解像度が1920×1080の場合、横の比率が1920÷1280、縦の比率が1080÷720となります。\n" 230 | "計算した結果を設定すると、値はそれぞれX_SCALE=1.5、Y_SCALE=1.5となります。" 231 | #if !ADDON_ADJUST_DEPTH 232 | "\n\n" 233 | "定義名は次の通りです。文字は完全に一致する必要があり、半角大文字の英字とアンダーバーを用いなければなりません。\n" 234 | "RESHADE_DEPTH_INPUT_X_SCALE=横の値\n" 235 | "RESHADE_DEPTH_INPUT_Y_SCALE=縦の値\n" 236 | "定義値は次の通りです。横の値はX_SCALE、縦の値はY_SCALEに指定して下さい。\n" 237 | "RESHADE_DEPTH_INPUT_X_SCALE=1.0\n" 238 | "RESHADE_DEPTH_INPUT_Y_SCALE=1.0" 239 | #endif 240 | ; 241 | ui_min = 0.0; ui_max = 2.0; 242 | ui_step = 0.001; 243 | > = float2(RESHADE_DEPTH_INPUT_X_SCALE, RESHADE_DEPTH_INPUT_Y_SCALE); 244 | 245 | uniform int2 iUIOffset < 246 | ui_category = "Preview settings"; 247 | ui_label = "Offset"; 248 | ui_label_ja_jp = "位置オフセット"; 249 | ui_type = "slider"; 250 | ui_tooltip = 251 | "Best use 'Present type'->'Depth map' and enable 'Offset' in the options below to set the offset in pixels.\n" 252 | "Use these values for:\nRESHADE_DEPTH_INPUT_X_PIXEL_OFFSET=\nRESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET="; 253 | ui_tooltip_ja_jp = 254 | "深度バッファにレンダリングされた物体の形状が画面効果と重なり合っていない場合に変更して下さい。\n" 255 | "この値は、ピクセル単位で指定します。" 256 | #if !ADDON_ADJUST_DEPTH 257 | "\n\n" 258 | "定義名は次の通りです。文字は完全に一致する必要があり、半角大文字の英字とアンダーバーを用いなければなりません。\n" 259 | "RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET=横の値\n" 260 | "RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET=縦の値\n" 261 | "定義値は次の通りです。横の値はX_PIXEL_OFFSET、縦の値はY_PIXEL_OFFSETに指定して下さい。\n" 262 | "RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET=0.0\n" 263 | "RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET=0.0" 264 | #endif 265 | ; 266 | ui_min = -BUFFER_SCREEN_SIZE; 267 | ui_max = BUFFER_SCREEN_SIZE; 268 | ui_step = 1; 269 | > = int2(RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET, RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET); 270 | 271 | uniform float fUIFarPlane < 272 | ui_category = "Preview settings"; 273 | ui_label = "Far Plane"; 274 | ui_label_ja_jp = "遠点距離"; 275 | ui_type = "drag"; 276 | ui_tooltip = 277 | "RESHADE_DEPTH_LINEARIZATION_FAR_PLANE=\n" 278 | "Changing this value is not necessary in most cases."; 279 | ui_tooltip_ja_jp = 280 | "深度マップの色合いが距離感と合致しない、法線マップの表面が平面に見える、などの場合に変更して下さい。\n" 281 | "遠点距離を1000に設定すると、ゲームの描画距離が1000メートルであると見なします。\n\n" 282 | "このプレビュー画面はあくまでプレビューであり、ほとんどの場合、深度バッファは深度マップの色数より遥かに高い精度で表現されています。\n" 283 | "例えば、10m前後の距離の形状が純粋な黒に見えるからという理由で値を変更しないで下さい。" 284 | #if !ADDON_ADJUST_DEPTH 285 | "\n\n" 286 | "定義名は次の通りです。文字は完全に一致する必要があり、半角大文字の英字とアンダーバーを用いなければなりません。\n" 287 | "RESHADE_DEPTH_LINEARIZATION_FAR_PLANE=値\n" 288 | "定義値は次の通りです。\n" 289 | "RESHADE_DEPTH_LINEARIZATION_FAR_PLANE=1000.0" 290 | #endif 291 | ; 292 | ui_min = 0.0; ui_max = 1000.0; 293 | ui_step = 0.1; 294 | > = RESHADE_DEPTH_LINEARIZATION_FAR_PLANE; 295 | 296 | uniform float fUIDepthMultiplier < 297 | ui_category = "Preview settings"; 298 | ui_label = "Multiplier"; 299 | ui_label_ja_jp = "深度乗数"; 300 | ui_type = "drag"; 301 | ui_tooltip = "RESHADE_DEPTH_MULTIPLIER="; 302 | ui_tooltip_ja_jp = 303 | "特定のエミュレータソフトウェアにおける深度バッファを修正するため、特別に追加された変数です。\n" 304 | "この値は僅かな変更でも計算式を破壊するため、設定すべき値を知らない場合は変更しないで下さい。" 305 | #if !ADDON_ADJUST_DEPTH 306 | "\n\n" 307 | "定義名は次の通りです。文字は完全に一致する必要があり、半角大文字の英字とアンダーバーを用いなければなりません。\n" 308 | "RESHADE_DEPTH_MULTIPLIER=値\n" 309 | "定義値は次の通りです。\n" 310 | "RESHADE_DEPTH_MULTIPLIER=1.0" 311 | #endif 312 | ; 313 | ui_min = 0.0; ui_max = 1000.0; 314 | ui_step = 0.001; 315 | > = RESHADE_DEPTH_MULTIPLIER; 316 | 317 | float GetLinearizedDepth(float2 texcoord) 318 | { 319 | if (!bUIUseLivePreview) 320 | { 321 | return ReShade::GetLinearizedDepth(texcoord); 322 | } 323 | else 324 | { 325 | if (iUIUpsideDown) // RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 326 | texcoord.y = 1.0 - texcoord.y; 327 | 328 | texcoord.x /= fUIScale.x; // RESHADE_DEPTH_INPUT_X_SCALE 329 | texcoord.y /= fUIScale.y; // RESHADE_DEPTH_INPUT_Y_SCALE 330 | texcoord.x -= iUIOffset.x * BUFFER_RCP_WIDTH; // RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET 331 | texcoord.y += iUIOffset.y * BUFFER_RCP_HEIGHT; // RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET 332 | 333 | float depth = tex2Dlod(ReShade::DepthBuffer, float4(texcoord, 0, 0)).x * fUIDepthMultiplier; 334 | 335 | const float C = 0.01; 336 | if (iUILogarithmic) // RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 337 | depth = (exp(depth * log(C + 1.0)) - 1.0) / C; 338 | 339 | if (iUIReversed) // RESHADE_DEPTH_INPUT_IS_REVERSED 340 | depth = 1.0 - depth; 341 | 342 | const float N = 1.0; 343 | depth /= fUIFarPlane - depth * (fUIFarPlane - N); 344 | 345 | return depth; 346 | } 347 | } 348 | 349 | float3 GetScreenSpaceNormal(float2 texcoord) 350 | { 351 | float3 offset = float3(BUFFER_PIXEL_SIZE, 0.0); 352 | float2 posCenter = texcoord.xy; 353 | float2 posNorth = posCenter - offset.zy; 354 | float2 posEast = posCenter + offset.xz; 355 | 356 | float3 vertCenter = float3(posCenter - 0.5, 1) * GetLinearizedDepth(posCenter); 357 | float3 vertNorth = float3(posNorth - 0.5, 1) * GetLinearizedDepth(posNorth); 358 | float3 vertEast = float3(posEast - 0.5, 1) * GetLinearizedDepth(posEast); 359 | 360 | return normalize(cross(vertCenter - vertNorth, vertCenter - vertEast)) * 0.5 + 0.5; 361 | } 362 | 363 | void PS_DisplayDepth(in float4 position : SV_Position, in float2 texcoord : TEXCOORD, out float3 color : SV_Target) 364 | { 365 | float3 depth = GetLinearizedDepth(texcoord).xxx; 366 | float3 normal = GetScreenSpaceNormal(texcoord); 367 | 368 | // Ordered dithering 369 | #if 1 370 | const float dither_bit = 8.0; // Number of bits per channel. Should be 8 for most monitors. 371 | // Calculate grid position 372 | float grid_position = frac(dot(texcoord, (BUFFER_SCREEN_SIZE * float2(1.0 / 16.0, 10.0 / 36.0)) + 0.25)); 373 | // Calculate how big the shift should be 374 | float dither_shift = 0.25 * (1.0 / (pow(2, dither_bit) - 1.0)); 375 | // Shift the individual colors differently, thus making it even harder to see the dithering pattern 376 | float3 dither_shift_RGB = float3(dither_shift, -dither_shift, dither_shift); // Subpixel dithering 377 | // Modify shift acording to grid position. 378 | dither_shift_RGB = lerp(2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position); 379 | depth += dither_shift_RGB; 380 | #endif 381 | 382 | color = depth; 383 | if (iUIPresentType == 1) 384 | color = normal; 385 | if (iUIPresentType == 2) 386 | color = lerp(normal, depth, step(BUFFER_WIDTH * 0.5, position.x)); 387 | 388 | if (bUIShowOffset) 389 | { 390 | float3 color_orig = tex2D(ReShade::BackBuffer, texcoord).rgb; 391 | 392 | // Blend depth and back buffer color with 'overlay' so the offset is more noticeable 393 | color = lerp(2 * color * color_orig, 1.0 - 2.0 * (1.0 - color) * (1.0 - color_orig), max(color.r, max(color.g, color.b)) < 0.5 ? 0.0 : 1.0); 394 | } 395 | } 396 | 397 | technique DisplayDepth < 398 | ui_tooltip = 399 | "This shader helps you set the right preprocessor settings for depth input.\n" 400 | "To set the settings click on 'Edit global preprocessor definitions' and set them there - not in this shader.\n" 401 | "The settings will then take effect for all shaders, including this one.\n" 402 | "\n" 403 | "By default calculated normals and depth are shown side by side.\n" 404 | "Normals (on the left) should look smooth and the ground should be greenish when looking at the horizon.\n" 405 | "Depth (on the right) should show close objects as dark and use gradually brighter shades the further away objects are.\n"; 406 | ui_tooltip_ja_jp = 407 | "これは、深度バッファの入力をReShade側の計算式に合わせる調節をするための、設定作業の支援に特化した特殊な扱いのエフェクトです。\n" 408 | "初期状態では「両方を表示」が選択されており、左に法線マップ、右に深度マップが表示されます。\n" 409 | "\n" 410 | "法線マップ(左側)は、形状を滑らかに表現します。正しい設定では、全体的に青緑風で、地平線を見たときに地面が緑を帯びた色になります。\n" 411 | "深度マップ(右側)は、形状の遠近を白黒で表現します。正しい設定では、近くの形状ほど黒く、遠くの形状ほど白くなります。\n" 412 | "\n" 413 | #if ADDON_ADJUST_DEPTH 414 | "設定を完了するには、DisplayDepth.fxエフェクトの変数の一覧にある'設定に保存して反映する'ボタンをクリックして下さい。\n" 415 | #else 416 | "設定を完了するには、エフェクト変数の編集画面にある'プリプロセッサの定義を編集'ボタンをクリックした後に開くダイアログに入力して下さい。\n" 417 | #endif 418 | "すると、インストール先のゲームに対して共通の設定として保存され、他のプリセットでも正しく表示されるようになります。"; 419 | > 420 | 421 | { 422 | pass 423 | { 424 | VertexShader = PostProcessVS; 425 | PixelShader = PS_DisplayDepth; 426 | } 427 | } 428 | -------------------------------------------------------------------------------- /Shaders/Blending.fxh: -------------------------------------------------------------------------------- 1 | /*------------------. 2 | | :: Description :: | 3 | '-------------------/ 4 | 5 | Blending Header (version 0.8) 6 | 7 | Blending Algorithm Sources: 8 | https://www.khronos.org/registry/OpenGL/extensions/NV/NV_blend_equation_advanced.txt 9 | 10 | http://www.nathanm.com/photoshop-blending-math/ 11 | (Alt) https://github.com/cplotts/WPFSLBlendModeFx/blob/master/PhotoshopMathFP.hlsl 12 | 13 | Header Authors: originalnicodr, prod80, uchu suzume, Marot Satil 14 | 15 | About: 16 | Provides a variety of blending methods for you to use as you wish. Just include this header. 17 | 18 | History: 19 | (*) Feature (+) Improvement (x) Bugfix (-) Information (!) Compatibility 20 | 21 | Version 0.1 by Marot Satil & uchu suzume 22 | * Added and improved upon multiple blending modes thanks to the work of uchu suzume, prod80, and originalnicodr. 23 | 24 | Version 0.2 by uchu suzume & Marot Satil 25 | * Added Addition, Subtract, Divide blending modes and improved code readability. 26 | 27 | Version 0.3 by uchu suzume & Marot Satil 28 | * Sorted blending modes in a more logical fashion, grouping by type. 29 | 30 | Version 0.4 by uchu suzume 31 | x Corrected Color Dodge blending behavior. 32 | 33 | Version 0.5 by Marot Satil & uchu suzume 34 | * Added preprocessor macros for uniform variable combo UI element & lerp. 35 | 36 | Version 0.6 by Marot Satil & uchu suzume 37 | * Added Divide (Alternative) and Divide (Photoshop) blending modes. 38 | 39 | Version 0.7 by prod80 40 | - Added original sources for blending algorithms. 41 | x Corrected average luminosity values. 42 | 43 | Version 0.8 by Marot Satil 44 | * Added a new funciton to output blended data. 45 | + Moved all code into the BlendingH namespace, which is part of the ComHeaders common namespace meant to be used by other headers. 46 | ! Removed old preprocessor macro blending output. 47 | 48 | .------------------. 49 | | :: How To Use :: | 50 | '------------------/ 51 | 52 | Blending two variables using this header in your own shaders is very straightforward. 53 | Very basic example code using the "Darken" blending mode follows: 54 | 55 | // First, include the header. 56 | #include "Blending.fxh" 57 | 58 | // You can use this preprocessor macro to generate an attractive and functional uniform int UI combo element containing the list of blending techniques: 59 | // BLENDING_COMBO(variable_name, label, tooltip, category, category_closed, spacing, default_value) 60 | BLENDING_COMBO(_BlendMode, "Blending Mode", "Select the blending mode applied to the layer.", "Blending Options", false, 0, 0) 61 | 62 | // Inside of your function you can call this function to apply the blending option specified by an int (variable) to your float3 (input) via 63 | // a lerp between your float3 (input), float3 (output), and a float (blending) for the alpha channel. 64 | // ComHeaders::Blending::Blend(int variable, float3 input, float3 output, float blending) 65 | outColor.rgb = ComHeaders::Blending::Blend(_BlendMode, inColor, outColor, outColor.a); 66 | */ 67 | 68 | 69 | // ------------------------------------- 70 | // Preprocessor Macros 71 | // ------------------------------------- 72 | 73 | #undef BLENDING_COMBO 74 | #define BLENDING_COMBO(variable, name_label, description, group, grp_closed, space, default_value) \ 75 | uniform int variable \ 76 | < \ 77 | ui_category = group; \ 78 | ui_category_closed = grp_closed; \ 79 | ui_items = \ 80 | "Normal\0" \ 81 | /* "Darken" */ \ 82 | "Darken\0" \ 83 | " Multiply\0" \ 84 | " Color Burn\0" \ 85 | " Linear Burn\0" \ 86 | /* "Lighten" */ \ 87 | "Lighten\0" \ 88 | " Screen\0" \ 89 | " Color Dodge\0" \ 90 | " Linear Dodge\0" \ 91 | " Addition\0" \ 92 | " Glow\0" \ 93 | /* "Contrast" */ \ 94 | "Overlay\0" \ 95 | " Soft Light\0" \ 96 | " Hard Light\0" \ 97 | " Vivid Light\0" \ 98 | " Linear Light\0" \ 99 | " Pin Light\0" \ 100 | " Hard Mix\0" \ 101 | /* "Inversion" */ \ 102 | "Difference\0" \ 103 | " Exclusion\0" \ 104 | /* "Cancelation" */ \ 105 | "Subtract\0" \ 106 | " Divide\0" \ 107 | " Divide (Alternative)\0" \ 108 | " Divide (Photoshop)\0" \ 109 | " Reflect\0" \ 110 | " Grain Extract\0" \ 111 | " Grain Merge\0" \ 112 | /* "Component" */ \ 113 | "Hue\0" \ 114 | " Saturation\0" \ 115 | " Color\0" \ 116 | " Luminosity\0"; \ 117 | ui_label = name_label; \ 118 | ui_tooltip = description; \ 119 | ui_type = "combo"; \ 120 | ui_spacing = space; \ 121 | > = default_value; 122 | 123 | namespace ComHeaders 124 | { 125 | namespace Blending 126 | { 127 | 128 | // ------------------------------------- 129 | // Helper Functions 130 | // ------------------------------------- 131 | 132 | float3 Aux(float3 a) 133 | { 134 | if (a.r <= 0.25 && a.g <= 0.25 && a.b <= 0.25) 135 | return ((16.0 * a - 12.0) * a + 4) * a; 136 | else 137 | return sqrt(a); 138 | } 139 | 140 | float Lum(float3 a) 141 | { 142 | return (0.33333 * a.r + 0.33334 * a.g + 0.33333 * a.b); 143 | } 144 | 145 | float3 SetLum (float3 a, float b){ 146 | const float c = b - Lum(a); 147 | return float3(a.r + c, a.g + c, a.b + c); 148 | } 149 | 150 | float min3 (float a, float b, float c) 151 | { 152 | return min(a, (min(b, c))); 153 | } 154 | 155 | float max3 (float a, float b, float c) 156 | { 157 | return max(a, max(b, c)); 158 | } 159 | 160 | float3 SetSat(float3 a, float b){ 161 | float ar = a.r; 162 | float ag = a.g; 163 | float ab = a.b; 164 | if (ar == max3(ar, ag, ab) && ab == min3(ar, ag, ab)) 165 | { 166 | //caso r->max g->mid b->min 167 | if (ar > ab) 168 | { 169 | ag = (((ag - ab) * b) / (ar - ab)); 170 | ar = b; 171 | } 172 | else 173 | { 174 | ag = 0.0; 175 | ar = 0.0; 176 | } 177 | ab = 0.0; 178 | } 179 | else 180 | { 181 | if (ar == max3(ar, ag, ab) && ag == min3(ar, ag, ab)) 182 | { 183 | //caso r->max b->mid g->min 184 | if (ar > ag) 185 | { 186 | ab = (((ab - ag) * b) / (ar - ag)); 187 | ar = b; 188 | } 189 | else 190 | { 191 | ab = 0.0; 192 | ar = 0.0; 193 | } 194 | ag = 0.0; 195 | } 196 | else 197 | { 198 | if (ag == max3(ar, ag, ab) && ab == min3(ar, ag, ab)) 199 | { 200 | //caso g->max r->mid b->min 201 | if (ag > ab) 202 | { 203 | ar = (((ar - ab) * b) / (ag - ab)); 204 | ag = b; 205 | } 206 | else 207 | { 208 | ar = 0.0; 209 | ag = 0.0; 210 | } 211 | ab = 0.0; 212 | } 213 | else 214 | { 215 | if (ag == max3(ar, ag, ab) && ar == min3(ar, ag, ab)) 216 | { 217 | //caso g->max b->mid r->min 218 | if (ag > ar) 219 | { 220 | ab = (((ab - ar) * b) / (ag - ar)); 221 | ag = b; 222 | } 223 | else 224 | { 225 | ab = 0.0; 226 | ag = 0.0; 227 | } 228 | ar = 0.0; 229 | } 230 | else 231 | { 232 | if (ab == max3(ar, ag, ab) && ag == min3(ar, ag, ab)) 233 | { 234 | //caso b->max r->mid g->min 235 | if (ab > ag) 236 | { 237 | ar = (((ar - ag) * b) / (ab - ag)); 238 | ab = b; 239 | } 240 | else 241 | { 242 | ar = 0.0; 243 | ab = 0.0; 244 | } 245 | ag = 0.0; 246 | } 247 | else 248 | { 249 | if (ab == max3(ar, ag, ab) && ar == min3(ar, ag, ab)) 250 | { 251 | //caso b->max g->mid r->min 252 | if (ab > ar) 253 | { 254 | ag = (((ag - ar) * b) / (ab - ar)); 255 | ab = b; 256 | } 257 | else 258 | { 259 | ag = 0.0; 260 | ab = 0.0; 261 | } 262 | ar = 0.0; 263 | } 264 | } 265 | } 266 | } 267 | } 268 | } 269 | return float3(ar, ag, ab); 270 | } 271 | 272 | float Sat(float3 a) 273 | { 274 | return max3(a.r, a.g, a.b) - min3(a.r, a.g, a.b); 275 | } 276 | 277 | 278 | // ------------------------------------- 279 | // Blending Modes 280 | // ------------------------------------- 281 | 282 | // Darken 283 | float3 Darken(float3 a, float3 b) 284 | { 285 | return min(a, b); 286 | } 287 | 288 | // Multiply 289 | float3 Multiply(float3 a, float3 b) 290 | { 291 | return a * b; 292 | } 293 | 294 | // Color Burn 295 | float3 ColorBurn(float3 a, float3 b) 296 | { 297 | if (b.r > 0 && b.g > 0 && b.b > 0) 298 | return 1.0 - min(1.0, (0.5 - a) / b); 299 | else 300 | return 0.0; 301 | } 302 | 303 | // Linear Burn 304 | float3 LinearBurn(float3 a, float3 b) 305 | { 306 | return max(a + b - 1.0f, 0.0f); 307 | } 308 | 309 | // Lighten 310 | float3 Lighten(float3 a, float3 b) 311 | { 312 | return max(a, b); 313 | } 314 | 315 | // Screen 316 | float3 Screen(float3 a, float3 b) 317 | { 318 | return 1.0 - (1.0 - a) * (1.0 - b); 319 | } 320 | 321 | // Color Dodge 322 | float3 ColorDodge(float3 a, float3 b) 323 | { 324 | if (b.r < 1 && b.g < 1 && b.b < 1) 325 | return min(1.0, a / (1.0 - b)); 326 | else 327 | return 1.0; 328 | } 329 | 330 | // Linear Dodge 331 | float3 LinearDodge(float3 a, float3 b) 332 | { 333 | return min(a + b, 1.0f); 334 | } 335 | 336 | // Addition 337 | float3 Addition(float3 a, float3 b) 338 | { 339 | return min((a + b), 1); 340 | } 341 | 342 | // Reflect 343 | float3 Reflect(float3 a, float3 b) 344 | { 345 | if (b.r >= 0.999999 || b.g >= 0.999999 || b.b >= 0.999999) 346 | return b; 347 | else 348 | return saturate(a * a / (1.0f - b)); 349 | } 350 | 351 | // Glow 352 | float3 Glow(float3 a, float3 b) 353 | { 354 | return Reflect(b, a); 355 | } 356 | 357 | // Overlay 358 | float3 Overlay(float3 a, float3 b) 359 | { 360 | return lerp(2 * a * b, 1.0 - 2 * (1.0 - a) * (1.0 - b), step(0.5, a)); 361 | } 362 | 363 | // Soft Light 364 | float3 SoftLight(float3 a, float3 b) 365 | { 366 | if (b.r <= 0.5 && b.g <= 0.5 && b.b <= 0.5) 367 | return clamp(a - (1.0 - 2 * b) * a * (1 - a), 0,1); 368 | else 369 | return clamp(a + (2 * b - 1.0) * (Aux(a) - a), 0, 1); 370 | } 371 | 372 | // Hard Light 373 | float3 HardLight(float3 a, float3 b) 374 | { 375 | return lerp(2 * a * b, 1.0 - 2 * (1.0 - b) * (1.0 - a), step(0.5, b)); 376 | } 377 | 378 | // Vivid Light 379 | float3 VividLight(float3 a, float3 b) 380 | { 381 | return lerp(2 * a * b, b / (2 * (1.01 - a)), step(0.50, a)); 382 | } 383 | 384 | // Linear Light 385 | float3 LinearLight(float3 a, float3 b) 386 | { 387 | if (b.r < 0.5 || b.g < 0.5 || b.b < 0.5) 388 | return LinearBurn(a, (2.0 * b)); 389 | else 390 | return LinearDodge(a, (2.0 * (b - 0.5))); 391 | } 392 | 393 | // Pin Light 394 | float3 PinLight(float3 a, float3 b) 395 | { 396 | if (b.r < 0.5 || b.g < 0.5 || b.b < 0.5) 397 | return Darken(a, (2.0 * b)); 398 | else 399 | return Lighten(a, (2.0 * (b - 0.5))); 400 | } 401 | 402 | // Hard Mix 403 | float3 HardMix(float3 a, float3 b) 404 | { 405 | const float3 vl = VividLight(a, b); 406 | if (vl.r < 0.5 || vl.g < 0.5 || vl.b < 0.5) 407 | return 0.0; 408 | else 409 | return 1.0; 410 | } 411 | 412 | // Difference 413 | float3 Difference(float3 a, float3 b) 414 | { 415 | return max(a - b, b - a); 416 | } 417 | 418 | // Exclusion 419 | float3 Exclusion(float3 a, float3 b) 420 | { 421 | return a + b - 2 * a * b; 422 | } 423 | 424 | // Subtract 425 | float3 Subtract(float3 a, float3 b) 426 | { 427 | return max((a - b), 0); 428 | } 429 | 430 | // Divide 431 | float3 Divide(float3 a, float3 b) 432 | { 433 | return (saturate(a / (b + 0.01))); 434 | } 435 | 436 | // Divide (Alternative) 437 | float3 DivideAlt(float3 a, float3 b) 438 | { 439 | return (saturate(1.0 / (a / b))); 440 | } 441 | 442 | // Divide (Photoshop) 443 | float3 DividePS(float3 a, float3 b) 444 | { 445 | return (saturate(a / b)); 446 | } 447 | 448 | // Grain Merge 449 | float3 GrainMerge(float3 a, float3 b) 450 | { 451 | return saturate(b + a - 0.5); 452 | } 453 | 454 | // Grain Extract 455 | float3 GrainExtract(float3 a, float3 b) 456 | { 457 | return saturate(a - b + 0.5); 458 | } 459 | 460 | // Hue 461 | float3 Hue(float3 a, float3 b) 462 | { 463 | return SetLum(SetSat(b, Sat(a)), Lum(a)); 464 | } 465 | 466 | // Saturation 467 | float3 Saturation(float3 a, float3 b) 468 | { 469 | return SetLum(SetSat(a, Sat(b)), Lum(a)); 470 | } 471 | 472 | // Color 473 | float3 ColorB(float3 a, float3 b) 474 | { 475 | return SetLum(b, Lum(a)); 476 | } 477 | 478 | // Luminousity 479 | float3 Luminosity(float3 a, float3 b) 480 | { 481 | return SetLum(a, Lum(b)); 482 | } 483 | 484 | 485 | // ------------------------------------- 486 | // Output Functions 487 | // ------------------------------------- 488 | 489 | float3 Blend(int mode, float3 input, float3 output, float blending) 490 | { 491 | switch (mode) 492 | { 493 | // Normal 494 | default: 495 | return lerp(input.rgb, output.rgb, blending); 496 | // Darken 497 | case 1: 498 | return lerp(input.rgb, Darken(input.rgb, output.rgb), blending); 499 | // Multiply 500 | case 2: 501 | return lerp(input.rgb, Multiply(input.rgb, output.rgb), blending); 502 | // Color Burn 503 | case 3: 504 | return lerp(input.rgb, ColorBurn(input.rgb, output.rgb), blending); 505 | // Linear Burn 506 | case 4: 507 | return lerp(input.rgb, LinearBurn(input.rgb, output.rgb), blending); 508 | // Lighten 509 | case 5: 510 | return lerp(input.rgb, Lighten(input.rgb, output.rgb), blending); 511 | // Screen 512 | case 6: 513 | return lerp(input.rgb, Screen(input.rgb, output.rgb), blending); 514 | // Color Dodge 515 | case 7: 516 | return lerp(input.rgb, ColorDodge(input.rgb, output.rgb), blending); 517 | // Linear Dodge 518 | case 8: 519 | return lerp(input.rgb, LinearDodge(input.rgb, output.rgb), blending); 520 | // Addition 521 | case 9: 522 | return lerp(input.rgb, Addition(input.rgb, output.rgb), blending); 523 | // Glow 524 | case 10: 525 | return lerp(input.rgb, Glow(input.rgb, output.rgb), blending); 526 | // Overlay 527 | case 11: 528 | return lerp(input.rgb, Overlay(input.rgb, output.rgb), blending); 529 | // Soft Light 530 | case 12: 531 | return lerp(input.rgb, SoftLight(input.rgb, output.rgb), blending); 532 | // Hard Light 533 | case 13: 534 | return lerp(input.rgb, HardLight(input.rgb, output.rgb), blending); 535 | // Vivid Light 536 | case 14: 537 | return lerp(input.rgb, VividLight(input.rgb, output.rgb), blending); 538 | // Linear Light 539 | case 15: 540 | return lerp(input.rgb, LinearLight(input.rgb, output.rgb), blending); 541 | // Pin Light 542 | case 16: 543 | return lerp(input.rgb, PinLight(input.rgb, output.rgb), blending); 544 | // Hard Mix 545 | case 17: 546 | return lerp(input.rgb, HardMix(input.rgb, output.rgb), blending); 547 | // Difference 548 | case 18: 549 | return lerp(input.rgb, Difference(input.rgb, output.rgb), blending); 550 | // Exclusion 551 | case 19: 552 | return lerp(input.rgb, Exclusion(input.rgb, output.rgb), blending); 553 | // Subtract 554 | case 20: 555 | return lerp(input.rgb, Subtract(input.rgb, output.rgb), blending); 556 | // Divide 557 | case 21: 558 | return lerp(input.rgb, Divide(input.rgb, output.rgb), blending); 559 | // Divide (Alternative) 560 | case 22: 561 | return lerp(input.rgb, DivideAlt(input.rgb, output.rgb), blending); 562 | // Divide (Photoshop) 563 | case 23: 564 | return lerp(input.rgb, DividePS(input.rgb, output.rgb), blending); 565 | // Reflect 566 | case 24: 567 | return lerp(input.rgb, Reflect(input.rgb, output.rgb), blending); 568 | // Grain Merge 569 | case 25: 570 | return lerp(input.rgb, GrainMerge(input.rgb, output.rgb), blending); 571 | // Grain Extract 572 | case 26: 573 | return lerp(input.rgb, GrainExtract(input.rgb, output.rgb), blending); 574 | // Hue 575 | case 27: 576 | return lerp(input.rgb, Hue(input.rgb, output.rgb), blending); 577 | // Saturation 578 | case 28: 579 | return lerp(input.rgb, Saturation(input.rgb, output.rgb), blending); 580 | // Color 581 | case 29: 582 | return lerp(input.rgb, ColorB(input.rgb, output.rgb), blending); 583 | // Luminosity 584 | case 30: 585 | return lerp(input.rgb, Luminosity(input.rgb, output.rgb), blending); 586 | } 587 | } 588 | } 589 | } 590 | -------------------------------------------------------------------------------- /Shaders/Macros.fxh: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////// 2 | // BASIC MACROS FOR RESHADE 4 // 3 | // AUTHOR: TREYM // 4 | //////////////////////////////////////////////////////////// 5 | // Modified by dddfault // 6 | // // 7 | // Changelogs : // 8 | // Added Sampler texture boundary resolver option // 9 | // Added float2 parameters option // 10 | //////////////////////////////////////////////////////////// 11 | // Macros Guide: // 12 | //////////////////////////////////////////////////////////// 13 | 14 | /* //////////////////////////////////////////////////// * 15 | * //////////////////////////////////////////////////// * 16 | 17 | Usage of these macros is very simple once you understand 18 | the syntax and variable names. Let's start with a Simple 19 | integer slider. To begin, type: 20 | 21 | UI_INT 22 | 23 | Next we need to add _S to indicate that this is a 24 | "slider" widget. Follow the syntax below: 25 | 26 | UI_INT_S(INT_NAME, "Label", "Tooltip", 0, 100, 50) 27 | 28 | Using just a single line of code, we have created a UI 29 | tweakable integer named INT_NAME with a minimum value of 30 | 0, a maximum value of 100, and a default value of 50. 31 | 32 | Next, let's create that same widget, but within a UI 33 | category. This time, we'll type: 34 | 35 | CAT_INT_S(INT_NAME, "Category", "Label", "Tooltip", 0, 100, 50) 36 | 37 | As you can see, the syntax follows the same pattern but 38 | with a new input for "Category" 39 | 40 | Below you will find a useful list of examples to get you 41 | started. I hope you find these useful and they help your 42 | workflow. Happy coding! 43 | 44 | - TreyM 45 | 46 | * //////////////////////////////////////////////////// * 47 | * //////////////////////////////////////////////////// * 48 | 49 | Widget Types 50 | Input = _I 51 | Slider = _S 52 | Drag = _D 53 | 54 | * //////////////////////////////////////////////////// * 55 | 56 | BOOLEAN Macro 57 | UI_BOOL(BOOL_NAME, "Label", "Tooltip", true) 58 | 59 | BOOLEAN Categorized Macro 60 | CAT_BOOL(BOOL_NAME, "Category", "Label", "Tooltip", true) 61 | 62 | * //////////////////////////////////////////////////// * 63 | 64 | INTEGER Combo Widget 65 | UI_COMBO(INT_NAME, "Label", "Tooltip", 0, 2, 0, "Item 1\0Item 2\0Item 3\0") 66 | 67 | INTEGER Drag Widget 68 | UI_INT_D(INT_NAME, "Label", "Tooltip", 0, 100, 50) 69 | 70 | INTEGER Input Widget 71 | UI_INT_I(INT_NAME, "Label", "Tooltip", 0, 100, 50) 72 | 73 | INTEGER Radio Widget 74 | UI_RADIO(INT_NAME, "Label", "Tooltip", 0, 2, 0, " Item 1 \0 Item 2 \0 Item 3\0") 75 | 76 | INTEGER Slider Widget 77 | UI_INT_S(INT_NAME, "Label", "Tooltip", 0, 100, 50) 78 | 79 | INTEGER Categorized Combo Widget 80 | CAT_COMBO(INT_NAME, "Category", "Label", "Tooltip", 0, 2, 0, " Item 1 \0 Item 2 \0 Item 3\0") 81 | 82 | INTEGER Categorized Drag Widget 83 | CAT_INT_D(INT_NAME, "Category", "Label", "Tooltip", 0, 100, 50) 84 | 85 | INTEGER Categorized Input Widget 86 | CAT_INT_I(INT_NAME, "Category", "Label", "Tooltip", 0, 100, 50) 87 | 88 | INTEGER Categorized Radio Widget 89 | CAT_RADIO(INT_NAME, "Category", "Label", "Tooltip", 0, 2, 0, " Item 1 \0 Item 2 \0 Item 3\0") 90 | 91 | INTEGER Categorized Slider Widget 92 | CAT_INT_S(INT_NAME, "Category", "Label", "Tooltip", 0, 100, 50) 93 | 94 | * //////////////////////////////////////////////////// * 95 | 96 | FLOAT Drag Widget 97 | UI_FLOAT_D(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5) 98 | 99 | FLOAT Input Widget 100 | UI_FLOAT_I(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5) 101 | 102 | FLOAT Slider Widget 103 | UI_FLOAT_S(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5) 104 | 105 | FLOAT Categorized Drag Widget 106 | CAT_FLOAT_D(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5) 107 | 108 | FLOAT Categorized Input Widget 109 | CAT_FLOAT_I(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5) 110 | 111 | FLOAT Categorized Slider Widget 112 | CAT_FLOAT_S(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5) 113 | 114 | FLOAT macro with full control (value after "Tooltip" is ui_step) 115 | UI_FLOAT_FULL(FLOAT_NAME, "ui_type", "Label", "Tooltip", 0.1, 0.0, 1.0, 0.5) 116 | 117 | FLOAT Categorized macro with full control (value after "Tooltip" is ui_step) 118 | CAT_FLOAT_FULL(FLOAT_NAME, "ui_type", "Category", "Label", "Tooltip", 0.1, 0.0, 1.0, 0.5) 119 | 120 | * //////////////////////////////////////////////////// * 121 | 122 | FLOAT2 Drag Widget 123 | UI_FLOAT2_D(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) 124 | 125 | FLOAT2 Input Widget 126 | UI_FLOAT2_I(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) 127 | 128 | FLOAT2 Slider Widget 129 | UI_FLOAT2_S(FLOAT_NAME, "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) 130 | 131 | FLOAT2 Categorized Drag Widget 132 | CAT_FLOAT2_D(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) 133 | 134 | FLOAT2 Categorized Input Widget 135 | CAT_FLOAT2_I(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) 136 | 137 | FLOAT2 Categorized Slider Widget 138 | CAT_FLOAT2_S(FLOAT_NAME, "Category", "Label", "Tooltip", 0.0, 1.0, 0.5, 0.5) 139 | 140 | FLOAT2 macro with full control (value after "Tooltip" is ui_step) 141 | UI_FLOAT2_FULL(FLOAT_NAME, "ui_type", "Label", "Tooltip", 0.1, 0.0, 1.0, 0.5, 0.5) 142 | 143 | FLOAT2 Categorized macro with full control (value after "Tooltip" is ui_step) 144 | CAT_FLOAT2_FULL(FLOAT_NAME, "ui_type", "Category", "Label", "Tooltip", 0.1, 0.0, 1.0, 0.5, 0.5) 145 | 146 | * //////////////////////////////////////////////////// * 147 | 148 | FLOAT3 Drag Widget 149 | UI_FLOAT3_D(FLOAT_NAME, "Label", "Tooltip", 0.5, 0.5, 0.5) 150 | 151 | FLOAT3 Input Widget 152 | UI_FLOAT3_I(FLOAT_NAME, "Label", "Tooltip", 0.5, 0.5, 0.5) 153 | 154 | FLOAT3 Slider Widget 155 | UI_FLOAT3_S(FLOAT_NAME, "Label", "Tooltip", 0.5, 0.5, 0.5) 156 | 157 | FLOAT3 Categorized Drag Widget 158 | CAT_FLOAT3_D(FLOAT_NAME, "Category", "Label", "Tooltip", 0.5, 0.5, 0.5) 159 | 160 | FLOAT3 Categorized Input Widget 161 | CAT_FLOAT3_I(FLOAT_NAME, "Category", "Label", "Tooltip", 0.5, 0.5, 0.5) 162 | 163 | FLOAT3 Categorized Slider Widget 164 | CAT_FLOAT3_S(FLOAT_NAME, "Category", "Label", "Tooltip", 0.5, 0.5, 0.5) 165 | 166 | * //////////////////////////////////////////////////// * 167 | 168 | FLOAT3 Color Widget 169 | UI_COLOR(FLOAT_NAME, "Label", "Tooltip", 0.5, 0.5, 0.5) 170 | 171 | FLOAT3 Categorized Color Widget 172 | CAT_COLOR(FLOAT_NAME, "Category", "Label", "Tooltip", 0.5, 0.5, 0.5) 173 | 174 | * //////////////////////////////////////////////////// * 175 | 176 | SAMPLER Macro 177 | SAMPLER(SamplerName, TextureName) 178 | 179 | SAMPLER Macro with texture boundary resolver option 180 | SAMPLER_UV(SamplerName, TextureName, ResolverType) 181 | 182 | TEXTURE Macro 183 | TEXTURE(TextureName, "TexturePath") 184 | 185 | TEXTURE Full Macro 186 | TEXTURE_FULL(TextureName, "TexturePath", Width, Height, Format) 187 | 188 | * //////////////////////////////////////////////////// * 189 | 190 | TECHNIQUE Macro 191 | TECHNIQUE(TechniqueName, PassMacro) 192 | 193 | PASS Macro 194 | PASS(PassID, VertexShader, PixelShader) 195 | 196 | PASS Macro with RenderTarget 197 | PASS_RT(PassID, VertexShader, PixelShader, RenderTarget) 198 | 199 | //////////////////////////////////////////////////// 200 | * //////////////////////////////////////////////////// */ 201 | 202 | // INTEGER MACROS //////////////////////////////// 203 | #define UI_COMBO(var, label, tooltip, minval, maxval, defval, items) \ 204 | uniform int var \ 205 | < \ 206 | ui_type = "combo"; \ 207 | ui_label = label; \ 208 | ui_tooltip = tooltip; \ 209 | ui_items = items; \ 210 | ui_min = minval; \ 211 | ui_max = maxval; \ 212 | > = defval; 213 | 214 | #define CAT_COMBO(var, category, label, tooltip, minval, maxval, defval, items) \ 215 | uniform int var \ 216 | < \ 217 | ui_type = "combo"; \ 218 | ui_category = category; \ 219 | ui_label = label; \ 220 | ui_tooltip = tooltip; \ 221 | ui_items = items; \ 222 | ui_min = minval; \ 223 | ui_max = maxval; \ 224 | > = defval; 225 | 226 | #define UI_INT_I(var, label, tooltip, minval, maxval, defval) \ 227 | uniform int var \ 228 | < \ 229 | ui_type = "input"; \ 230 | ui_label = label; \ 231 | ui_tooltip = tooltip; \ 232 | ui_min = minval; \ 233 | ui_max = maxval; \ 234 | > = defval; 235 | 236 | #define CAT_INT_I(var, category, label, tooltip, minval, maxval, defval) \ 237 | uniform int var \ 238 | < \ 239 | ui_type = "input"; \ 240 | ui_category = category; \ 241 | ui_label = label; \ 242 | ui_tooltip = tooltip; \ 243 | ui_min = minval; \ 244 | ui_max = maxval; \ 245 | > = defval; 246 | 247 | #define UI_INT_S(var, label, tooltip, minval, maxval, defval) \ 248 | uniform int var \ 249 | < \ 250 | ui_type = "slider"; \ 251 | ui_label = label; \ 252 | ui_tooltip = tooltip; \ 253 | ui_min = minval; \ 254 | ui_max = maxval; \ 255 | > = defval; 256 | 257 | #define CAT_INT_S(var, category, label, tooltip, minval, maxval, defval) \ 258 | uniform int var \ 259 | < \ 260 | ui_type = "slider"; \ 261 | ui_category = category; \ 262 | ui_label = label; \ 263 | ui_tooltip = tooltip; \ 264 | ui_min = minval; \ 265 | ui_max = maxval; \ 266 | > = defval; 267 | 268 | #define UI_INT_D(var, label, tooltip, minval, maxval, defval) \ 269 | uniform int var \ 270 | < \ 271 | ui_type = "drag"; \ 272 | ui_label = label; \ 273 | ui_tooltip = tooltip; \ 274 | ui_min = minval; \ 275 | ui_max = maxval; \ 276 | > = defval; 277 | 278 | #define CAT_INT_D(var, category, label, tooltip, minval, maxval, defval) \ 279 | uniform int var \ 280 | < \ 281 | ui_type = "drag"; \ 282 | ui_category = category; \ 283 | ui_label = label; \ 284 | ui_tooltip = tooltip; \ 285 | ui_min = minval; \ 286 | ui_max = maxval; \ 287 | > = defval; 288 | 289 | #define UI_RADIO(var, label, tooltip, minval, maxval, defval, items) \ 290 | uniform int var \ 291 | < \ 292 | ui_type = "radio"; \ 293 | ui_label = label; \ 294 | ui_tooltip = tooltip; \ 295 | ui_items = items; \ 296 | ui_min = minval; \ 297 | ui_max = maxval; \ 298 | > = defval; 299 | 300 | #define CAT_RADIO(var, category, label, tooltip, minval, maxval, defval, items) \ 301 | uniform int var \ 302 | < \ 303 | ui_type = "radio"; \ 304 | ui_category = category; \ 305 | ui_label = label; \ 306 | ui_tooltip = tooltip; \ 307 | ui_items = items; \ 308 | ui_min = minval; \ 309 | ui_max = maxval; \ 310 | > = defval; 311 | 312 | // BOOL MACROS /////////////////////////////////// 313 | #define UI_BOOL(var, label, tooltip, def) \ 314 | uniform bool var \ 315 | < \ 316 | ui_label = label; \ 317 | ui_tooltip = tooltip; \ 318 | > = def; 319 | 320 | #define CAT_BOOL(var, category, label, tooltip, def) \ 321 | uniform bool var \ 322 | < \ 323 | ui_category = category; \ 324 | ui_label = label; \ 325 | ui_tooltip = tooltip; \ 326 | > = def; 327 | 328 | // FLOAT MACROS ////////////////////////////////// 329 | #define UI_FLOAT_D(var, label, tooltip, minval, maxval, defval) \ 330 | uniform float var \ 331 | < \ 332 | ui_type = "drag"; \ 333 | ui_label = label; \ 334 | ui_tooltip = tooltip; \ 335 | ui_min = minval; \ 336 | ui_max = maxval; \ 337 | > = defval; 338 | 339 | #define CAT_FLOAT_D(var, category, label, tooltip, minval, maxval, defval) \ 340 | uniform float var \ 341 | < \ 342 | ui_type = "drag"; \ 343 | ui_category = category; \ 344 | ui_label = label; \ 345 | ui_tooltip = tooltip; \ 346 | ui_min = minval; \ 347 | ui_max = maxval; \ 348 | > = defval; 349 | 350 | #define UI_FLOAT_FULL(var, uitype, label, tooltip, uistep, minval, maxval, defval) \ 351 | uniform float var \ 352 | < \ 353 | ui_type = uitype; \ 354 | ui_label = label; \ 355 | ui_tooltip = tooltip; \ 356 | ui_step = uistep; \ 357 | ui_min = minval; \ 358 | ui_max = maxval; \ 359 | > = defval; 360 | 361 | #define CAT_FLOAT_FULL(var, uitype, category, label, tooltip, uistep, minval, maxval, defval) \ 362 | uniform float var \ 363 | < \ 364 | ui_type = uitype; \ 365 | ui_category = category; \ 366 | ui_label = label; \ 367 | ui_tooltip = tooltip; \ 368 | ui_step = uistep; \ 369 | ui_min = minval; \ 370 | ui_max = maxval; \ 371 | > = defval; 372 | 373 | #define UI_FLOAT_I(var, label, tooltip, minval, maxval, defval) \ 374 | uniform float var \ 375 | < \ 376 | ui_type = "input"; \ 377 | ui_label = label; \ 378 | ui_tooltip = tooltip; \ 379 | ui_min = minval; \ 380 | ui_max = maxval; \ 381 | > = defval; 382 | 383 | #define CAT_FLOAT_I(var, category, label, tooltip, minval, maxval, defval) \ 384 | uniform float var \ 385 | < \ 386 | ui_type = "input"; \ 387 | ui_category = category; \ 388 | ui_label = label; \ 389 | ui_tooltip = tooltip; \ 390 | ui_min = minval; \ 391 | ui_max = maxval; \ 392 | > = defval; 393 | 394 | #define UI_FLOAT_S(var, label, tooltip, minval, maxval, defval) \ 395 | uniform float var \ 396 | < \ 397 | ui_type = "slider"; \ 398 | ui_label = label; \ 399 | ui_tooltip = tooltip; \ 400 | ui_min = minval; \ 401 | ui_max = maxval; \ 402 | > = defval; 403 | 404 | #define CAT_FLOAT_S(var, category, label, tooltip, minval, maxval, defval) \ 405 | uniform float var \ 406 | < \ 407 | ui_type = "slider"; \ 408 | ui_category = category; \ 409 | ui_label = label; \ 410 | ui_tooltip = tooltip; \ 411 | ui_min = minval; \ 412 | ui_max = maxval; \ 413 | > = defval; 414 | 415 | #define UI_FLOAT2_D(var, label, tooltip, minval, maxval, defval1, defval2) \ 416 | uniform float2 var \ 417 | < \ 418 | ui_type = "drag"; \ 419 | ui_label = label; \ 420 | ui_tooltip = tooltip; \ 421 | ui_min = minval; \ 422 | ui_max = maxval; \ 423 | > = float2(defval1, defval2); 424 | 425 | #define CAT_FLOAT2_D(var, category, label, tooltip, minval, maxval, defval1, defval2) \ 426 | uniform float2 var \ 427 | < \ 428 | ui_type = "drag"; \ 429 | ui_category = category; \ 430 | ui_label = label; \ 431 | ui_tooltip = tooltip; \ 432 | ui_min = minval; \ 433 | ui_max = maxval; \ 434 | > = float2(defval1, defval2); 435 | 436 | #define UI_FLOAT2_FULL(var, uitype, label, tooltip, uistep, minval, maxval, defval1, defval2) \ 437 | uniform float2 var \ 438 | < \ 439 | ui_type = uitype; \ 440 | ui_label = label; \ 441 | ui_tooltip = tooltip; \ 442 | ui_step = uistep; \ 443 | ui_min = minval; \ 444 | ui_max = maxval; \ 445 | > = float2(defval1, defval2); 446 | 447 | #define CAT_FLOAT2_FULL(var, uitype, category, label, tooltip, uistep, minval, defval1, defval2) \ 448 | uniform float2 var \ 449 | < \ 450 | ui_type = uitype; \ 451 | ui_category = category; \ 452 | ui_label = label; \ 453 | ui_tooltip = tooltip; \ 454 | ui_step = uistep; \ 455 | ui_min = minval; \ 456 | ui_max = maxval; \ 457 | > = float2(defval1, defval2); 458 | 459 | #define UI_FLOAT2_I(var, label, tooltip, minval, maxval, defval1, defval2) \ 460 | uniform float2 var \ 461 | < \ 462 | ui_type = "input"; \ 463 | ui_label = label; \ 464 | ui_tooltip = tooltip; \ 465 | ui_min = minval; \ 466 | ui_max = maxval; \ 467 | > = float2(defval1, defval2); 468 | 469 | #define CAT_FLOAT2_I(var, category, label, tooltip, minval, maxval, defval1, defval2) \ 470 | uniform float2 var \ 471 | < \ 472 | ui_type = "input"; \ 473 | ui_category = category; \ 474 | ui_label = label; \ 475 | ui_tooltip = tooltip; \ 476 | ui_min = minval; \ 477 | ui_max = maxval; \ 478 | > = float2(defval1, defval2); 479 | 480 | #define UI_FLOAT2_S(var, label, tooltip, minval, maxval, defval1, defval2) \ 481 | uniform float2 var \ 482 | < \ 483 | ui_type = "slider"; \ 484 | ui_label = label; \ 485 | ui_tooltip = tooltip; \ 486 | ui_min = minval; \ 487 | ui_max = maxval; \ 488 | > = float2(defval1, defval2); 489 | 490 | #define CAT_FLOAT2_S(var, category, label, tooltip, minval, maxval, defval1, defval2) \ 491 | uniform float2 var \ 492 | < \ 493 | ui_type = "slider"; \ 494 | ui_category = category; \ 495 | ui_label = label; \ 496 | ui_tooltip = tooltip; \ 497 | ui_min = minval; \ 498 | ui_max = maxval; \ 499 | > = float2(defval1, defval2); 500 | 501 | #define UI_FLOAT3_D(var, label, tooltip, defval1, defval2, defval3) \ 502 | uniform float3 var \ 503 | < \ 504 | ui_type = "drag"; \ 505 | ui_label = label; \ 506 | ui_tooltip = tooltip; \ 507 | > = float3(defval1, defval2, defval3); 508 | 509 | #define CAT_FLOAT3_D(var, category, label, tooltip, defval1, defval2, defval3) \ 510 | uniform float3 var \ 511 | < \ 512 | ui_type = "drag"; \ 513 | ui_category = category; \ 514 | ui_label = label; \ 515 | ui_tooltip = tooltip; \ 516 | > = float3(defval1, defval2, defval3); 517 | 518 | #define UI_FLOAT3_I(var, label, tooltip, defval1, defval2, defval3) \ 519 | uniform float3 var \ 520 | < \ 521 | ui_type = "input"; \ 522 | ui_label = label; \ 523 | ui_tooltip = tooltip; \ 524 | > = float3(defval1, defval2, defval3); 525 | 526 | #define CAT_FLOAT3_I(var, category, label, tooltip, defval1, defval2, defval3) \ 527 | uniform float3 var \ 528 | < \ 529 | ui_type = "input"; \ 530 | ui_category = category; \ 531 | ui_label = label; \ 532 | ui_tooltip = tooltip; \ 533 | > = float3(defval1, defval2, defval3); 534 | 535 | #define UI_FLOAT3_S(var, label, tooltip, defval1, defval2, defval3) \ 536 | uniform float3 var \ 537 | < \ 538 | ui_type = "slider"; \ 539 | ui_label = label; \ 540 | ui_tooltip = tooltip; \ 541 | > = float3(defval1, defval2, defval3); 542 | 543 | #define CAT_FLOAT3_S(var, category, label, tooltip, defval1, defval2, defval3) \ 544 | uniform float3 var \ 545 | < \ 546 | ui_type = "slider"; \ 547 | ui_category = category; \ 548 | ui_label = label; \ 549 | ui_tooltip = tooltip; \ 550 | > = float3(defval1, defval2, defval3); 551 | 552 | 553 | // COLOR WIDGET MACROS /////////////////////////// 554 | #define UI_COLOR(var, label, tooltip, defval1, defval2, defval3) \ 555 | uniform float3 var \ 556 | < \ 557 | ui_type = "color"; \ 558 | ui_label = label; \ 559 | ui_tooltip = tooltip; \ 560 | > = float3(defval1, defval2, defval3); 561 | 562 | #define CAT_COLOR(var, category, label, tooltip, defval1, defval2, defval3) \ 563 | uniform float3 var \ 564 | < \ 565 | ui_type = "color"; \ 566 | ui_category = category; \ 567 | ui_label = label; \ 568 | ui_tooltip = tooltip; \ 569 | > = float3(defval1, defval2, defval3); 570 | 571 | 572 | // SAMPLER MACRO ///////////////////////////////// 573 | #define SAMPLER(sname, tname) \ 574 | sampler sname \ 575 | { \ 576 | Texture = tname; \ 577 | }; 578 | 579 | #define SAMPLER_UV(sname, tname, addUVW) \ 580 | sampler sname \ 581 | { \ 582 | Texture = tname; \ 583 | AddressU = addUVW; \ 584 | AddressV = addUVW; \ 585 | AddressW = addUVW; \ 586 | }; 587 | 588 | 589 | // TEXTURE MACROs //////////////////////////////// 590 | #define TEXTURE(tname, src) \ 591 | texture tname \ 592 | { \ 593 | Width = BUFFER_WIDTH; \ 594 | Height = BUFFER_HEIGHT; \ 595 | Format = RGBA8; \ 596 | }; 597 | 598 | #define TEXTURE_FULL(tname, src, width, height, fomat) \ 599 | texture tname \ 600 | { \ 601 | Width = width; \ 602 | Height = height; \ 603 | Format = fomat; \ 604 | }; 605 | 606 | 607 | // TECHNIQUE MACROS ////////////////////////////// 608 | #define TECHNIQUE(tname, pass) \ 609 | technique tname \ 610 | { \ 611 | pass \ 612 | } 613 | 614 | #define PASS(ID, vs, ps) pass \ 615 | { \ 616 | VertexShader = vs; \ 617 | PixelShader = ps; \ 618 | } 619 | 620 | #define PASS_RT(ID, vs, ps, rt) pass \ 621 | { \ 622 | VertexShader = vs; \ 623 | PixelShader = ps; \ 624 | RenderTarget = rt; \ 625 | } 626 | -------------------------------------------------------------------------------- /REFERENCE.md: -------------------------------------------------------------------------------- 1 | ReShade FX shading language 2 | =========================== 3 | 4 | The ReShade FX shading language is heavily based on the DX9-style HLSL syntax, with a few extensions. For more details on HLSL, check out the Programming Guide: https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-writing-shaders-9 .\ 5 | This document will instead primarily focus on syntax and features that are unique to ReShade FX. 6 | 7 | * [Macros](#macros) 8 | * [Texture object](#texture-object) 9 | * [Sampler object](#sampler-object) 10 | * [Storage object](#storage-object) 11 | * [Uniform variables](#uniform-variables) 12 | * [Structs](#structs) 13 | * [Namespaces](#namespaces) 14 | * [User functions](#user-functions) 15 | * [Intrinsic functions](#intrinsic-functions) 16 | * [Techniques](#techniques) 17 | 18 | ## Macros 19 | 20 | The ReShade FX compiler predefines certain preprocessor macros, as listed below: 21 | * ``__FILE__`` Current file path 22 | * ``__FILE_NAME__`` Current file name without path 23 | * ``__FILE_STEM__`` Current file name without extension and path 24 | * ``__LINE__`` Current line number 25 | * ``__RESHADE__`` Version of the injector (in the format `MAJOR * 10000 + MINOR * 100 + REVISION`) 26 | * ``__APPLICATION__`` 32-bit truncated Fnv1a hash of the application executable name 27 | * ``__VENDOR__`` Vendor id (e.g. 0x10de for NVIDIA, 0x1002 for AMD, 0x8086 for Intel) 28 | * ``__DEVICE__`` Device id 29 | * ``__RENDERER__`` Graphics API used to render effects 30 | * D3D9: 0x9000 31 | * D3D10: 0xa000 or higher 32 | * D3D11: 0xb000 or higher (e.g. 0xb100 for D3D11.1) 33 | * D3D12: 0xc000 or higher 34 | * OpenGL: 0x10000 or higher (e.g. 0x14300 for OpenGL 4.3) 35 | * Vulkan: 0x20000 or higher (e.g. 0x21100 for Vulkan 1.1) 36 | * ``BUFFER_WIDTH`` Backbuffer width (essentially the width of the image the application renders to the screen) 37 | * ``BUFFER_HEIGHT`` Backbuffer height 38 | * ``BUFFER_RCP_WIDTH`` Reciprocal of the backbuffer width (equals `1.0 / BUFFER_WIDTH`) 39 | * ``BUFFER_RCP_HEIGHT`` Reciprocal of the backbuffer height (equals `1.0 / BUFFER_HEIGHT`) 40 | * ``BUFFER_COLOR_FORMAT`` Backbuffer texture format 41 | * ``BUFFER_COLOR_BIT_DEPTH`` Color bit depth of the backbuffer (8, 10 or 16) 42 | * ``BUFFER_COLOR_SPACE`` Color space type for presentation; 0 = unknown, 1 = sRGB, 2 = scRGB, 3 = HDR10 ST2084, 4 = HDR10 HLG. 43 | 44 | Additionally every enabled addon will cause a ``ADDON_[NAME]`` definition to be defined for it. 45 | Therefore the built-in addons "Generic Depth" and "Effect Runtime Sync" will cause the ``ADDON_GENERIC_DEPTH`` and ``ADDON_EFFECT_RUNTIME_SYNC`` definitions to be set, unless they have been turned off. 46 | 47 | Constructs like the following may be interpreted as a configurable UI option. To prevent this, the preprocessor define name can be prefixed with an underscore or made shorter than 8 characters, in which case ReShade will not display it in the UI. 48 | ```c 49 | #ifndef MY_PREPROCESSOR_DEFINE 50 | #define MY_PREPROCESSOR_DEFINE 0 51 | #endif 52 | ``` 53 | 54 | You can disable optimization during shader compilation by adding this line to an effect file: 55 | ```c 56 | #pragma reshade skipoptimization 57 | ``` 58 | 59 | ## Texture Object 60 | 61 | Textures are multidimensional data containers usually used to store images. 62 | Declared textures are created at runtime with the parameters specified in their definition body. 63 | 64 | #### Annotations: 65 | 66 | * ``texture2D imageTex < source = "path/to/image.bmp"; > { ... };`` 67 | Opens image from the patch specified, resizes it to the texture size and loads it into the texture.\ 68 | ReShade supports Bitmap (\*.bmp), Portable Network Graphics (\*.png), JPEG (\*.jpg), Targa Image (\*.tga) and DirectDraw Surface (\*.dds) files. 69 | * ``texture2D myTex1 < pooled = true; > { Width = 100; Height = 100; Format = RGBA8; };`` 70 | ``texture2D myTex2 < pooled = true; > { Width = 100; Height = 100; Format = RGBA8; };`` 71 | ReShade will attempt to re-use the same memory for textures with the same dimensions and format across effect files if the pooled annotation is set. 72 | 73 | #### ReShade FX allows semantics to be used on texture declarations. This is used to request special textures: 74 | 75 | * ``texture2D texColor : COLOR;`` 76 | Receives the backbuffer contents (read-only). 77 | * ``texture2D texDepth : DEPTH;`` 78 | Receives the game's depth information (read-only). 79 | 80 | ```hlsl 81 | texture2D texColorBuffer : COLOR; 82 | texture2D texDepthBuffer : DEPTH; 83 | 84 | texture2D texTarget 85 | { 86 | // The texture dimensions (default: 1x1). 87 | Width = BUFFER_WIDTH / 2; // Used with texture1D, texture2D and texture3D 88 | Height = BUFFER_HEIGHT / 2; // Used with texture2D and texture3D 89 | Depth = 1; // Used with texture3D 90 | 91 | // The number of mipmaps including the base level (default: 1). 92 | MipLevels = 1; 93 | 94 | // The internal texture format (default: RGBA8). 95 | // Available formats: 96 | // R8, R16, R16F, R32F, R32I, R32U 97 | // RG8, RG16, RG16F, RG32F 98 | // RGBA8, RGBA16, RGBA16F, RGBA32F, RGBA32I, RGBA32U 99 | // RGB10A2, R11G11B10F 100 | Format = RGBA8; 101 | 102 | // Unspecified properties are set to the defaults shown here. 103 | }; 104 | 105 | texture3D texIntegerVolume 106 | { 107 | Width = 10; 108 | Height = 10; 109 | Depth = 10; 110 | Format = R32I; // Single-component integer format, which means sampler and storage have to be of that integer type (sampler3D or storage3D) 111 | }; 112 | ``` 113 | 114 | ## Sampler Object 115 | 116 | Samplers are the bridge between textures and shaders. They define how a texture is read from and how data outside texel coordinates is sampled. Multiple samplers can refer to the same texture using different options. 117 | 118 | ```hlsl 119 | sampler2D samplerColor 120 | { 121 | // The texture to be used for sampling. 122 | Texture = texColorBuffer; 123 | 124 | // The method used for resolving texture coordinates which are out of bounds. 125 | // Available values: CLAMP, MIRROR, WRAP or REPEAT, BORDER 126 | AddressU = CLAMP; 127 | AddressV = CLAMP; 128 | AddressW = CLAMP; 129 | 130 | // The magnification, minification and mipmap filtering types. 131 | // Available values: POINT, LINEAR, ANISOTROPIC 132 | MagFilter = LINEAR; 133 | MinFilter = LINEAR; 134 | MipFilter = LINEAR; 135 | 136 | // The maximum mipmap levels accessible. 137 | MinLOD = 0.0f; 138 | MaxLOD = 1000.0f; 139 | 140 | // An offset applied to the calculated mipmap level (default: 0). 141 | MipLODBias = 0.0f; 142 | 143 | // Enable or disable converting to linear colors when sampling from the 144 | // texture. 145 | SRGBTexture = false; 146 | 147 | // Unspecified properties are set to the defaults shown here. 148 | }; 149 | 150 | sampler2D samplerDepth 151 | { 152 | Texture = texDepthBuffer; 153 | }; 154 | sampler2D samplerTarget 155 | { 156 | Texture = texTarget; 157 | }; 158 | ``` 159 | 160 | ## Storage Object 161 | 162 | Storage objects define how a texture should be written to from compute shaders. 163 | 164 | ```hlsl 165 | storage2D storageTarget 166 | { 167 | // The texture to be used as storage. 168 | Texture = texTarget; 169 | 170 | // The mipmap level of the texture to fetch/store. 171 | MipLevel = 0; 172 | }; 173 | 174 | storage3D storageIntegerVolume 175 | { 176 | Texture = texIntegerVolume; 177 | }; 178 | ``` 179 | 180 | ## Uniform Variables 181 | 182 | Global variables with the `uniform` qualifier are constant across each iteration of a shader per pass and may be controlled via the UI. 183 | 184 | #### Annotations to customize UI appearance: 185 | 186 | * ui_type: Can be `input`, `drag`, `slider`, `combo` (on integer variables), `radio` (on integer variables), `color` (on vector variables) or `button` (on boolean variables) 187 | * ui_min: The smallest value allowed in this variable (required when `ui_type = "drag"` or `ui_type = "slider"`) 188 | * ui_max: The largest value allowed in this variable (required when `ui_type = "drag"` or `ui_type = "slider"`) 189 | * ui_step: The value added/subtracted when clicking the button next to the slider 190 | * ui_items: A list of items for the combo box or radio buttons, each item is terminated with a `\0` character (required when `ui_type = "combo"` or `ui_type = "radio"`) 191 | * ui_label: Display name of the variable in the UI. If this is missing, the variable name is used instead. 192 | * ui_tooltip: Text that is displayed when the user hovers over the variable in the UI. Use this for a description. 193 | * ui_category: Groups values together under a common headline. Note that all variables in the same category also have to be declared next to each other for this to be displayed correctly. 194 | * ui_category_closed: Set to true to show a category closed by default. 195 | * ui_category_toggle: Set to true to make the boolean value of this variable toggle visibility of the whole category. 196 | * ui_text: Adds a text block with the specfified string above the the UI widget. 197 | * ui_spacing: Adds space before the UI widget (multiplied by the value of the annotation). 198 | * ui_units: Adds units description on the slider/drag bar (only used when `ui_type = "drag"` or `ui_type = "slider"`) 199 | * hidden: Set to true to hide this variable in the UI. 200 | * noedit: Set to true to show this variable in the UI, but prevent modification. 201 | * nosave: Set to true to prevent the value of this variable from being saved to presets. 202 | * noreset: Set to true to prevent resetting this variable to its default in the UI. 203 | 204 | #### Annotations are also used to request special runtime values (via the `source` annotation): 205 | 206 | * ``uniform float frametime < source = "frametime"; >;`` 207 | Time in milliseconds it took for the last frame to complete. 208 | * ``uniform int framecount < source = "framecount"; >;`` 209 | Total amount of frames since the game started. 210 | * ``uniform float4 date < source = "date"; >;`` 211 | float4(year, month (1 - 12), day of month (1 - 31), time in seconds) 212 | * ``uniform float timer < source = "timer"; >;`` 213 | Timer counting time in milliseconds since game start. 214 | * ``uniform float2 pingpong < source = "pingpong"; min = 0; max = 10; step = 2; smoothing = 0.0; >;`` 215 | Value that smoothly interpolates between `min` and `max` using `step` as the increase/decrease value every second (so a step value of 1 means the value is increased/decreased by 1 per second).\ 216 | In this case it would go from 0 to 10 in 5 seconds and then back to 0 in another 5 seconds (interpolated every frame). 217 | The `smoothing` value affects the interpolation curve (0 is linear interpolation and anything else changes the speed depending on how close the current value is to `min` or `max`). 218 | The second component is either +1 or -1 depending on the direction it currently goes. 219 | * ``uniform int random_value < source = "random"; min = 0; max = 10; >;`` 220 | Gets a new random value between min and max every pass. 221 | * ``uniform bool space_bar_down < source = "key"; keycode = 0x20; mode = ""; >;`` 222 | True if specified keycode (in this case the spacebar) is pressed and false otherwise. 223 | If mode is set to "press" the value is true only in the frame the key was initially held down. 224 | If mode is set to "toggle" the value stays true until the key is pressed a second time. 225 | * ``uniform bool left_mouse_button_down < source = "mousebutton"; keycode = 0; mode = ""; >;`` 226 | True if specified mouse button (0 - 4) is pressed and false otherwise. 227 | If mode is set to "press" the value is true only in the frame the key was initially held down. 228 | If mode is set to "toggle" the value stays true until the key is pressed a second time. 229 | * ``uniform float2 mouse_point < source = "mousepoint"; >;`` 230 | Gets the position of the mouse cursor in screen coordinates. 231 | * ``uniform float2 mouse_delta < source = "mousedelta"; >;`` 232 | Gets the movement of the mouse cursor in screen coordinates. 233 | * ``uniform float2 mouse_value < source = "mousewheel"; min = 0.0; max = 10.0; > = 1.0;`` 234 | The first component value is modified via the mouse wheel. Starts at 1.0, goes up (but not past 10.0) when mouse wheel is moved forward and down (but not past 0.0) when it is moved backward. 235 | The second component holds the current wheel state (how much the mouse wheel was moved this frame). It's positive for forward movement, negative for backward movement or zero for no movement. 236 | * ``uniform bool has_depth < source = "bufready_depth"; >;`` 237 | True if the application's depth buffer is available in textures declared with `DEPTH`, false if not. 238 | * ``uniform bool overlay_open < source = "overlay_open"; >;`` 239 | True if the ReShade in-game overlay is currently open, false if not. 240 | * ``uniform int active_variable < source = "overlay_active"; >;`` 241 | Contains the one-based index of the uniform variable currently being modified in the overlay, zero if none. 242 | * ``uniform int hovered_variable < source = "overlay_hovered"; >;`` 243 | Contains the one-based index of the uniform variable currently hovered with the cursor in the overlay, zero if none. 244 | * ``uniform bool screenshot < source = "screenshot"; >;`` 245 | True if a screenshot is being taken, false if not. 246 | 247 | ```hlsl 248 | // Initializers are used to specify the default value (zero is used if not specified). 249 | uniform float4 UniformSingleValue = float4(0.0f, 0.0f, 0.0f, 0.0f); 250 | 251 | // It is recommended to use constants instead of uniforms if the value is not changing or user-configurable. 252 | static const float4 ConstantSingleValue = float4(0.0f, 0.0f, 0.0f, 0.0f); 253 | ``` 254 | 255 | ## Structs 256 | 257 | Structs are user defined data types that can be used as types for variables. These behave the same as in HLSL. 258 | 259 | ```hlsl 260 | struct MyStruct 261 | { 262 | int MyField1, MyField2; 263 | float MyField3; 264 | }; 265 | ``` 266 | 267 | ## Namespaces 268 | 269 | Namespaces are used to group functions and variables together, which is especially useful to prevent name clashing.\ 270 | The "::" operator is used to resolve variables or functions inside other namespaces. 271 | 272 | ```hlsl 273 | namespace MyNamespace 274 | { 275 | namespace MyNestedNamespace 276 | { 277 | void DoNothing() 278 | { 279 | } 280 | } 281 | 282 | void DoNothing() 283 | { 284 | MyNestedNamespace::DoNothing(); 285 | } 286 | } 287 | ``` 288 | 289 | ## User functions 290 | 291 | #### Attributes: 292 | 293 | * ``[numthreads(X, Y, Z)]`` 294 | Specifies the local thread group size, with X, Y and Z being the size in the corresponding dimension. 295 | * ``[shader("vertex")]``/``[shader("pixel")]``/``[shader("compute")]`` 296 | Optionally specifies the shader type this function implements. 297 | 298 | #### Parameter qualifiers: 299 | 300 | * ``in`` Declares an input parameter. Default and implicit if none is used. Functions expect these to be filled with a value. 301 | * ``out`` Declares an output parameter. The value is filled in the function and can be used in the caller again. 302 | * ``inout`` Declares a parameter that provides input and also expects output. 303 | 304 | #### Supported flow-control statements: 305 | 306 | * ``[attribute] if ([condition]) { [statement...] } [else { [statement...] }]`` 307 | Statements after if are only executed if condition is true, otherwise the ones after else are executed (if it exists). 308 | Possible attributes are : ``[flatten]`` and ``[branch]`` 309 | * ``[attribute] switch ([expression]) { [case [constant]/default]: [statement...] }`` 310 | Selects the case matching the switch expression or default if non does and it exists. 311 | Possible attributes are : ``[flatten]``, ``[branch]``, ``[forcecase]`` and ``[call]`` 312 | * ``[attribute] for ([declaration]; [condition]; [iteration]) { [statement...] }`` 313 | Runs the statements in the body as long as the condition is true. The iteration expression is executed after each run. 314 | Possible attributes are : ``[unroll]``, ``[loop]`` and ``[fastopt]`` 315 | * ``[attribute] while ([condition]) { [statement...] }`` 316 | Runs the statements in the body as long as the condition is true. 317 | Possible attributes are : ``[unroll]``, ``[loop]``, and ``[fastopt]`` 318 | * ``[attribute] do { [statement...] } while ([condition]);`` 319 | Similar to a normal while loop with the difference that the statements are executed at least once. 320 | Possible attributes are : ``[fastopt]`` 321 | * ``break;`` 322 | Breaks out of the current loop or switch statement and jumps to the statement after. 323 | * ``continue;`` 324 | Jumps directly to the next loop iteration ignoring any left code in the current one. 325 | * ``return [expression];`` 326 | Jumps out of the current function, optionally providing a value to the caller. 327 | * ``discard;`` 328 | Abort rendering of the current pixel and step out of the shader. Can be used in pixel shaders only. 329 | 330 | ```hlsl 331 | // Semantics are used to tell the runtime which arguments to connect between shader stages. 332 | // They are ignored on non-entry-point functions (those not used in any pass below). 333 | // Semantics starting with "SV_" are system value semantics and serve a special meaning. 334 | // The following vertex shader demonstrates how to generate a simple fullscreen triangle with the three vertices provided by ReShade (http://redd.it/2j17wk): 335 | [shader("vertex")] 336 | void ExampleVS(uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD0) 337 | { 338 | texcoord.x = (id == 2) ? 2.0 : 0.0; 339 | texcoord.y = (id == 1) ? 2.0 : 0.0; 340 | position = float4(texcoord * float2(2, -2) + float2(-1, 1), 0, 1); 341 | } 342 | 343 | // The following pixel shader simply returns the color of the games output again without modifying it (via the "color" output parameter): 344 | [shader("pixel")] 345 | void ExamplePS0(float4 pos : SV_Position, float2 texcoord : TEXCOORD0, out float4 color : SV_Target) 346 | { 347 | color = tex2D(samplerColor, texcoord); 348 | } 349 | 350 | // The following pixel shader takes the output of the previous pass and adds the depth buffer content to the right screen side. 351 | [shader("pixel")] 352 | float4 ExamplePS1(float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target 353 | { 354 | // Here color information is sampled with "samplerTarget" and thus from "texTarget" (see sampler declaration above), 355 | // which was set as render target in the previous pass (see the technique definition below) and now contains its output. 356 | // In this case it is the game output, but downsampled to half because the texture is only half of the screen size. 357 | float4 color = tex2D(samplerTarget, texcoord); 358 | 359 | // Only execute the following code block when on the right half of the screen. 360 | if (texcoord.x > 0.5f) 361 | { 362 | // Sample from the game depth buffer using the "samplerDepth" sampler declared above. 363 | float depth = tex2D(samplerDepth, texcoord).r; 364 | 365 | // Linearize the depth values to better visualize them. 366 | depth = 2.0 / (-99.0 * depth + 101.0); 367 | 368 | color.rgb = depth.rrr; 369 | } 370 | 371 | return color; 372 | } 373 | 374 | // The following compute shader uses shared memory within a thread group: 375 | groupshared int sharedMem[64]; 376 | [shader("compute")] 377 | void ExampleCS0(uint3 tid : SV_GroupThreadID) 378 | { 379 | if (tid.y == 0) 380 | sharedMem[tid.x] = tid.x; 381 | barrier(); 382 | if (tid.y == 0 && (tid.x % 2) != 0) 383 | sharedMem[tid.x] += sharedMem[tid.x + 1]; 384 | } 385 | 386 | // The following compute shader writes a color gradient to the "texTarget" texture: 387 | [shader("compute")] 388 | void ExampleCS1(uint3 id : SV_DispatchThreadID, uint3 tid : SV_GroupThreadID) 389 | { 390 | tex2Dstore(storageTarget, id.xy, float4(tid.xy / float2(20 * 64, 2 * 8), 0, 1)); 391 | } 392 | ``` 393 | 394 | ## Intrinsic functions 395 | 396 | ReShade FX supports most of the standard HLSL intrinsics.\ 397 | Check out https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-intrinsic-functions for reference on them: 398 | 399 | * abs 400 | * acos 401 | * all 402 | * any 403 | * asfloat 404 | * asin 405 | * asint 406 | * asuint 407 | * atan 408 | * atan2 409 | * ceil 410 | * clamp 411 | * countbits 412 | * cos 413 | * cosh 414 | * cross 415 | * ddx 416 | * ddy 417 | * degrees 418 | * determinant 419 | * distance 420 | * dot 421 | * exp 422 | * exp2 423 | * f16tof32 424 | * f32tof16 425 | * faceforward 426 | * firstbitlow 427 | * firstbithigh 428 | * floor 429 | * frac 430 | * frexp 431 | * fwidth 432 | * isinf 433 | * isnan 434 | * ldexp 435 | * length 436 | * lerp 437 | * log 438 | * log10 439 | * log2 440 | * mad 441 | * max 442 | * min 443 | * modf 444 | * mul 445 | * normalize 446 | * pow 447 | * radians 448 | * rcp 449 | * reflect 450 | * refract 451 | * reversebits 452 | * round 453 | * rsqrt 454 | * saturate 455 | * sign 456 | * sin 457 | * sincos 458 | * sinh 459 | * smoothstep 460 | * sqrt 461 | * step 462 | * tan 463 | * tanh 464 | * transpose 465 | * trunc 466 | 467 | In addition to these, ReShade FX provides a few additional ones: 468 | 469 | * ``T tex1D(sampler1D s, float coords)`` 470 | ``T tex1D(sampler1D s, float coords, int offset)`` 471 | ``T tex2D(sampler2D s, float2 coords)`` 472 | ``T tex2D(sampler2D s, float2 coords, int2 offset)`` 473 | ``T tex3D(sampler3D s, float3 coords)`` 474 | ``T tex3D(sampler3D s, float3 coords, int3 offset)`` 475 | Samples a texture.\ 476 | See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-sample. 477 | * ``T tex1Dlod(sampler1D s, float4 coords)`` 478 | ``T tex1Dlod(sampler1D s, float4 coords, int offset)`` 479 | ``T tex2Dlod(sampler2D s, float4 coords)`` 480 | ``T tex2Dlod(sampler2D s, float4 coords, int2 offset)`` 481 | ``T tex3Dlod(sampler3D s, float4 coords)`` 482 | ``T tex3Dlod(sampler3D s, float4 coords, int3 offset)`` 483 | Samples a texture on a specific mipmap level.\ 484 | The accepted coordinates are in the form `float4(x, y, 0, lod)`.\ 485 | See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-samplelevel. 486 | * ``T tex1Dgrad(sampler1D s, float coords, float ddx, float ddy)`` 487 | ``T tex1Dgrad(sampler1D s, float coords, float ddx, float ddy, int offset)`` 488 | ``T tex2Dgrad(sampler2D s, float2 coords, float2 ddx, float2 ddy)`` 489 | ``T tex2Dgrad(sampler2D s, float2 coords, float2 ddx, float2 ddy, int2 offset)`` 490 | ``T tex3Dgrad(sampler3D s, float3 coords, float3 ddx, float3 ddy)`` 491 | ``T tex3Dgrad(sampler3D s, float3 coords, float3 ddx, float3 ddy, int3 offset)`` 492 | Samples a texture using a gradient to influence the way the sample location is calculated.\ 493 | See also https://learn.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-samplegrad. 494 | * ``T tex1Dfetch(sampler1D s, int coords)`` 495 | ``T tex1Dfetch(sampler1D s, int coords, int lod)`` 496 | ``T tex1Dfetch(storage1D s, int coords)`` 497 | ``T tex2Dfetch(sampler2D s, int2 coords)`` 498 | ``T tex2Dfetch(sampler2D s, int2 coords, int lod)`` 499 | ``T tex2Dfetch(storage2D s, int2 coords)`` 500 | ``T tex3Dfetch(sampler3D s, int3 coords)`` 501 | ``T tex3Dfetch(sampler3D s, int3 coords, int lod)`` 502 | ``T tex3Dfetch(storage3D s, int3 coords)`` 503 | Fetches a value from the texture directly without any sampling.\ 504 | See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-load. 505 | * ``float4 tex2DgatherR(sampler2D s, float2 coords)`` 506 | ``float4 tex2DgatherR(sampler2D s, float2 coords, int2 offset)`` 507 | ``float4 tex2DgatherG(sampler2D s, float2 coords)`` 508 | ``float4 tex2DgatherG(sampler2D s, float2 coords, int2 offset)`` 509 | ``float4 tex2DgatherB(sampler2D s, float2 coords)`` 510 | ``float4 tex2DgatherB(sampler2D s, float2 coords, int2 offset)`` 511 | ``float4 tex2DgatherA(sampler2D s, float2 coords)`` 512 | ``float4 tex2DgatherA(sampler2D s, float2 coords, int2 offset)`` 513 | Gathers the specified component of the four neighboring pixels and returns the result.\ 514 | `tex2DgatherR` for example is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/texture2d-gatherred. 515 | The return value is effectively: 516 | ``` 517 | float4(tex2Dfetch(s, coords * tex2Dsize(s) + int2(0, 1)).comp, 518 | tex2Dfetch(s, coords * tex2Dsize(s) + int2(1, 1)).comp, 519 | tex2Dfetch(s, coords * tex2Dsize(s) + int2(1, 0)).comp, 520 | tex2Dfetch(s, coords * tex2Dsize(s) + int2(0, 0)).comp) 521 | ``` 522 | * ``int tex1Dsize(sampler1D s)`` 523 | ``int tex1Dsize(sampler1D s, int lod)`` 524 | ``int tex1Dsize(storage1D s)`` 525 | ``int2 tex2Dsize(sampler2D s)`` 526 | ``int2 tex2Dsize(sampler2D s, int lod)`` 527 | ``int2 tex2Dsize(storage2D s)`` 528 | ``int3 tex3Dsize(sampler3D s)`` 529 | ``int3 tex3Dsize(sampler3D s, int lod)`` 530 | ``int3 tex3Dsize(storage3D s)`` 531 | Gets the texture dimensions of the specified mipmap level.\ 532 | See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-getdimensions 533 | * ``void tex1Dstore(storage1D s, int coords, T value)`` 534 | ``void tex2Dstore(storage2D s, int2 coords, T value)`` 535 | ``void tex3Dstore(storage2D s, int3 coords, T value)`` 536 | Writes the specified value to the texture referenced by the storage. Only valid from within compute shaders.\ 537 | See also https://docs.microsoft.com/windows/win32/direct3dhlsl/sm5-object-rwtexture2d-operatorindex 538 | * ``void barrier()`` 539 | Synchronizes threads in a thread group.\ 540 | Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/groupmemorybarrierwithgroupsync 541 | * ``void memoryBarrier()`` 542 | Waits on the completion of all memory accesses resulting from the use of texture or storage operations.\ 543 | Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/allmemorybarrier 544 | * ``void groupMemoryBarrier()`` 545 | Waits on the completion of all memory accesses within the thread group resulting from the use of texture or storage operations.\ 546 | Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/groupmemorybarrier 547 | * ``int atomicAdd(inout int dest, int value)`` 548 | ``int atomicAdd(storage1D s, int coords, int value)`` 549 | ``int atomicAdd(storage2D s, int2 coords, int value)`` 550 | ``int atomicAdd(storage3D s, int3 coords, int value)`` 551 | https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedadd 552 | * ``int atomicAnd(inout int dest, int value)`` 553 | ``int atomicAnd(storage1D s, int coords, int value)`` 554 | ``int atomicAnd(storage2D s, int2 coords, int value)`` 555 | ``int atomicAnd(storage3D s, int3 coords, int value)`` 556 | https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedand 557 | * ``int atomicOr(inout int dest, int value)`` 558 | ``int atomicOr(storage1D s, int coords, int value)`` 559 | ``int atomicOr(storage2D s, int2 coords, int value)`` 560 | ``int atomicOr(storage3D s, int3 coords, int value)`` 561 | https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedor 562 | * ``int atomicXor(inout int dest, int value)`` 563 | ``int atomicXor(storage1D s, int coords, int value)`` 564 | ``int atomicXor(storage2D s, int2 coords, int value)`` 565 | ``int atomicXor(storage3D s, int3 coords, int value)`` 566 | https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedxor 567 | * ``int atomicMin(inout int dest, int value)`` 568 | ``int atomicMin(storage1D s, int coords, int value)`` 569 | ``int atomicMin(storage2D s, int2 coords, int value)`` 570 | ``int atomicMin(storage3D s, int3 coords, int value)`` 571 | https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedmin 572 | * ``int atomicMax(inout int dest, int value)`` 573 | ``int atomicMax(storage s, int coords, int value)`` 574 | ``int atomicMax(storage s, int2 coords, int value)`` 575 | ``int atomicMax(storage s, int3 coords, int value)`` 576 | https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedmax 577 | * ``int atomicExchange(inout int dest, int value)`` 578 | ``int atomicExchange(storage1D s, int coords, int value)`` 579 | ``int atomicExchange(storage2D s, int2 coords, int value)`` 580 | ``int atomicExchange(storage3D s, int3 coords, int value)`` 581 | https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedexchange 582 | * ``int atomicCompareExchange(inout int dest, int compare, int value)`` 583 | ``int atomicCompareExchange(storage1D s, int coords, int compare, int value)`` 584 | ``int atomicCompareExchange(storage2D s, int2 coords, int compare, int value)`` 585 | ``int atomicCompareExchange(storage3D s, int3 coords, int compare, int value)`` 586 | https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedcompareexchange 587 | 588 | ## Techniques 589 | 590 | An effect file can have multiple techniques, each representing a full render pipeline, which is executed to apply post-processing effects. ReShade executes all enabled techniques in the order they were defined in the effect file.\ 591 | A technique is made up of one or more passes which contain info about which render states to set and what shaders to execute. They are run sequentially starting with the top most declared. A name is optional.\ 592 | Each pass can set render states. The default value is used if one is not specified in the pass body. 593 | 594 | #### Annotations: 595 | 596 | * ``technique Name < enabled = true; >`` 597 | Enable (or disable if false) this technique by default. 598 | * ``technique Name < enabled_in_screenshot = true; >`` 599 | Set this to false to disabled this technique while a screenshot is taken. 600 | * ``technique Name < timeout = 1000; >`` 601 | Auto-toggle this technique off 1000 milliseconds after it was enabled.\ 602 | This can for example be used to have a technique run a single time only to do some initialization work, via ``technique Name < enabled = true; timeout = 1; >`` 603 | * ``technique Name < hidden = true; >`` 604 | Hide this technique in the UI. 605 | * ``technique Name < ui_label = "My Effect Name"; >`` 606 | Uses a custom name for the technique in the UI. 607 | * ``technique Name < ui_tooltip = "My Effect description"; >`` 608 | Shows the specified text when the user hovers the technique in the UI. 609 | 610 | ```hlsl 611 | technique Example < ui_tooltip = "This is an example!"; > 612 | { 613 | pass p0 614 | { 615 | // The primitive topology rendered in the draw call. 616 | // Available values: 617 | // POINTLIST, LINELIST, LINESTRIP, TRIANGLELIST, TRIANGLESTRIP 618 | PrimitiveTopology = TRIANGLELIST; // or PrimitiveType 619 | 620 | // The number of vertices ReShade generates for the draw call. 621 | // This has different effects on the rendered primitives based on the primitive topology. 622 | // A triangle list needs 3 separate vertices for every triangle for example, a strip on the other hand reuses the last 2, so only 1 is needed for every additional triangle. 623 | VertexCount = 3; 624 | 625 | // The following two accept function names declared above which are used as entry points for the shader. 626 | // Please note that all parameters must have an associated semantic so the runtime can match them between shader stages. 627 | VertexShader = ExampleVS; 628 | PixelShader = ExamplePS0; 629 | 630 | // The number of thread groups to dispatch when a compute shader is used. 631 | DispatchSizeX = 1; 632 | DispatchSizeY = 1; 633 | DispatchSizeZ = 1; 634 | 635 | // Compute shaders are specified with the number of threads per thread group in brackets. 636 | // The following for example will create groups of 64x1x1 threads: 637 | ComputeShader = ExampleCS0<64,1,1>; 638 | 639 | // RenderTarget0 to RenderTarget7 allow to set one or more render targets for rendering to textures. 640 | // Set them to a texture name declared above in order to write the color output (SV_Target0 to RenderTarget0, SV_Target1 to RenderTarget1, ...) to this texture in this pass. 641 | // If multiple render targets are used, the dimensions of them has to match each other. 642 | // If no render targets are set here, RenderTarget0 points to the backbuffer. 643 | // Be aware that you can only read **OR** write a texture at the same time, so do not sample from it while it is still bound as render target here. 644 | // RenderTarget and RenderTarget0 are aliases. 645 | RenderTarget = texTarget; 646 | 647 | // Set to true to clear all bound render targets to zero before rendering. 648 | ClearRenderTargets = false; 649 | 650 | // Set to false to disable automatic rebuilding of the mipmap chain of all render targets and/or storage objects. 651 | // This is useful when using a compute shader that writes to specific mipmap levels, rather than relying on the automatic generation. 652 | // Note that the texture must have MipLevels set to a number higher than 1 for this to work. 653 | GenerateMipMaps = true; 654 | 655 | // A mask applied to the color output before it is written to the render target. 656 | RenderTargetWriteMask = 0xF; // or ColorWriteEnable 657 | 658 | // Enable or disable gamma correction applied to the output. 659 | SRGBWriteEnable = false; 660 | 661 | // BlendEnable0 to BlendEnable7 allow to enable or disable color and alpha blending for the respective render target. 662 | // Don't forget to also set "ClearRenderTargets" to "false" if you want to blend with existing data in a render target. 663 | // BlendEnable and BlendEnable0 are aliases, 664 | BlendEnable = false; 665 | 666 | // The operator used for color and alpha blending. 667 | // To set these individually for each render target, append the render target index to the pass state name, e.g. BlendOp3 for the fourth render target (zero-based index 3). 668 | // Available values: 669 | // ADD, SUBTRACT, REVSUBTRACT, MIN, MAX 670 | BlendOp = ADD; 671 | BlendOpAlpha = ADD; 672 | 673 | // The data source and optional pre-blend operation used for blending. 674 | // To set these individually for each render target, append the render target index to the pass state name, e.g. SrcBlend3 for the fourth render target (zero-based index 3). 675 | // Available values: 676 | // ZERO, ONE, 677 | // SRCCOLOR, SRCALPHA, INVSRCCOLOR, INVSRCALPHA 678 | // DESTCOLOR, DESTALPHA, INVDESTCOLOR, INVDESTALPHA 679 | SrcBlend = ONE; 680 | SrcBlendAlpha = ONE; 681 | DestBlend = ZERO; 682 | DestBlendAlpha = ZERO; 683 | 684 | // Enable or disable the stencil test. 685 | // The depth and stencil buffers are cleared before rendering each pass in a technique. 686 | StencilEnable = false; 687 | 688 | // The masks applied before reading from/writing to the stencil. 689 | // Available values: 690 | // 0-255 691 | StencilReadMask = 0xFF; // or StencilMask 692 | StencilWriteMask = 0xFF; 693 | 694 | // The function used for stencil testing. 695 | // Available values: 696 | // NEVER, ALWAYS 697 | // EQUAL, NEQUAL or NOTEQUAL 698 | // LESS, GREATER, LEQUAL or LESSEQUAL, GEQUAL or GREATEREQUAL 699 | StencilFunc = ALWAYS; 700 | 701 | // The reference value used with the stencil function. 702 | StencilRef = 0; 703 | 704 | // The operation to perform on the stencil buffer when the 705 | // stencil test passed/failed or stencil passed but depth test 706 | // failed. 707 | // Available values: 708 | // KEEP, ZERO, REPLACE, INCR, INCRSAT, DECR, DECRSAT, INVERT 709 | StencilPassOp = KEEP; // or StencilPass 710 | StencilFailOp = KEEP; // or StencilFail 711 | StencilDepthFailOp = KEEP; // or StencilZFail 712 | } 713 | pass p1 714 | { 715 | // Alternatively just "ComputeShader = ExampleCS1" if the thread group size was specified via the "numthreads" function attribute 716 | ComputeShader = ExampleCS1<64,8>; 717 | 718 | DispatchSizeX = 20; // 20 * 64 threads total in X dimension 719 | DispatchSizeY = 2; // 2 * 8 threads total in Y dimension 720 | } 721 | pass p2 722 | { 723 | VertexShader = ExampleVS; 724 | PixelShader = ExamplePS1; 725 | } 726 | } 727 | ``` 728 | --------------------------------------------------------------------------------