我正在构建一个 iOS 应用程序,在其中使用 Metal 着色器将灰度滤镜应用于实时摄像机源。灰度效果效果很好,但是当我应用它时,相机预览会垂直拉伸。下面是我的 Metal 着色器和相机预览设置的代码。
着色器.金属
#include <metal_stdlib>
using namespace metal;
typedef struct {
float4 renderedCoordinate [[position]];
float2 textureCoordinate;
} TextureMappingVertex;
vertex TextureMappingVertex mapTexture(unsigned int vertex_id [[vertex_id]]) {
float4x4 renderedCoordinates = float4x4(
float4( -1.0, -1.0, 0.0, 1.0 ),
float4( 1.0, -1.0, 0.0, 1.0 ),
float4( -1.0, 1.0, 0.0, 1.0 ),
float4( 1.0, 1.0, 0.0, 1.0 )
);
float4x2 textureCoordinates = float4x2(
float2( 0.0, 1.0 ),
float2( 1.0, 1.0 ),
float2( 0.0, 0.0 ),
float2( 1.0, 0.0 )
);
TextureMappingVertex outVertex;
outVertex.renderedCoordinate = renderedCoordinates[vertex_id];
outVertex.textureCoordinate = textureCoordinates[vertex_id];
return outVertex;
}
fragment half4 displayTexture(TextureMappingVertex mappingVertex [[stage_in]],
texture2d<float, access::sample> texture [[texture(0)]]) {
constexpr sampler s(address::clamp_to_edge, filter::linear);
float4 color = texture.sample(s, mappingVertex.textureCoordinate);
float grayscale = (color.r + color.g + color.b) / 3.0;
return half4(grayscale, grayscale, grayscale, color.a);
}
问题:
附加信息:
目标:
您可以根据屏幕高度和屏幕宽度设置float4x2纹理坐标的大小 只需将其传递给着色器顶点函数,然后根据屏幕的纵横比更改 float4x2 纹理坐标
float screenWidth = screenParams.screenWidth;
float screenHeight = screenParams.screenHeight;
float screenAspectRatio = (screenWidth / screenHeight) + 0.3;
float2 topLeft = float2(0.0, 1.0);
float2 topRight = float2(1.0, 1.0);
float2 bottomLeft = float2(0.0, 0.0);
float2 bottomRight = float2(1.0, 0.0);
topLeft.x *= screenAspectRatio;
topRight.x *= screenAspectRatio;
bottomLeft.x *= screenAspectRatio;
bottomRight.x *= screenAspectRatio;
float4x2 textureCoordinates = float4x2(topLeft, topRight, bottomLeft, bottomRight);
此后就不会再拉伸了