flat_2d.metal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <metal_stdlib>
using namespace metal;
enum InputBufferIndexForVertexData {
InputBufferIndexForVertexData = 0,
InputBufferIndexForViewportSize = 1,
};
struct VertexData {
float2 position;
float4 color;
};
/// A type that stores the vertex shader's output and serves as an input to the
/// fragment shader.
struct RasterizerData
{
/// A 4D position in clip space from a vertex shader function.
///
/// The `[[position]]` attribute indicates that the position is the vertex's clip-space
/// position.
float4 position [[position]];
/// A color value, either for a vertex as an output from a vertex shader, or for a fragment as
/// input to a fragment shader.
///
/// As an input to a fragment shader, the rasterizer interpolates the color values between the
/// vertices for each fragment because this member doesn't have a special attribute.
float4 color;
};
/// A vertex shader that converts each input vertex from pixel coordinates to clip-space
/// coordinates.
///
/// The vertex shader doesn't modify the color values.
vertex RasterizerData vertex_shader(
uint vertex_id [[vertex_id]],
constant VertexData *vertex_data [[buffer(InputBufferIndexForVertexData)]],
constant uint2 *viewport_size_data [[buffer(InputBufferIndexForViewportSize)]]
) {
RasterizerData out;
// Retrieve the 2D position in pixel coordinates.
float2 pixel_space_position = vertex_data[vertex_id].position.xy;
// Retrieve the viewport's size by casting it to a 2D float value.
float2 viewport_size = (float2) *viewport_size_data;
// Convert the position in pixel coordinates to clip-space by dividing the pixel's coordinates
// by half the size of the viewport.
out.position.xy = pixel_space_position / (viewport_size / 2.0);
out.position.z = 0.0;
out.position.w = 1.0;
// Pass the input color directly to the rasterizer.
out.color = vertex_data[vertex_id].color;
return out;
}
/// A basic fragment shader that returns the color data from the rasterizer without modifying it.
fragment float4 fragment_shader(RasterizerData in [[stage_in]])
{
// Return the color the rasterizer interpolates between the vertices.
return in.color;
}