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:
You draw a dotted outline of the square.
You connect the dotted outline of the square.
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}