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}