duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

REFERENCE.md (30512B)


      1 ReShade FX shading language
      2 ===========================
      3 
      4 # Contents
      5 
      6 * [Macros](#macros)
      7 * [Texture object](#texture-object)
      8 * [Sampler object](#sampler-object)
      9 * [Storage object](#storage-object)
     10 * [Uniform variables](#uniform-variables)
     11 * [Structs](#structs)
     12 * [Namespaces](#namespaces)
     13 * [User functions](#user-functions)
     14 * [Intrinsic functions](#intrinsic-functions)
     15 * [Techniques](#techniques)
     16 
     17 # Concepts
     18 
     19 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 .\
     20 This document will instead primarily focus on syntax and features that are unique to ReShade FX.
     21 
     22 ### Macros
     23 
     24 The ReShade FX compiler predefines certain preprocessor macros, as listed below:
     25 * ``__FILE__`` Current file path
     26 * ``__FILE_NAME__`` Current file name without path
     27 * ``__FILE_STEM__`` Current file name without extension and path
     28 * ``__LINE__`` Current line number
     29 * ``__RESHADE__`` Version of the injector (in the format `MAJOR * 10000 + MINOR * 100 + REVISION`)
     30 * ``__APPLICATION__`` 32-bit truncated Fnv1a hash of the application executable name
     31 * ``__VENDOR__`` Vendor id (e.g. 0x10de for NVIDIA, 0x1002 for AMD)
     32 * ``__DEVICE__`` Device id
     33 * ``__RENDERER__`` Graphics API used to render effects
     34   * D3D9: 0x9000
     35   * D3D10: 0xa000 or higher
     36   * D3D11: 0xb000 or higher (e.g. 0xb100 for D3D11.1)
     37   * D3D12: 0xc000 or higher
     38   * OpenGL: 0x10000 or higher (e.g. 0x14300 for OpenGL 4.3)
     39   * Vulkan: 0x20000 or higher (e.g. 0x21100 for Vulkan 1.1)
     40 * ``BUFFER_WIDTH`` Backbuffer width (essentially the width of the image the application renders to the screen)
     41 * ``BUFFER_HEIGHT`` Backbuffer height
     42 * ``BUFFER_RCP_WIDTH`` Reciprocal of the backbuffer width (equals `1.0 / BUFFER_WIDTH`)
     43 * ``BUFFER_RCP_HEIGHT`` Reciprocal of the backbuffer height (equals `1.0 / BUFFER_HEIGHT`)
     44 * ``BUFFER_COLOR_BIT_DEPTH`` Color bit depth of the backbuffer (8 or 10)
     45 * ``BUFFER_COLOR_SPACE`` Color space type for presentation; 0 = unknown, 1 = sRGB, 2 = scRGB, 3 = HDR10 ST2084, 4 = HDR10 HLG.
     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 ```hlsl
     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 
     63 Annotations:
     64 
     65  * ``texture2D imageTex < source = "path/to/image.bmp"; > { ... };``  
     66  Opens image from the patch specified, resizes it to the texture size and loads it into the texture.\
     67  ReShade supports Bitmap (\*.bmp), Portable Network Graphics (\*.png), JPEG (\*.jpg), Targa Image (\*.tga) and DirectDraw Surface (\*.dds) files.
     68 
     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 Declared textures are created at runtime with the parameters specified in their definition body.
     81 
     82 ```hlsl
     83 texture2D texColorBuffer : COLOR;
     84 texture2D texDepthBuffer : DEPTH;
     85 
     86 texture2D texTarget
     87 {
     88 	// The texture dimensions (default: 1x1).
     89 	Width = BUFFER_WIDTH / 2; // Used with texture1D
     90 	Height = BUFFER_HEIGHT / 2; // Used with texture1D and texture2D
     91 	Depth = 1; // Used with texture1D, texture2D and texture3D
     92 	
     93 	// The number of mipmaps including the base level (default: 1).
     94 	MipLevels = 1;
     95 	
     96 	// The internal texture format (default: RGBA8).
     97 	// Available formats:
     98 	//   R8, R16, R16F, R32F, R32I, R32U
     99 	//   RG8, RG16, RG16F, RG32F
    100 	//   RGBA8, RGBA16, RGBA16F, RGBA32F
    101 	//   RGB10A2
    102 	Format = RGBA8;
    103 
    104 	// Unspecified properties are set to the defaults shown here.
    105 };
    106 
    107 texture3D texIntegerVolume
    108 {
    109 	Width = 10;
    110 	Height = 10;
    111 	Depth = 10;
    112 	Format = R32I; // Single-component integer format, which means sampler and storage have to be of that integer type (sampler3D<int> or storage3D<int>)
    113 };
    114 ```
    115 
    116 ### Sampler Object
    117 
    118 > 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.
    119 
    120 ```hlsl
    121 sampler2D samplerColor
    122 {
    123 	// The texture to be used for sampling.
    124 	Texture = texColorBuffer;
    125 
    126 	// The method used for resolving texture coordinates which are out of bounds.
    127 	// Available values: CLAMP, MIRROR, WRAP or REPEAT, BORDER
    128 	AddressU = CLAMP;
    129 	AddressV = CLAMP;
    130 	AddressW = CLAMP;
    131 
    132 	// The magnification, minification and mipmap filtering types.
    133 	// Available values: POINT, LINEAR
    134 	MagFilter = LINEAR;
    135 	MinFilter = LINEAR;
    136 	MipFilter = LINEAR;
    137 
    138 	// The maximum mipmap levels accessible.
    139 	MinLOD = 0.0f;
    140 	MaxLOD = 1000.0f;
    141 
    142 	// An offset applied to the calculated mipmap level (default: 0).
    143 	MipLODBias = 0.0f;
    144 
    145 	// Enable or disable converting  to linear colors when sampling from the
    146 	// texture.
    147 	SRGBTexture = false;
    148 
    149 	// Unspecified properties are set to the defaults shown here.
    150 };
    151 
    152 sampler2D samplerDepth
    153 {
    154 	Texture = texDepthBuffer;
    155 };
    156 sampler2D samplerTarget
    157 {
    158 	Texture = texTarget;
    159 };
    160 ```
    161 
    162 ### Storage Object
    163 
    164 > Storage objects define how a texture should be written to from compute shaders.
    165 
    166 ```hlsl
    167 storage2D storageTarget
    168 {
    169 	// The texture to be used as storage.
    170 	Texture = texTarget;
    171 
    172 	// The mipmap level of the texture to fetch/store.
    173 	MipLevel = 0;
    174 };
    175 
    176 storage3D<int> storageIntegerVolume
    177 {
    178 	Texture = texIntegerVolume;
    179 };
    180 ```
    181 
    182 ### Uniform Variables
    183 
    184 > Global variables with the `uniform` qualifier are constant across each iteration of a shader per pass and may be controlled via the UI.
    185 
    186 Annotations to customize UI appearance:
    187 
    188  * ui_type: Can be `input`, `drag`, `slider`, `combo`, `radio` or `color`
    189  * ui_min: The smallest value allowed in this variable (required when `ui_type = "drag"` or `ui_type = "slider"`)
    190  * ui_max: The largest value allowed in this variable (required when `ui_type = "drag"` or `ui_type = "slider"`)
    191  * ui_step: The value added/subtracted when clicking the button next to the slider
    192  * 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"`)
    193  * ui_label: Display name of the variable in the UI. If this is missing, the variable name is used instead.
    194  * ui_tooltip: Text that is displayed when the user hovers over the variable in the UI. Use this for a description.
    195  * 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.
    196  * ui_category_closed: Set to true to show a category closed by default.
    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 technique in the UI.
    200 
    201 Annotations are also used to request special runtime values (via the `source` annotation):
    202 
    203  * ``uniform float frametime < source = "frametime"; >;``  
    204  Time in milliseconds it took for the last frame to complete.
    205  * ``uniform int framecount < source = "framecount"; >;``  
    206  Total amount of frames since the game started.
    207  * ``uniform float4 date < source = "date"; >;``  
    208  float4(year, month (1 - 12), day of month (1 - 31), time in seconds)
    209  * ``uniform float timer < source = "timer"; >;``  
    210  Timer counting time in milliseconds since game start.
    211  * ``uniform float2 pingpong < source = "pingpong"; min = 0; max = 10; step = 2; smoothing = 0.0; >;``  
    212  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).\
    213  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).
    214  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`).
    215  The second component is either +1 or -1 depending on the direction it currently goes.
    216  * ``uniform int random_value < source = "random"; min = 0; max = 10; >;``  
    217  Gets a new random value between min and max every pass.
    218  * ``uniform bool space_bar_down < source = "key"; keycode = 0x20; mode = ""; >;``  
    219  True if specified keycode (in this case the spacebar) is pressed and false otherwise.
    220  If mode is set to "press" the value is true only in the frame the key was initially held down.
    221  If mode is set to "toggle" the value stays true until the key is pressed a second time.
    222  * ``uniform bool left_mouse_button_down < source = "mousebutton"; keycode = 0; mode = ""; >;``  
    223  True if specified mouse button (0 - 4) is pressed and false otherwise.
    224  If mode is set to "press" the value is true only in the frame the key was initially held down.
    225  If mode is set to "toggle" the value stays true until the key is pressed a second time.
    226  * ``uniform float2 mouse_point < source = "mousepoint"; >;``  
    227  Gets the position of the mouse cursor in screen coordinates.
    228  * ``uniform float2 mouse_delta < source = "mousedelta"; >;``  
    229  Gets the movement of the mouse cursor in screen coordinates.
    230  * ``uniform float2 mouse_value < source = "mousewheel"; min = 0.0; max = 10.0; > = 1.0;``  
    231  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.
    232  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.
    233  * ``uniform bool has_depth < source = "bufready_depth"; >;``  
    234  True if the application's depth buffer is available in textures declared with `DEPTH`, false if not.
    235  * ``uniform bool overlay_open < source = "overlay_open"; >;``  
    236  True if the ReShade in-game overlay is currently open, false if not.
    237  * ``uniform int active_variable < source = "overlay_active"; >;``  
    238  Contains the one-based index of the uniform variable currently being modified in the overlay, zero if none.
    239  * ``uniform int hovered_variable < source = "overlay_hovered"; >;``  
    240  Contains the one-based index of the uniform variable currently hovered with the cursor in the overlay, zero if none.
    241  * ``uniform bool screenshot < source = "screenshot"; >;``  
    242  True if a screenshot is being taken, false if not.
    243 
    244 ```hlsl
    245 // Initializers are used to specify the default value (zero is used if not specified).
    246 uniform float4 UniformSingleValue = float4(0.0f, 0.0f, 0.0f, 0.0f);
    247 
    248 // It is recommended to use constants instead of uniforms if the value is not changing or user-configurable.
    249 static const float4 ConstantSingleValue = float4(0.0f, 0.0f, 0.0f, 0.0f);
    250 ```
    251 
    252 ### Structs
    253 
    254 > Structs are user defined data types that can be used as types for variables. These behave the same as in HLSL.
    255 
    256 ```hlsl
    257 struct MyStruct
    258 {
    259 	int MyField1, MyField2;
    260 	float MyField3;
    261 };
    262 ```
    263 
    264 ### Namespaces
    265 
    266 > Namespaces are used to group functions and variables together, which is especially useful to prevent name clashing.
    267 > The "::" operator is used to resolve variables or functions inside other namespaces.
    268 
    269 ```hlsl
    270 namespace MyNamespace
    271 {
    272 	namespace MyNestedNamespace
    273 	{
    274 		void DoNothing()
    275 		{
    276 		}
    277 	}
    278 
    279 	void DoNothing()
    280 	{
    281 		MyNestedNamespace::DoNothing();
    282 	}
    283 }
    284 ```
    285 
    286 ### User functions
    287 
    288 Parameter qualifiers:
    289 
    290  * ``in`` Declares an input parameter. Default and implicit if none is used. Functions expect these to be filled with a value.
    291  * ``out`` Declares an output parameter. The value is filled in the function and can be used in the caller again.
    292  * ``inout`` Declares a parameter that provides input and also expects output.
    293 
    294 Supported flow-control statements:
    295 
    296  * ``if ([condition]) { [statement...] } [else { [statement...] }]``  
    297  Statements after if are only executed  if condition is true, otherwise the ones after else are executed (if it exists).
    298  * ``switch ([expression]) { [case [constant]/default]: [statement...] }``  
    299  Selects the case matching the switch expression or default if non does and it exists.
    300  * ``for ([declaration]; [condition]; [iteration]) { [statement...] }``  
    301  Runs the statements in the body as long as the condition is true. The iteration expression is executed after each run.
    302  * ``while ([condition]) { [statement...] }``  
    303  Runs the statements in the body as long as the condition is true.
    304  * ``do { [statement...] } while ([condition]);``  
    305  Similar to a normal while loop with the difference that the statements are executed at least once.
    306  * ``break;``  
    307  Breaks out  of the current loop or switch statement and jumps to the statement after.
    308  * ``continue;``  
    309  Jumps directly to the next loop iteration ignoring any left code in the current one.
    310  * ``return [expression];``  
    311  Jumps out of the current function, optionally providing a value to the caller.
    312  * ``discard;``  
    313  Abort rendering of the current pixel and step out of the shader. Can be used in pixel shaders only.
    314 
    315 ```hlsl
    316 // Semantics are used to tell the runtime which arguments to connect between shader stages.
    317 // They are ignored on non-entry-point functions (those not used in any pass below).
    318 // Semantics starting with "SV_" are system value semantics and serve a special meaning.
    319 // The following vertex shader demonstrates how to generate a simple fullscreen triangle with the three vertices provided by ReShade (http://redd.it/2j17wk):
    320 void ExampleVS(uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD0)
    321 {
    322 	texcoord.x = (id == 2) ? 2.0 : 0.0;
    323 	texcoord.y = (id == 1) ? 2.0 : 0.0;
    324 	position = float4(texcoord * float2(2, -2) + float2(-1, 1), 0, 1);
    325 }
    326 
    327 // The following pixel shader simply returns the color of the games output again without modifying it (via the "color" output parameter):
    328 void ExamplePS0(float4 pos : SV_Position, float2 texcoord : TEXCOORD0, out float4 color : SV_Target)
    329 {
    330 	color = tex2D(samplerColor, texcoord);
    331 }
    332 
    333 // The following pixel shader takes the output of the previous pass and adds the depth buffer content to the right screen side.
    334 float4 ExamplePS1(float4 pos : SV_Position, float2 texcoord : TEXCOORD0) : SV_Target
    335 {
    336 	// Here color information is sampled with "samplerTarget" and thus from "texTarget" (see sampler declaration above),
    337 	// which was set as render target in the previous pass (see the technique definition below) and now contains its output.
    338 	// In this case it is the game output, but downsampled to half because the texture is only half of the screen size.
    339 	float4 color = tex2D(samplerTarget, texcoord);
    340 	
    341 	// Only execute the following code block when on the right half of the screen.
    342 	if (texcoord.x > 0.5f)
    343 	{
    344 		// Sample from the game depth buffer using the "samplerDepth" sampler declared above.
    345 		float depth = tex2D(samplerDepth, texcoord).r;
    346 		
    347 		// Linearize the depth values to better visualize them.
    348 		depth = 2.0 / (-99.0 * depth + 101.0);
    349 		
    350 		color.rgb = depth.rrr;
    351 	}
    352 
    353 	return color;
    354 }
    355 
    356 // The following compute shader uses shared memory within a thread group:
    357 groupshared int sharedMem[64];
    358 void ExampleCS0(uint3 tid : SV_GroupThreadID)
    359 {
    360 	if (tid.y == 0)
    361 		sharedMem[tid.x] = tid.x;
    362 	barrier();
    363 	if (tid.y == 0 && (tid.x % 2) != 0)
    364 		sharedMem[tid.x] += sharedMem[tid.x + 1];
    365 }
    366 
    367 // The following compute shader writes a color gradient to the "texTarget" texture:
    368 void ExampleCS1(uint3 id : SV_DispatchThreadID, uint3 tid : SV_GroupThreadID)
    369 {
    370 	tex2Dstore(storageTarget, id.xy, float4(tid.xy / float2(20 * 64, 2 * 8), 0, 1));
    371 }
    372 ```
    373 
    374 ### Intrinsic functions
    375 
    376 ReShade FX supports most of the standard HLSL intrinsics.\
    377 Check out https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-intrinsic-functions for reference on them:
    378 
    379 > 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
    380 
    381 In addition to these, ReShade FX provides a few additional ones:
    382 
    383  * ``T tex1D(sampler1D<T> s, float coords)``  
    384  * ``T tex1D(sampler1D<T> s, float coords, int offset)``  
    385  * ``T tex2D(sampler2D<T> s, float2 coords)``  
    386  * ``T tex2D(sampler2D<T> s, float2 coords, int2 offset)``  
    387  * ``T tex3D(sampler3D<T> s, float3 coords)``  
    388  * ``T tex3D(sampler3D<T> s, float3 coords, int3 offset)``  
    389  Samples a texture.\
    390  See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-sample.
    391  * ``T tex1Dlod(sampler1D<T> s, float4 coords)``  
    392  * ``T tex1Dlod(sampler1D<T> s, float4 coords, int offset)``  
    393  * ``T tex2Dlod(sampler2D<T> s, float4 coords)``  
    394  * ``T tex2Dlod(sampler2D<T> s, float4 coords, int2 offset)``  
    395  * ``T tex3Dlod(sampler3D<T> s, float4 coords)``  
    396  * ``T tex3Dlod(sampler3D<T> s, float4 coords, int3 offset)``  
    397  Samples a texture on a specific mipmap level.\
    398  The accepted coordinates are in the form `float4(x, y, 0, lod)`.\
    399  See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-samplelevel.
    400  * ``T tex1Dfetch(sampler1D<T> s, int coords)``  
    401  * ``T tex1Dfetch(sampler1D<T> s, int coords, int lod)``  
    402  * ``T tex1Dfetch(storage1D<T> s, int coords)``  
    403  * ``T tex2Dfetch(sampler2D<T> s, int2 coords)``  
    404  * ``T tex2Dfetch(sampler2D<T> s, int2 coords, int lod)``  
    405  * ``T tex2Dfetch(storage2D<T> s, int2 coords)``  
    406  * ``T tex3Dfetch(sampler3D<T> s, int3 coords)``  
    407  * ``T tex3Dfetch(sampler3D<T> s, int3 coords, int lod)``  
    408  * ``T tex3Dfetch(storage3D<T> s, int3 coords)``  
    409  Fetches a value from the texture directly without any sampling.\
    410  See also https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-load.
    411  * ``float4 tex2DgatherR(sampler2D s, float2 coords)``  
    412  * ``float4 tex2DgatherR(sampler2D s, float2 coords, int2 offset)``  
    413  * ``float4 tex2DgatherG(sampler2D s, float2 coords)``  
    414  * ``float4 tex2DgatherG(sampler2D s, float2 coords, int2 offset)``  
    415  * ``float4 tex2DgatherB(sampler2D s, float2 coords)``  
    416  * ``float4 tex2DgatherB(sampler2D s, float2 coords, int2 offset)``  
    417  * ``float4 tex2DgatherA(sampler2D s, float2 coords)``  
    418  * ``float4 tex2DgatherA(sampler2D s, float2 coords, int2 offset)``  
    419  Gathers the specified component of the four neighboring pixels and returns the result.\
    420  `tex2DgatherR` for example is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/texture2d-gatherred.  
    421  The return value is effectively:
    422  ```
    423  float4(tex2Dfetch(s, coords * tex2Dsize(s) + int2(0, 1)).comp,
    424         tex2Dfetch(s, coords * tex2Dsize(s) + int2(1, 1)).comp,
    425         tex2Dfetch(s, coords * tex2Dsize(s) + int2(0, 1)).comp,
    426         tex2Dfetch(s, coords * tex2Dsize(s) + int2(0, 0)).comp)
    427  ```
    428  * ``int tex1Dsize(sampler1D<T> s)``  
    429  * ``int tex1Dsize(sampler1D<T> s, int lod)``  
    430  * ``int tex1Dsize(storage1D<T> s)``  
    431  * ``int2 tex2Dsize(sampler2D<T> s)``  
    432  * ``int2 tex2Dsize(sampler2D<T> s, int lod)``  
    433  * ``int2 tex2Dsize(storage2D<T> s)``  
    434  * ``int3 tex3Dsize(sampler3D<T> s)``  
    435  * ``int3 tex3Dsize(sampler3D<T> s, int lod)``  
    436  * ``int3 tex3Dsize(storage3D<T> s)``  
    437  Gets the texture dimensions of the specified mipmap level.\
    438  See also https://docs.microsoft.com/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-getdimensions
    439  * ``void tex1Dstore(storage1D<T> s, int coords, T value)``  
    440  * ``void tex2Dstore(storage2D<T> s, int2 coords, T value)``  
    441  * ``void tex3Dstore(storage2D<T> s, int3 coords, T value)``  
    442  Writes the specified value to the texture referenced by the storage. Only valid from within compute shaders.\
    443  See also https://docs.microsoft.com/windows/win32/direct3dhlsl/sm5-object-rwtexture2d-operatorindex
    444  * ``void barrier()``  
    445  Synchronizes threads in a thread group.\
    446  Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/groupmemorybarrierwithgroupsync
    447  * ``void memoryBarrier()``  
    448  Waits on the completion of all memory accesses resulting from the use of texture or storage operations.\
    449  Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/allmemorybarrier
    450  * ``void groupMemoryBarrier()``  
    451  Waits on the completion of all memory accesses within the thread group resulting from the use of texture or storage operations.\
    452  Is equivalent to https://docs.microsoft.com/windows/win32/direct3dhlsl/groupmemorybarrier
    453  * ``int atomicAdd(inout int dest, int value)``  
    454  * ``int atomicAdd(storage1D<int> s, int coords, int value)``  
    455  * ``int atomicAdd(storage2D<int> s, int2 coords, int value)``  
    456  * ``int atomicAdd(storage3D<int> s, int3 coords, int value)``  
    457  https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedadd
    458  * ``int atomicAnd(inout int dest, int value)``  
    459  * ``int atomicAnd(storage1D<int> s, int coords, int value)``  
    460  * ``int atomicAnd(storage2D<int> s, int2 coords, int value)``  
    461  * ``int atomicAnd(storage3D<int> s, int3 coords, int value)``  
    462  https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedand
    463  * ``int atomicOr(inout int dest, int value)``  
    464  * ``int atomicOr(storage1D<int> s, int coords, int value)``  
    465  * ``int atomicOr(storage2D<int> s, int2 coords, int value)``  
    466  * ``int atomicOr(storage3D<int> s, int3 coords, int value)``  
    467  https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedor
    468  * ``int atomicXor(inout int dest, int value)``  
    469  * ``int atomicXor(storage1D<int> s, int coords, int value)``  
    470  * ``int atomicXor(storage2D<int> s, int2 coords, int value)``  
    471  * ``int atomicXor(storage3D<int> s, int3 coords, int value)``  
    472  https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedxor
    473  * ``int atomicMin(inout int dest, int value)``  
    474  * ``int atomicMin(storage1D<int> s, int coords, int value)``  
    475  * ``int atomicMin(storage2D<int> s, int2 coords, int value)``  
    476  * ``int atomicMin(storage3D<int> s, int3 coords, int value)``  
    477  https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedmin
    478  * ``int atomicMax(inout int dest, int value)``  
    479  * ``int atomicMax(storage<int> s, int coords, int value)``  
    480  * ``int atomicMax(storage<int> s, int2 coords, int value)``  
    481  * ``int atomicMax(storage<int> s, int3 coords, int value)``  
    482  https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedmax
    483  * ``int atomicExchange(inout int dest, int value)``  
    484  * ``int atomicExchange(storage1D<int> s, int coords, int value)``  
    485  * ``int atomicExchange(storage2D<int> s, int2 coords, int value)``  
    486  * ``int atomicExchange(storage3D<int> s, int3 coords, int value)``  
    487  https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedexchange
    488  * ``int atomicCompareExchange(inout int dest, int compare, int value)``  
    489  * ``int atomicCompareExchange(storage1D<int> s, int coords, int compare, int value)``  
    490  * ``int atomicCompareExchange(storage2D<int> s, int2 coords, int compare, int value)``  
    491  * ``int atomicCompareExchange(storage3D<int> s, int3 coords, int compare, int value)``  
    492  https://docs.microsoft.com/windows/win32/direct3dhlsl/interlockedcompareexchange
    493 
    494 ### Techniques
    495 
    496 > 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.
    497 > 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.
    498 > Each pass can set render states. The default value is used if one is not specified in the pass body.
    499 
    500 Annotations:
    501 
    502  * ``technique Name < enabled = true; >``  
    503  Enable (or disable if false) this technique by default.
    504  * ``technique Name < enabled_in_screenshot = true; >``  
    505  Set this to false to disabled this technique while a screenshot is taken.
    506  * ``technique Name < timeout = 1000; >``  
    507  Auto-toggle this technique off 1000 milliseconds after it was enabled.\
    508  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; >``
    509  * ``technique Name < toggle = 0x20; togglectrl = false; toggleshift = false; togglealt = false; >``  
    510  Toggle this technique when the specified key is pressed.
    511  * ``technique Name < hidden = true; >``  
    512  Hide this technique in the UI.
    513  * ``technique Name < ui_label = "My Effect Name"; >``  
    514  Uses a custom name for the technique in the UI.
    515  * ``technique Name < ui_tooltip = "My Effect description"; >``  
    516  Shows the specified text when the user hovers the technique in the UI.
    517 
    518 ```hlsl
    519 technique Example < ui_tooltip = "This is an example!"; >
    520 {
    521 	pass p0
    522 	{
    523 		// The primitive topology rendered in the draw call.
    524 		// Available values:
    525 		//   POINTLIST, LINELIST, LINESTRIP, TRIANGLELIST, TRIANGLESTRIP
    526 		PrimitiveTopology = TRIANGLELIST; // or PrimitiveType
    527 
    528 		// The number of vertices ReShade generates for the draw call.
    529 		// This has different effects on the rendered primitives based on the primitive topology.
    530 		// 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.
    531 		VertexCount = 3;
    532 
    533 		// The following two accept function names declared above which are used as entry points for the shader.
    534 		// Please note that all parameters must have an associated semantic so the runtime can match them between shader stages.
    535 		VertexShader = ExampleVS;
    536 		PixelShader = ExamplePS0;
    537 
    538 		// The number of thread groups to dispatch when a compute shader is used.
    539 		DispatchSizeX = 1;
    540 		DispatchSizeY = 1;
    541 		DispatchSizeZ = 1;
    542 
    543 		// Compute shaders are specified with the number of threads per thread group in brackets.
    544 		// The following for example will create groups of 64x1x1 threads:
    545 		ComputeShader = ExampleCS0<64,1,1>;
    546 	
    547 		// RenderTarget0 to RenderTarget7 allow to set one or more render targets for rendering to textures.
    548 		// 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.
    549 		// If multiple render targets are used, the dimensions of them has to match each other.
    550 		// If no render targets are set here, RenderTarget0 points to the backbuffer.
    551 		// 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.
    552 		// RenderTarget and RenderTarget0 are aliases.
    553 		RenderTarget = texTarget;
    554 
    555 		// Set to true to clear all bound render targets to zero before rendering.
    556 		ClearRenderTargets = false;
    557 
    558 		// Set to false to disable automatic rebuilding of the mipmap chain of all render targets and/or storage objects.
    559 		// This is useful when using a compute shader that writes to specific mipmap levels, rather than relying on the automatic generation.
    560 		GenerateMipMaps = true;
    561 		
    562 		// A mask applied to the color output before it is written to the render target.
    563 		RenderTargetWriteMask = 0xF; // or ColorWriteEnable
    564 		
    565 		// Enable or disable gamma correction applied to the output.
    566 		SRGBWriteEnable = false;
    567 
    568 		// BlendEnable0 to BlendEnable7 allow to enable or disable color and alpha blending for the respective render target.
    569 		// Don't forget to also set "ClearRenderTargets" to "false" if you want to blend with existing data in a render target.
    570 		// BlendEnable and BlendEnable0 are aliases,
    571 		BlendEnable = false;
    572 
    573 		// The operator used for color and alpha blending.
    574 		// 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).
    575 		// Available values:
    576 		//   ADD, SUBTRACT, REVSUBTRACT, MIN, MAX
    577 		BlendOp = ADD;
    578 		BlendOpAlpha = ADD;
    579 
    580 		// The data source and optional pre-blend operation used for blending.
    581 		// 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).
    582 		// Available values:
    583 		//   ZERO, ONE,
    584 		//   SRCCOLOR, SRCALPHA, INVSRCCOLOR, INVSRCALPHA
    585 		//   DESTCOLOR, DESTALPHA, INVDESTCOLOR, INVDESTALPHA
    586 		SrcBlend = ONE;
    587 		SrcBlendAlpha = ONE;
    588 		DestBlend = ZERO;
    589 		DestBlendAlpha = ZERO;
    590 		
    591 		// Enable or disable the stencil test.
    592 		// The depth and stencil buffers are cleared before rendering each pass in a technique.
    593 		StencilEnable = false;
    594 
    595 		// The masks applied before reading from/writing to the stencil.
    596 		// Available values:
    597 		//   0-255
    598 		StencilReadMask = 0xFF; // or StencilMask
    599 		StencilWriteMask = 0xFF;
    600 		
    601 		// The function used for stencil testing.
    602 		// Available values:
    603 		//   NEVER, ALWAYS
    604 		//   EQUAL, NEQUAL or NOTEQUAL
    605 		//   LESS, GREATER, LEQUAL or LESSEQUAL, GEQUAL or GREATEREQUAL
    606 		StencilFunc = ALWAYS;
    607 
    608 		// The reference value used with the stencil function.
    609 		StencilRef = 0;
    610 		
    611 		// The operation  to  perform  on  the stencil  buffer when  the
    612 		// stencil  test passed/failed or stencil passed  but depth test
    613 		// failed.
    614 		// Available values:
    615 		//   KEEP, ZERO, REPLACE, INCR, INCRSAT, DECR, DECRSAT, INVERT
    616 		StencilPassOp = KEEP; // or StencilPass
    617 		StencilFailOp = KEEP; // or StencilFail
    618 		StencilDepthFailOp = KEEP; // or StencilZFail
    619 	}
    620 	pass p1
    621 	{
    622 		ComputeShader = ExampleCS1<64,8>;
    623 		DispatchSizeX = 20; // 20 * 64 threads total in X dimension
    624 		DispatchSizeY = 2;  //  2 *  8 threads total in Y dimension
    625 	}
    626 	pass p2
    627 	{
    628 		VertexShader = ExampleVS;
    629 		PixelShader = ExamplePS1;
    630 	}
    631 }
    632 ```