Echo Writes Code

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;
}