首页 文章

通过改变紫外线坐标,金属意外受到影响

提问于
浏览
2

下面是 metal 中的一个简单的顶点和片段着色器组合,它渲染了64个相同的2D四边形 .

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

采样器使用标准化坐标,因此 dudv 的范围可以从0到1,并控制从左下角开始采样纹理剪辑的大小 .

似乎我对采样在金属中的工作方式存在误解 . 我期望计算成本保持不变,无论 dudv 持有什么值 . 但是,当我将 dudv 增加到1时,帧速率会下降 . 我没有使用任何mipmapping,也没有改变屏幕上光栅化的四边形的大小 . 线性滤波的影响更为显着,但最近的滤波也会发生 . 在我看来,由于绘制到屏幕的像素数相同,因此GPU上的负载不应该依赖于 dudv . 我错过了什么?

编辑:这是我的采样器和颜色附件:

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

1 回答

  • 0

    当您增加 dudv 时,您的四边形会显示更多纹理 . GPU往往具有纹理数据的小容量缓存,并且当您显示更多纹理时,您将丢弃并重新填充该缓存 .

    抖动纹理缓存将使用更多的内存带宽,这是非常有限的资源,通常纹理内存带宽不是瓶颈,但是因为你的片段着色器除了纹理提取之外几乎什么也没做,所以它是你的瓶颈并不奇怪 . 因此,改变UV对性能有影响并不奇怪 .

    令人惊讶的是,在这些功能非常强大的设备上,帧率降至60以下,当你所做的只是渲染64个四边形时(特别是iPad Pro是一个非常强大的设备) . 也就是说,如果所有64个四边形都覆盖了大部分屏幕,那么帧率下降可能是可以理解的 .

    为了提高性能,您需要减少需要由GPU铲除的纹理数据量 . 从32位纹理格式(8888)更改为16位(565/4444)或4位(PVRTC压缩纹理)会产生很大影响 .

    真正的大赢家可能是启用mipmapping . 假设 dudv 的值较高,你最终会最小化纹理,然后使用mipmapping将获得 huge 性能优势,并且作为一个额外的好处,你的纹理也会看起来更好(它会修复锯齿) . 纹理内存增加33%并不是一个糟糕的回报 .

相关问题