Path: blob/master/data/resources/shaders/reshade/REFERENCE.md
4806 views
ReShade FX shading language
Contents
Concepts
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 . This document will instead primarily focus on syntax and features that are unique to ReShade FX.
Macros
The ReShade FX compiler predefines certain preprocessor macros, as listed below:
__FILE__
Current file path__FILE_NAME__
Current file name without path__FILE_STEM__
Current file name without extension and path__LINE__
Current line number__RESHADE__
Version of the injector (in the formatMAJOR * 10000 + MINOR * 100 + REVISION
)__APPLICATION__
32-bit truncated Fnv1a hash of the application executable name__VENDOR__
Vendor id (e.g. 0x10de for NVIDIA, 0x1002 for AMD)__DEVICE__
Device id__RENDERER__
Graphics API used to render effectsD3D9: 0x9000
D3D10: 0xa000 or higher
D3D11: 0xb000 or higher (e.g. 0xb100 for D3D11.1)
D3D12: 0xc000 or higher
OpenGL: 0x10000 or higher (e.g. 0x14300 for OpenGL 4.3)
Vulkan: 0x20000 or higher (e.g. 0x21100 for Vulkan 1.1)
BUFFER_WIDTH
Backbuffer width (essentially the width of the image the application renders to the screen)BUFFER_HEIGHT
Backbuffer heightBUFFER_RCP_WIDTH
Reciprocal of the backbuffer width (equals1.0 / BUFFER_WIDTH
)BUFFER_RCP_HEIGHT
Reciprocal of the backbuffer height (equals1.0 / BUFFER_HEIGHT
)BUFFER_COLOR_BIT_DEPTH
Color bit depth of the backbuffer (8 or 10)BUFFER_COLOR_SPACE
Color space type for presentation; 0 = unknown, 1 = sRGB, 2 = scRGB, 3 = HDR10 ST2084, 4 = HDR10 HLG.
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.
You can disable optimization during shader compilation by adding this line to an effect file:
Texture Object
Textures are multidimensional data containers usually used to store images.
Annotations:
texture2D imageTex < source = "path/to/image.bmp"; > { ... };
Opens image from the patch specified, resizes it to the texture size and loads it into the texture. ReShade supports Bitmap (*.bmp), Portable Network Graphics (*.png), JPEG (*.jpg), Targa Image (*.tga) and DirectDraw Surface (*.dds) files.texture2D myTex1 < pooled = true; > { Width = 100; Height = 100; Format = RGBA8; };
texture2D myTex2 < pooled = true; > { Width = 100; Height = 100; Format = RGBA8; };
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.
ReShade FX allows semantics to be used on texture declarations. This is used to request special textures:
texture2D texColor : COLOR;
Receives the backbuffer contents (read-only).texture2D texDepth : DEPTH;
Receives the game's depth information (read-only).
Declared textures are created at runtime with the parameters specified in their definition body.
Sampler Object
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.
Storage Object
Storage objects define how a texture should be written to from compute shaders.
Uniform Variables
Global variables with the
uniform
qualifier are constant across each iteration of a shader per pass and may be controlled via the UI.
Annotations to customize UI appearance:
ui_type: Can be
input
,drag
,slider
,combo
,radio
orcolor
ui_min: The smallest value allowed in this variable (required when
ui_type = "drag"
orui_type = "slider"
)ui_max: The largest value allowed in this variable (required when
ui_type = "drag"
orui_type = "slider"
)ui_step: The value added/subtracted when clicking the button next to the slider
ui_items: A list of items for the combo box or radio buttons, each item is terminated with a
\0
character (required whenui_type = "combo"
orui_type = "radio"
)ui_label: Display name of the variable in the UI. If this is missing, the variable name is used instead.
ui_tooltip: Text that is displayed when the user hovers over the variable in the UI. Use this for a description.
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.
ui_category_closed: Set to true to show a category closed by default.
ui_spacing: Adds space before the UI widget (multiplied by the value of the annotation).
ui_units: Adds units description on the slider/drag bar (only used when
ui_type = "drag"
orui_type = "slider"
)hidden: Set to true to hide this technique in the UI.
Annotations are also used to request special runtime values (via the source
annotation):
uniform float frametime < source = "frametime"; >;
Time in milliseconds it took for the last frame to complete.uniform int framecount < source = "framecount"; >;
Total amount of frames since the game started.uniform float4 date < source = "date"; >;
float4(year, month (1 - 12), day of month (1 - 31), time in seconds)uniform float timer < source = "timer"; >;
Timer counting time in milliseconds since game start.uniform float2 pingpong < source = "pingpong"; min = 0; max = 10; step = 2; smoothing = 0.0; >;
Value that smoothly interpolates betweenmin
andmax
usingstep
as the increase/decrease value every second (so a step value of 1 means the value is increased/decreased by 1 per second). 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). Thesmoothing
value affects the interpolation curve (0 is linear interpolation and anything else changes the speed depending on how close the current value is tomin
ormax
). The second component is either +1 or -1 depending on the direction it currently goes.uniform int random_value < source = "random"; min = 0; max = 10; >;
Gets a new random value between min and max every pass.uniform bool space_bar_down < source = "key"; keycode = 0x20; mode = ""; >;
True if specified keycode (in this case the spacebar) is pressed and false otherwise. If mode is set to "press" the value is true only in the frame the key was initially held down. If mode is set to "toggle" the value stays true until the key is pressed a second time.uniform bool left_mouse_button_down < source = "mousebutton"; keycode = 0; mode = ""; >;
True if specified mouse button (0 - 4) is pressed and false otherwise. If mode is set to "press" the value is true only in the frame the key was initially held down. If mode is set to "toggle" the value stays true until the key is pressed a second time.uniform float2 mouse_point < source = "mousepoint"; >;
Gets the position of the mouse cursor in screen coordinates.uniform float2 mouse_delta < source = "mousedelta"; >;
Gets the movement of the mouse cursor in screen coordinates.uniform float2 mouse_value < source = "mousewheel"; min = 0.0; max = 10.0; > = 1.0;
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. 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.uniform bool has_depth < source = "bufready_depth"; >;
True if the application's depth buffer is available in textures declared withDEPTH
, false if not.uniform bool overlay_open < source = "overlay_open"; >;
True if the ReShade in-game overlay is currently open, false if not.uniform int active_variable < source = "overlay_active"; >;
Contains the one-based index of the uniform variable currently being modified in the overlay, zero if none.uniform int hovered_variable < source = "overlay_hovered"; >;
Contains the one-based index of the uniform variable currently hovered with the cursor in the overlay, zero if none.uniform bool screenshot < source = "screenshot"; >;
True if a screenshot is being taken, false if not.
Structs
Structs are user defined data types that can be used as types for variables. These behave the same as in HLSL.
Namespaces
Namespaces are used to group functions and variables together, which is especially useful to prevent name clashing. The "::" operator is used to resolve variables or functions inside other namespaces.
User functions
Parameter qualifiers:
in
Declares an input parameter. Default and implicit if none is used. Functions expect these to be filled with a value.out
Declares an output parameter. The value is filled in the function and can be used in the caller again.inout
Declares a parameter that provides input and also expects output.
Supported flow-control statements:
if ([condition]) { [statement...] } [else { [statement...] }]
Statements after if are only executed if condition is true, otherwise the ones after else are executed (if it exists).switch ([expression]) { [case [constant]/default]: [statement...] }
Selects the case matching the switch expression or default if non does and it exists.for ([declaration]; [condition]; [iteration]) { [statement...] }
Runs the statements in the body as long as the condition is true. The iteration expression is executed after each run.while ([condition]) { [statement...] }
Runs the statements in the body as long as the condition is true.do { [statement...] } while ([condition]);
Similar to a normal while loop with the difference that the statements are executed at least once.break;
Breaks out of the current loop or switch statement and jumps to the statement after.continue;
Jumps directly to the next loop iteration ignoring any left code in the current one.return [expression];
Jumps out of the current function, optionally providing a value to the caller.discard;
Abort rendering of the current pixel and step out of the shader. Can be used in pixel shaders only.
Intrinsic functions
ReShade FX supports most of the standard HLSL intrinsics. Check out https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-intrinsic-functions for reference on them:
abs, acos, all, any, asfloat, asin, asint, asuint, atan, atan2, ceil, clamp, cos, cosh, cross, ddx, ddy, degrees, determinant, distance, dot, exp, exp2, faceforward, floor, frac, frexp, fwidth, isinf, isnan, ldexp, length, lerp, log, log10, log2, mad, max, min, modf, mul, normalize, pow, radians, rcp, reflect, refract, round, rsqrt, saturate, sign, sin, sincos, sinh, smoothstep, sqrt, step, tan, tanh, transpose, trunc
In addition to these, ReShade FX provides a few additional ones:
T tex1D(sampler1D<T> s, float coords)
T tex1D(sampler1D<T> s, float coords, int offset)
T tex2D(sampler2D<T> s, float2 coords)
T tex2D(sampler2D<T> s, float2 coords, int2 offset)
T tex3D(sampler3D<T> s, float3 coords)
T tex3D(sampler3D<T> s, float3 coords, int3 offset)
Samples a texture. See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-sample.T tex1Dlod(sampler1D<T> s, float4 coords)
T tex1Dlod(sampler1D<T> s, float4 coords, int offset)
T tex2Dlod(sampler2D<T> s, float4 coords)
T tex2Dlod(sampler2D<T> s, float4 coords, int2 offset)
T tex3Dlod(sampler3D<T> s, float4 coords)
T tex3Dlod(sampler3D<T> s, float4 coords, int3 offset)
Samples a texture on a specific mipmap level. The accepted coordinates are in the formfloat4(x, y, 0, lod)
. See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-samplelevel.T tex1Dfetch(sampler1D<T> s, int coords)
T tex1Dfetch(sampler1D<T> s, int coords, int lod)
T tex1Dfetch(storage1D<T> s, int coords)
T tex2Dfetch(sampler2D<T> s, int2 coords)
T tex2Dfetch(sampler2D<T> s, int2 coords, int lod)
T tex2Dfetch(storage2D<T> s, int2 coords)
T tex3Dfetch(sampler3D<T> s, int3 coords)
T tex3Dfetch(sampler3D<T> s, int3 coords, int lod)
T tex3Dfetch(storage3D<T> s, int3 coords)
Fetches a value from the texture directly without any sampling. See also https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-load.float4 tex2DgatherR(sampler2D s, float2 coords)
float4 tex2DgatherR(sampler2D s, float2 coords, int2 offset)
float4 tex2DgatherG(sampler2D s, float2 coords)
float4 tex2DgatherG(sampler2D s, float2 coords, int2 offset)
float4 tex2DgatherB(sampler2D s, float2 coords)
float4 tex2DgatherB(sampler2D s, float2 coords, int2 offset)
float4 tex2DgatherA(sampler2D s, float2 coords)
float4 tex2DgatherA(sampler2D s, float2 coords, int2 offset)
Gathers the specified component of the four neighboring pixels and returns the result.tex2DgatherR
for example is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/texture2d-gatherred. The return value is effectively:
int tex1Dsize(sampler1D<T> s)
int tex1Dsize(sampler1D<T> s, int lod)
int tex1Dsize(storage1D<T> s)
int2 tex2Dsize(sampler2D<T> s)
int2 tex2Dsize(sampler2D<T> s, int lod)
int2 tex2Dsize(storage2D<T> s)
int3 tex3Dsize(sampler3D<T> s)
int3 tex3Dsize(sampler3D<T> s, int lod)
int3 tex3Dsize(storage3D<T> s)
Gets the texture dimensions of the specified mipmap level. See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-getdimensionsvoid tex1Dstore(storage1D<T> s, int coords, T value)
void tex2Dstore(storage2D<T> s, int2 coords, T value)
void tex3Dstore(storage2D<T> s, int3 coords, T value)
Writes the specified value to the texture referenced by the storage. Only valid from within compute shaders. See also https://docs.microsoft.com/windows/win32/direct3dhlsl/sm5-object-rwtexture2d-operatorindexvoid barrier()
Synchronizes threads in a thread group. Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/groupmemorybarrierwithgroupsyncvoid memoryBarrier()
Waits on the completion of all memory accesses resulting from the use of texture or storage operations. Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/allmemorybarriervoid groupMemoryBarrier()
Waits on the completion of all memory accesses within the thread group resulting from the use of texture or storage operations. Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/groupmemorybarrierint atomicAdd(inout int dest, int value)
int atomicAdd(storage1D<int> s, int coords, int value)
int atomicAdd(storage2D<int> s, int2 coords, int value)
int atomicAdd(storage3D<int> s, int3 coords, int value)
https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedaddint atomicAnd(inout int dest, int value)
int atomicAnd(storage1D<int> s, int coords, int value)
int atomicAnd(storage2D<int> s, int2 coords, int value)
int atomicAnd(storage3D<int> s, int3 coords, int value)
https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedandint atomicOr(inout int dest, int value)
int atomicOr(storage1D<int> s, int coords, int value)
int atomicOr(storage2D<int> s, int2 coords, int value)
int atomicOr(storage3D<int> s, int3 coords, int value)
https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedorint atomicXor(inout int dest, int value)
int atomicXor(storage1D<int> s, int coords, int value)
int atomicXor(storage2D<int> s, int2 coords, int value)
int atomicXor(storage3D<int> s, int3 coords, int value)
https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedxorint atomicMin(inout int dest, int value)
int atomicMin(storage1D<int> s, int coords, int value)
int atomicMin(storage2D<int> s, int2 coords, int value)
int atomicMin(storage3D<int> s, int3 coords, int value)
https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedminint atomicMax(inout int dest, int value)
int atomicMax(storage<int> s, int coords, int value)
int atomicMax(storage<int> s, int2 coords, int value)
int atomicMax(storage<int> s, int3 coords, int value)
https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedmaxint atomicExchange(inout int dest, int value)
int atomicExchange(storage1D<int> s, int coords, int value)
int atomicExchange(storage2D<int> s, int2 coords, int value)
int atomicExchange(storage3D<int> s, int3 coords, int value)
https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedexchangeint atomicCompareExchange(inout int dest, int compare, int value)
int atomicCompareExchange(storage1D<int> s, int coords, int compare, int value)
int atomicCompareExchange(storage2D<int> s, int2 coords, int compare, int value)
int atomicCompareExchange(storage3D<int> s, int3 coords, int compare, int value)
https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedcompareexchange
Techniques
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. 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. Each pass can set render states. The default value is used if one is not specified in the pass body.
Annotations:
technique Name < enabled = true; >
Enable (or disable if false) this technique by default.technique Name < enabled_in_screenshot = true; >
Set this to false to disabled this technique while a screenshot is taken.technique Name < timeout = 1000; >
Auto-toggle this technique off 1000 milliseconds after it was enabled. This can for example be used to have a technique run a single time only to do some initialization work, viatechnique Name < enabled = true; timeout = 1; >
technique Name < toggle = 0x20; togglectrl = false; toggleshift = false; togglealt = false; >
Toggle this technique when the specified key is pressed.technique Name < hidden = true; >
Hide this technique in the UI.technique Name < ui_label = "My Effect Name"; >
Uses a custom name for the technique in the UI.technique Name < ui_tooltip = "My Effect description"; >
Shows the specified text when the user hovers the technique in the UI.