下面是一个简单的顶点和片段着色器组合,其中metal
表示64个相同的2D四边形。通过更改UV坐标在金属中发生意外的性能下降
vertex VertexOut vertexMain(uint k [[ vertex_id ]],
uint ii [[instance_id]],
device float2* tex [[buffer(2)]],
device float2* position [[buffer(1)]],
device float* state [[buffer(0)]]){
VertexOut output;
int i = 4*ii+1;
float2 pos = position[k];
pos *= float2(state[i+2],state[i+3]);
pos += float2(state[i],state[i+1]);
pos.x *= state[0];
output.position = float4(pos,0,1);
output.tex = tex[k]*float2(du,dv);
return output;
};
fragment float4 fragmentMain(VertexOut input [[stage_in]],
texture2d<float> texture [[texture(0)]],
sampler sam [[sampler(0)]]){
return texture.sample(sam, input.tex);
};
采样是使用归一化的坐标,以便du
和dv
的范围可以从0到1,并控制如何大纹理的剪辑的将被采样开始在左下角。
看来我对如何在金属中进行取样工作存在误解。无论du
和dv
是什么值,我都希望计算成本保持不变。但是,当我将du
和dv
增加到1时,帧频下降。我没有使用任何mipmapping,也没有更改屏幕上栅格化四边形的大小。线性滤波的影响更加剧烈,但最接近的滤波也会发生。在我看来,由于绘制到屏幕上的像素数量相同,因此GPU上的负载不应取决于du
和dv
。我错过了什么?
编辑:这是我的采样器和附色:
let samplerDescriptor = MTLSamplerDescriptor()
samplerDescriptor.normalizedCoordinates = true
samplerDescriptor.minFilter = .linear
samplerDescriptor.magFilter = .linear
let sampler = device.makeSamplerState(descriptor: samplerDescriptor)
let attachment = pipelineStateDescriptor.colorAttachments[0]
attachment?.isBlendingEnabled = true
attachment?.sourceRGBBlendFactor = .one
attachment?.destinationRGBBlendFactor = .oneMinusSourceAlpha
你能量化你经历多少帧频下降吗? – warrenm
从60到40线性采样。从最近的采样60到50。 – gloo
在哪个设备和操作系统版本? – warrenm