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