ReShadeFX for Beginners

No bullshit, just move along.

Recap
Vertex Shader:

Code that does math on every vertex

Pixel Shader:

Code that does math on every pixel

What is a Shader?

A shader is code that does math.

A shader is like a drawing a square. Here is how you draw a red square:

  1. You draw a dotted outline of the square.

  2. You connect the dotted outline of the square.

  3. You color red inside the square.

Your First Vertex Shader

 1// Vertex shader generating a triangle covering the entire screen.
 2// See also https://www.reddit.com/r/gamedev/comments/2j17wk/a_slightly_faster_bufferless_vertex_shader_trick/
 3
 4// Make a function that calculate on each vertex.
 5// PostProcessVS() outputs a triangle that is twice the screen's size.
 6void PostProcessVS
 7(
 8    in uint id : SV_VertexID, // Get "id" from CPU memory named "SV_VertexID"
 9    out float4 position : SV_Position, // Send "position" to GPU memory named "SV_Position"
10    out float2 texcoord : TEXCOORD // Send "texcoord" to GPU memory named "TEXCOORD"
11)
12{
13    /*
14        PART 1
15        ---
16        Use the vertex's ID to calculate its texture coordinates.
17        NOTE: Texture coordinates are 0-1
18        ---
19        ID 0 -> texcoord (0.0, 0.0)
20        ID 1 -> texcoord (0.0, 2.0)
21        ID 2 -> texcoord (2.0, 0.0)
22    */
23
24    // If the vertex's ID is 2, set the its texcoord's X position to 2.
25    // If the vertex's ID is not 2, set its texcoord's X position to 0.
26    texcoord.x = (id == 2) ? 2.0 : 0.0;
27
28    // If the vertex's ID is 1, set the its texcoord's Y position to 2.
29    // If the vertex's ID is not 1, set its texcoord's Y position to 0.
30    texcoord.y = (id == 1) ? 2.0 : 0.0;
31
32    /*
33        PART 2
34        ---
35        We stretch the triangle to be twice the size of the screen.
36        To do this, use the vertex's texture coordinates to calculate it's position in clip-space.
37
38        In clip-space, the values represent:
39            Bottom-left of screen: (-1.0, -1.0)
40            Bottom-right of screen: (1.0, -1.0)
41            Top-left of screen: (-1.0, 1.0)
42            Top-right of screen: (1.0, 1.0)
43        ---
44        texcoord (0.0, 0.0) -> position (-1.0, 1.0)
45        texcoord (0.0, 2.0) -> position (-1.0, 3.0)
46        texcoord (2.0, 0.0) -> position (3.0, 1.0)
47    */
48
49    position = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
50
51    /*
52        PART 3
53        ---
54        1. The GPU will "clip" fragments that have a position beyond -1 or 1.
55        2. The GPU will interpolate the "texcoord" and "position" data between vertices
56    */
57}

Your First Pixel Shader

 1// Make a function that calculate on each pixel.
 2// PostProcessPS() outputs a color on each of the triangle's pixel.
 3void PostProcessPS
 4(
 5    in float2 texcoord : TEXCOORD, // Get "texcoord" from GPU memory named "TEXCOORD"
 6    out float4 color : SV_Target // Send "color" to GPU memory named "SV_Target"
 7)
 8{
 9    /*
10        Use the texcoord's XY value to set the triangle's red and green value.
11            texcoord(1.0, 0.0) -> color(1.0, 0.0, 0.0, 1.0) -> all red
12            texcoord(0.0, 1.0) -> color(1.0, 0.0, 0.0, 1.0) -> all green
13            texcoord(1.0, 1.0) -> color(1.0, 1.0, 0.0, 1.0) -> mix of red and green
14    */
15    color.r = texcoord.x;
16    color.g = texcoord.y;
17    color.b = 0.0;
18    color.a = 1.0;
19}

Your First Technique

1technique ExampleShader
2{
3    pass
4    {
5        VertexShader = PostProcessVS;
6        PixelShader = PostProcessPS;
7    }
8}