下面是一個簡單的頂點和片段着色器組合,其中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