crosire-reshade-shaders

repository·slim·Indexed 22 days ago

https://github.com/crosire/reshade-shaders

A collection of post-processing shaders written in the ReShade FX shader language for use with the ReShade injector. Includes a comprehensive reference for the ReShade FX language, covering predefined macros, texture and sampler objects, storage objects, uniform variable UI annotations, runtime value sources, and HLSL-style structs, namespaces, and control flow.

Tokens
5.8K
Snippets
17
Records
20
Agent score
29%

What's inside crosire-reshade-shaders

  1. Define Structs and Namespaces

    slim

    ReShade FX supports standard HLSL-style structs and namespaces to organize data and prevent name collisions.

    Structs

    Used to define custom data types.

    struct MyStruct {
        int MyField1;
        float MyField3;
    };

    Namespaces

    Used to group functions and variables. Use the :: operator to resolve members.

    namespace MyNamespace {
        namespace MyNested {
            void DoSomething() {}
        }
        void DoSomething() {
            MyNested::DoSomething();
        }
    }
    struct MyStruct
    {
    	int MyField1, MyField2;
    	float MyField3;
    };
    
    namespace MyNamespace
    {
    	namespace MyNestedNamespace
    	{
    		void DoNothing()
    		{
    		}
    	}
    
    	void DoNothing()
    	{
    		MyNestedNamespace::DoNothing();
    	}
    }
  2. Define Techniques and Passes in ReShade FX

    slim

    An effect file can contain multiple techniques, each representing a full render pipeline. ReShade executes all enabled techniques in the order they are defined.

    A technique consists of one or more passes that execute sequentially. Each pass defines the render states and the shaders to be used.

    Technique Annotations

    You can use annotations within the technique declaration to control UI behavior and execution:

    • enabled = true/false: Set the default enabled state.
    • enabled_in_screenshot = true/false: Control if the technique is active during screenshots.
    • timeout = <ms>: Automatically toggle the technique off after a specified number of milliseconds (useful for one-time initialization).
    • hidden = true: Hide the technique from the ReShade UI.
    • ui_label = "Name": Provide a custom display name in the UI.
    • ui_tooltip = "Description": Provide a tooltip description for the UI.
    technique Example < ui_tooltip = "This is an example!"; enabled = true; >
    {
        pass p0
        {
            // Pass configuration goes here
        }
    }
  3. Prevent preprocessor defines from appearing in the ReShade UI

    slim

    ReShade interprets certain preprocessor defines as configurable UI options. To prevent a define from being displayed as a user-configurable setting in the ReShade menu, you can either:

    1. Prefix the define name with an underscore (e.g., _MY_DEFINE).
    2. Ensure the define name is shorter than 8 characters.
    #ifndef MY_PREPROCESSOR_DEFINE
    	#define MY_PREPROCESSOR_DEFINE 0
    #endif
  4. Install ReShade FX shaders

    slim

    To use the shaders from this repository in a game, follow these steps:

    1. Download the repository archive from GitHub.
    2. Extract the archive to a local folder.
    3. Launch your game and open the ReShade in-game menu.
    4. Navigate to the Settings tab.
    5. In the Effect Search Paths field, add the path to the extracted Shaders folder.
    6. In the Texture Search Paths field, add the path to the extracted Textures folder.
    7. Switch to the Home tab and click Reload to initialize the shaders.
  5. Customize Uniform Variable UI with Annotations

    slim

    Variables declared with the uniform qualifier are constant per pass and can be controlled via the ReShade UI. You can use annotations to customize how these variables appear and behave in the interface.

    UI Appearance Annotations

    • ui_type: Sets the widget type. Options: input, drag, slider, combo (for integers), radio (for integers), color (for vectors), or button (for booleans).
    • ui_min / ui_max: Defines the range (required for drag or slider).
    • ui_step: The increment/decrement value for buttons.
    • ui_items: A null-terminated list of strings for combo or radio types.
    • ui_label: The display name (defaults to variable name).
    • ui_tooltip: Hover text for descriptions.
    • ui_category: Groups variables under a headline (variables must be declared adjacently).
    • ui_category_closed: If true, the category is collapsed by default.
    • ui_category_toggle: If true, a boolean variable toggles the visibility of its category.
    • ui_text: Adds a text block above the widget.
    • ui_spacing: Adds space before the widget (multiplied by the value).
    • ui_units: Adds unit descriptions to sliders/drags.
    • hidden: Hides the variable from the UI.
    • noedit: Shows the variable but prevents user modification.
    • nosave: Prevents the value from being saved to presets.
    • noreset: Prevents the user from resetting the variable to its default.
    // Example of a customized slider
    uniform float MySlider < ui_type = "slider"; ui_min = 0.0; ui_max = 1.0; ui_label = "Intensity"; ui_tooltip = "Adjusts the effect strength"; >; 
  6. Perform atomic operations on integers

    slim

    ReShade FX supports atomic operations for thread-safe manipulation of integer values, either on local variables (inout int dest) or directly on storage objects (1D, 2D, or 3D). Supported operations include:

    • atomicAdd: Addition
    • atomicAnd: Bitwise AND
    • atomicOr: Bitwise OR
    • atomicXor: Bitwise XOR
    • atomicMin: Minimum
    • atomicMax: Maximum
    • atomicExchange: Exchange value
    • atomicCompareExchange: Compare and exchange
    // Example: Atomic add to a storage texture coordinate
    int result = atomicAdd(storage2D<int> s, int2 coords, int value);
  7. Declare and configure Sampler Objects

    slim

    Samplers act as the bridge between textures and shaders, defining how data is read from a texture. A single texture can be used by multiple samplers with different settings.

    Key Properties

    • Texture: The texture object to be sampled.
    • AddressU, AddressV, AddressW: Boundary handling methods (CLAMP, MIRROR, WRAP, REPEAT, BORDER).
    • MagFilter, MinFilter, MipFilter: Filtering types (POINT, LINEAR, ANISOTROPIC).
    • MinLOD, MaxLOD: Mipmap level range.
    • MipLODBias: Offset applied to the calculated mipmap level.
    • SRGBTexture: Boolean to enable/disable conversion to linear colors when sampling.
    sampler2D samplerColor
    {
    	Texture = texColorBuffer;
    	AddressU = CLAMP;
    	AddressV = CLAMP;
    	AddressW = CLAMP;
    	MagFilter = LINEAR;
    	MinFilter = LINEAR;
    	MipFilter = LINEAR;
    	MinLOD = 0.0f;
    	MaxLOD = 1000.0f;
    	MipLODBias = 0.0f;
    	SRGBTexture = false;
    };
  8. Implement User Functions and Control Flow

    slim

    User functions can be defined with specific attributes and parameter qualifiers to control how they interact with the shader pipeline.

    Function Attributes

    • [numthreads(X, Y, Z)]: Specifies local thread group size for compute shaders.
    • [shader("vertex")], [shader("pixel")], [shader("compute")]: Specifies the shader stage.

    Parameter Qualifiers

    • in: Input parameter (default). The function expects this to be provided.
    • out: Output parameter. The function fills this value for the caller.
    • inout: Both input and output. The function uses the provided value and updates it.

    Flow Control and Attributes

    Standard HLSL flow control is supported with optional optimization attributes:

    • if ([condition]) / else: Use [flatten] or [branch].
    • switch ([expression]): Use [flatten], [branch], [forcecase], or [call].
    • for / while / do-while: Use [unroll], [loop], or [fastopt].
    • break, continue, return: Standard loop/function control.
    • discard: Aborts rendering of the current pixel (Pixel shaders only).
    [shader("pixel")]
    void ExamplePS0(float4 pos : SV_Position, float2 texcoord : TEXCOORD0, out float4 color : SV_Target)
    {
    	color = tex2D(samplerColor, texcoord);
    }
  9. Declare and configure Texture Objects

    slim

    Textures are multidimensional data containers. They are created at runtime based on their definition.

    Annotations

    • Loading from file: Use < source = "path/to/image.bmp"; > to load images. Supported formats: .bmp, .png, .jpg, .tga, .cube, .dds.
    • Memory Pooling: Use < pooled = true; > to allow ReShade to reuse memory for textures with identical dimensions and formats across different effect files.

    Semantics (Special Textures)

    You can request specific system textures using semantics:

    • texture2D texColor : COLOR; (Read-only backbuffer contents)
    • texture2D texDepth : DEPTH; (Read-only game depth information)

    Configuration Properties

    When defining a texture block, you can specify:

    • Width, Height, Depth (Dimensions)
    • MipLevels (Number of mipmaps, default: 1)
    • Format (Internal format, e.g., RGBA8, R16F, R32I, R11G11B10F, etc.)
    texture2D texColorBuffer : COLOR;
    texture2D texDepthBuffer : DEPTH;
    
    texture2D texTarget
    {
    	Width = BUFFER_WIDTH / 2;
    	Height = BUFFER_HEIGHT / 2;
    	Depth = 1;
    	MipLevels = 1;
    	Format = RGBA8;
    };
    
    texture3D texIntegerVolume
    {
    	Width = 10;
    	Height = 10;
    	Depth = 10;
    	Format = R32I;
    };
  10. Gather neighboring pixel components with tex2Dgather

    slim

    The tex2Dgather[R|G|B|A] functions allow you to gather the specified component from the four neighboring pixels around the given coordinates. This is useful for high-performance neighborhood operations.

    // Example: Gathering the Red component
    float4 result = tex2DgatherR(sampler2D s, float2 coords);
    
    /* The return value is effectively:
    float4(tex2Dfetch(s, coords * tex2Dsize(s) + int2(0, 1)).comp,
           tex2Dfetch(s, coords * tex2Dsize(s) + int2(1, 1)).comp,
           tex2Dfetch(s, coords * tex2Dsize(s) + int2(1, 0)).comp,
           tex2Dfetch(s, coords * tex2Dsize(s) + int2(0, 0)).comp)
    */
  11. Synchronize threads and memory in ReShade FX

    slim

    Use the following functions to manage execution flow and memory visibility:

    • barrier(): Synchronizes all threads within a single thread group.
    • groupMemoryBarrier(): Waits for all memory accesses within the thread group to complete.
    • memoryBarrier(): Waits for all memory accesses (including texture and storage operations) to complete globally.