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
| //
| // Shaders.metal
| // LiveProject
| //
| // Created by 倪路朋 on 6/27/25.
| //
|
| #include <metal_stdlib>
| using namespace metal;
|
| struct VertexOut {
| float4 position [[position]];
| float2 texCoord;
| };
|
| struct Uniforms {
| float2 textureSize;
| float2 drawableSize;
| };
|
| vertex VertexOut vertex_main(uint vertexID [[vertex_id]],
| constant Uniforms& uniforms [[buffer(0)]]) {
| float4 positions[4] = {
| float4(-1.0, -1.0, 0, 1),
| float4( 1.0, -1.0, 0, 1),
| float4(-1.0, 1.0, 0, 1),
| float4( 1.0, 1.0, 0, 1)
| };
|
| float2 texCoords[4] = {
| float2(0.0, 1.0),
| float2(1.0, 1.0),
| float2(0.0, 0.0),
| float2(1.0, 0.0)
| };
|
| float texAspect = uniforms.textureSize.x / uniforms.textureSize.y;
| float viewAspect = uniforms.drawableSize.x / uniforms.drawableSize.y;
|
| float scaleX = 1.0;
| float scaleY = 1.0;
|
| if (texAspect > viewAspect) {
| scaleY = viewAspect / texAspect;
| } else {
| scaleX = texAspect / viewAspect;
| }
|
| VertexOut out;
| float4 pos = positions[vertexID];
| pos.x *= scaleX;
| pos.y *= scaleY;
|
| out.position = pos;
| out.texCoord = texCoords[vertexID];
| return out;
| }
|
| fragment float4 fragment_main(VertexOut in [[stage_in]],
| texture2d<half> tex [[texture(0)]]) {
| constexpr sampler s(filter::linear);
| return float4(tex.sample(s, in.texCoord));
| }
|
|